From f14677b6f5a81a5cf885f31c687091106025406b Mon Sep 17 00:00:00 2001 From: Moritz Gmeiner Date: Wed, 14 Aug 2024 12:36:36 +0200 Subject: [PATCH] fnished first draft of expression parser --- lib/parser.ml | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/parser.ml b/lib/parser.ml index 10dbb90..ab384f3 100644 --- a/lib/parser.ml +++ b/lib/parser.ml @@ -22,6 +22,18 @@ module State = struct let advance_if state tt = if (peek state).token_type == tt then (true, advance state) else (false, state) + let consume state tt = + if (peek state).token_type == tt then advance state + else + let state = + append_error + (Printf.sprintf "Unexpected %s, expected %s" + (show_token_type (peek state).token_type) + (show_token_type tt)) + (peek state).pos state + in + state + let matches state tts = let f = ( == ) (peek state).token_type in Array.fold_left (fun acc tt -> acc || f tt) false tts @@ -40,10 +52,27 @@ module State = struct (Array.of_list (List.rev !out_list_rev), !state_ref) let primary (state : state) : expr * state = - let token, state = next state in - (make_string @@ show_token_type token.token_type, state) + match (peek state).token_type with + | Number x -> (make_number x, advance state) + | String s -> (make_string s, advance state) + | True -> (make_bool true, advance state) + | False -> (make_bool false, advance state) + | Nil -> (make_nil (), advance state) + | tt -> + ( make_nil (), + append_error + (Printf.sprintf "Unexpected %s, expected valid expression" (show_token_type tt)) + (peek state).pos state ) - let rec neg_not (state : state) : expr * state = + let rec grouping (state : state) : expr * state = + if matches state [| LeftParen |] then + let state = advance state in + let expr, state = expression state in + let state = consume state RightParen in + (expr, state) + else primary state + + and neg_not (state : state) : expr * state = if matches state [| Bang; Minus |] then let token, state = next state in let expr, state = neg_not state in @@ -55,9 +84,9 @@ module State = struct in let expr = make_unary op expr in (expr, state) - else primary state + else grouping state - let mul_or_div (state : state) : expr * state = + and mul_or_div (state : state) : expr * state = let expr, state = neg_not state in let exprs_tokens, state = collect_chain state [| Star; Slash |] neg_not in let f acc (expr, token) = @@ -72,7 +101,7 @@ module State = struct let expr = Array.fold_left f expr exprs_tokens in (expr, state) - let sum_or_diff (state : state) : expr * state = + and sum_or_diff (state : state) : expr * state = let expr, state = mul_or_div state in let exprs_tokens, state = collect_chain state [| Plus; Minus |] mul_or_div in let f acc (expr, token) = @@ -87,7 +116,7 @@ module State = struct let expr = Array.fold_left f expr exprs_tokens in (expr, state) - let inequality (state : state) : expr * state = + and inequality (state : state) : expr * state = (* TODO: maybe rework to only have Less and Greater as ops; performance? *) let expr, state = sum_or_diff state in let exprs_tokens, state = @@ -107,7 +136,7 @@ module State = struct let expr = Array.fold_left f expr exprs_tokens in (expr, state) - let equality (state : state) : expr * state = + and equality (state : state) : expr * state = let expr, state = inequality state in let exprs_tokens, state = collect_chain state [| EqualEqual; BangEqual |] inequality in let f acc (expr, token) = @@ -121,7 +150,7 @@ module State = struct let expr = Array.fold_left f expr exprs_tokens in (expr, state) - let expression (state : state) : expr * state = equality state + and expression (state : state) : expr * state = equality state end let parse (tokens : token list) : parse_result =