summaryrefslogtreecommitdiff
path: root/lexer.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
commitc5150ee31f07208422f1435de9b35a0d0168cbb5 (patch)
tree78150bf0339cf81401c00973f96c94a3c231015e /lexer.c
parent59dc46ca8fe1eb6f98abb98fe8579aeaedd2ff15 (diff)
Completely changed the assembler.
It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller.
Diffstat (limited to 'lexer.c')
-rw-r--r--lexer.c885
1 files changed, 885 insertions, 0 deletions
diff --git a/lexer.c b/lexer.c
new file mode 100644
index 0000000..47aea24
--- /dev/null
+++ b/lexer.c
@@ -0,0 +1,885 @@
+#include "asmmon.h"
+
+struct symbol *symbols = 0;
+struct fixup *fixups = 0;
+
+struct symbol *mksymbol(const char *name, uint64_t val, uint8_t def, uint8_t useid, uint16_t id, uint8_t dbg) {
+ struct symbol *s;
+ uint16_t i = 0;
+ uint8_t flag;
+ for (s = symbols; s; s = s->nxt) {
+ if (useid) {
+ flag = id == s->id;
+ } else {
+ flag = !strcmp(name, s->name);
+ }
+ if (flag) {
+ if (def) {
+ if (s->def) {
+ if (dbg) {
+ printf("mksymbol(): oof, you cannot redefine the symbol: %s\n", name);
+ }
+ defined = 1;
+ } else {
+ defined = 0;
+ }
+ s->def = def;
+ s->val = val;
+ if (dbg) {
+ printf("mksymbol(): def: %u, val: $%016llX, name: %s\n", def, val, name);
+ }
+ }
+ return s;
+ }
+ i++;
+ }
+ s = malloc(sizeof(*s) + strlen(name));
+ s->def = def;
+ s->val = val;
+ strcpy(s->name, name);
+ s->nxt = symbols;
+ s->id = i;
+ symbols = s;
+ defined = 0;
+ if (dbg) {
+ printf("mksymbol(): def: %u, val: $%016llX, name: %s, id: $%04X\n", def, val, name, i);
+ }
+ return s;
+}
+
+uint64_t use_symbol(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, useid, id, dbg);
+ val++;
+ if (s->def) {
+ return s->val;
+ } else {
+ if (dbg) {
+ printf("use_symbol(): ");
+ printf("oof, symbol ");
+ if (useid) {
+ printf("id $%04X, ", id);
+ } else {
+ printf("%s, ", name);
+ }
+ puts("does not exist, yet.");
+ }
+ return val-1;
+ }
+}
+
+uint8_t set_symval(const char *name, uint16_t id, uint64_t val, uint8_t useid, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, useid, id, dbg);
+ if (s->def) {
+ s->val = val;
+ return 1;
+ } else {
+ if (dbg) {
+ printf("set_symval(): ");
+ printf("oof, symbol ");
+ if (useid) {
+ printf("id $%04X, ", id);
+ } else {
+ printf("%s, ", name);
+ }
+ puts("does not exist, yet.");
+ }
+ return 0;
+ }
+}
+
+char *get_symname(uint16_t id, uint8_t dbg) {
+ struct symbol *s = mksymbol("", 0, 0, 1, id, dbg);
+ if (s->def) {
+ return s->name;
+ } else {
+ if (dbg) {
+ printf("get_symname(): oof, symbol id $%04X, has not been defined, yet.\n", id);
+ }
+ return NULL;
+ }
+}
+
+uint16_t get_symid(const char *name, uint64_t val, uint16_t ln, uint8_t dbg) {
+ struct symbol *s = mksymbol(name, 0, 0, 0, 0, dbg);
+ if (s->def) {
+ return s->id;
+ } else {
+ if (dbg) {
+ printf("get_symid(): oof, symbol %s, does not exist, yet.\n", name);
+ }
+ struct fixup *f = malloc(sizeof(*f));
+ f->nxt = fixups;
+ f->adr = val;
+ f->ln = ln;
+ f->s = s;
+ fixups = f;
+ return 0xFFFF;
+ }
+}
+
+uint16_t get_comment(const char *cmnt, uint8_t dbg) {
+ uint16_t i = 0;
+ uint8_t iscom = 0;
+ for (; i < comidx; i++) {
+ if (comment[i] != NULL) {
+ iscom = !strcmp(cmnt, comment[i]);
+ } else {
+ break;
+ }
+ if (iscom) {
+ break;
+ }
+ }
+ if (comment[i] == NULL) {
+ if (dbg) {
+ printf("get_comment(): oof, the index $%04X is NULL.\n", i);
+ }
+ return 0xFFFF;
+ }
+ if (i == comidx) {
+ if (dbg) {
+ printf("get_comment(): oof, the comment \"%s\", was not found in the comment table.\n", cmnt);
+ }
+ return 0xFFFF;
+ }
+ if (dbg) {
+ printf("get_comment(): Found comment \"%s\", in the table, at index $%04X.\n", cmnt, i);
+ }
+ return i;
+}
+
+uint16_t reslv_fixups(uint8_t dbg) {
+ uint16_t i = 0, j = 0;
+ struct fixup *f;
+ f = fixups;
+ for (; f;) {
+ /*printf("f: $%016llX, f->nxt: $%016llX, f->s->name: %s, f->s->val: $%016llX\n", &f, &f->nxt, f->s->name, f->s->val);*/
+ if (f->s->def) {
+ if (f->ln == 0xFFFF) {
+ addr[f->adr] = f->s->val & 0xFF;
+ if (f->s->val & 0xFF00)
+ addr[f->adr+1] = f->s->val >> 8;
+ if (f->s->val & 0xFF000000) {
+ addr[f->adr+2] = f->s->val >> 16;
+ addr[f->adr+3] = f->s->val >> 24;
+ }
+ if (f->s->val & 0xFF00000000000000) {
+ addr[f->adr+4] = f->s->val >> 32;
+ addr[f->adr+5] = f->s->val >> 40;
+ addr[f->adr+6] = f->s->val >> 48;
+ addr[f->adr+7] = f->s->val >> 56;
+ }
+ } else {
+ tokline[f->ln].sym = f->s->id;
+ }
+ } else {
+ if (dbg) {
+ printf("reslv_fixups(): oof, undefined reference to '%s', at $%016llX.\n", f->s->name, f->adr);
+ }
+ i++;
+ }
+ f = f->nxt;
+ j++;
+ }
+ return i;
+
+}
+
+uint64_t update_addr(uint64_t address, uint8_t fixup, uint8_t dbg) {
+ uint64_t value = 0;
+ uint16_t i = 0;
+ uint16_t j = 0;
+ uint16_t flags = 0;
+ uint8_t opsize = 0;
+
+ uint16_t l = lineidx;
+ uint16_t symid = tokline[l].sym;
+ uint16_t str = tokline[l].str;
+ uint16_t com = tokline[l].com;
+ uint8_t islabel = tokline[l].islabel;
+ uint8_t issym = tokline[l].issym;
+ uint8_t opbase = tokline[l].opbase;
+ uint8_t aopbase = tokline[l].aopbase;
+ uint8_t dir = tokline[l].dir;
+ uint8_t am = tokline[l].am;
+ uint8_t cm = tokline[l].cm;
+ uint8_t rs = tokline[l].rs;
+ uint8_t mne = tokline[l].mne;
+
+ flags |= (dir != 0x00FF) << 0x00;
+ flags |= (mne != 0x00FF) << 0x01;
+ flags |= (rs != 0x00FF) << 0x02;
+ flags |= (am != 0x00FF) << 0x03;
+ flags |= (opbase != 0x00FF) << 0x04;
+ flags |= (aopbase != 0x00FF) << 0x05;
+ flags |= (symid != 0xFFFF) << 0x06;
+ flags |= (fixup > 0x0000) << 0x06;
+ flags |= (islabel ) << 0x07;
+ flags |= (issym ) << 0x07;
+ flags |= (am != 0x00FF) << 0x08;
+ flags |= (cm != 0x00FF) << 0x09;
+ flags |= (str != 0xFFFF) << 0x0A;
+
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("flags: $%04X\n", flags);
+ }
+ if (!flags || flags == 0x40) {
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("This line only contains a comment, so don't update the address.");
+ }
+ return address;
+ }
+ if (((flags & 0x53) == 0x42)) {
+ if (isfixup && symid == 0xFFFF && (opcodes[mne][IMPL] == 0xFF)) {
+ value = address;
+ } else {
+ value = use_symbol("", symid, address, 1, dbg);
+ }
+ } else {
+ value = tokline[l].op;
+ }
+ if (flags & 0x220) {
+ switch (cm) {
+ case 0: value += tokline[l].aop; break;
+ case 1: value -= tokline[l].aop; break;
+ }
+ }
+ if (dbg) {
+ printf("update_addr(): value: $%llX\n", value);
+ }
+ switch (dir) {
+ case DIR_ORG:
+ address = value;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Set the Program Counter's Origin to $%llX.\n", address);
+ }
+ break;
+ case DIR_BYTE:
+ if (flags & 0x400) {
+ for (; string[str][i] != '\0'; i++, j++, address++) {
+ i += string[str][i] == '\\';
+ }
+ j++;
+ address++;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%04X", j);
+ puts(", to make room for the string.");
+ }
+ } else {
+ address += 1;
+ }
+ break;
+ case DIR_WORD: address += 2; break;
+ case DIR_DWORD: address += 4; break;
+ case DIR_QWORD: address += 8; break;
+ }
+ if (flags & 0x01) {
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("This line contains a directive, so skip everything else.");
+ }
+ return address;
+ }
+ if ((flags & 0x15B) == 0x02 || (opcodes[mne][IMPL] != 0xFF && am == 0xFF && opbase == 0xFF && symid == 0xFFFF)) {
+ tokline[l].am = IMPL;
+ am = IMPL;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Implied.");
+ }
+ }
+ if (am == IMPL) {
+ opsize = 0;
+ } else if (am == IMM) {
+ switch (rs) {
+ case 3: address += 8; break;
+ case 2: address += 4; break;
+ case 1: address += 2; break;
+ default: address += 1; break;
+ }
+ if (dbg) {
+ if (!(flags & 0x04)) {
+ rs = 0;
+ }
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%02X", 1 << rs);
+ puts(", to make room for the operand.");
+ }
+ } else if ((flags & 0x158) && (!(flags & 0x80))) {
+ opsize = 0;
+ opsize = (value <= 0x00000000000000FF) ? 1 : opsize;
+ opsize = (value > 0x00000000000000FF) ? 2 : opsize;
+ opsize = (value > 0x000000000000FFFF) ? 3 : opsize;
+ opsize = (value > 0x0000000000FFFFFF) ? 4 : opsize;
+ opsize = (value > 0x00000000FFFFFFFF) ? 5 : opsize;
+ opsize = (value > 0x000000FFFFFFFFFF) ? 6 : opsize;
+ opsize = (value > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
+ opsize = (value > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
+ if (opsize) {
+ switch (opsize-1) {
+ case 0:
+ case 2:
+ case 5:
+ case 3:
+ if (!(flags & 0x100)) {
+ am = ZM;
+ tokline[l].am = am;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Zero Matrix.");
+ }
+ /*address += !(opsize-1);*/
+ }
+ break;
+ case 1:
+ case 4:
+ case 6:
+ case 7:
+ if (!(flags & 0x100)) {
+ am = ABS;
+ tokline[l].am = am;
+ if (dbg) {
+ printf("update_addr(): ");
+ puts("Addressing Mode has been set to Absolute.");
+ }
+ }
+ break;
+ }
+ address += opsize;
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Increment Program Counter by $%02X", opsize);
+ puts(", to make room for the address.");
+ }
+ }
+ }
+ if (dbg) {
+ printf("update_addr(): ");
+ printf("Address: $%llX\n", address);
+ }
+ return address;
+}
+
+uint64_t lex(char *str, uint64_t address, uint8_t dbg) {
+ char sym[0x100];
+ uint16_t i = 0;
+ uint16_t j = 0;
+ uint16_t comid = 0;
+ lex_type = 0xFF;
+ uint8_t k = 0;
+ uint8_t rs = 0;
+ uint8_t isop = 0;
+ int num = 0;
+ int isch = 0;
+ int16_t ln = -1;
+ char lnum[6];
+ uint8_t islinenum;
+ uint8_t space = 0;
+ uint8_t tab = 0;
+ uint8_t isstart = 1;
+ uint8_t fall = 0;
+ tokline[lineidx].dir = 0xFF;
+ tokline[lineidx].mne = 0xFF;
+ tokline[lineidx].rs = 0xFF;
+ tokline[lineidx].am = 0xFF;
+ tokline[lineidx].cm = 0xFF;
+ tokline[lineidx].opbase = 0xFF;
+ tokline[lineidx].aopbase = 0xFF;
+ tokline[lineidx].islabel = 0;
+ tokline[lineidx].issym = 0;
+ tokline[lineidx].str = 0xFFFF;
+ tokline[lineidx].com = 0xFFFF;
+ tokline[lineidx].sym = 0xFFFF;
+ tokline[lineidx].op = 0;
+ tokline[lineidx].aop = 0;
+ tokline[lineidx].addr = address;
+
+ while (isdigit(str[i]) && !isspace(str[i])) {
+ lnum[j++] = str[i++];
+ }
+ islinenum = i;
+ if (i) {
+ lnum[j] = '\0';
+ ln = strtol(lnum, NULL, 10);
+ j = 0;
+ } else {
+ ln = linenum;
+ }
+ uint8_t done = 0;
+ while (str[i] != '\0' && str[i] != '\n') {
+ space = 0;
+ tab = 0;
+ while (isspace(str[i+j])) {
+ tab += str[i+j] == '\t';
+ space += str[i+j] == ' ';
+ j++;
+ }
+ j = 0;
+ if (dbg) {
+ printf("lex(): tab: %u, space: %u\n", tab, space);
+ }
+ if (isstart) {
+ tokline[lineidx].stab = tab;
+ tokline[lineidx].sspace = space;
+ if (dbg) {
+ printf("lex(): starting tabs: %u, starting spaces: %u\n", tokline[lineidx].stab, tokline[lineidx].sspace);
+ }
+ }
+ if (isspace(str[i])) {
+ while (isspace(str[i])) {
+ i++;
+ }
+ }
+ switch (str[i]) {
+ case '.':
+ i++;
+ while (!isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ if (!isop) {
+ for (k = 0; k < 5; k++) {
+ if (!strcasecmp(lexeme, dir_t[k])) {
+ lex_type = TOK_DIR;
+ break;
+ }
+ }
+ tokline[lineidx].dir = k;
+ } else {
+ lex_type = TOK_RS;
+ switch (tolower(lexeme[j-1])) {
+ case '2':
+ case 'w':
+ rs = 1;
+ break;
+ case '4':
+ case 'd':
+ rs = 2;
+ break;
+ case '8':
+ case 'q':
+ rs = 3;
+ break;
+ }
+ address++;
+ tokline[lineidx].rs = rs;
+ isop = 0;
+ }
+ break;
+ case '\"':
+ i++;
+ while (str[i] != '\"') {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ string[stridx] = malloc(j+1);
+ memcpy(string[stridx], lexeme, j+1);
+ tokline[lineidx].str = stridx;
+ if (dbg) {
+ printf("lex(): str[0x%04X]: %s\n", stridx, string[stridx]);
+ }
+ stridx++;
+ lex_type = TOK_STRING;
+ break;
+ case '#':
+ lexeme[j] = '#';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ tokline[lineidx].am = IMM;
+ lex_type = TOK_IMM;
+ break;
+ case '$':
+ i++;
+ while (isxdigit(str[i]) && (str[i] != '\0' && str[i] != '\n')) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 16);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_HEX;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].aopbase = BASE_HEX;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].aopbase = BASE_HEX;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 16);
+ tokline[lineidx].opbase = BASE_HEX;
+ }
+ break;
+
+ }
+ lex_type = TOK_HEX;
+ break;
+ case '%':
+ i++;
+ while (isdigit(str[i]) && (str[i] != '\0' && str[i] != '\n')) {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 2);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_BIN;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].aopbase = BASE_BIN;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].aopbase = BASE_BIN;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 2);
+ tokline[lineidx].opbase = BASE_BIN;
+ }
+ break;
+
+ }
+ lex_type = TOK_BIN;
+ break;
+ case '+':
+ lexeme[j] = '+';
+ lexeme[j+1] = '\0';
+ tokline[lineidx].cm = 0;
+ lex_type = TOK_PLUS;
+ break;
+ case '-':
+ lexeme[j] = '-';
+ lexeme[j+1] = '\0';
+ tokline[lineidx].cm = 1;
+ lex_type = TOK_MINUS;
+ break;
+ case '(':
+ lexeme[j] = '(';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ tokline[lineidx].am = IND;
+ break;
+ case ')':
+ i++;
+ if (str[i] == ',') {
+ i++;
+ while (isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ if (tokline[lineidx].am == IND && tolower(str[i]) == 'y') {
+ lexeme[j++] = 'y';
+ tokline[lineidx].am = INDY;
+ }
+ lexeme[j] = '\0';
+ } else {
+ lexeme[j] = ')';
+ lexeme[j+1] = '\0';
+ lexeme[j+2] = '\0';
+ }
+ break;
+ case ',':
+ i++;
+ while (isspace(str[i])) {
+ lexeme[j++] = str[i++];
+ }
+ if (tokline[lineidx].am == IND && tolower(str[i]) == 'x') {
+ tokline[lineidx].am = INDX;
+ lexeme[j++] = 'x';
+ i++;
+ } else {
+ switch (tolower(str[i])) {
+ case 'x':
+ tokline[lineidx].am = ZMX;
+ lexeme[j++] = 'x';
+ break;
+ case 'y':
+ tokline[lineidx].am = ZMY;
+ lexeme[j++] = 'y';
+ break;
+ }
+ }
+ lexeme[j] = '\0';
+ break;
+ case ':':
+ i++;
+ lexeme[j] = ':';
+ lexeme[j+1] = '\0';
+ lex_type = TOK_LABEL;
+ tokline[lineidx].islabel = 1;
+ mksymbol(sym, address, 1, 0, 0, dbg);
+ if (isfixup) {
+ isfixup = reslv_fixups(dbg);
+ }
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ break;
+ case '=':
+ i++;
+ lexeme[j] = '=';
+ lexeme[j+1] = 0;
+ tokline[lineidx].issym = 1;
+ lex_type = TOK_SYM;
+ break;
+ case ';':
+ i++;
+ while (str[i] != '\0' && str[i] != '\n') {
+ lexeme[j++] = str[i++];
+ }
+ lexeme[j] = '\0';
+ comid = get_comment(lexeme, dbg);
+ if (comid == 0xFFFF) {
+ comment[comidx] = malloc(j+1);
+ memcpy(comment[comidx], lexeme, j+1);
+ tokline[lineidx].com = comidx;
+ if (dbg) {
+ printf("lex(): com[0x%04X]: %s\n", comidx, comment[comidx]);
+ }
+ comidx++;
+ } else {
+ tokline[lineidx].com = comid;
+ if (dbg) {
+ printf("lex(): com[0x%04X]: %s\n", comid, comment[comid]);
+ }
+ }
+ lex_type = TOK_COMMENT;
+ break;
+ default:
+ if (isalnum(str[i]) || str[i] == '_') {
+ while (!isspace(str[i])) {
+ switch (str[i]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case '=':
+ case ';':
+ case '\0':
+ case '\n':
+ isch = 0;
+ break;
+ default:
+ isch = 1;
+ lexeme[j++] = str[i++];
+ break;
+ }
+ if (!isch) {
+ break;
+ }
+ }
+ lexeme[j] = '\0';
+ isch = 0;
+ isop = 0;
+ if (j == 3 && str[i] != ':') {
+ for (k = 0; k < OPNUM; k++) {
+ if (!strcasecmp(lexeme, mne[k])) {
+ lex_type = TOK_OPCODE;
+ isop = 1;
+ tokline[lineidx].mne = k;
+ address++;
+ break;
+ }
+ }
+ }
+ if (!isop) {
+ for (k = 0; lexeme[k] != '\0';) {
+ switch (lexeme[k]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case ';':
+ case '=':
+ case '\0':
+ case '\n':
+ fall = 1;
+ break;
+ default:
+ fall = 0;
+ break;
+ }
+ if (fall) {
+ break;
+ }
+ if ((isalnum(lexeme[k]) || lexeme[k] == '_')) {
+ if (!isch) {
+ isch = isalpha(lexeme[k]);
+ }
+ num = isdigit(lexeme[k]) && !isch;
+ k++;
+ } else {
+ break;
+ }
+ }
+ if (lexeme[k] == '\0') {
+ if (num) {
+ switch (lex_type) {
+ case TOK_SYM:
+ tokline[lineidx].op = strtoull(lexeme, NULL, 10);
+ mksymbol(sym, tokline[lineidx].op, 1, 0, 0, dbg);
+ if (isfixup) {
+ isfixup = reslv_fixups(dbg);
+ }
+ tokline[lineidx].sym = get_symid(sym, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ tokline[lineidx].opbase = BASE_DEC;
+ break;
+ case TOK_PLUS:
+ case TOK_MINUS:
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].aopbase = BASE_DEC;
+ break;
+ default:
+ if (tokline[lineidx].cm != 0xFF) {
+ tokline[lineidx].aop = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].aopbase = BASE_DEC;
+ } else {
+ tokline[lineidx].op = strtoull(lexeme, NULL, 10);
+ tokline[lineidx].opbase = BASE_DEC;
+ }
+ break;
+
+ }
+ lex_type = TOK_DEC;
+ } else if (isch && lex_type != TOK_HEX && lex_type != TOK_BIN) {
+ lex_type = TOK_SYM;
+ memcpy(sym, lexeme, j+1);
+ uint8_t spaces = 0;
+ for (; isspace(str[i+spaces]); spaces++);
+ if (dbg) {
+ printf("lex(): spaces: %u\n", spaces);
+ }
+ if (str[i+spaces] != ':' && str[i+spaces] != '=') {
+ tokline[lineidx].sym = get_symid(lexeme, address, lineidx, dbg);
+ isfixup += tokline[lineidx].sym == 0xFFFF;
+ if (dbg) {
+ printf("lex(): isfixup: %u\n", isfixup);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (dbg) {
+ printf("lex(): lexeme: %s, lex_type: %s\n", lexeme, (lex_type != 0xFF) ? lex_tok[lex_type] : "TOK_NONE");
+ }
+ isstart = 0;
+ /*lex_type = 0xFF;*/
+ j = 0;
+ if (lex_type == TOK_OPCODE && !isop) {
+ j = 0;
+ } else {
+ if (lex_type == TOK_PLUS || lex_type == TOK_MINUS) {
+ i++;
+ } else {
+ switch (str[i]) {
+ case ')':
+ case ',':
+ case '.':
+ case '+':
+ case '-':
+ case ':':
+ case ';':
+ case '=':
+ case ' ':
+ case '\t':
+ case '\n':
+ case '\0':
+ break;
+ default:
+ i++;
+ break;
+ }
+ }
+ }
+ if (lex_type == TOK_COMMENT) {
+ if (!isstart) {
+ tokline[lineidx].etab = tab;
+ tokline[lineidx].espace = space;
+ if (dbg) {
+ printf("lex(): ending tabs: %u, ending spaces: %u\n", tokline[lineidx].etab, tokline[lineidx].espace);
+ }
+ }
+ }
+ if (lex_type != TOK_SYM) {
+ for (k = 0; lexeme[k] != '\0';) {
+ lexeme[k] = 0;
+ ++k;
+ }
+ lex_type = 0xFF;
+ }
+ }
+ if (i) {
+ address = update_addr(address, isfixup, dbg);
+ if (dbg) {
+ printf("lex(): Next address: $%llX\n", address);
+ printf(
+ "lex(): "
+ "address: $%llX"
+ ", dir: %u"
+ ", mne: $%02X"
+ ", rs: %u"
+ ", am: %u"
+ ", cm: %u"
+ ", opbase: %u"
+ ", com: $%04X"
+ ", sym: $%04X"
+ ", op: $%016X"
+ ", aop: $%016X"
+ ", ln: %i\n"
+ , tokline[lineidx].addr
+ , tokline[lineidx].dir
+ , tokline[lineidx].mne
+ , tokline[lineidx].rs
+ , tokline[lineidx].am
+ , tokline[lineidx].cm
+ , tokline[lineidx].opbase
+ , tokline[lineidx].com
+ , tokline[lineidx].sym
+ , tokline[lineidx].op
+ , tokline[lineidx].aop
+ , lineidx);
+ }
+ if (ln > linenum) {
+ linenum+=(10+(ln & 10));
+ tokline[lineidx].linenum = ln;
+ } else if (!islinenum) {
+ tokline[lineidx].linenum = linenum;
+ linenum += 10;
+ }
+ lineidx++;
+ }
+ return address;
+}