mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
implemented parsing up to neg/not
This commit is contained in:
parent
3590a78154
commit
3bd18634d5
1 changed files with 61 additions and 60 deletions
121
lib/parser.ml
121
lib/parser.ml
|
|
@ -24,9 +24,9 @@ module State = struct
|
|||
|
||||
let matches state tts =
|
||||
let f = ( == ) (peek state).token_type in
|
||||
List.fold_left (fun acc tt -> acc || f tt) false tts
|
||||
Array.fold_left (fun acc tt -> acc || f tt) false tts
|
||||
|
||||
let collect_chain (state : state) (tts : token_type list) higher_prec :
|
||||
let collect_chain (state : state) (tts : token_type array) higher_prec :
|
||||
(expr * token) array * state =
|
||||
(* ([], state) *)
|
||||
let state_ref = ref state in
|
||||
|
|
@ -39,59 +39,61 @@ module State = struct
|
|||
done;
|
||||
(Array.of_list (List.rev !out_list_rev), !state_ref)
|
||||
|
||||
let mul_or_div (state : state) : expr * state =
|
||||
let primary (state : state) : expr * state =
|
||||
let token, state = next state in
|
||||
(make_string @@ show_token_type token.token_type, state)
|
||||
|
||||
let sum_or_diff (state : state) : expr * state =
|
||||
let expr, state = mul_or_div state in
|
||||
(* if (not (is_at_end state)) && matches state [ Plus; Minus ] then
|
||||
let token, state = next state in
|
||||
let expr2, state = sum_or_diff state in
|
||||
let (op : binary_op) =
|
||||
match token.token_type with
|
||||
| Plus -> Plus
|
||||
| Minus -> Minus
|
||||
| _ -> assert false (* should only be here if tt is + - *)
|
||||
in
|
||||
let expr = make_binary op expr expr2 in
|
||||
(expr, state)
|
||||
else (expr, state) *)
|
||||
(* turn expr and state to refs for the loop *)
|
||||
(* Printf.printf "expr: %s\n\n" (show_expr expr);
|
||||
let expr_ref, state_ref = (ref expr, ref state) in
|
||||
while (not (is_at_end !state_ref)) && matches !state_ref [ Plus; Minus ] do
|
||||
let token, state = next !state_ref in
|
||||
let expr2, state = mul_or_div state in
|
||||
let (op : binary_op) =
|
||||
match token.token_type with
|
||||
| Plus -> Plus
|
||||
| Minus -> Minus
|
||||
| _ -> assert false (* should only be here if tt is + - *)
|
||||
in
|
||||
let expr = make_binary op !expr_ref expr2 in
|
||||
(* (expr_ref, state_ref) := (expr, state) *)
|
||||
Printf.printf "expr: %s\n\n" (show_expr expr);
|
||||
expr_ref := expr;
|
||||
state_ref := state
|
||||
done;
|
||||
(!expr_ref, !state_ref) *)
|
||||
let exprs_tokens, state = collect_chain state [ Plus; Minus ] mul_or_div in
|
||||
let rec 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
|
||||
let op =
|
||||
match token.token_type with
|
||||
| Bang -> Not
|
||||
| Minus -> Neg
|
||||
| _ -> assert false (* should only be here if tt is - ! *)
|
||||
in
|
||||
let expr = make_unary op expr in
|
||||
(expr, state)
|
||||
else primary state
|
||||
|
||||
let 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) =
|
||||
let op : binary_op =
|
||||
match token.token_type with Plus -> Plus | Minus -> Minus | _ -> assert false
|
||||
match token.token_type with
|
||||
| Star -> Mul
|
||||
| Slash -> Div
|
||||
| _ -> assert false (* should only be here if tt is * / *)
|
||||
in
|
||||
make_binary op acc expr
|
||||
in
|
||||
let expr = Array.fold_left f expr exprs_tokens in
|
||||
(expr, state)
|
||||
|
||||
let rec inequality (state : state) : expr * state =
|
||||
let 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) =
|
||||
let op : binary_op =
|
||||
match token.token_type with
|
||||
| Plus -> Plus
|
||||
| Minus -> Minus
|
||||
| _ -> assert false (* should only be here if tt is + - *)
|
||||
in
|
||||
make_binary op acc expr
|
||||
in
|
||||
let expr = Array.fold_left f expr exprs_tokens in
|
||||
(expr, state)
|
||||
|
||||
let 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
|
||||
if (not (is_at_end state)) && matches state [ Greater; GreaterEqual; Less; LessEqual ] then
|
||||
let token, state = next state in
|
||||
let expr2, state = inequality state in
|
||||
(* TODO: maybe rework to only have Less and Greater as ops; performance? *)
|
||||
let exprs_tokens, state =
|
||||
collect_chain state [| Greater; GreaterEqual; Less; LessEqual |] sum_or_diff
|
||||
in
|
||||
let f acc (expr, token) =
|
||||
let (op : binary_op) =
|
||||
match token.token_type with
|
||||
| Greater -> Greater
|
||||
|
|
@ -100,25 +102,24 @@ module State = struct
|
|||
| LessEqual -> LessEqual
|
||||
| _ -> assert false (* should only be here if tt is > < >= <= *)
|
||||
in
|
||||
let expr = make_binary op expr expr2 in
|
||||
(expr, state)
|
||||
else (expr, state)
|
||||
make_binary op acc expr
|
||||
in
|
||||
let expr = Array.fold_left f expr exprs_tokens in
|
||||
(expr, state)
|
||||
|
||||
let rec equality (state : state) : expr * state =
|
||||
let equality (state : state) : expr * state =
|
||||
let expr, state = inequality state in
|
||||
if matches state [ EqualEqual; BangEqual ] then
|
||||
let token, state = next state in
|
||||
let expr2, state = equality state in
|
||||
let expr =
|
||||
match token.token_type with
|
||||
| EqualEqual -> make_binary Equal expr expr2
|
||||
| BangEqual ->
|
||||
let expr = make_binary Equal expr expr2 in
|
||||
make_unary Not expr
|
||||
| _ -> assert false (* should only be here if tt is == != *)
|
||||
in
|
||||
(expr, state)
|
||||
else (expr, state)
|
||||
let exprs_tokens, state = collect_chain state [| EqualEqual; BangEqual |] inequality in
|
||||
let f acc (expr, token) =
|
||||
match token.token_type with
|
||||
| EqualEqual -> make_binary Equal acc expr
|
||||
| BangEqual ->
|
||||
let expr = make_binary Equal acc expr in
|
||||
make_unary Not expr
|
||||
| _ -> assert false (* should only be here if tt is == != *)
|
||||
in
|
||||
let expr = Array.fold_left f expr exprs_tokens in
|
||||
(expr, state)
|
||||
|
||||
let expression (state : state) : expr * state = equality state
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue