mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
fnished first draft of expression parser
This commit is contained in:
parent
3bd18634d5
commit
f14677b6f5
1 changed files with 38 additions and 9 deletions
|
|
@ -22,6 +22,18 @@ module State = struct
|
||||||
let advance_if state tt =
|
let advance_if state tt =
|
||||||
if (peek state).token_type == tt then (true, advance state) else (false, state)
|
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 matches state tts =
|
||||||
let f = ( == ) (peek state).token_type in
|
let f = ( == ) (peek state).token_type in
|
||||||
Array.fold_left (fun acc tt -> acc || f tt) false tts
|
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)
|
(Array.of_list (List.rev !out_list_rev), !state_ref)
|
||||||
|
|
||||||
let primary (state : state) : expr * state =
|
let primary (state : state) : expr * state =
|
||||||
let token, state = next state in
|
match (peek state).token_type with
|
||||||
(make_string @@ show_token_type token.token_type, state)
|
| 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
|
if matches state [| Bang; Minus |] then
|
||||||
let token, state = next state in
|
let token, state = next state in
|
||||||
let expr, state = neg_not state in
|
let expr, state = neg_not state in
|
||||||
|
|
@ -55,9 +84,9 @@ module State = struct
|
||||||
in
|
in
|
||||||
let expr = make_unary op expr in
|
let expr = make_unary op expr in
|
||||||
(expr, state)
|
(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 expr, state = neg_not state in
|
||||||
let exprs_tokens, state = collect_chain state [| Star; Slash |] neg_not in
|
let exprs_tokens, state = collect_chain state [| Star; Slash |] neg_not in
|
||||||
let f acc (expr, token) =
|
let f acc (expr, token) =
|
||||||
|
|
@ -72,7 +101,7 @@ module State = struct
|
||||||
let expr = Array.fold_left f expr exprs_tokens in
|
let expr = Array.fold_left f expr exprs_tokens in
|
||||||
(expr, state)
|
(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 expr, state = mul_or_div state in
|
||||||
let exprs_tokens, state = collect_chain state [| Plus; Minus |] mul_or_div in
|
let exprs_tokens, state = collect_chain state [| Plus; Minus |] mul_or_div in
|
||||||
let f acc (expr, token) =
|
let f acc (expr, token) =
|
||||||
|
|
@ -87,7 +116,7 @@ module State = struct
|
||||||
let expr = Array.fold_left f expr exprs_tokens in
|
let expr = Array.fold_left f expr exprs_tokens in
|
||||||
(expr, state)
|
(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? *)
|
(* TODO: maybe rework to only have Less and Greater as ops; performance? *)
|
||||||
let expr, state = sum_or_diff state in
|
let expr, state = sum_or_diff state in
|
||||||
let exprs_tokens, state =
|
let exprs_tokens, state =
|
||||||
|
|
@ -107,7 +136,7 @@ module State = struct
|
||||||
let expr = Array.fold_left f expr exprs_tokens in
|
let expr = Array.fold_left f expr exprs_tokens in
|
||||||
(expr, state)
|
(expr, state)
|
||||||
|
|
||||||
let equality (state : state) : expr * state =
|
and equality (state : state) : expr * state =
|
||||||
let expr, state = inequality state in
|
let expr, state = inequality state in
|
||||||
let exprs_tokens, state = collect_chain state [| EqualEqual; BangEqual |] inequality in
|
let exprs_tokens, state = collect_chain state [| EqualEqual; BangEqual |] inequality in
|
||||||
let f acc (expr, token) =
|
let f acc (expr, token) =
|
||||||
|
|
@ -121,7 +150,7 @@ module State = struct
|
||||||
let expr = Array.fold_left f expr exprs_tokens in
|
let expr = Array.fold_left f expr exprs_tokens in
|
||||||
(expr, state)
|
(expr, state)
|
||||||
|
|
||||||
let expression (state : state) : expr * state = equality state
|
and expression (state : state) : expr * state = equality state
|
||||||
end
|
end
|
||||||
|
|
||||||
let parse (tokens : token list) : parse_result =
|
let parse (tokens : token list) : parse_result =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue