Implementing better macros

This commit is contained in:
neauoire 2021-03-13 10:31:29 -08:00
parent e865be5d88
commit fd883dc4c8
3 changed files with 63 additions and 67 deletions

View File

@ -24,17 +24,17 @@ typedef struct {
typedef struct { typedef struct {
Uint8 len, length[16], size, refs; Uint8 len, length[16], size, refs;
char name[64], params[16][64]; char name[64], params[16][64];
} Macro; } Template;
typedef struct { typedef struct {
Uint8 len, offset, refs; Uint8 len, offset, refs;
Uint16 addr; Uint16 addr;
char name[64]; char name[64];
Macro *macro; Template *template;
} Label; } Label;
int macroslen; int templateslen;
Macro macros[256]; Template templates[256];
int labelslen; int labelslen;
Label labels[256]; Label labels[256];
@ -91,13 +91,13 @@ pushtext(char *s, int lit)
pushbyte(c, 0); pushbyte(c, 0);
} }
Macro * Template *
findmacro(char *s) findtemplate(char *s)
{ {
int i; int i;
for(i = 0; i < macroslen; ++i) for(i = 0; i < templateslen; ++i)
if(scmp(macros[i].name, s, 64)) if(scmp(templates[i].name, s, 64))
return &macros[i]; return &templates[i];
return NULL; return NULL;
} }
@ -122,12 +122,12 @@ findlabeladdr(char *s)
if(scin(s, '.') < 1) if(scin(s, '.') < 1)
return l->addr; return l->addr;
param = s + scin(s, '.') + 1; param = s + scin(s, '.') + 1;
for(i = 0; i < l->macro->len; ++i) { for(i = 0; i < l->template->len; ++i) {
if(scmp(l->macro->params[i], param, 64)) if(scmp(l->template->params[i], param, 64))
return l->addr + o; return l->addr + o;
o += l->macro->length[i]; o += l->template->length[i];
} }
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->macro->name); printf("!!! Warning %s.%s[%s]\n", l->name, param, l->template->name);
return 0; return 0;
} }
@ -140,10 +140,10 @@ findlabellen(char *s)
if(scin(s, '.') < 1) if(scin(s, '.') < 1)
return l->len; return l->len;
param = s + scin(s, '.') + 1; param = s + scin(s, '.') + 1;
for(i = 0; i < l->macro->len; ++i) for(i = 0; i < l->template->len; ++i)
if(scmp(l->macro->params[i], param, 64)) if(scmp(l->template->params[i], param, 64))
return l->macro->length[i]; return l->template->length[i];
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->macro->name); printf("!!! Warning %s.%s[%s]\n", l->name, param, l->template->name);
return 0; return 0;
} }
@ -186,18 +186,18 @@ error(char *name, char *id)
} }
int int
makemacro(char *name, FILE *f) maketemplate(char *name, FILE *f)
{ {
Uint8 mode = 0; Uint8 mode = 0;
Macro *m; Template *m;
char wv[64]; char wv[64];
if(findmacro(name)) if(findtemplate(name))
return error("Macro duplicate", name); return error("Template duplicate", name);
if(sihx(name) && slen(name) % 2 == 0) if(sihx(name) && slen(name) % 2 == 0)
return error("Macro name is hex number", name); return error("Template name is hex number", name);
if(findopcode(name)) if(findopcode(name))
return error("Macro name is invalid", name); return error("Template name is invalid", name);
m = &macros[macroslen++]; m = &templates[templateslen++];
scpy(name, m->name, 64); scpy(name, m->name, 64);
while(fscanf(f, "%s", wv)) { while(fscanf(f, "%s", wv)) {
if(wv[0] == '{') if(wv[0] == '{')
@ -213,12 +213,12 @@ makemacro(char *name, FILE *f)
} }
mode = !mode; mode = !mode;
} }
printf("New macro: %s[%d:%d]\n", name, m->len, m->size); printf("New template: %s[%d:%d]\n", name, m->len, m->size);
return 1; return 1;
} }
int int
makelabel(char *name, Uint16 addr, Uint8 len, Macro *m) makelabel(char *name, Uint16 addr, Uint8 len, Template *m)
{ {
Label *l; Label *l;
if(findlabel(name)) if(findlabel(name))
@ -233,35 +233,27 @@ makelabel(char *name, Uint16 addr, Uint8 len, Macro *m)
l->refs = 0; l->refs = 0;
scpy(name, l->name, 64); scpy(name, l->name, 64);
if(m) if(m)
l->macro = m; l->template = m;
printf("New label: %s, at 0x%04x[%d]\n", l->name, l->addr, l->len); printf("New label: %s, at 0x%04x[%d]\n", l->name, l->addr, l->len);
return 1; return 1;
} }
int
makeconst(char *id, FILE *f)
{
char wv[64];
fscanf(f, "%s", wv);
return makelabel(id, shex(wv), 1, 0);
}
int int
makevariable(char *id, Uint16 *addr, FILE *f) makevariable(char *id, Uint16 *addr, FILE *f)
{ {
char wv[64]; char wv[64];
Uint16 origin; Uint16 origin;
Uint8 len; Uint8 len;
Macro *m = NULL; Template *m = NULL;
fscanf(f, "%s", wv); fscanf(f, "%s", wv);
origin = *addr; origin = *addr;
if(sihx(wv)) if(sihx(wv))
len = shex(wv); len = shex(wv);
else if((m = findmacro(wv))) { else if((m = findtemplate(wv))) {
len = m->size; len = m->size;
m->refs++; m->refs++;
} else } else
return error("Invalid macro", wv); return error("Invalid template", wv);
*addr += len; *addr += len;
return makelabel(id, origin, len, m); return makelabel(id, origin, len, m);
} }
@ -305,10 +297,7 @@ pass1(FILE *f)
if(!makevariable(w + 1, &addr, f)) if(!makevariable(w + 1, &addr, f))
return error("Pass1 failed", w); return error("Pass1 failed", w);
} else if(w[0] == '&') { } else if(w[0] == '&') {
if(!makemacro(w + 1, f)) if(!maketemplate(w + 1, f))
return error("Pass1 failed", w);
} else if(w[0] == ':') {
if(!makeconst(w + 1, f))
return error("Pass1 failed", w); return error("Pass1 failed", w);
} else if(findopcode(w) || scmp(w, "BRK", 4)) } else if(findopcode(w) || scmp(w, "BRK", 4))
addr += 1; addr += 1;
@ -338,7 +327,7 @@ pass1(FILE *f)
int int
pass2(FILE *f) pass2(FILE *f)
{ {
int ccmnt = 0, cbits = 0, cmacro = 0; int ccmnt = 0, cbits = 0, ctemplate = 0;
char w[64], scope[64], subw[64]; char w[64], scope[64], subw[64];
printf("Pass 2\n"); printf("Pass 2\n");
while(fscanf(f, "%s", w) == 1) { while(fscanf(f, "%s", w) == 1) {
@ -355,7 +344,7 @@ pass2(FILE *f)
scpy(subw, w + 1, 64); scpy(subw, w + 1, 64);
} }
if(skipblock(w, &ccmnt, '(', ')')) continue; if(skipblock(w, &ccmnt, '(', ')')) continue;
if(skipblock(w, &cmacro, '{', '}')) continue; if(skipblock(w, &ctemplate, '{', '}')) continue;
/* clang-format off */ /* clang-format off */
if(skipblock(w, &cbits, '[', ']')) { if(skipblock(w, &cbits, '[', ']')) {
if(w[0] == '[' || w[0] == ']') { continue; } if(w[0] == '[' || w[0] == ']') { continue; }
@ -395,9 +384,9 @@ cleanup(void)
for(i = 0; i < labelslen; ++i) for(i = 0; i < labelslen; ++i)
if(!labels[i].refs) if(!labels[i].refs)
printf("--- Unused label: %s\n", labels[i].name); printf("--- Unused label: %s\n", labels[i].name);
for(i = 0; i < macroslen; ++i) for(i = 0; i < templateslen; ++i)
if(!macros[i].refs) if(!templates[i].refs)
printf("--- Unused macro: %s\n", macros[i].name); printf("--- Unused template: %s\n", templates[i].name);
} }
int int

View File

@ -21,4 +21,4 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr
# run # run
./bin/assembler projects/software/left.usm bin/boot.rom ./bin/assembler projects/software/left.usm bin/boot.rom
./bin/emulator bin/boot.rom # ./bin/emulator bin/boot.rom

View File

@ -6,6 +6,9 @@
- Double-click select word - Double-click select word
- Right-click find next instance of selection - Right-click find next instance of selection
- Draw tab characters - Draw tab characters
- Don't redraw if nothing has changed
- Input on selection should erase selection range
- Erase on selection should erase selection range
- Scrollbar - Scrollbar
- Don't scroll past oef - Don't scroll past oef
- Hor scroll - Hor scroll
@ -33,7 +36,6 @@
;i 2 ;j 2 ;k 1 ;l 1 ;addr 2 ;i 2 ;j 2 ;k 1 ;l 1 ;addr 2
;selection Range2d ;position Point2d ;scroll Point2d ;selection Range2d ;position Point2d ;scroll Point2d
;pt Point2d ;mouse Point2d ;touch Touch2d ;pt Point2d ;mouse Point2d ;touch Touch2d
;textarea Textarea2d ;textarea Textarea2d
;label Label2d ( remove ) ;label Label2d ( remove )
@ -42,7 +44,6 @@
( load file ) ( load file )
,filepath ,load-file JSR2 ,filepath ,load-file JSR2
( place textarea ) ( place textarea )
#0018 =textarea.x1 ~SCRN.height #0008 SUB2 =textarea.y2 #0018 =textarea.x1 ~SCRN.height #0008 SUB2 =textarea.y2
@ -72,11 +73,11 @@ BRK
,no-ctrl-left ~CTRL #40 NEQ JMP2? POP2 ,no-ctrl-left ~CTRL #40 NEQ JMP2? POP2
( clamp ) ,no-ctrl-left ~selection.from ,document.body EQU2 JMP2? POP2 ( clamp ) ,no-ctrl-left ~selection.from ,document.body EQU2 JMP2? POP2
~selection.from #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to ~selection.from #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to
,clamp-selection JSR2,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2 ,clamp-selection JSR2 ,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
@no-ctrl-left @no-ctrl-left
,no-ctrl-right ~CTRL #80 NEQ JMP2? POP2 ,no-ctrl-right ~CTRL #80 NEQ JMP2? POP2
~selection.from #0001 ADD2 DUP2 =selection.from #0001 ADD2 =selection.to ~selection.from #0001 ADD2 DUP2 =selection.from #0001 ADD2 =selection.to
,clamp-selection JSR2,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2 ,clamp-selection JSR2 ,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
@no-ctrl-right @no-ctrl-right
( alt ) ( alt )
,no-alt ~CTRL #0f AND #02 NEQ JMP2? POP2 ,no-alt ~CTRL #0f AND #02 NEQ JMP2? POP2
@ -119,27 +120,33 @@ BRK
( keys ) ( keys )
,keys-end ~KEYS #00 EQU JMP2? POP2 ,no-keys ~KEYS #00 EQU JMP2? POP2
,no-backspace ~KEYS #08 NEQ JMP2? POP2 ,$no-backspace ~KEYS #08 NEQ JMP2? POP2
( erase ) ( erase )
,$erase-multiple ~selection.to ~selection.from SUB2 #0001 NEQ2 JMP2? POP2
$erase-single
~selection.to ~selection.from SUB2 ,shift-left JSR2 ~selection.to ~selection.from SUB2 ,shift-left JSR2
,$erase-end JMP2
$erase-multiple
~selection.from #0001 ADD2 =selection.from
~selection.to ~selection.from SUB2 #0001 ADD2 ,shift-left JSR2
$erase-end
~selection.from #0001 SUB2 =selection.from ~selection.from #0001 SUB2 =selection.from
~selection.from #0001 ADD2 =selection.to ,$keys-end JMP2
( release ) #00 =KEYS $no-backspace
,redraw JSR2
,keys-end JMP2
@no-backspace
( insert ) ( insert )
~selection.to ~selection.from SUB2 ,shift-right JSR2 ~selection.to ~selection.from SUB2 ,shift-right JSR2
~KEYS ~selection.from STR ~KEYS ~selection.from STR
~selection.from #0001 ADD2 =selection.from ~selection.from #0001 ADD2 =selection.from
$keys-end
~selection.from #0001 ADD2 =selection.to ~selection.from #0001 ADD2 =selection.to
( release ) #00 =KEYS ( release ) #00 =KEYS
,redraw JSR2 ,redraw JSR2
@keys-end @no-keys
( mouse ) ( mouse )
@ -532,7 +539,7 @@ RTS
( draw ) #01 ( draw ) #01
~i ~selection.from #0001 SUB2 GTH2 ~i ~selection.from #0001 SUB2 GTH2
~i ~selection.to LTH2 #0101 EQU2 ~i ~selection.to LTH2 #0101 EQU2
#05 MUL ADD =SPRT.color #05 MUL ADD ~i ~selection.from EQU2 ADD =SPRT.color
,$no-linebreak ~i LDR #0a NEQ ~i LDR #0d NEQ #0101 EQU2 JMP2? POP2 ,$no-linebreak ~i LDR #0a NEQ ~i LDR #0d NEQ #0101 EQU2 JMP2? POP2
( draw linebreak ) ( draw linebreak )
@ -578,10 +585,10 @@ RTS
#0000 =SPRT.y #0000 =SPRT.y
,scrollbar_bg =SPRT.addr ,scrollbar_bg =SPRT.addr
$loop $loop NOP
( draw ) #08 =SPRT.color ( draw ) #08 =SPRT.color
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y ( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
,$loop ~SPRT.y ~SCRN.height LTH2 JMP2? POP2 ~SPRT.y ~SCRN.height LTH2 ^$loop MUL JMPS
#0000 =SPRT.y #0000 =SPRT.y
,arrowup_icn =SPRT.addr ,arrowup_icn =SPRT.addr