Odin icon indicating copy to clipboard operation
Odin copied to clipboard

odin/parser: unable to parse when ternary expressions

Open laytan opened this issue 1 year ago • 0 comments

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
	}
}

laytan avatar Jun 27 '24 17:06 laytan