diff options
author | pommicket <pommicket@gmail.com> | 2022-02-06 16:52:50 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-02-06 16:52:50 -0500 |
commit | dd035eb2247201e329d383158c2e330d56fc7388 (patch) | |
tree | b41823244769855e0e732bbdbb2999b0705b6c10 /05 | |
parent | 029be0600d25d1ee220ee1fb55a7495633e8b742 (diff) |
switch, for
Diffstat (limited to '05')
-rw-r--r-- | 05/main.c | 14 | ||||
-rw-r--r-- | 05/parse.b | 170 |
2 files changed, 181 insertions, 3 deletions
@@ -9,6 +9,13 @@ int f(void) { break; continue; }while(0); + if (0) { + if(1) { + return g; + }else; + } else if (5 == 6){ + return 6 * g; + } lbl1:break;;goto blah; case -1-3: continue;a:break;return;return 6+3<<sizeof(int); @@ -17,6 +24,13 @@ int f(void) { return g; static int x = 0x12345; return x; + switch(g<<17){ + case 88: break; + case 99: int x = 3; + } + int i; + for(i=0;i < 100; i ++); + for(;;); } int h(void) { @@ -350,6 +350,9 @@ function parse_statement if c == KEYWORD_EXTERN goto stmt_extern_declaration if c == KEYWORD_WHILE goto stmt_while if c == KEYWORD_DO goto stmt_do + if c == KEYWORD_FOR goto stmt_for + if c == KEYWORD_SWITCH goto stmt_switch + if c == KEYWORD_IF goto stmt_if b = token_is_type(token) if b != 0 goto stmt_local_declaration @@ -368,6 +371,34 @@ function parse_statement ; @NONSTANDARD string Local extern declarations are not supported. byte 0 + :stmt_switch + write_statement_header(out, STATEMENT_SWITCH, token) + token += 16 + if *1token != SYMBOL_LPAREN goto switch_no_lparen + p = token_matching_rparen(token) + token += 16 + out += 8 + *8out = expressions_end + expressions_end = parse_expression(token, p, expressions_end) + token = p + 16 + out += 8 + + ; put the body statement 1 block_depth deeper + p = statement_datas_ends + p += block_depth < 3 + block_depth += 1 + if block_depth >= BLOCK_DEPTH_LIMIT goto too_much_nesting + *8out = *8p + out += 24 + parse_statement(&token, p) ; the body + block_depth -= 1 + + goto parse_statement_ret + :switch_no_lparen + token_error(token, .str_switch_no_lparen) + :str_switch_no_lparen + string No ( after switch. + byte 0 :stmt_while write_statement_header(out, STATEMENT_WHILE, token) token += 16 @@ -381,7 +412,7 @@ function parse_statement out += 8 ; put the body statement 1 block_depth deeper - p = statement_datas + p = statement_datas_ends p += block_depth < 3 block_depth += 1 if block_depth >= BLOCK_DEPTH_LIMIT goto too_much_nesting @@ -402,7 +433,7 @@ function parse_statement token += 16 ; put the body statement 1 block_depth deeper - p = statement_datas + p = statement_datas_ends p += block_depth < 3 block_depth += 1 if block_depth >= BLOCK_DEPTH_LIMIT goto too_much_nesting @@ -440,6 +471,91 @@ function parse_statement :str_do_no_semicolon string No semicolon after do ... while (...) byte 0 + :stmt_for + write_statement_header(out, STATEMENT_FOR, token) + out += 8 + token += 16 + if *1token != SYMBOL_LPAREN goto for_no_lparen + c = token_matching_rparen(token) + token += 16 + p = token_next_semicolon_not_in_brackets(token) + if token == p goto for_no_expr1 + *8out = expressions_end + expressions_end = parse_expression(token, p, expressions_end) + :for_no_expr1 + out += 8 + token = p + 16 + p = token_next_semicolon_not_in_brackets(token) + if token == p goto for_no_expr2 + *8out = expressions_end + expressions_end = parse_expression(token, p, expressions_end) + :for_no_expr2 + out += 8 + token = p + 16 + if c < token goto bad_for + if c == token goto for_no_expr3 + *8out = expressions_end + expressions_end = parse_expression(token, c, expressions_end) + :for_no_expr3 + out += 8 + token = c + 16 + + ; put the body statement 1 block_depth deeper + p = statement_datas_ends + p += block_depth < 3 + block_depth += 1 + if block_depth >= BLOCK_DEPTH_LIMIT goto too_much_nesting + *8out = *8p + out += 8 + parse_statement(&token, p) ; the body + block_depth -= 1 + + goto parse_statement_ret + + :bad_for + token_error(c, .str_bad_for) + :str_bad_for + string Bad for loop header. + byte 0 + :for_no_lparen + token_error(token, .str_for_no_lparen) + :str_for_no_lparen + string Missing ( after for. + byte 0 + :stmt_if + write_statement_header(out, STATEMENT_IF, token) + out += 8 + token += 16 + if *1token != SYMBOL_LPAREN goto if_no_lparen + p = token_matching_rparen(token) + token += 16 + *8out = expressions_end + out += 8 + expressions_end = parse_expression(token, p, expressions_end) + token = p + 16 + + + ; put the body statement(s) 1 block_depth deeper + p = statement_datas_ends + p += block_depth < 3 + block_depth += 1 + if block_depth >= BLOCK_DEPTH_LIMIT goto too_much_nesting + *8out = *8p + out += 8 + parse_statement(&token, p) ; if body + if *1token != KEYWORD_ELSE goto stmt_if_no_else + token += 16 + *8out = *8p + parse_statement(&token, p) ; else body + :stmt_if_no_else + out += 16 + block_depth -= 1 + goto parse_statement_ret + :if_no_lparen + token_error(token, .str_if_no_lparen) + :str_if_no_lparen + string No ( after if + byte 0 :stmt_local_declaration local l_base_type local l_prefix @@ -734,6 +850,9 @@ function print_statement_with_depth if c == STATEMENT_CASE goto print_stmt_case if c == STATEMENT_WHILE goto print_stmt_while if c == STATEMENT_DO goto print_stmt_do + if c == STATEMENT_IF goto print_stmt_if + if c == STATEMENT_SWITCH goto print_stmt_switch + if c == STATEMENT_FOR goto print_stmt_for if c == STATEMENT_LOCAL_DECLARATION goto print_stmt_local_decl die(.pristmtNI) @@ -753,7 +872,6 @@ function print_statement_with_depth return :print_stmt_while puts(.str_stmt_while) - putc(40) print_expression(dat1) putcln(41) print_statement_with_depth(dat2, depth) @@ -761,6 +879,38 @@ function print_statement_with_depth :str_stmt_while string while ( byte 0 + :print_stmt_for + puts(.str_stmt_for) + if dat1 == 0 goto print_for_noexpr1 + print_expression(dat1) + :print_for_noexpr1 + puts(.str_for_sep) + if dat2 == 0 goto print_for_noexpr2 + print_expression(dat2) + :print_for_noexpr2 + puts(.str_for_sep) + if dat2 == 0 goto print_for_noexpr3 + print_expression(dat3) + :print_for_noexpr3 + putcln(41) + print_statement_with_depth(dat4, depth) + return + :str_stmt_for + string for ( + byte 0 + :str_for_sep + byte 59 + byte 32 + byte 0 + :print_stmt_switch + puts(.str_stmt_switch) + print_expression(dat1) + putcln(41) + print_statement_with_depth(dat2, depth) + return + :str_stmt_switch + string switch ( + byte 0 :print_stmt_do puts(.str_stmt_do) print_statement_with_depth(dat1, depth) @@ -774,6 +924,19 @@ function print_statement_with_depth string do byte 10 byte 0 + :print_stmt_if + puts(.str_stmt_if) + print_expression(dat1) + putcln(41) + print_statement_with_depth(dat2, depth) + if dat3 == 0 goto return_0 + print_indents(depth) + putsln(.str_else) + print_statement_with_depth(dat3, depth) + return + :str_stmt_if + string if ( + byte 0 :print_stmt_break puts(.str_stmt_break) return @@ -2183,6 +2346,7 @@ function parse_expression if c == EXPRESSION_GT goto type_int if c == EXPRESSION_COMMA goto type_binary_right if c == EXPRESSION_EQ goto type_binary_left + if c == EXPRESSION_ASSIGN goto type_binary_left if c == EXPRESSION_ASSIGN_ADD goto type_binary_left if c == EXPRESSION_ASSIGN_SUB goto type_binary_left if c == EXPRESSION_ASSIGN_MUL goto type_binary_left |