break, continue

This commit is contained in:
pommicket 2022-02-13 12:43:34 -05:00
parent 70523ba1bb
commit a26f0d52d9
2 changed files with 112 additions and 7 deletions

View file

@ -23,6 +23,9 @@ global functions_labels ; ident list of ident lists of label addresses
global curr_function_labels ; ident list of labels for current function (written to in 1st pass, read from in 2nd pass)
global curr_function_return_type
global break_refs ; 0-terminated array of pointers to be filled in with the break offset
global continue_refs
#define REG_RAX 0
#define REG_RBX 3
#define REG_RCX 1
@ -2503,6 +2506,43 @@ function generate_push_expression
emit_add_rsp_imm32(args_size)
return
; fill in break/continue jump addresses
function handle_refs
argument p_refs
argument prev_refs
argument ref_addr
local refs
local p
local addr
local d
refs = *8p_refs
p = refs
:handle_refs_loop
if *8p == 0 goto handle_refs_loop_end
addr = *8p
p += 8
d = ref_addr - addr
addr -= 4
*4addr = d
goto handle_refs_loop
:handle_refs_loop_end
free(refs)
*8p_refs = prev_refs
return
function add_ref
argument refs
argument addr
:add_ref_loop
if *8refs == 0 goto add_ref_loop_end
refs += 8
goto add_ref_loop
:add_ref_loop_end
*8refs = addr
return
function generate_statement
argument statement
local dat1
@ -2512,11 +2552,16 @@ function generate_statement
local addr0
local addr1
local addr2
local prev_continue_refs
local prev_break_refs
local n
local p
local c
local d
prev_continue_refs = continue_refs
prev_break_refs = break_refs
dat1 = statement + 8
dat1 = *8dat1
dat2 = statement + 16
@ -2528,6 +2573,7 @@ function generate_statement
c = *1statement
if c == STATEMENT_NOOP goto return_0
if c == STATEMENT_BLOCK goto gen_block
if c == STATEMENT_RETURN goto gen_return
if c == STATEMENT_LOCAL_DECLARATION goto gen_local_decl
@ -2535,6 +2581,9 @@ function generate_statement
if c == STATEMENT_IF goto gen_stmt_if
if c == STATEMENT_WHILE goto gen_stmt_while
if c == STATEMENT_DO goto gen_stmt_do
if c == STATEMENT_FOR goto gen_stmt_for
if c == STATEMENT_CONTINUE goto gen_stmt_continue
if c == STATEMENT_BREAK goto gen_stmt_break
; @TODO
die(.str_genstmtNI)
@ -2616,6 +2665,9 @@ function generate_statement
*4addr1 = d
return
:gen_stmt_while
continue_refs = malloc(8000)
break_refs = malloc(8000)
addr0 = code_output
p = dat1 + 4
generate_push_expression(statement, dat1)
@ -2625,6 +2677,10 @@ function generate_statement
generate_statement(dat2)
emit_jmp_rel32(0) ; jmp +0 (temporary)
addr2 = code_output
handle_refs(&continue_refs, prev_continue_refs, addr0)
handle_refs(&break_refs, prev_break_refs, addr2)
; fill in je
d = addr2 - addr1
p = addr1 - 4
@ -2635,6 +2691,9 @@ function generate_statement
*4p = d
return
:gen_stmt_do
continue_refs = malloc(8000)
break_refs = malloc(8000)
addr0 = code_output
generate_statement(dat1)
p = dat2 + 4
@ -2642,10 +2701,52 @@ function generate_statement
generate_stack_compare_against_zero(statement, *4p)
emit_jne_rel32(0) ; jne +0 (temorary)
addr1 = code_output
handle_refs(&continue_refs, prev_continue_refs, addr0)
handle_refs(&break_refs, prev_break_refs, addr1)
d = addr0 - addr1
addr1 -= 4
*4addr1 = d
return
:gen_stmt_for
continue_refs = malloc(8000)
break_refs = malloc(8000)
generate_push_expression_casted(statement, dat1, TYPE_VOID)
emit_add_rsp_imm32(8) ; void is stored as 8 bytes
addr0 = code_output
p = dat2 + 4
generate_push_expression(statement, dat2)
generate_stack_compare_against_zero(statement, *4p)
emit_je_rel32(0) ; je +0 (temporary)
addr1 = code_output
generate_statement(dat4)
handle_refs(&continue_refs, prev_continue_refs, code_output)
generate_push_expression_casted(statement, dat3, TYPE_VOID)
emit_add_rsp_imm32(8) ; void is stored as 8 bytes
emit_jmp_rel32(0) ; jmp +0 (temporary)
addr2 = code_output
handle_refs(&break_refs, prev_break_refs, addr2)
; fill in je
d = addr2 - addr1
p = addr1 - 4
*4p = d
; fill in jmp
d = addr0 - addr2
p = addr2 - 4
*4p = d
return
:gen_stmt_continue
emit_jmp_rel32(0) ; jmp +0 (temporary)
add_ref(continue_refs, code_output)
return
:gen_stmt_break
emit_jmp_rel32(0) ; jmp +0 (temporary)
add_ref(break_refs, code_output)
return
function generate_function
argument function_name

View file

@ -24,12 +24,16 @@ long gcd(long a, long b) {
}
int main(int argc, char **argv) {
double f = 1;
int exp = 0;
do {
f /= 2;
++exp;
} while (f);
return exp;
int i;
int j;
for (i = 0; i < 10; ++i) {
for (j = 0; j < 10; ++j) {
if (j >= i) break;
exp += 1;
}
if (i >= 5) break;
}
return exp ;
}