feat: execute conditionals through typed IR
Use typed singleton arrays for braceless arm blocks: &[statement] compiled but trapped under the Bro bootstrap.
This commit is contained in:
@@ -26,6 +26,8 @@ keywords strmap.StaticStringMap(TokenKind) :: strmap.init([
|
||||
{ "for", .for },
|
||||
{ "else", .else },
|
||||
{ "while", .while },
|
||||
{ "true", .true },
|
||||
{ "false", .false },
|
||||
])
|
||||
|
||||
#! owns token storage and retains its allocator; release with deinit.
|
||||
@@ -203,8 +205,28 @@ scan proc(
|
||||
continue
|
||||
}
|
||||
|
||||
if (cursor + 1 < program.len and program[cursor + 1] == '=') {
|
||||
comparison ?TokenKind :: match char {
|
||||
'=': .equal_equal
|
||||
'!': .not_equal
|
||||
'<': .less_equal
|
||||
'>': .greater_equal
|
||||
else: null
|
||||
}
|
||||
if (comparison) |value| {
|
||||
try add_token(state, Token{
|
||||
span = make_span(cursor, cursor + 2),
|
||||
kind = value,
|
||||
})
|
||||
cursor += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
kind ?TokenKind :: match char {
|
||||
'=': .equal
|
||||
'<': .less
|
||||
'>': .greater
|
||||
',': .comma
|
||||
'(': .open_paren
|
||||
')': .close_paren
|
||||
|
||||
@@ -30,3 +30,26 @@ reports_invalid_input_and_keeps_scanning test {
|
||||
try testing.expect_equal(u32(3), state.tokens.items[1].span.start)
|
||||
try testing.expect_equal(u32(7), state.tokens.items[1].span.end)
|
||||
}
|
||||
|
||||
reserves_boolean_keywords_and_scans_comparisons test {
|
||||
strpool.strings = strpool.init(mem.c_allocator)
|
||||
defer strpool.deinit(&strpool.strings)
|
||||
diagnostic_store := diagnostics.init(mem.c_allocator)
|
||||
defer diagnostics.deinit(&diagnostic_store)
|
||||
state := init(mem.c_allocator)
|
||||
defer deinit(&state)
|
||||
source :: "true false bool trueish == != < <= > >="
|
||||
try scan(&state, source, &diagnostic_store)
|
||||
expected [11]TokenKind :: [
|
||||
TokenKind.true, .false, .ident, .ident,
|
||||
.equal_equal, .not_equal, .less, .less_equal, .greater, .greater_equal, .eof,
|
||||
]
|
||||
try testing.expect_equal(expected.len, state.tokens.items.len)
|
||||
for (expected) |kind, index| try testing.expect_equal(kind, state.tokens.items[index].kind)
|
||||
try testing.expect_equal(u32(0), state.tokens.items[0].span.start)
|
||||
try testing.expect_equal(u32(4), state.tokens.items[0].span.end)
|
||||
try testing.expect_equal(u32(5), state.tokens.items[1].span.start)
|
||||
try testing.expect_equal(u32(10), state.tokens.items[1].span.end)
|
||||
try testing.expect_equal("bool", strpool.get_str(&strpool.strings, state.tokens.items[2].data.str_id)?)
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ TokenKind :: enum {
|
||||
if, else
|
||||
for, while
|
||||
proc, return
|
||||
true, false
|
||||
|
||||
# literals
|
||||
ident, string
|
||||
|
||||
Reference in New Issue
Block a user