Odin
Odin copied to clipboard
odin/parser: unable to parse when ternary expressions
The core:odin/parser can't parse expressions like this:
LIB :: (
"lib/cgltf.lib" when ODIN_OS == .Windows
else "lib/cgltf.a" when ODIN_OS == .Linux
else "lib/darwin/cgltf.a" when ODIN_OS == .Darwin
else ""
)
as seen in vendor/cgltf/cgltf.odin.
More cases in vendor, but afaik the same backing error/bug:
cgltf.odin(5:52): expected 'else', got 'newline'
cgltf.odin(6:2): expected an operand
cgltf.odin(6:50): expected ')', got 'newline'
cgltf.odin(7:2): 'else' unattached to an 'if' statement
cgltf.odin(8:2): 'else' unattached to an 'if' statement
cgltf.odin(9:1): expected a statement, got )
stb_image.odin(7:59): expected 'else', got 'newline'
stb_image.odin(8:2): expected an operand
stb_image.odin(8:57): expected ')', got 'newline'
stb_image.odin(9:2): 'else' unattached to an 'if' statement
stb_image.odin(10:2): 'else' unattached to an 'if' statement
stb_image.odin(11:1): expected a statement, got )
stb_image_resize.odin(7:66): expected 'else', got 'newline'
stb_image_resize.odin(8:2): expected an operand
stb_image_resize.odin(8:64): expected ')', got 'newline'
stb_image_resize.odin(9:2): 'else' unattached to an 'if' statement
stb_image_resize.odin(10:2): 'else' unattached to an 'if' statement
stb_image_resize.odin(11:1): expected a statement, got )
stb_image_write.odin(7:65): expected 'else', got 'newline'
stb_image_write.odin(8:2): expected an operand
stb_image_write.odin(8:63): expected ')', got 'newline'
stb_image_write.odin(9:2): 'else' unattached to an 'if' statement
stb_image_write.odin(10:2): 'else' unattached to an 'if' statement
stb_image_write.odin(11:1): expected a statement, got )
stb_rect_pack.odin(9:63): expected 'else', got 'newline'
stb_rect_pack.odin(10:2): expected an operand
stb_rect_pack.odin(10:61): expected ')', got 'newline'
stb_rect_pack.odin(11:2): 'else' unattached to an 'if' statement
stb_rect_pack.odin(12:2): 'else' unattached to an 'if' statement
stb_rect_pack.odin(13:1): expected a statement, got )
stb_truetype.odin(8:62): expected 'else', got 'newline'
stb_truetype.odin(9:2): expected an operand
stb_truetype.odin(9:60): expected ')', got 'newline'
stb_truetype.odin(10:2): 'else' unattached to an 'if' statement
stb_truetype.odin(11:2): 'else' unattached to an 'if' statement
stb_truetype.odin(12:1): expected a statement, got )
stb_vorbis.odin(7:60): expected 'else', got 'newline'
stb_vorbis.odin(8:2): expected an operand
stb_vorbis.odin(8:58): expected ')', got 'newline'
stb_vorbis.odin(9:2): 'else' unattached to an 'if' statement
stb_vorbis.odin(10:2): 'else' unattached to an 'if' statement
stb_vorbis.odin(11:1): expected a statement, got )
I wrote this test to check each package in vendor:
@test
test_parse_core :: proc(t: ^testing.T) {
allocator: virtual.Arena
err := virtual.arena_init_growing(&allocator)
testing.expect_value(t, err, nil)
State :: struct {
t: ^testing.T,
allocator: runtime.Allocator,
}
state := State{
t,
virtual.arena_allocator(&allocator),
}
path := filepath.join({ODIN_ROOT, "vendor"})
defer delete(path)
errno := filepath.walk(path, walker, &state)
testing.expect_value(t, errno, os.ERROR_NONE)
handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
log.error(
fmt.tprintf("%s(%d:%d): ", pos.file, pos.line, pos.column),
fmt.tprintf(msg, ..args),
)
}
walker :: proc(fi: os.File_Info, errno: os.Errno, state: rawptr) -> (os.Errno, bool) {
state := (^State)(state)
if !fi.is_dir {
return os.ERROR_NONE, false
}
log.debugf("parsing %v", fi.fullpath)
context.allocator = state.allocator
defer free_all(context.allocator)
_, ok := parser.parse_package_from_path(fi.fullpath, &parser.Parser{
flags = {.Optional_Semicolons},
err = handler,
warn = handler,
})
testing.expect(state.t, ok, fmt.tprintf("failed parsing %v", fi.fullpath))
return os.ERROR_NONE, false
}
}