diff --git a/src/uxnasm.c b/src/uxnasm.c index db1d3dd..ece3ed6 100644 --- a/src/uxnasm.c +++ b/src/uxnasm.c @@ -11,30 +11,32 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ +/* clang-format off */ + #define PAGE 0x0100 +enum Type { LABEL, REF, MACRO }; typedef unsigned char Uint8; typedef signed char Sint8; typedef unsigned short Uint16; - typedef struct { + enum Type type; char *name, rune, *content; Uint16 addr, refs; } Item; - typedef struct { int line; char *path; } Context; +static Item items[0x4000]; +static int items_len; static int ptr, length; static char token[0x40], scope[0x40], sublabel[0x80], lambda[0x05]; static char dict[0x4000], *dictnext = dict; static Uint8 data[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len; -static Uint16 label_len, refs_len, macro_len; -static Item labels[0x400], refs[0x1000], macros[0x100]; - -/* clang-format off */ +static Uint16 refs_len, macro_len; +static Item refs[0x1000], macros[0x100]; static char *runes = "|$@&,_.-;=!?#\"%~"; static char *hexad = "0123456789abcdef"; @@ -52,13 +54,13 @@ static int scmp(char *a, char *b, int len) { int i = 0; while(a[i] == b[i]) if static int slen(char *s) { int i = 0; while(s[i]) i++; return i; } /* str length */ static char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* str copy */ static char *scat(char *dst, char *src) { char *o = dst + slen(dst); while(*src) *o++ = *src++; *o = '\0'; return dst; } /* str concat */ -static char *save(char *s, char c) { char *o = dictnext; while((*dictnext++ = *s++) && *s); *dictnext++ = c; return o; } +static char *save(char *s, char c) { char *o = dictnext; while((*dictnext++ = *s++) && *s); *dictnext++ = c; return o; } /* save to dict */ #define isopcode(x) (findopcode(x) || scmp(x, "BRK", 4)) #define isinvalid(x) (!slen(x) || sihx(x) || isopcode(x) || cndx(runes, x[0]) >= 0) #define writeshort(x) (writebyte(x >> 8, ctx) && writebyte(x & 0xff, ctx)) #define makesublabel(x) push(scat(scat(scpy(scope, sublabel, 0x40), "/"), x), 0) -#define findlabel(x) finditem(x, labels, label_len) +#define findlabel(x) finditem(x, items, items_len) #define findmacro(x) finditem(x, macros, macro_len) #define error_top(name, msg) !fprintf(stderr, "%s: %s\n", name, msg) #define error_asm(name) !fprintf(stderr, "%s: %s in @%s, %s:%d.\n", name, token, scope, ctx->path, ctx->line) @@ -71,7 +73,6 @@ static char * push(char *s, char c) { char *d = dict; - /* find */ for(d = dict; d < dictnext; d++) { char *ss = s, *dd = d, a, b; while((a = *dd++) == (b = *ss++)) @@ -192,13 +193,14 @@ makelabel(char *name, int setscope, Context *ctx) Item *l; if(name[0] == '&') name = makesublabel(name + 1); - if(label_len == 0x400) return error_asm("Labels limit exceeded"); + if(items_len == 0x400) return error_asm("Labels limit exceeded"); if(isinvalid(name)) return error_asm("Label is invalid"); if(findlabel(name)) return error_asm("Label is duplicate"); - l = &labels[label_len++]; + l = &items[items_len++]; l->name = push(name, 0); l->addr = ptr; l->refs = 0; + l->type = LABEL; if(setscope) { int i = 0; while(name[i] != '/' && i < 0x3e && (scope[i] = name[i])) @@ -384,26 +386,28 @@ build(char *rompath) /* rom */ if(!(dst = fopen(rompath, "wb"))) return !error_top("Invalid output file", rompath); - for(i = 0; i < label_len; i++) - if(labels[i].name[0] - 'A' > 25 && !labels[i].refs) - fprintf(stdout, "-- Unused label: %s\n", labels[i].name); + for(i = 0; i < items_len; i++) + if(items[i].type == LABEL && items[i].name[0] - 'A' > 25 && !items[i].refs) + fprintf(stdout, "-- Unused label: %s\n", items[i].name); + else if(items[i].type == MACRO && items[i].name[0] - 'A' > 25 && !items[i].refs) + fprintf(stdout, "-- Unused macro: %s\n", items[i].name); fwrite(data + PAGE, length - PAGE, 1, dst); fprintf(stdout, "Assembled %s in %d bytes(%.2f%% used), %d labels, %d macros.\n", rompath, length - PAGE, (length - PAGE) / 652.80, - label_len, + items_len, macro_len); /* sym */ sympath = dictnext, save(rompath, '.'), save("sym", 0); if(!(dstsym = fopen(sympath, "w"))) return !error_top("Invalid symbols file", sympath); - for(i = 0; i < label_len; i++) { - Uint8 hb = labels[i].addr >> 8, lb = labels[i].addr; + for(i = 0; i < items_len; i++) { + Uint8 hb = items[i].addr >> 8, lb = items[i].addr; fwrite(&hb, 1, 1, dstsym); fwrite(&lb, 1, 1, dstsym); - fwrite(labels[i].name, slen(labels[i].name) + 1, 1, dstsym); + fwrite(items[i].name, slen(items[i].name) + 1, 1, dstsym); } fclose(dst), fclose(dstsym); return 1;