(uxnasm) Check against label/macro overlaps
This commit is contained in:
parent
63f1cf68d1
commit
436e579df4
38
src/uxnasm.c
38
src/uxnasm.c
|
@ -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 = ¯os[macro_len++];
|
m = ¯os[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 '.':
|
||||||
|
|
Loading…
Reference in New Issue