Implemented local templated labels

This commit is contained in:
neauoire 2021-03-11 15:47:28 -08:00
parent 59e6ced7b9
commit b42cec41ef
8 changed files with 93 additions and 75 deletions

View File

@ -27,6 +27,7 @@ evaluxn(u, u->vframe); /* Each frame
### Define
- `@label`, assign the current address to a label.
- `$label`, assign the current address to a local label.
- `;variable 2`, assign an address to a label automatically.
- `:const 1a2b`, assign an address to a label manually.
- `&macro { x 2 y 2 }`, define a macro named `macro`.
@ -75,16 +76,16 @@ BRK
@print-label ( text )
NOP
( send ) DUP2 LDR =CNSL.char
( incr ) #0001 ADD2
( loop ) DUP2 LDR #00 NEQ ^print-label MUL JMPS
$loop NOP
( send ) DUP2 LDR =CNSL.char
( incr ) #0001 ADD2
( loop ) DUP2 LDR #00 NEQ ^$loop MUL JMPS
POP2
RTS
RTS
@text1 [ Hello 20 World 0a00 ] ( text with linebreak and null bytes )
@text2 [ Welcome 20 to 20 UxnVM 0a00 ]
@text1 [ Welcome 20 to 20 UxnVM 0a00 ]
@text2 [ Hello 20 World 0a00 ]
|c000 @FRAME
|d000 @ERROR

View File

@ -167,6 +167,15 @@ findopcode(char *s)
return 0;
}
char *
sublabel(char *src, char *scope, char *name)
{
scpy(scope, src, 64);
scpy("-", src + slen(src), 64);
scpy(name, src + slen(src), 64);
return src;
}
#pragma mark - Parser
int
@ -274,7 +283,7 @@ pass1(FILE *f)
{
int ccmnt = 0, cbits = 0;
Uint16 addr = 0;
char w[64];
char w[64], scope[64], subw[64];
printf("Pass 1\n");
while(fscanf(f, "%s", w) == 1) {
if(skipblock(w, &ccmnt, '(', ')')) continue;
@ -288,6 +297,10 @@ pass1(FILE *f)
} else if(w[0] == '@') {
if(!makelabel(w + 1, addr, 0, NULL))
return error("Pass1 failed", w);
scpy(w + 1, scope, 64);
} else if(w[0] == '$') {
if(!makelabel(sublabel(subw, scope, w + 1), addr, 0, NULL))
return error("Pass1 failed", w);
} else if(w[0] == ';') {
if(!makevariable(w + 1, &addr, f))
return error("Pass1 failed", w);
@ -308,8 +321,6 @@ pass1(FILE *f)
break;
case '=': addr += 4; break; /* STR helper (lit addr-hb addr-lb str) */
case '~': addr += 4; break; /* LDR helper (lit addr-hb addr-lb ldr) */
case '$': addr += 4; break; /* JSR helper (lit addr-hb addr-lb jsr) */
case '/': addr += 4; break; /* JMP helper (lit addr-hb addr-lb jmp) */
case ',': addr += 3; break;
case '.': addr += 2; break;
case '^': addr += 2; break; /* Relative jump: lit addr-offset */
@ -328,13 +339,21 @@ int
pass2(FILE *f)
{
int ccmnt = 0, cbits = 0, cmacro = 0;
char w[64];
char w[64], scope[64], subw[64];
printf("Pass 2\n");
while(fscanf(f, "%s", w) == 1) {
Uint8 op = 0;
Label *l;
if(w[0] == '@') continue;
if(w[0] == '&') continue;
if(w[0] == '$') continue;
if(w[0] == '@') {
scpy(w + 1, scope, 64);
continue;
}
if(w[1] == '$') {
sublabel(subw, scope, w + 2);
scpy(subw, w + 1, 64);
}
if(skipblock(w, &ccmnt, '(', ')')) continue;
if(skipblock(w, &cmacro, '{', '}')) continue;
/* clang-format off */
@ -357,8 +376,6 @@ pass2(FILE *f)
else if(w[0] == ',' && (l = findlabel(w + 1))) { pushshort(findlabeladdr(w + 1), 1); l->refs++; }
else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w + 1) == 2 ? "STR2" : "STR"), 0); l->refs++;}
else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode(findlabellen(w + 1) == 2 ? "LDR2" : "LDR"), 0); l->refs++;}
else if(w[0] == '/' && (l = findlabel(w + 1))){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode("JMP2"), 0); l->refs++;}
else if(w[0] == '$' && (l = findlabel(w + 1))){ pushshort(findlabeladdr(w + 1), 1); pushbyte(findopcode("JSR2"), 0); l->refs++;}
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 1);
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 1);
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);

View File

@ -30,6 +30,9 @@ contexts:
- match: '\&(\S+)\s?'
scope: string.control
pop: true
- match: '\$(\S+)\s?'
scope: string.control
pop: true
# Special

View File

@ -4,8 +4,8 @@
|0100 @RESET
,text1 $print-label
,text2 $print-label
,text1 ,print-label JSR2
,text2 ,print-label JSR2
#ab =CNSL.byte
#cdef =CNSL.short
@ -13,16 +13,14 @@ BRK
@print-label ( text )
@print-label-loop NOP
$loop NOP
( send ) DUP2 LDR =CNSL.char
( incr ) #0001 ADD2
( loop ) DUP2 LDR #00 NEQ ^print-label-loop MUL JMPS
( loop ) DUP2 LDR #00 NEQ ^$loop MUL JMPS
POP2
RTS
( store text in memory )
@text1 [ Welcome 20 to 20 UxnVM 0a00 ]
@text2 [ Hello 20 World 0a00 ]

View File

@ -65,45 +65,45 @@ RTS
=dev/sprite.addr =color =rect.y2 =rect.x2 DUP2 =dev/sprite.y =rect.y1 DUP2 =dev/sprite.x =rect.x1
@tile-rect-ver
$ver
~rect.x1 =dev/sprite.x
@tile-rect-hor
$hor
( draw ) ~color =dev/sprite.color
( incr ) ~dev/sprite.x #0008 ADD2 =dev/sprite.x
,tile-rect-hor ~dev/sprite.x ~rect.x2 LTH2 JMP2? POP2
,$hor ~dev/sprite.x ~rect.x2 LTH2 JMP2? POP2
( incr ) ~dev/sprite.y #0008 ADD2 =dev/sprite.y
,tile-rect-ver ~dev/sprite.y ~rect.y2 LTH2 JMP2? POP2
,$ver ~dev/sprite.y ~rect.y2 LTH2 JMP2? POP2
RTS
@fill-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =dev/screen.y =rect.y1 DUP2 =dev/screen.x =rect.x1
@fill-rect-ver
$ver
~rect.x1 =dev/screen.x
@fill-rect-hor
$hor
( draw ) ~color =dev/screen.color
( incr ) ~dev/screen.x #0001 ADD2 =dev/screen.x
,fill-rect-hor ~dev/screen.x ~rect.x2 LTH2 JMP2? POP2
,$hor ~dev/screen.x ~rect.x2 LTH2 JMP2? POP2
( incr ) ~dev/screen.y #0001 ADD2 =dev/screen.y
,fill-rect-ver ~dev/screen.y ~rect.y2 LTH2 JMP2? POP2
,$ver ~dev/screen.y ~rect.y2 LTH2 JMP2? POP2
RTS
@line-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =dev/screen.y =rect.y1 DUP2 =dev/screen.x =rect.x1
@line-rect-hor
$hor
( incr ) ~dev/screen.x #0001 ADD2 =dev/screen.x
( draw ) ~rect.y1 =dev/screen.y ~color =dev/screen.color
( draw ) ~rect.y2 =dev/screen.y ~color =dev/screen.color
,line-rect-hor ~dev/screen.x ~rect.x2 LTH2 JMP2? POP2
,$hor ~dev/screen.x ~rect.x2 LTH2 JMP2? POP2
~rect.y1 =dev/screen.y
@line-rect-ver
$ver
( draw ) ~rect.x1 =dev/screen.x ~color =dev/screen.color
( draw ) ~rect.x2 =dev/screen.x ~color =dev/screen.color
( incr ) ~dev/screen.y #0001 ADD2 =dev/screen.y
,line-rect-ver ~dev/screen.y ~rect.y2 #0001 ADD2 LTH2 JMP2? POP2
,$ver ~dev/screen.y ~rect.y2 #0001 ADD2 LTH2 JMP2? POP2
RTS
@ -111,20 +111,17 @@ RTS
( load ) =textarea.addr =textarea.color =dev/sprite.y =dev/sprite.x
~textarea.addr
@draw-textarea-left-loop
$loop
( draw ) DUP2 LDR #00 SWP #0008 MUL2 ,font ADD2 =dev/sprite.addr ~textarea.color =dev/sprite.color
( detect linebreaks )
DUP2 LDR #0d NEQ ,no-return ROT JMP2? POP2
DUP2 LDR #0d NEQ ,$no-return ROT JMP2? POP2
~textarea.x1 =dev/sprite.x
( incr ) ~dev/sprite.y #0008 ADD2 =dev/sprite.y
( decr ) ~dev/sprite.x #0008 SUB2 =dev/sprite.x
@no-return
$no-return
( incr ) #0001 ADD2
( incr ) ~dev/sprite.x #0008 ADD2 =dev/sprite.x
DUP2 LDR #00 NEQ ,draw-textarea-left-loop ROT JMP2? POP2
DUP2 LDR #00 NEQ ,$loop ROT JMP2? POP2
POP2
RTS

View File

@ -129,11 +129,11 @@ RTS
( load ) =label.addr =label.color =dev/sprite.y =dev/sprite.x
~label.addr
@draw-label-loop
$loop
( draw ) DUP2 LDR #00 SWP #0008 MUL2 ,font ADD2 =dev/sprite.addr ~label.color =dev/sprite.color
( incr ) #0001 ADD2
( incr ) ~dev/sprite.x #0008 ADD2 =dev/sprite.x
DUP2 #0001 ADD2 LDR #00 NEQ ,draw-label-loop ROT JMP2? POP2
DUP2 #0001 ADD2 LDR #00 NEQ ,$loop ROT JMP2? POP2
POP2
RTS

View File

@ -270,7 +270,7 @@ RTS
( guides )
#00 =i ,font_hex =SPRT.addr
@draw-bankview-guides
$guides
~bankview.x #0010 SUB2 =SPRT.x
~bankview.y #00 ~i #08 MUL ADD2 =SPRT.y
( draw ) #02 =SPRT.color
@ -279,28 +279,28 @@ RTS
( draw ) #02 =SPRT.color
~SPRT.addr #0008 ADD2 =SPRT.addr
( incr ) ~i #01 ADD =i
,draw-bankview-guides ~i #10 LTH JMP2? POP2
,$guides ~i #10 LTH JMP2? POP2
( body )
~bankview.x =SPRT.x ~bankview.y =SPRT.y
#00 =pt.x #00 =pt.y ~bankview.addr =SPRT.addr
@draw-bankview-tiles-ver
$ver
#00 =pt.x
~bankview.x =SPRT.x
@draw-bankview-tiles-hor
$hor
( draw ) #01 =SPRT.color
,no-highlight ~SPRT.addr ~tileview.addr LTH2 JMP2? POP2
,no-highlight ~SPRT.addr ~tileview.addr #0018 ADD2 GTH2 JMP2? POP2
,$no-highlight ~SPRT.addr ~tileview.addr LTH2 JMP2? POP2
,$no-highlight ~SPRT.addr ~tileview.addr #0018 ADD2 GTH2 JMP2? POP2
( draw ) #0c =SPRT.color
@no-highlight
$no-highlight
( incr ) ~SPRT.x #0008 ADD2 =SPRT.x
( incr ) ~SPRT.addr #0008 ADD2 =SPRT.addr
( incr ) ~pt.x #01 ADD =pt.x
,draw-bankview-tiles-hor ~pt.x #10 LTH JMP2? POP2
,$hor ~pt.x #10 LTH JMP2? POP2
( incr ) ~pt.y #01 ADD =pt.y
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
,draw-bankview-tiles-ver ~pt.y #10 LTH JMP2? POP2
,$ver ~pt.y #10 LTH JMP2? POP2
RTS
@ -344,18 +344,18 @@ RTS
( line hor )
~tileview.y #003f ADD2 =SCRN.y
~tileview.x =SCRN.x
@draw-hor
$line-hor
( draw ) #03 =SCRN.color
( incr ) ~SCRN.x #0002 ADD2 =SCRN.x
~SCRN.x ~tileview.x #0082 ADD2 LTH2 ,draw-hor ROT JMP2? POP2
~SCRN.x ~tileview.x #0082 ADD2 LTH2 ,$line-hor ROT JMP2? POP2
( line ver )
~tileview.y =SCRN.y
~tileview.x #003f ADD2 =SCRN.x
@draw-ver
$line-ver
( draw ) #03 =SCRN.color
( incr ) ~SCRN.y #0002 ADD2 =SCRN.y
~SCRN.y ~tileview.y #0081 ADD2 LTH2 ,draw-ver ROT JMP2? POP2
~SCRN.y ~tileview.y #0081 ADD2 LTH2 ,$line-ver ROT JMP2? POP2
( rewind ) ~tileview.addr #0018 SUB2 =tileview.addr
@ -363,7 +363,7 @@ RTS
~tileview.y #0018 ADD2 =SPRT.y
#00 =i
@draw-tileview-bytes
$bytes
~tileview.x #0088 ADD2 =SPRT.x
,font_hex #00 ~tileview.addr #00 ~i ADD2 LDR #f0 AND #04 ROR #08 MUL ADD2 =SPRT.addr
( draw ) #02 =SPRT.color
@ -372,7 +372,7 @@ RTS
( draw ) #02 =SPRT.color
( incr ) ~i #01 ADD =i
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
,draw-tileview-bytes ~i #08 LTH JMP2? POP2
,$bytes ~i #08 LTH JMP2? POP2
( operations )
@ -387,27 +387,27 @@ RTS
~tileview.y =SPRT.y
#00 =pt.x #00 =pt.y ~tileview.addr =SPRT.addr
@draw-tileview-tiles-ver
$tiles-ver
#00 =pt.x
~tileview.x #0088 ADD2 =SPRT.x
@draw-tileview-tiles-hor
$tiles-hor
( draw ) #03 =SPRT.color
( incr ) ~SPRT.x #0008 ADD2 =SPRT.x
( incr ) ~SPRT.addr #0008 ADD2 =SPRT.addr
( incr ) ~pt.x #01 ADD =pt.x
,draw-tileview-tiles-hor ~pt.x #02 LTH JMP2? POP2
,$tiles-hor ~pt.x #02 LTH JMP2? POP2
( incr ) ~pt.y #01 ADD =pt.y
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
,draw-tileview-tiles-ver ~pt.y #02 LTH JMP2? POP2
,$tiles-ver ~pt.y #02 LTH JMP2? POP2
RTS
@draw-tileview-icn
#00 =pt.x #00 =pt.y
@redraw-ver
$ver
#00 =pt.x
@redraw-hor
$hor
( get bit )
,blank_icn #00
~tileview.addr #00 ~pt.y ADD2 LDR #07 ~pt.x SUB ROR #01 AND ( get bit )
@ -415,11 +415,11 @@ RTS
( draw ) #01 =SPRT.color
( incr ) ~SPRT.x #0008 ADD2 =SPRT.x
( incr ) ~pt.x #01 ADD =pt.x
,redraw-hor ~pt.x #08 LTH JMP2? POP2
,$hor ~pt.x #08 LTH JMP2? POP2
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
( incr ) ~pt.y #01 ADD =pt.y
~SPRT.x #0040 SUB2 =SPRT.x
,redraw-ver ~pt.y #08 LTH JMP2? POP2
,$ver ~pt.y #08 LTH JMP2? POP2
RTS
@ -470,17 +470,17 @@ RTS
@line-rect ( x1 y1 x2 y2 color )
( load ) =color =rect.y2 =rect.x2 DUP2 =SCRN.y =rect.y1 DUP2 =SCRN.x =rect.x1
@line-rect-hor NOP
$hor NOP
( incr ) ~SCRN.x #0001 ADD2 =SCRN.x
( draw ) ~rect.y1 =SCRN.y ~color =SCRN.color
( draw ) ~rect.y2 =SCRN.y ~color =SCRN.color
~SCRN.x ~rect.x2 LTH2 ^line-rect-hor MUL JMPS
~SCRN.x ~rect.x2 LTH2 ^$hor MUL JMPS
~rect.y1 =SCRN.y
@line-rect-ver NOP
$ver NOP
( draw ) ~rect.x1 =SCRN.x ~color =SCRN.color
( draw ) ~rect.x2 =SCRN.x ~color =SCRN.color
( incr ) ~SCRN.y #0001 ADD2 =SCRN.y
~SCRN.y ~rect.y2 #0001 ADD2 LTH2 ^line-rect-ver MUL JMPS
~SCRN.y ~rect.y2 #0001 ADD2 LTH2 ^$ver MUL JMPS
RTS

View File

@ -7,22 +7,24 @@
|0100 @RESET
( type: padded muljmp )
@loop1 NOP
@part1
$loop NOP
~a #01 ADD =a
~a #d0 LTH ^loop1 MUL JMPS
~a #d0 LTH ^$loop MUL JMPS
( type: jmppop )
@loop2
@part2
$loop
~b #01 ADD =b
,loop2 ~b #d0 LTH JMP2? POP2
,$loop ~b #d0 LTH JMP2? POP2
( type: padded jmppop )
@loop3 NOP
@part3
$loop NOP
~c #01 ADD =c
~c #d0 LTH ^loop3 SWP JMPS? POP
~c #d0 LTH ^$loop SWP JMPS? POP
~a =dev/console.byte
~b =dev/console.byte