labels, goto
This commit is contained in:
parent
a26f0d52d9
commit
5dba28b8ba
2 changed files with 38 additions and 10 deletions
32
05/codegen.b
32
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
|
||||
|
|
16
05/main.c
16
05/main.c
|
@ -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 ;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue