diff options
author | pommicket <pommicket@gmail.com> | 2022-02-13 12:51:21 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-02-13 12:51:21 -0500 |
commit | 5dba28b8bac76835e437091f3aed22a2578b7652 (patch) | |
tree | 7f5f30ae6ad80611543712431f49fe567db06ff8 /05 | |
parent | a26f0d52d9f6934d792eb2e7457946a0515b9a5c (diff) |
labels, goto
Diffstat (limited to '05')
-rw-r--r-- | 05/codegen.b | 32 | ||||
-rw-r--r-- | 05/main.c | 16 |
2 files changed, 38 insertions, 10 deletions
diff --git a/05/codegen.b b/05/codegen.b index a75c4d4..6c8728a 100644 --- a/05/codegen.b +++ b/05/codegen.b @@ -2584,6 +2584,8 @@ function generate_statement if c == STATEMENT_FOR goto gen_stmt_for if c == STATEMENT_CONTINUE goto gen_stmt_continue if c == STATEMENT_BREAK goto gen_stmt_break + if c == STATEMENT_LABEL goto gen_stmt_label + if c == STATEMENT_GOTO goto gen_stmt_goto ; @TODO die(.str_genstmtNI) @@ -2747,7 +2749,35 @@ function generate_statement emit_jmp_rel32(0) ; jmp +0 (temporary) add_ref(break_refs, code_output) return - + :gen_stmt_label + if codegen_second_pass != 0 goto gen_label_pass2 + ident_list_add(curr_function_labels, dat1, code_output) + return + :gen_label_pass2 + addr1 = ident_list_lookup(curr_function_labels, dat1) + if addr1 != code_output goto bad_label_addr + return + :bad_label_addr + die(.str_bad_label_addr) + :str_bad_label_addr + string Internal compiler error: Label address on 2nd pass doesn't match 1st pass. + byte 0 + :gen_stmt_goto + if codegen_second_pass == 0 goto gen_goto_pass1 + addr0 = ident_list_lookup(curr_function_labels, dat1) + if addr0 == 0 goto bad_label + d = addr0 - code_output + d -= 5 ; subtract length of jmp instruction + emit_jmp_rel32(d) + return + :gen_goto_pass1 + emit_jmp_rel32(0) ; we don't know the address of the label; just use 0 + return + :bad_label + statement_error(statement, .str_bad_label) + :str_bad_label + string Unrecognized label. + byte 0 function generate_function argument function_name argument function_statement @@ -23,17 +23,15 @@ long gcd(long a, long b) { return b; } +int f() { + lb: goto lb; +} + int main(int argc, char **argv) { int exp = 0; - 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; - } + lb: + exp++; + if (exp < 10) goto lb; return exp ; } |