diff --git a/compiler.c b/compiler.c index 428fd6f..f55ffa8 100644 --- a/compiler.c +++ b/compiler.c @@ -471,16 +471,28 @@ if_statement() consume(TOKEN_LPAREN); expression(); consume(TOKEN_RPAREN); - emitter.emit_jump(); + emitter.emit_if(); statement(); - emitter.emit_patch_jump(emitter.ifs); - if (match(TOKEN_KEYWORD_ELSE)) { + emitter.emit_patch_if(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++); + } + if(emitter.else_if_depth == 0) emitter.emit_patch_if_done(emitter.ifs++); +} + +void +while_statement() +{ + emitter.emit_while(emitter.loops); + consume(TOKEN_LPAREN); + expression(); + consume(TOKEN_RPAREN); + emitter.emit_while_postfix(); + statement(); + emitter.emit_patch_while(emitter.loops++); } void @@ -500,6 +512,8 @@ statement() scope_pop(); } else if(match(TOKEN_KEYWORD_IF)) { if_statement(); + } else if(match(TOKEN_KEYWORD_WHILE)) { + while_statement(); } else if(match(TOKEN_KEYWORD_PRINT)) { print_statement(); } else if(match(TOKEN_KEYWORD_PUTCHAR)) { diff --git a/emit.h b/emit.h index 0aa3ccf..2bd902f 100644 --- a/emit.h +++ b/emit.h @@ -17,6 +17,8 @@ typedef struct emitter_s Emitter; struct emitter_s { i32 ifs; i32 else_if_depth; + i32 loops; + i32 loop_depth; ErrorMsg error; VoidArgEmit prolog; VoidArgEmit epilogue; @@ -100,9 +102,12 @@ struct emitter_s { VoidArgEmit emit_mod; VoidArgEmit emit_and; VoidArgEmit emit_or; - VoidArgEmit emit_jump; - I32ArgEmit emit_patch_jump; - I32ArgEmit emit_patch_jump_done; + VoidArgEmit emit_if; + I32ArgEmit emit_patch_if; + I32ArgEmit emit_patch_if_done; + I32ArgEmit emit_while; + VoidArgEmit emit_while_postfix; + I32ArgEmit emit_patch_while; }; Emitter rer_emitter(); diff --git a/emit/rer/emit.c b/emit/rer/emit.c index 6fb5f21..b8b099d 100644 --- a/emit/rer/emit.c +++ b/emit/rer/emit.c @@ -1,3 +1,4 @@ + #include "../../emit.h" #include #include @@ -24,10 +25,7 @@ rer_prolog() void rer_epilogue() { - printf("BRK\n\n@str/ ( str* -- )\n\ - LDAk DUP ?{ POP POP2 JMP2r }\n\ - #18 DEO\n\ - INC2 !/\n"); + printf("BRK\n\n"); } void @@ -117,7 +115,7 @@ rer_emit_neg() void rer_emit_not() { - printf("#ffff EOR2 "); + printf("#0000 EQU2 "); } void @@ -294,9 +292,9 @@ rer_emit_str(const char *str, i32 length) /* set a pointer to the string literal and then jump over it */ printf(";{ #0002 ADD2 } !{ "); - for(i32 i = 1; i < length - 1; i++) printf("#%02x ", str[i]); + for(i32 i = 1; i < length - 1; i++) printf("%02x ", str[i]); - printf("#00 } "); + printf("00 } "); } void @@ -397,6 +395,7 @@ rer_emit_stat() void rer_emit_end_statement() { + printf("\n"); } void @@ -412,46 +411,55 @@ rer_emit_plex_def() void rer_emit_cast_int_to_nat() { + printf("int_to_nat_ "); } void rer_emit_cast_int_to_real() { + printf("int_to_real_ "); } void rer_emit_cast_int_to_str() { + printf("int_to_str_ "); } void rer_emit_cast_nat_to_int() { + printf("nat_to_int_ "); } void rer_emit_cast_nat_to_real() { + printf("nat_to_real_ "); } void rer_emit_cast_nat_to_str() { + printf("nat_to_str_ "); } void rer_emit_cast_real_to_int() { + printf("real_to_int_ "); } void rer_emit_cast_real_to_nat() { + printf("real_to_nat_ "); } void rer_emit_cast_real_to_str() { + printf("real_to_str_ "); } void @@ -543,47 +551,49 @@ rer_emit_print() printf("str/ "); } -i32 -rer_emit_const_type(SymbolType type, const char *var, i32 var_length, - const char *val, i32 val_legnth, bool local) -{ - - if(local) - printf("&%.*s ", var_length, var); - else - printf("@%.*s ", var_length, var); - - if(type == SYMBOL_STR) { - for(i32 i = 1; i < val_legnth - 1; i++) printf("#%02x ", val[i]); - } else { - i32 i = (i32)strtol(val, nil, 10); - printf("#%04x ", i); - } - - return 2; -} void -rer_emit_jump() +rer_emit_if() { printf("#03 JCN !{ "); } void -rer_emit_patch_jump(i32 local_ifs) +rer_emit_patch_if(i32 local_ifs) { - printf("!&if_end.%d } ", local_ifs); + printf("!&if_end.%d } ", local_ifs); } void -rer_emit_patch_jump_done(i32 local_ifs) +rer_emit_patch_if_done(i32 local_ifs) { - printf("&if_end.%d ", local_ifs); + printf("&if_end.%d ", local_ifs); } -Emitter -rer_emitter() + +void +rer_emit_while(i32 local_whiles) +{ + printf("&while.%d ", local_whiles); +} + +void +rer_emit_while_postfix() +{ + printf("#03 JCN !{ "); +} + +void +rer_emit_patch_while(i32 local_whiles) +{ + printf("!&while.%d } ", local_whiles); +} + + +Emitter rer_emitter() { return (Emitter){ + 0, + 0, 0, 0, rer_emit_error, @@ -669,8 +679,11 @@ rer_emitter() rer_emit_mod, rer_emit_and, rer_emit_or, - rer_emit_jump, - rer_emit_patch_jump, - rer_emit_patch_jump_done, + rer_emit_if, + rer_emit_patch_if, + rer_emit_patch_if_done, + rer_emit_while, + rer_emit_while_postfix, + rer_emit_patch_while, }; } diff --git a/emit/uxn/emit.c b/emit/uxn/emit.c index 5765af9..802407c 100644 --- a/emit/uxn/emit.c +++ b/emit/uxn/emit.c @@ -698,27 +698,48 @@ uxn_emit_print() } void -uxn_emit_jump() +uxn_emit_if() { printf("#03 JCN !{ "); } void -uxn_emit_patch_jump(i32 local_ifs) +uxn_emit_patch_if(i32 local_ifs) { printf("!&if_end.%d } ", local_ifs); } void -uxn_emit_patch_jump_done(i32 local_ifs) +uxn_emit_patch_if_done(i32 local_ifs) { printf("&if_end.%d ", local_ifs); } -Emitter -uxn_emitter() + +void +uxn_emit_while(i32 local_whiles) +{ + printf("&while.%d ", local_whiles); +} + +void +uxn_emit_while_postfix() +{ + printf("#03 JCN !{ "); +} + +void +uxn_emit_patch_while(i32 local_whiles) +{ + printf("!&while.%d } ", local_whiles); +} + + +Emitter uxn_emitter() { return (Emitter){ + 0, + 0, 0, 0, uxn_emit_error, @@ -804,8 +825,11 @@ uxn_emitter() uxn_emit_mod, uxn_emit_and, uxn_emit_or, - uxn_emit_jump, - uxn_emit_patch_jump, - uxn_emit_patch_jump_done, + uxn_emit_if, + uxn_emit_patch_if, + uxn_emit_patch_if_done, + uxn_emit_while, + uxn_emit_while_postfix, + uxn_emit_patch_while, }; } diff --git a/test/hardcoded-while.tal b/test/hardcoded-while.tal new file mode 100644 index 0000000..96daf28 --- /dev/null +++ b/test/hardcoded-while.tal @@ -0,0 +1,13 @@ +|100 +!{ @i $2 } #0000 ;i STA2 + +&while.1 [ ;i LDA2 #0008 LTH2 ] #03 JCN !{ ( Loop while iterator is less than limit. ) + ;i LDA2 print-num ( Run function to print number ) + ;i LDA2 INC2 ;i STA2 ( incriment counter ) +!&while.1 } +BRK ( Halt. ) + +@print-num ( int -- ) + LIT "0 ADD ( Add number to ascii character 0 ) + #18 DEO ( Send to Console/write ) + JMP2r diff --git a/test/if.tal b/test/if.tal index 90beac6..69864db 100644 --- a/test/if.tal +++ b/test/if.tal @@ -1,8 +1,8 @@ |100 !{ @x $2 } #0014 ;x STA2 -;x LDA2 #000a EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 31 30 00 } str/ -!&if_end.0 } ;x LDA2 #0014 EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 32 30 00 } str/ -!&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/ +;x LDA2 #000a EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 31 30 00 } str/ !&if_end.0 } +;x LDA2 #0014 EQU2 #03 JCN !{ ;{ #0002 ADD2 } !{ 78 20 69 73 20 32 30 00 } str/ !&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/ &if_end.0 BRK @sext diff --git a/test/while.tal b/test/while.tal new file mode 100644 index 0000000..b1e7fd9 --- /dev/null +++ b/test/while.tal @@ -0,0 +1,70 @@ +|100 +!{ @i $2 } #0000 ;i STA2 + +&loop.0 ;i LDA2 #000a LTH2 #03 JCN !{ ;i LDA2 nat_to_str_ str/ +;i LDA2 ;i LDA2 #0001 ADD2 ;i STA2 !&loop.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/ ( str* -- ) + LDAk DUP ?{ POP POP2 JMP2r } + #18 DEO + INC2 !/ + +@mem_length_ #0000 +@mem_