From 632f9fc0faf20a4dc65a6b4ad63ee8f1b88d6e2a Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Wed, 27 Mar 2024 16:36:28 -0700 Subject: [PATCH] (uxnasm) Asbtracted ref resolve --- src/uxnasm.c | 107 +++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 55 deletions(-) diff --git a/src/uxnasm.c b/src/uxnasm.c index bf01691..5ed195e 100644 --- a/src/uxnasm.c +++ b/src/uxnasm.c @@ -18,7 +18,7 @@ typedef signed char Sint8; typedef unsigned short Uint16; typedef struct { - char *name, *content; + char *name, rune, *content; Uint16 addr, refs; } Item; @@ -226,7 +226,7 @@ makepad(char *w) } static int -addref(char *label, Uint16 addr) +addref(char *label, char rune, Uint16 addr) { Item *r; if(refs_len >= 0x1000) @@ -235,12 +235,11 @@ addref(char *label, Uint16 addr) if(label[0] == '{') { lambda_stack[lambda_ptr++] = lambda_len; r->name = push(makelambda(lambda_len++), 0); - } else if(label[1] == '&') - r->name = makesublabel(label + 2); - else if(label[0] == '/') + } else if(label[0] == '&' || label[0] == '/') { r->name = makesublabel(label + 1); - else + } else r->name = push(label, 0); + r->rune = rune; r->addr = addr; return 1; } @@ -308,15 +307,15 @@ parse(char *w, FILE *f, Context *ctx) case '&': return !makelabel(w, 0, ctx) ? error_asm("Invalid sublabel") : 1; case '}': return !makelabel(makelambda(lambda_stack[--lambda_ptr]), 0, ctx) ? error_asm("Invalid label") : 1; case '#': return !sihx(w + 1) || !writehex(w, ctx) ? error_asm("Invalid hexadecimal") : 1; - case '_': return addref(w, ptr) && writebyte(0xff, ctx); - case ',': return addref(w, ptr + 1) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx); - case '-': return addref(w, ptr) && writebyte(0xff, ctx); - case '.': return addref(w, ptr + 1) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx); + case '_': return addref(w + 1, w[0], ptr) && writebyte(0xff, ctx); + case ',': return addref(w + 1, w[0], ptr + 1) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx); + case '-': return addref(w + 1, w[0], ptr) && writebyte(0xff, ctx); + case '.': return addref(w + 1, w[0], ptr + 1) && writebyte(findopcode("LIT"), ctx) && writebyte(0xff, ctx); case ':': fprintf(stderr, "Deprecated rune %s, use =%s\n", w, w + 1); /* fall-through */ - case '=': return addref(w, ptr) && writeshort(0xffff); - case ';': return addref(w, ptr + 1) && writebyte(findopcode("LIT2"), ctx) && writeshort(0xffff); - case '?': return addref(w, ptr + 1) && writebyte(0x20, ctx) && writeshort(0xffff); - case '!': return addref(w, ptr + 1) && writebyte(0x40, ctx) && writeshort(0xffff); + case '=': return addref(w + 1, w[0], ptr) && writeshort(0xffff); + case ';': return addref(w + 1, w[0], ptr + 1) && writebyte(findopcode("LIT2"), ctx) && writeshort(0xffff); + case '?': return addref(w + 1, w[0], ptr + 1) && writebyte(0x20, ctx) && writeshort(0xffff); + case '!': return addref(w + 1, w[0], ptr + 1) && writebyte(0x40, ctx) && writeshort(0xffff); case '"': return !writestring(w + 1, ctx) ? error_asm("Invalid string") : 1; case '$': case '|': return !makepad(w) ? error_asm("Invalid padding") : 1; @@ -329,54 +328,52 @@ parse(char *w, FILE *f, Context *ctx) return writebyte(findopcode(w), ctx); else if((m = findmacro(w))) return walkmacro(m, ctx); - return addref(w, ptr + 1) && writebyte(0x60, ctx) && writeshort(0xffff); + return addref(w, ' ', ptr + 1) && writebyte(0x60, ctx) && writeshort(0xffff); +} + +static int +resolveref(Item *r) +{ + Uint16 a; + Uint8 *rom = data + r->addr; + Item *l = findlabel(r->name); + if(!l) return 0; + switch(r->rune) { + case '_': + case ',': + *rom = (Sint8)(l->addr - r->addr - 2); + if((Sint8)data[r->addr] != (l->addr - r->addr - 2)) + return error_top("Relative reference is too far", r->name); + l->refs++; + break; + case '-': + case '.': + *rom = l->addr; + l->refs++; + break; + case ':': + case '=': + case ';': + *rom++ = l->addr >> 8, *rom = l->addr; + l->refs++; + break; + case '?': + case '!': + default: + a = l->addr - r->addr - 2; + *rom++ = a >> 8, *rom = a; + l->refs++; + break; + } } static int resolve(void) { int i; - Uint16 a; for(i = 0; i < refs_len; i++) { Item *r = &refs[i]; - Uint8 *rom = data + r->addr; - Item *l; - switch(r->name[0]) { - case '_': - case ',': - if(!(l = findlabel(r->name + 1))) return error_top("Unknown relative reference", r->name); - *rom = (Sint8)(l->addr - r->addr - 2); - if((Sint8)data[r->addr] != (l->addr - r->addr - 2)) - return error_top("Relative reference is too far", r->name); - l->refs++; - break; - case '-': - case '.': - if(!(l = findlabel(r->name + 1))) return error_top("Unknown zero-page reference", r->name); - *rom = l->addr; - l->refs++; - break; - case ':': - case '=': - case ';': - if(!(l = findlabel(r->name + 1))) return error_top("Unknown absolute reference", r->name); - *rom++ = l->addr >> 8, *rom = l->addr; - l->refs++; - break; - case '?': - case '!': - if(!(l = findlabel(r->name + 1))) return error_top("Unknown immediate reference", r->name); - a = l->addr - r->addr - 2; - *rom++ = a >> 8, *rom = a; - l->refs++; - break; - default: - if(!(l = findlabel(r->name))) return error_top("Unknown subroutine reference", r->name); - a = l->addr - r->addr - 2; - *rom++ = a >> 8, *rom = a; - l->refs++; - break; - } + if(!resolveref(r)) return error_top("Unknown reference", r->name); } return 1; } @@ -432,4 +429,4 @@ main(int argc, char *argv[]) fwrite(data + PAGE, length - PAGE, 1, dst); writesym(argv[2]); return 0; -} +} \ No newline at end of file