* @brief 文字をメモリに書き込む
*
* @param *str アドレスを表す文字列。リテラル/10進定数/16進定数/アドレス定数が含まれる
- * @param literal リテラルの場合はtrue
* @param pass アセンブラが何回目かを表す数
*/
-void writestr(const char *str, bool literal, PASS pass);
+void writestr(const char *str, PASS pass);
/**
* @brief DC命令を書込
{ 122, "cannot create hash table" },
{ 124, "more than one character in literal" },
{ 125, "not GR in operand x" },
+ { 128, "syntax error in literal" },
};
/**
{
assert(str[0] == '=');
str++;
- WORD val = (str[0] == '\'') ? (WORD)str[1] : nh2word(str);
+ WORD val = 0;
WORD adr = 0;
+
+ if(str[0] == '\'') {
+ if(str[1] == '\'' && str[2] != '\'') {
+ setcerr(128, str); /* syntax error in literal */
+ return 0;
+ } else if((str[1] == '\'' && str[2] == '\'' && str[3] == '\0') || str[2] == '\0' ) {
+ setcerr(123, str); /* unclosed quote */
+ return 0;
+ } else if((str[1] == '\'' && str[2] == '\'' && str[3] != '\'') || str[2] != '\'') {
+ setcerr(124, str); /* more than one character in literal */
+ return 0;
+ }
+ val = (WORD)str[1];
+ } else {
+ val = nh2word(str);
+ }
/* PASS FIRSTでは、lptrがまだ確定していない(ENDで初めて確定する)ため、
* 重複排除の登録・検索は行わず、従来通りダミーの書き込みのみ行う */
if(pass == FIRST) {
}
}
-void writestr(const char *str, bool literal, PASS pass)
+void writestr(const char *str, PASS pass)
{
assert(str[0] == '\'');
- bool lw = false;
- /* 「'」の場合、1文字スキップし、次の文字が「'」でなければ正常終了 */
+ /* 「'」1文字スキップし、次の文字が「'」でなければ正常終了 */
for(int i = 1; str[i] != '\'' || str[++i] == '\''; i++) {
/* 「'」が閉じないまま文字列が終了した場合はエラー */
if(!str[i]) {
setcerr(123, str); /* unclosed quote */
break;
}
- if(literal == true && lw == true) {
- setcerr(124, str); /* more than one character in literal */
- break;
- }
- /*リテラルの場合はリテラル領域に書込 */
- if(literal == true) {
- writememory(str[i], (asptr->lptr)++, pass);
- lw = true;
- } else {
- writememory(str[i], (asptr->ptr)++, pass);
- }
+ writememory(str[i], (asptr->ptr)++, pass);
}
}
WORD adr = 0;
if(*str == '\'') {
- writestr(str, false, pass);
+ writestr(str, pass);
} else {
if(str[0] == '#' || isdigit(str[0]) || str[0] == '-') {
adr = nh2word(str);
goto asfin;
}
}
- if(pass == FIRST && asmode.label == true) {
- fprintf(stdout, "\nLabel::::\n");
- printlabel();
- if(asmode.onlylabel == true) {
- break;
+ if(asmode.label == true) {
+ if(pass == FIRST) {
+ printlabel();
+ if(asmode.onlylabel == true) {
+ break;
+ }
+ }
+ if(pass == SECOND) {
+ printliteral();
}
}
}
*/
int compare_adr(const void *a, const void *b);
+/**
+ * 定義されているラベルまたはリテラルの一覧を表示する
+ *
+ * @return ラベルが同一の場合は0、異なる場合は0以外
+ *
+ * @param literal リテラルの場合はtrue、それ以外はfalse
+ */
+void printlabel_full(bool literal);
+
/**
* @brief ラベル数
*/
return (**(LABELARRAY **)a).adr - (**(LABELARRAY **)b).adr;
}
+void printlabel_full(bool literal)
+{
+ int s = 0;
+ LABELTAB *p = NULL;
+ LABELARRAY **l = NULL;
+
+ l = calloc_chk(labelcnt, sizeof(LABELARRAY *), "printlabel_full");
+ for(int i = 0; i < LABELTABSIZE; i++) {
+ for(p = labels[i]; p != NULL; p = p->next) {
+ assert(p->label->label != NULL);
+ if((literal == true && p->label->label[0] == '=') || (literal == false && p->label->label[0] != '=')) {
+ l[s++] = p->label;
+ }
+ }
+ }
+ if(s > 0) {
+ qsort(l, s, sizeof(*l), compare_adr);
+ fprintf(stdout, "\n%s::::\n", (literal == true) ? "Literal" : "Label");
+ for(int i = 0; i < s; i++) {
+ if(l[i]->prog[0]) {
+ fprintf(stdout, "%s.", l[i]->prog);
+ }
+ fprintf(stdout, "%s ---> #%04X\n", l[i]->label, l[i]->adr);
+ }
+ if(literal == true) {
+ fprintf(stdout, "\n");
+ }
+ }
+ FREE(l);
+}
+
/* assemble.hで定義された関数群 */
void addcerrlist_label()
{
void printlabel()
{
- int s = 0;
- LABELTAB *p = NULL;
- LABELARRAY **l = {NULL};
+ printlabel_full(false);
+}
- l = calloc_chk(labelcnt, sizeof(LABELARRAY **), "labels");
- for(int i = 0; i < LABELTABSIZE; i++) {
- for(p = labels[i]; p != NULL; p = p->next) {
- assert(p->label != NULL);
- l[s++] = p->label;
- }
- }
- qsort(l, s, sizeof(*l), compare_adr);
- for(int i = 0; i < s; i++) {
- if(l[i]->prog[0]) {
- fprintf(stdout, "%s.", l[i]->prog);
- }
- fprintf(stdout, "%s ---> #%04X\n", l[i]->label, l[i]->adr);
- }
- FREE(l);
+void printliteral()
+{
+ printlabel_full(true);
}
void freelabel()