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 matches state tts =
|
||||||
let f = ( == ) (peek state).token_type in
|
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 =
|
(expr * token) array * state =
|
||||||
(* ([], state) *)
|
(* ([], state) *)
|
||||||
let state_ref = ref state in
|
let state_ref = ref state in
|
||||||
|
|
@ -39,59 +39,61 @@ module State = struct
|
||||||
done;
|
done;
|
||||||
(Array.of_list (List.rev !out_list_rev), !state_ref)
|
(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
|
let token, state = next state in
|
||||||
(make_string @@ show_token_type token.token_type, state)
|
(make_string @@ show_token_type token.token_type, state)
|
||||||
|
|
||||||
let sum_or_diff (state : state) : expr * state =
|
let rec neg_not (state : state) : expr * state =
|
||||||
let expr, state = mul_or_div state in
|
if matches state [| Bang; Minus |] then
|
||||||
(* if (not (is_at_end state)) && matches state [ Plus; Minus ] then
|
let token, state = next state in
|
||||||
let token, state = next state in
|
let expr, state = neg_not state in
|
||||||
let expr2, state = sum_or_diff state in
|
let op =
|
||||||
let (op : binary_op) =
|
match token.token_type with
|
||||||
match token.token_type with
|
| Bang -> Not
|
||||||
| Plus -> Plus
|
| Minus -> Neg
|
||||||
| Minus -> Minus
|
| _ -> assert false (* should only be here if tt is - ! *)
|
||||||
| _ -> assert false (* should only be here if tt is + - *)
|
in
|
||||||
in
|
let expr = make_unary op expr in
|
||||||
let expr = make_binary op expr expr2 in
|
(expr, state)
|
||||||
(expr, state)
|
else primary state
|
||||||
else (expr, state) *)
|
|
||||||
(* turn expr and state to refs for the loop *)
|
let mul_or_div (state : state) : expr * state =
|
||||||
(* Printf.printf "expr: %s\n\n" (show_expr expr);
|
let expr, state = neg_not state in
|
||||||
let expr_ref, state_ref = (ref expr, ref state) in
|
let exprs_tokens, state = collect_chain state [| Star; Slash |] neg_not 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 f acc (expr, token) =
|
let f acc (expr, token) =
|
||||||
let op : binary_op =
|
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
|
in
|
||||||
make_binary op acc expr
|
make_binary op acc expr
|
||||||
in
|
in
|
||||||
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 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
|
let expr, state = sum_or_diff state in
|
||||||
if (not (is_at_end state)) && matches state [ Greater; GreaterEqual; Less; LessEqual ] then
|
let exprs_tokens, state =
|
||||||
let token, state = next state in
|
collect_chain state [| Greater; GreaterEqual; Less; LessEqual |] sum_or_diff
|
||||||
let expr2, state = inequality state in
|
in
|
||||||
(* TODO: maybe rework to only have Less and Greater as ops; performance? *)
|
let f acc (expr, token) =
|
||||||
let (op : binary_op) =
|
let (op : binary_op) =
|
||||||
match token.token_type with
|
match token.token_type with
|
||||||
| Greater -> Greater
|
| Greater -> Greater
|
||||||
|
|
@ -100,25 +102,24 @@ module State = struct
|
||||||
| LessEqual -> LessEqual
|
| LessEqual -> LessEqual
|
||||||
| _ -> assert false (* should only be here if tt is > < >= <= *)
|
| _ -> assert false (* should only be here if tt is > < >= <= *)
|
||||||
in
|
in
|
||||||
let expr = make_binary op expr expr2 in
|
make_binary op acc expr
|
||||||
(expr, state)
|
in
|
||||||
else (expr, state)
|
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
|
let expr, state = inequality state in
|
||||||
if matches state [ EqualEqual; BangEqual ] then
|
let exprs_tokens, state = collect_chain state [| EqualEqual; BangEqual |] inequality in
|
||||||
let token, state = next state in
|
let f acc (expr, token) =
|
||||||
let expr2, state = equality state in
|
match token.token_type with
|
||||||
let expr =
|
| EqualEqual -> make_binary Equal acc expr
|
||||||
match token.token_type with
|
| BangEqual ->
|
||||||
| EqualEqual -> make_binary Equal expr expr2
|
let expr = make_binary Equal acc expr in
|
||||||
| BangEqual ->
|
make_unary Not expr
|
||||||
let expr = make_binary Equal expr expr2 in
|
| _ -> assert false (* should only be here if tt is == != *)
|
||||||
make_unary Not expr
|
in
|
||||||
| _ -> assert false (* should only be here if tt is == != *)
|
let expr = Array.fold_left f expr exprs_tokens in
|
||||||
in
|
(expr, state)
|
||||||
(expr, state)
|
|
||||||
else (expr, state)
|
|
||||||
|
|
||||||
let expression (state : state) : expr * state = equality state
|
let expression (state : state) : expr * state = equality state
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue