(uxnasm) Check against label/macro overlaps

This commit is contained in:
Devine Lu Linvega 2024-08-25 10:18:44 -07:00
parent 63f1cf68d1
commit 436e579df4
1 changed files with 21 additions and 17 deletions

View File

@ -22,7 +22,7 @@ typedef struct { int line; char *path; } Context;
typedef struct { char *name, rune, *data; Uint16 addr, refs, line; } Item; typedef struct { char *name, rune, *data; Uint16 addr, refs, line; } Item;
static int ptr, length; static int ptr, length;
static char token[0x40], scope[0x40], lambda[0x05]; static char token[0x30], scope[0x40], lambda[0x05];
static char dict[0x8000], *dictnext = dict; static char dict[0x8000], *dictnext = dict;
static Uint8 data[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len; static Uint8 data[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len;
static Uint16 labels_len, refs_len, macro_len; static Uint16 labels_len, refs_len, macro_len;
@ -123,14 +123,16 @@ static int
walkmacro(Item *m, Context *ctx) walkmacro(Item *m, Context *ctx)
{ {
unsigned char c; unsigned char c;
char *dataptr = m->data, *cptr = token; char *dataptr = m->data, *_token = token;
while((c = *dataptr++)) { while((c = *dataptr++)) {
if(c < 0x21) { if(c < 0x21) {
*cptr++ = 0x00; *_token++ = 0x00;
if(token[0] && !parse(token, NULL, ctx)) return 0; if(token[0] && !parse(token, NULL, ctx)) return 0;
cptr = token; _token = token;
} else } else if(_token - token < 0x2f)
*cptr++ = c; *_token++ = c;
else
return error_asm("Token size exceeded");
} }
return 1; return 1;
} }
@ -139,19 +141,19 @@ static int
walkfile(FILE *f, Context *ctx) walkfile(FILE *f, Context *ctx)
{ {
unsigned char c; unsigned char c;
char *cptr = token; char *_token = token;
while(f && fread(&c, 1, 1, f)) { while(f && fread(&c, 1, 1, f)) {
if(c < 0x21) { if(c < 0x21) {
*cptr++ = 0x00; *_token++ = 0x00;
if(token[0] && !parse(token, f, ctx)) return 0; if(token[0] && !parse(token, f, ctx)) return 0;
if(c == 0xa) ctx->line++; if(c == 0xa) ctx->line++;
cptr = token; _token = token;
} else if(cptr - token < 0x3f) } else if(_token - token < 0x2f)
*cptr++ = c; *_token++ = c;
else else
return error_asm("Token too long"); return error_asm("Token size exceeded");
} }
*cptr++ = 0; *_token++ = 0;
return parse(token, f, ctx); return parse(token, f, ctx);
} }
@ -172,8 +174,9 @@ makemacro(char *name, FILE *f, Context *ctx)
char c; char c;
Item *m; Item *m;
if(macro_len >= 0x100) return error_asm("Macros limit exceeded"); if(macro_len >= 0x100) return error_asm("Macros limit exceeded");
if(isinvalid(name)) return error_asm("Macro is invalid"); if(isinvalid(name)) return error_asm("Macro invalid");
if(findmacro(name)) return error_asm("Macro is duplicate"); if(findmacro(name)) return error_asm("Macro duplicate");
if(findlabel(name)) return error_asm("Label duplicate");
m = &macros[macro_len++]; m = &macros[macro_len++];
m->name = push(name, 0); m->name = push(name, 0);
m->data = dictnext; m->data = dictnext;
@ -201,6 +204,7 @@ makelabel(char *name, int setscope, Context *ctx)
name = join(scope, '/', name + 1); name = join(scope, '/', name + 1);
if(labels_len >= 0x400) return error_asm("Labels limit exceeded"); if(labels_len >= 0x400) return error_asm("Labels limit exceeded");
if(isinvalid(name)) return error_asm("Label invalid"); if(isinvalid(name)) return error_asm("Label invalid");
if(findmacro(name)) return error_asm("Label duplicate");
if(findlabel(name)) return error_asm("Label duplicate"); if(findlabel(name)) return error_asm("Label duplicate");
l = &labels[labels_len++]; l = &labels[labels_len++];
l->name = push(name, 0); l->name = push(name, 0);
@ -294,7 +298,7 @@ assemble(char *filename)
ctx.line = 1; ctx.line = 1;
ctx.path = push(filename, 0); ctx.path = push(filename, 0);
if(!(f = fopen(filename, "r"))) if(!(f = fopen(filename, "r")))
return error_top("Source missing", filename); return error_top("File missing", filename);
res = walkfile(f, &ctx); res = walkfile(f, &ctx);
fclose(f); fclose(f);
return res; return res;
@ -348,7 +352,7 @@ resolve(char *filename)
case ',': case ',':
*rom = rel = l->addr - r->addr - 2; *rom = rel = l->addr - r->addr - 2;
if((Sint8)data[r->addr] != rel) if((Sint8)data[r->addr] != rel)
return error_ref("Relative reference too far"); return error_ref("Reference too far");
break; break;
case '-': case '-':
case '.': case '.':