add while loops
This commit is contained in:
parent
ab5a7ee185
commit
3ac64d18a0
22
compiler.c
22
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)) {
|
||||
|
|
|
|||
11
emit.h
11
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();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#include "../../emit.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -24,10 +25,7 @@ rer_prolog()
|
|||
void
|
||||
rer_epilogue()
|
||||
{
|
||||
printf("BRK\n\n@str/<print> ( str* -- )\n\
|
||||
LDAk DUP ?{ POP POP2 JMP2r }\n\
|
||||
#18 DEO\n\
|
||||
INC2 !/<print>\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/<print> ");
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
rer_emit_patch_jump_done(i32 local_ifs)
|
||||
rer_emit_patch_if_done(i32 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,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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/<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>
|
||||
;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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
|100
|
||||
!{ @i $2 } #0000 ;i STA2
|
||||
|
||||
&loop.0 ;i LDA2 #000a LTH2 #03 JCN !{ ;i LDA2 nat_to_str_ str/<print>
|
||||
;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/<print> ( str* -- )
|
||||
LDAk DUP ?{ POP POP2 JMP2r }
|
||||
#18 DEO
|
||||
INC2 !/<print>
|
||||
|
||||
@mem_length_ #0000
|
||||
@mem_
|
||||
Loading…
Reference in New Issue