diff --git a/examples/sample.spooky b/examples/sample.spooky index 74718eb..b1e7ede 100644 --- a/examples/sample.spooky +++ b/examples/sample.spooky @@ -12,7 +12,7 @@ int sum_array(int[] arr) { } int main() { - struct Point p; + Point p; int[] nums; int x = 1 + 2 * 3; p.x = x; diff --git a/examples/with_imports.spooky b/examples/with_imports.spooky index eb09e79..d38db5a 100644 --- a/examples/with_imports.spooky +++ b/examples/with_imports.spooky @@ -2,7 +2,7 @@ import "modules/types.spooky"; import "modules/math.spooky"; int main() { - struct Point p; + Point p; p.x = 1; p.y = 2; return add(p.x, p.y); diff --git a/lib/parser.ml b/lib/parser.ml index 9f84aeb..0d6d75e 100644 --- a/lib/parser.ml +++ b/lib/parser.ml @@ -10,6 +10,9 @@ type parser_state = { let mk_state toks = { toks = Array.of_list toks; i = 0 } let peek st = if st.i < Array.length st.toks then st.toks.(st.i) else TEOF +let peek_n st n = + let idx = st.i + n in + if idx < Array.length st.toks then st.toks.(idx) else TEOF let consume st = let t = peek st in @@ -61,7 +64,23 @@ let expect_ident st = | TIdent s -> s | _ -> raise (Parse_error "expected identifier") -let starts_type = function TIntKw | TBoolKw | TVoidKw | TStructKw -> true | _ -> false +let starts_builtin_type = function TIntKw | TBoolKw | TVoidKw | TStructKw -> true | _ -> false + +let rec skip_array_suffixes st j = + match peek_n st j with + | TLBracket -> + (match peek_n st (j + 1) with + | TRBracket -> skip_array_suffixes st (j + 2) + | _ -> j) + | _ -> j + +let looks_like_type_start st = + match peek st with + | t when starts_builtin_type t -> true + | TIdent _ -> + let j = skip_array_suffixes st 1 in + (match peek_n st j with TIdent _ -> true | _ -> false) + | _ -> false let rec parse_type st = let base = @@ -70,6 +89,7 @@ let rec parse_type st = | TBoolKw -> TBool | TVoidKw -> TVoid | TStructKw -> TStruct (expect_ident st) + | TIdent s -> TStruct s | _ -> raise (Parse_error "expected type") in let rec arrays t = @@ -115,6 +135,7 @@ and parse_top st = let ty = TStruct sname in parse_top_after_type st ty) | _ -> + if not (looks_like_type_start st) then raise (Parse_error "expected top-level declaration"); let ty = parse_type st in parse_top_after_type st ty @@ -208,7 +229,7 @@ and parse_stmt st = in expect st TSemicolon; Return v - | t when starts_type t -> + | _ when looks_like_type_start st -> let ty = parse_type st in let n = expect_ident st in let init = diff --git a/test/test_spooky.ml b/test/test_spooky.ml index fdc03d1..f2bc81e 100644 --- a/test/test_spooky.ml +++ b/test/test_spooky.ml @@ -14,7 +14,7 @@ int fold(int[] xs) { int main() { int[] xs; - struct Item it; + Item it; int y = 2 + 3 * 4; it.value = y; if (y >= 0) {