diff options
-rw-r--r-- | asmmon.c | 178 | ||||
-rw-r--r-- | asmmon.h | 17 | ||||
-rw-r--r-- | assemble.c | 12 | ||||
-rw-r--r-- | lexer.c | 88 |
4 files changed, 163 insertions, 132 deletions
@@ -112,19 +112,31 @@ char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg) { } +static inline uint8_t isopdone(token *t) { + switch (t->id) { + case TOK_OF : + case TOK_HEX : + case TOK_BIN : + case TOK_DEC : + case TOK_CHAR: + case TOK_EXPR: return 0; + default : return 1; + } +} + void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint64_t address, uint8_t dbg) { - line *s = (!all) ? find_line(start, dbg) : lines ; - line *e = (!all) ? find_line( end, dbg) : last_line; + line *s = (!all) ? find_line(start, dbg) : lines; + line *e = (!all) ? find_line( end, dbg) : NULL; uint8_t j = 0; uint8_t flags = 0; uint8_t isstr; uint8_t iscom; uint8_t iscm = 0; - uint8_t fall = 0; uint8_t bitnum; uint8_t opsize = 0; uint8_t spaces; uint8_t tabs; + char mne_lower[4]; char ch[6]; do { @@ -132,29 +144,48 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u token *t = s->tok; uint8_t am = 0xFF; uint8_t rs = 0xFF; + uint8_t am_done = 1; + uint8_t op_done = 1; + uint16_t bline = s->bline; + for (; bline; bline--) { + putchar('\n'); + } if (dbg) { printf("list(): "); } if (ln) { - printf("%u\t\t", s->linenum); + printf("%5u\t\t", s->linenum); } else if (addr) { printf("$%"PRIX64":\t\t", s->addr); } - spaces = s->sspace; - tabs = s->stab; - while (spaces || tabs) { - if (spaces) { - putchar(' '); - spaces--; + while (t) { + if (am != 0xFF && op_done && t->id != TOK_RS) { + switch (am) { + case IMM : putchar('#'); am_done = 1; break; + case IND : + case INDX: + case INDY: putchar('('); am_done = 0; break; + case ZMY : + case ZMX : am_done = 0; break; + case BREG: putchar('b'); am_done = 1; break; + } + am = (am_done) ? 0xFF : am; } - if (tabs) { - putchar('\t'); - tabs--; + spaces = t->space; + tabs = t->tab; + while (spaces || tabs) { + if (spaces) { + putchar(' '); + spaces--; + } + if (tabs) { + putchar('\t'); + tabs--; + } } - } - while (t && t->id != TOK_COMMENT) { switch (t->id) { - case TOK_DIR : printf(".%s ", dir_t[t->type] ); break; + case TOK_DIR : printf(".%s", dir_t[t->type]); break; + case TOK_RS : printf("%s", rs_t[t->type]); break; case TOK_OPCODE: for (; j < 3; j++) { mne_lower[j] = tolower(mne[t->byte][j]); @@ -163,19 +194,6 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u j = 0; printf("%s", mne_lower); am = t->type; - if (t->next && t->next->id == TOK_RS) { - t = t->next; - rs = t->type; - printf("%s", rs_t[t->type]); - } - putchar(' '); - switch (am) { - case IMM : putchar('#'); break; - case IND : - case INDX: - case INDY: putchar('('); break; - case BREG: putchar('b'); break; - } break; case TOK_OF: switch (t->type) { @@ -191,18 +209,16 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u printf("%s", (t->sym) ? t->sym->name : "unknown"); if (t->id == TOK_LABEL) { putchar(':'); - } else if (t == s->tok && t->id == TOK_SYM) { - printf(" = "); } break; case TOK_HEX: if (t->id == TOK_HEX) { - printf("$%02"PRIX64, t->qword); + printf("$%0*"PRIX64, t->digits, t->qword); } else if (t->id == TOK_DEC) { - case TOK_DEC: printf( "%"PRIu64, t->qword); + case TOK_DEC: printf( "%0*"PRIu64, t->digits, t->qword); } else if (t->id == TOK_BIN) { - case TOK_BIN: if (rs != 0xFF) { - bitnum = (rs << 3); + case TOK_BIN: if (t->digits) { + bitnum = t->digits; } else { opsize = 1; opsize = (t->qword > 0x000000FF) ? 2 : opsize; @@ -238,15 +254,14 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u if (t->next) { switch (t->next->id) { case TOK_STRING: - case TOK_HEX: - case TOK_BIN: - case TOK_DEC: - case TOK_CHAR: - printf(", "); - break; + case TOK_HEX : + case TOK_BIN : + case TOK_DEC : + case TOK_CHAR : putchar(','); break; } } break; + case TOK_COMMENT: printf(";%s", (t->str) ? t->str : ""); break; case TOK_EXPR: switch (t->type) { case EXPR_PLUS : putchar('+'); break; @@ -258,50 +273,49 @@ void list(uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, u case EXPR_OR : putchar('|'); break; } break; + } - t = t->next; - } - if (am != 0xFF) { - if (fall) { - fall = 0; - } - switch (am) { - case INDX: - case ZMX: - printf(", x"); - if (am == ZMX) { - break; + if (t->subspace || t->subtab) { + spaces = t->subspace; + tabs = t->subtab; + while (spaces || tabs) { + if (spaces) { + putchar(' '); + spaces--; } - fall = 1; - /* Falls Through. */ - case INDY: - fall = !fall; - /* Falls Through. */ - case IND: - putchar(')'); - if (!fall) { - break; + if (tabs) { + putchar('\t'); + tabs--; } - /* Falls Through. */ - case ZMY: - printf(", y"); - break; + } } - } - spaces = s->espace; - tabs = s->etab; - while (spaces || tabs) { - if (spaces) { - putchar(' '); - spaces--; + if (t->next && !isopdone(t)) { + op_done = isopdone(t->next); } - if (tabs) { - putchar('\t'); - tabs--; + if (am != 0xFF && !am_done && op_done) { + switch (am) { + case INDX: + case ZMX : + printf(", x"); + if (am == ZMX) { + break; + } + /* Falls Through. */ + case INDY: + case IND : + putchar(')'); + if (am == IND) { + break; + } + case ZMY : printf(", y"); break; + } + am = 0xFF; + am_done = 1; } - } - if (t && t->id == TOK_COMMENT) { - printf(";%s", (t->str) ? t->str : ""); + if (t == s->tok && t->id == TOK_SYM) { + putchar('='); + } + t = t->next; } puts(""); s = s->next; @@ -339,6 +353,7 @@ int asmmon(const char *fn) { uint8_t dbg = 0; uint8_t isinclude = 0; uint16_t tmp_lineidx = 0; + uint16_t bline = 0; while (!done) { char *cmd; char *arg = malloc(sizeof(char *)*128); @@ -534,9 +549,12 @@ int asmmon(const char *fn) { case 0xFF: break; default: - address = lex(lex_line, address, dbg); + address = lex(lex_line, address, bline, dbg); + bline = 0; break; } + } else if (lex_line[0] == '\n') { + bline++; } } free(path); @@ -16,6 +16,14 @@ struct tok { uint8_t id; /* Token ID. */ uint8_t type; /* Token type ID. */ + uint8_t tab; /* Number of tabs. */ + uint8_t space; /* Number of spaces. */ + + uint8_t subtab; /* Number of sub-token tabs. */ + uint8_t subspace; /* Number of sub-token spaces. */ + + uint8_t digits; /* Number of digits. */ + /* Token value(s). */ union { symbol *sym; @@ -31,12 +39,9 @@ struct ln { line *next; /* Pointer to the next line. */ token *tok; /* The token(s) for this line. */ uint16_t count; /* Total tokens for this line. */ + uint16_t bline; /* Number of blank lines. */ uint32_t linenum; /* Line number. */ uint64_t addr; /* The address of this line. */ - uint8_t stab; /* Number of starting tabs. */ - uint8_t sspace; /* Number of starting spaces. */ - uint8_t etab; /* Number of ending tabs. */ - uint8_t espace; /* Number of ending spaces. */ }; @@ -536,9 +541,9 @@ extern uint8_t defined; extern uint8_t isfixup; extern line *find_line(uint32_t ln, uint8_t dbg); -extern uint64_t lex(char *str, uint64_t address, uint8_t dbg); +extern uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg); extern uint64_t parse_tokens(token *tm, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg); -extern token *make_token(uint8_t id, uint8_t type, uint64_t value, char *str, symbol *sym); +extern token *make_token(uint8_t id, uint8_t type, uint8_t space, uint8_t tab, uint64_t value, char *str, symbol *s); extern void assemble(line *ln, bytecount *bc, uint8_t dbg); extern void cleanup(); @@ -456,11 +456,21 @@ uint64_t parse_tokens(token *t, bytecount *bc, uint8_t isasm, uint64_t address, return address; } -token *make_token(uint8_t id, uint8_t type, uint64_t value, char *str, symbol *s) { +token *make_token(uint8_t id, uint8_t type, uint8_t space, uint8_t tab, uint64_t value, char *str, symbol *s) { token *new_tok = malloc(sizeof(token)); (last_tok) ? (last_tok->next = new_tok) : (tokens = new_tok); + new_tok->id = id; new_tok->type = type; + + new_tok->tab = tab; + new_tok->space = space; + + new_tok->subtab = 0; + new_tok->subspace = 0; + + new_tok->digits = 0; + if (s) { new_tok->sym = s; } else if (str[0]) { @@ -118,22 +118,27 @@ uint16_t reslv_fixups(uint8_t dbg) { uint16_t get_comment(const char *com, uint8_t dbg) { uint16_t i = 0; - uint8_t iscom = 0; - for (; i < comidx; i++) { - if (comment[i] == NULL || iscom) { + for (; comment[i] && i < comidx; i++) { + if (com[0] == comment[i][0] && !strcmp(com, comment[i])) { break; - } else if (com[0] == comment[i][0]) { - iscom = !strcmp(com, comment[i]); } } - if (comment[i] == NULL || i == comidx) { + if (comment[i] == NULL) { if (dbg) { printf("get_comment(): oof, the index $%04X is NULL.\n", i); printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", com); } - return 0xFFFF; + size_t size = strlen(com)+1; + comment[comidx] = malloc(size); + memcpy(comment[comidx], com, size); + return comidx++; + } if (dbg) { + if (strcmp(com, comment[i])) { + printf("get_comment(): oof, the comment \"%s\" is somehow not in the comment table, even though it should be at index $%04X.\n", com, i); + } + printf("get_comment(): The return value of strcmp(com, comment[$%04X]) is %i.\n", i, strcmp(com, comment[i])); printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", com, i); } return i; @@ -182,7 +187,7 @@ line *find_line(uint32_t ln, uint8_t dbg) { return l; } -uint64_t lex(char *str, uint64_t address, uint8_t dbg) { +uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { char sym[0x100]; uint16_t i = 0; uint16_t j = 0; @@ -212,9 +217,11 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { uint8_t space = 0; uint8_t tab = 0; - uint8_t isstart = 1; uint8_t fall = 0; uint8_t done = 0; + + + /*uint8_t is_newcom = 0;*/ line *l = NULL; token *st = NULL; token *t = NULL; @@ -241,10 +248,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { l->tok = NULL; l->next = NULL; l->count = 0; - l->espace = 0; - l->etab = 0; - l->sspace = 0; - l->stab = 0; + l->bline = bline; last_line = l; } @@ -263,13 +267,6 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { if (dbg) { printf("lex(): tab: %u, space: %u\n", tab, space); } - if (isstart) { - l->stab = tab; - l->sspace = space; - if (dbg) { - printf("lex(): starting tabs: %u, starting spaces: %u\n", l->stab, l->sspace); - } - } if (isdelm(str[i], dbg) == 16) { for (; isdelm(str[i], dbg) == 16; i++); } @@ -306,7 +303,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } } l->count++; - t = make_token(lex_type, k, 0, "", NULL); + t = make_token(lex_type, k, space, tab, 0, "", NULL); } else { lex_type = TOK_RS; switch (tolower(lexeme[j-1])) { @@ -324,7 +321,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { break; } l->count++; - t = make_token(lex_type, rs, 0, "", NULL); + t = make_token(lex_type, rs, space, tab, 0, "", NULL); isop = 0; } break; @@ -353,7 +350,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } lex_type = TOK_STRING; l->count++; - t = make_token(lex_type, 0, 0, string[strid], NULL); + t = make_token(lex_type, 0, space, tab, 0, string[strid], NULL); break; case PTOK_DOLLAR: case PTOK_PERCENT: @@ -385,7 +382,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } } l->count++; - t = make_token(lex_type, 0, value, "", NULL); + t = make_token(lex_type, 0, space, tab, value, "", NULL); + t->digits = (lt->id != TOK_SYM) ? j : 0; break; case PTOK_SQUOTE: i++; @@ -413,7 +411,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } lex_type = TOK_CHAR; l->count++; - t = make_token(lex_type, 0, ch, "", NULL); + t = make_token(lex_type, 0, space, tab, ch, "", NULL); break; case PTOK_LBRACK: case PTOK_HASH : @@ -421,6 +419,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lex_type = (ptok == PTOK_LBRACK) ? TOK_IND : TOK_IMM; memset(lexeme, 0, strlen(lexeme)+1); lexeme[j++] = str[i]; + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); break; case PTOK_PLUS: case PTOK_MINUS: @@ -436,7 +436,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { case PTOK_LT : value = (get_ptok(str[i+1], dbg) == PTOK_LT) ? (EXPR_LSHFT) : (EXPR_HIGH); break; } l->count++; - t = make_token(lex_type, value, 0, "", NULL); + t = make_token(lex_type, value, space, tab, 0, "", NULL); memset(lexeme, 0, strlen(lexeme)+1); lexeme[j++] = str[i]; if (value == EXPR_LSHFT || value == EXPR_RSHFT) { @@ -448,6 +448,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lex_type = TOK_SYM; memset(lexeme, 0, strlen(lexeme)+1); lexeme[j] = str[i]; + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); break; case PTOK_RBRACK: i++; @@ -471,6 +473,8 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j+2] = '\0'; lex_type = TOK_BREG; l->tok->type = BREG; + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); break; case PTOK_X: case PTOK_Y: @@ -499,13 +503,17 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { case PTOK_P: of = 2; break; } lex_type = TOK_OF; - t = make_token(lex_type, of, 0, "", NULL); + t = make_token(lex_type, of, space, tab, 0, "", NULL); break; case PTOK_AT: memset(lexeme, 0, strlen(lexeme)+1); lexeme[j] = '@'; islocal = 1; lex_type = TOK_LOCAL; + if (lt || t) { + (t) ? (t->subspace = space) : (lt->subspace = space); + (t) ? (t->subtab = tab) : (lt->subtab = tab); + } break; case PTOK_COLON: i++; @@ -547,18 +555,18 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lexeme[j] = '\0'; i += j; comid = get_comment(lexeme, dbg); + /*is_newcom = (comid == 0xFFFF); if (comid == 0xFFFF) { - /*if (line != lineidx && l[line].com != 0xFFFF) { + if (line != lineidx && l[line].com != 0xFFFF) { comid = l[line].com; } else { comid = comidx; - }*/ + } comid = comidx; comment[comid] = malloc(j+1); memcpy(comment[comid], lexeme, j+1); comidx++; - } else { - } + }*/ if (dbg) { printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]); } @@ -566,9 +574,9 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lex_type = TOK_COMMENT; l->count++; if (j) { - t = make_token(lex_type, 0, 0, comment[comid], NULL); + t = make_token(lex_type, 0, space, tab, 0, comment[comid], NULL); } else { - t = make_token(lex_type, 0, 0, "" , NULL); + t = make_token(lex_type, 0, space, tab, 0, "" , NULL); } break; @@ -586,7 +594,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { lex_type = TOK_OPCODE; isop = 1; l->count++; - t = make_token(lex_type, 0xFF, k, "", NULL); + t = make_token(lex_type, 0xFF, space, tab, k, "", NULL); break; } } @@ -600,7 +608,7 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { } lex_type = TOK_SYM; l->count++; - t = make_token(lex_type, islocal, 0, "", NULL); + t = make_token(lex_type, islocal, space, tab, 0, "", NULL); memcpy(sym, lexeme, j+1); if (dbg) { printf("lex(): spaces: %u\n", spaces); @@ -622,22 +630,12 @@ uint64_t lex(char *str, uint64_t address, uint8_t dbg) { if (dbg) { printf("lex(): lexeme: %s, lex_type: %s\n", lexeme, (lex_type != 0xFF) ? lex_tok[lex_type] : "TOK_NONE"); } - isstart = 0; j = 0; if (lex_type == TOK_OPCODE && !isop) { j = 0; } else if (lex_type == TOK_EXPR || !isdelm2(str[i], dbg)) { i++; } - if (lex_type == TOK_COMMENT) { - if (!isstart) { - l->etab = tab; - l->espace = space; - if (dbg) { - printf("lex(): ending tabs: %u, ending spaces: %u\n", l->etab, l->espace); - } - } - } switch (lex_type) { default: lex_type = 0xFF; |