diff --git a/TODOLIST b/TODOLIST new file mode 100644 index 0000000..3cb4c92 --- /dev/null +++ b/TODOLIST @@ -0,0 +1,14 @@ +globals +arrays +assert +c abi +orelse +size +trailing zeroes +leading zeroes +while true +returns inside loops (if conditional) +returns inside loops (else conditional) +returns inside loops (non-conditional) +function pointers +for loops diff --git a/bootstrap/compiler.zig b/bootstrap/compiler.zig index 59ddcbc..5009406 100644 --- a/bootstrap/compiler.zig +++ b/bootstrap/compiler.zig @@ -1403,6 +1403,7 @@ const Keyword = enum{ @"else", @"for", @"if", + @"loop", @"break", }; @@ -3601,6 +3602,53 @@ pub fn analyze_local_block(thread: *Thread, analyzer: *Analyzer, parser: *Parser terminated = terminated or if_block.terminated; } }, + 'l' => { + const identifier = parser.parse_raw_identifier(src); + + const loop_text = "loop"; + if (byte_equal(identifier, loop_text)) { + parser.skip_space(src); + + const loop_header_block = create_basic_block(thread); + const loop_body_block = create_basic_block(thread); + const loop_exit_block = create_basic_block(thread); + _ = emit_jump(analyzer, thread, loop_header_block); + analyzer.current_basic_block = loop_header_block; + + if (src[parser.i] == '(') { + const condition = parser.parse_condition(analyzer, thread, file); + + _ = emit_branch(analyzer, thread, condition, loop_body_block, loop_exit_block); + } else { + _ = emit_jump(analyzer, thread, loop_body_block); + } + + parser.skip_space(src); + + analyzer.current_basic_block = loop_body_block; + _ = analyzer.loops.append(.{ + .continue_block = loop_header_block, + .break_block = loop_exit_block, + }); + + switch (src[parser.i]) { + brace_open => { + const loop_block = analyze_local_block(thread, analyzer, parser, file); + if (!loop_block.terminated) { + _ = emit_jump(analyzer, thread, loop_header_block); + } else { + unreachable; + } + }, + else => unreachable, + } + + analyzer.current_basic_block = loop_exit_block; + analyzer.loops.length -= 1; + } else { + parser.i = statement_start_ch_index; + } + }, 'r' => { const identifier = parser.parse_raw_identifier(src); @@ -3655,49 +3703,6 @@ pub fn analyze_local_block(thread: *Thread, analyzer: *Analyzer, parser: *Parser parser.i = statement_start_ch_index; } }, - 'w' => { - const identifier = parser.parse_raw_identifier(src); - - const while_text = "while"; - if (byte_equal(identifier, while_text)) { - parser.skip_space(src); - - const loop_header = create_basic_block(thread); - _ = emit_jump(analyzer, thread, loop_header); - analyzer.current_basic_block = loop_header; - - const condition = parser.parse_condition(analyzer, thread, file); - - parser.skip_space(src); - - const loop_body_block = create_basic_block(thread); - const loop_exit_block = create_basic_block(thread); - - _ = emit_branch(analyzer, thread, condition, loop_body_block, loop_exit_block); - analyzer.current_basic_block = loop_body_block; - _ = analyzer.loops.append(.{ - .continue_block = loop_header, - .break_block = loop_exit_block, - }); - - switch (src[parser.i]) { - '{' => { - const loop_block = analyze_local_block(thread, analyzer, parser, file); - if (!loop_block.terminated) { - _ = emit_jump(analyzer, thread, loop_header); - } else { - unreachable; - } - }, - else => unreachable, - } - - analyzer.current_basic_block = loop_exit_block; - analyzer.loops.length -= 1; - } else { - parser.i = statement_start_ch_index; - } - }, else => {}, } diff --git a/retest/standalone/while_loop/main.nat b/retest/standalone/loop/main.nat similarity index 83% rename from retest/standalone/while_loop/main.nat rename to retest/standalone/loop/main.nat index adb92d5..1617a33 100644 --- a/retest/standalone/while_loop/main.nat +++ b/retest/standalone/loop/main.nat @@ -1,7 +1,7 @@ fn[cc(.c)] main[export]() s32 { >i: s32 = 0; >top: s32 = 10; - while (i < top) { + loop (i < top) { i += 1; } diff --git a/retest/standalone/while_break/main.nat b/retest/standalone/loop_break/main.nat similarity index 88% rename from retest/standalone/while_break/main.nat rename to retest/standalone/loop_break/main.nat index 6f71cfe..7dee352 100644 --- a/retest/standalone/while_break/main.nat +++ b/retest/standalone/loop_break/main.nat @@ -1,7 +1,7 @@ fn[cc(.c)] main[export]() s32 { >i: s32 = 0; >n: s32 = 5; - while (i < 10) { + loop (i < 10) { i += 1; if (i == n) { break; diff --git a/retest/standalone/while_continue/main.nat b/retest/standalone/loop_continue/main.nat similarity index 89% rename from retest/standalone/while_continue/main.nat rename to retest/standalone/loop_continue/main.nat index d933677..e36c223 100644 --- a/retest/standalone/while_continue/main.nat +++ b/retest/standalone/loop_continue/main.nat @@ -1,7 +1,7 @@ fn[cc(.c)] main[export]() s32 { >i: s32 = 0; >n: s32 = 0; - while (i < 10) { + loop (i < 10) { i += 1; if (n == 0) { continue; diff --git a/retest/standalone/loop_no_condition/main.nat b/retest/standalone/loop_no_condition/main.nat new file mode 100644 index 0000000..3f661d8 --- /dev/null +++ b/retest/standalone/loop_no_condition/main.nat @@ -0,0 +1,18 @@ + +fn foo() s32 { + >n: s32 = 6; + >a: s32 = 0; + loop { + if (a == n) { + return a; + } + + a += 1; + } +} + +fn[cc(.c)] main[export]() s32 { + >n: s32 = 6; + >result = foo(); + return result - n; +}