feat: execute Bro-compatible integer range loops
This commit is contained in:
+18
-1
@@ -134,6 +134,18 @@ scan proc(
|
||||
continue
|
||||
}
|
||||
|
||||
if (char == '.' and cursor + 1 < program.len and program[cursor + 1] == '.') {
|
||||
inclusive :: cursor + 2 < program.len and program[cursor + 2] == '='
|
||||
width :: if (inclusive) 3 else 2
|
||||
range_kind :: if (inclusive) .range_inclusive else .range
|
||||
try add_token(state, Token{
|
||||
span = make_span(cursor, cursor + width),
|
||||
kind = range_kind,
|
||||
})
|
||||
cursor += width
|
||||
continue
|
||||
}
|
||||
|
||||
if char == ':' {
|
||||
if cursor + 1 < program.len and program[cursor + 1] == ':' {
|
||||
try add_token(state, Token{
|
||||
@@ -233,6 +245,8 @@ scan proc(
|
||||
'<': .less
|
||||
'>': .greater
|
||||
',': .comma
|
||||
'|': .pipe
|
||||
'@': .at
|
||||
'(': .open_paren
|
||||
')': .close_paren
|
||||
'[': .open_bracket
|
||||
@@ -304,7 +318,10 @@ scan_number proc(start usize, program []u8) ScanNumResult ! ScanError {
|
||||
cursor := start
|
||||
has_decimal := false
|
||||
while (cursor < program.len and is_digit(program[cursor])) cursor += 1
|
||||
if cursor < program.len and program[cursor] == '.' {
|
||||
if (
|
||||
cursor < program.len and program[cursor] == '.'
|
||||
and !(cursor + 1 < program.len and program[cursor + 1] == '.')
|
||||
) {
|
||||
has_decimal = true
|
||||
cursor += 1
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ reports_invalid_input_and_keeps_scanning test {
|
||||
state := init(mem.c_allocator)
|
||||
defer deinit(&state)
|
||||
|
||||
try scan(&state, "if name # comment\n@1. 2 3.5 \"hi\"", &diagnostic_store)
|
||||
try scan(&state, "if name # comment\n$1. 2 3.5 \"hi\"", &diagnostic_store)
|
||||
|
||||
try testing.expect_equal(8, state.tokens.items.len)
|
||||
try testing.expect_equal(TokenKind.if, state.tokens.items[0].kind)
|
||||
@@ -100,3 +100,25 @@ scans_loop_controls_with_exact_keyword_boundaries test {
|
||||
try testing.expect_equal("continued", strpool.get_str(&strpool.strings, state.tokens.items[3].data.str_id)?)
|
||||
try testing.expect_equal(0, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
scans_ranges_without_consuming_float_dots 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)
|
||||
try scan(&state, "0..10 0..=10 1.5..2.5 |@item, _| ... 1.", &diagnostic_store)
|
||||
expected [19]TokenKind :: [
|
||||
.int, .range, .int, .int, .range_inclusive, .int,
|
||||
.float, .range, .float, .pipe, .at, .ident, .comma, .ident, .pipe,
|
||||
.range, .invalid, .invalid, .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(1), state.tokens.items[1].span.start)
|
||||
try testing.expect_equal(u32(3), state.tokens.items[1].span.end)
|
||||
try testing.expect_equal(u32(7), state.tokens.items[4].span.start)
|
||||
try testing.expect_equal(u32(10), state.tokens.items[4].span.end)
|
||||
try testing.expect_equal(2, diagnostics.count(&diagnostic_store))
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ TokenKind :: enum {
|
||||
plus, minus
|
||||
star, slash
|
||||
|
||||
range, range_inclusive
|
||||
pipe, at
|
||||
|
||||
# logical
|
||||
bang
|
||||
|
||||
|
||||
Reference in New Issue
Block a user