add if / else statements

This commit is contained in:
zongor 2026-04-27 22:02:37 -07:00
parent 46336105aa
commit ab5a7ee185
10 changed files with 279 additions and 122 deletions

View File

@ -49,7 +49,7 @@ main(int argc, char **argv)
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
if(argc != 3) { if(argc < 3) {
print_help(); print_help();
return EXIT_FAILURE; return EXIT_FAILURE;
} }

View File

@ -443,8 +443,8 @@ print_statement()
{ {
expression(); expression();
consume(TOKEN_SEMICOLON); consume(TOKEN_SEMICOLON);
emitter.emit_end_statement();
emitter.emit_print(); emitter.emit_print();
emitter.emit_end_statement();
} }
void void
@ -473,7 +473,14 @@ if_statement()
consume(TOKEN_RPAREN); consume(TOKEN_RPAREN);
emitter.emit_jump(); emitter.emit_jump();
statement(); statement();
emitter.emit_patch_jump();
emitter.emit_patch_jump(emitter.ifs);
if (match(TOKEN_KEYWORD_ELSE)) {
emitter.else_if_depth++;
statement();
emitter.else_if_depth--;
}
if (emitter.else_if_depth == 0) emitter.emit_patch_jump_done(emitter.ifs++);
} }
void void

6
emit.h
View File

@ -11,9 +11,12 @@ typedef void (*StrArgEmit)(const char *str, i32 length);
typedef i32 (*TypeVariableEmit)(const char *str, i32 length, bool local); typedef i32 (*TypeVariableEmit)(const char *str, i32 length, bool local);
typedef void (*ConstEmit)(const char *str, i32 length, bool local); typedef void (*ConstEmit)(const char *str, i32 length, bool local);
typedef void (*VarEmit)(Symbol *sym, bool local); typedef void (*VarEmit)(Symbol *sym, bool local);
typedef void (*I32ArgEmit)(i32 val);
typedef struct emitter_s Emitter; typedef struct emitter_s Emitter;
struct emitter_s { struct emitter_s {
i32 ifs;
i32 else_if_depth;
ErrorMsg error; ErrorMsg error;
VoidArgEmit prolog; VoidArgEmit prolog;
VoidArgEmit epilogue; VoidArgEmit epilogue;
@ -98,7 +101,8 @@ struct emitter_s {
VoidArgEmit emit_and; VoidArgEmit emit_and;
VoidArgEmit emit_or; VoidArgEmit emit_or;
VoidArgEmit emit_jump; VoidArgEmit emit_jump;
VoidArgEmit emit_patch_jump; I32ArgEmit emit_patch_jump;
I32ArgEmit emit_patch_jump_done;
}; };
Emitter rer_emitter(); Emitter rer_emitter();

View File

@ -294,9 +294,7 @@ rer_emit_str(const char *str, i32 length)
/* set a pointer to the string literal and then jump over it */ /* set a pointer to the string literal and then jump over it */
printf(";{ #0002 ADD2 } !{ "); printf(";{ #0002 ADD2 } !{ ");
for (i32 i = 1; i < length - 1 ; i++) { for(i32 i = 1; i < length - 1; i++) printf("#%02x ", str[i]);
printf("#%02x ", str[i]);
}
printf("#00 } "); printf("#00 } ");
} }
@ -545,31 +543,18 @@ rer_emit_print()
printf("str/<print> "); printf("str/<print> ");
} }
void
rer_emit_jump()
{
printf("?{ ");
}
void
rer_emit_patch_jump()
{
printf("} ");
}
i32 i32
rer_emit_const_type(SymbolType type, const char *var, i32 var_length, const char *val, i32 val_legnth, bool local) { rer_emit_const_type(SymbolType type, const char *var, i32 var_length,
const char *val, i32 val_legnth, bool local)
{
if(local) if(local)
printf("&%.*s ", var_length, var); printf("&%.*s ", var_length, var);
else else
printf("@%.*s ", var_length, var); printf("@%.*s ", var_length, var);
if (type == SYMBOL_STR) { if(type == SYMBOL_STR) {
for (i32 i = 1; i < val_legnth - 1 ; i++) { for(i32 i = 1; i < val_legnth - 1; i++) printf("#%02x ", val[i]);
printf("#%02x ", val[i]);
}
} else { } else {
i32 i = (i32)strtol(val, nil, 10); i32 i = (i32)strtol(val, nil, 10);
printf("#%04x ", i); printf("#%04x ", i);
@ -577,11 +562,30 @@ rer_emit_const_type(SymbolType type, const char *var, i32 var_length, const char
return 2; return 2;
} }
void
rer_emit_jump()
{
printf("#03 JCN !{ ");
}
void
rer_emit_patch_jump(i32 local_ifs)
{
printf("!&if_end.%d } ", local_ifs);
}
void
rer_emit_patch_jump_done(i32 local_ifs)
{
printf("&if_end.%d ", local_ifs);
}
Emitter Emitter
rer_emitter() rer_emitter()
{ {
return (Emitter){ return (Emitter){
0,
0,
rer_emit_error, rer_emit_error,
rer_prolog, rer_prolog,
rer_epilogue, rer_epilogue,
@ -667,5 +671,6 @@ rer_emitter()
rer_emit_or, rer_emit_or,
rer_emit_jump, rer_emit_jump,
rer_emit_patch_jump, rer_emit_patch_jump,
rer_emit_patch_jump_done,
}; };
} }

View File

@ -168,7 +168,7 @@ uxn_prolog()
void void
uxn_epilogue() uxn_epilogue()
{ {
printf("\n\n"); printf("BRK\n\n");
for (u32 i = 0; i < __lib_undar_len; i++) { for (u32 i = 0; i < __lib_undar_len; i++) {
putchar(__lib_undar[i]); putchar(__lib_undar[i]);
} }
@ -261,7 +261,7 @@ uxn_emit_neg()
void void
uxn_emit_not() uxn_emit_not()
{ {
printf("#ffff EOR2 "); printf("#0000 EQU2 ");
} }
void void
@ -700,19 +700,27 @@ uxn_emit_print()
void void
uxn_emit_jump() uxn_emit_jump()
{ {
printf("?{ "); printf("#03 JCN !{ ");
} }
void void
uxn_emit_patch_jump() uxn_emit_patch_jump(i32 local_ifs)
{ {
printf("} "); printf("!&if_end.%d } ", local_ifs);
}
void
uxn_emit_patch_jump_done(i32 local_ifs)
{
printf("&if_end.%d ", local_ifs);
} }
Emitter Emitter
uxn_emitter() uxn_emitter()
{ {
return (Emitter){ return (Emitter){
0,
0,
uxn_emit_error, uxn_emit_error,
uxn_prolog, uxn_prolog,
uxn_epilogue, uxn_epilogue,
@ -798,5 +806,6 @@ uxn_emitter()
uxn_emit_or, uxn_emit_or,
uxn_emit_jump, uxn_emit_jump,
uxn_emit_patch_jump, uxn_emit_patch_jump,
uxn_emit_patch_jump_done,
}; };
} }

View File

@ -1,8 +1,69 @@
|100 |100
!{ @flag $1 } #0000 ;flag STA2 ;flag LDA2 #ffff EOR2 ?{ ;{ #0002 ADD2 } !{ #66 #6c #61 #67 #20 #69 #73 #20 #66 #61 #6c #73 #65 #00 } str/<print> } BRK !{ @flag $1 } #0000 ;flag STA2
;flag LDA2 #0000 EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 66 6c 61 67 20 69 73 20 66 61 6c 73 65 00 } str/<print>
!&if_end.0 } &if_end.0 BRK
@sext
#80 ANDk EQU #ff MUL SWP JMP2r
@aalloc_ ( size* -- result* )
OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2
;mem_length_ LDA2 STH2kr STA2
;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2
;mem_ STH2kr LDA2 ADD2 !&return
#0000
&return
POP2r JMP2r
@amcpy_ ( length* from* -- result* )
OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2
STH2kr #0004 ADD2 STA2
STH2kr #0004 ADD2 LDA2 aalloc_
STH2kr INC2 INC2 STA2
#0000 STH2kr STA2
&begin.1
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
POP
&continue.1
STH2kr LDA2k INC2k ROT2 STA2
POP2 !&begin.1
&break.1
STH2kr INC2 INC2 LDA2 !&return
#0000
&return
POP2r JMP2r
@nat_to_str_ ( n* -- result* )
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
#0005 STH2kr STA2
&begin.1
STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2
&continue.1
#0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1
&break.1
#0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_
!&return
#0000
&return
POP2r JMP2r
@str/<print> ( str* -- ) @str/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r } LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO #18 DEO
INC2 !/<print> INC2 !/<print>
@mem_length_ #0000
@mem_

71
test/if.tal Normal file
View File

@ -0,0 +1,71 @@
|100
!{ @x $2 } #0014 ;x STA2
;x LDA2 #000a EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 31 30 00 } str/<print>
!&if_end.0 } ;x LDA2 #0014 EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 32 30 00 } str/<print>
!&if_end.0 } ;{ #0002 ADD2 } !{ 78 20 69 73 20 73 6f 6d 65 74 68 69 6e 67 20 65 6c 73 65 00 } str/<print>
&if_end.0 BRK
@sext
#80 ANDk EQU #ff MUL SWP JMP2r
@aalloc_ ( size* -- result* )
OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2
;mem_length_ LDA2 STH2kr STA2
;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2
;mem_ STH2kr LDA2 ADD2 !&return
#0000
&return
POP2r JMP2r
@amcpy_ ( length* from* -- result* )
OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2
STH2kr #0004 ADD2 STA2
STH2kr #0004 ADD2 LDA2 aalloc_
STH2kr INC2 INC2 STA2
#0000 STH2kr STA2
&begin.1
STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1
STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext
STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA
POP
&continue.1
STH2kr LDA2k INC2k ROT2 STA2
POP2 !&begin.1
&break.1
STH2kr INC2 INC2 LDA2 !&return
#0000
&return
POP2r JMP2r
@nat_to_str_ ( n* -- result* )
OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2
#0005 STH2kr STA2
&begin.1
STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k
POP2 ADD2 STA
POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2
&continue.1
#0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1
&break.1
#0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_
!&return
#0000
&return
POP2r JMP2r
@str/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO
INC2 !/<print>
@mem_length_ #0000
@mem_

View File

@ -1,4 +1,4 @@
nat x = 10; nat x = 20;
if (x == 10) { if (x == 10) {
print("x is 10"); print("x is 10");

View File

@ -1,7 +1,7 @@
#include <stdio.h> #include <stdio.h>
char* msg = " damage inflicted!\n"; char* msg = " damage inflicted!\n";
int main() { void main() {
unsigned AT = 14; unsigned AT = 14;
unsigned accuracy = 150; unsigned accuracy = 150;