mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
global and local variables with scope
also reworked arg parsing, now has --debug flag
This commit is contained in:
parent
222de81a19
commit
77e57cd8c2
8 changed files with 341 additions and 95 deletions
24
lib/lexer.ml
24
lib/lexer.ml
|
|
@ -67,7 +67,7 @@ module State = struct
|
|||
let get_lexeme (state : state) (first : int) (last : int) =
|
||||
String.sub state.source first (last - first)
|
||||
|
||||
let advance (state : state) : char * state =
|
||||
let next (state : state) : char * state =
|
||||
let c = state.source.[state.cur_pos] in
|
||||
let state = { state with cur_pos = state.cur_pos + 1 } in
|
||||
let state =
|
||||
|
|
@ -78,21 +78,25 @@ module State = struct
|
|||
in
|
||||
(c, state)
|
||||
|
||||
let advance (state : state) : state =
|
||||
let _, state = next state in
|
||||
state
|
||||
|
||||
let peek (state : state) : char option =
|
||||
if not (is_at_end state) then Some state.source.[state.cur_pos] else None
|
||||
|
||||
let advance_if (c : char) (state : state) : bool * state =
|
||||
if peek state = Some c then (true, snd (advance state)) else (false, state)
|
||||
if peek state = Some c then (true, snd (next state)) else (false, state)
|
||||
|
||||
let rec advance_until (c : char) (state : state) : bool * state =
|
||||
if is_at_end state then (false, state)
|
||||
else
|
||||
let c', state = advance state in
|
||||
let c', state = next state in
|
||||
if c' = c then (true, state) else advance_until c state
|
||||
|
||||
let rec advance_while (f : char -> bool) (state : state) : state =
|
||||
match peek state with
|
||||
| Some c when f c -> advance_while f (snd (advance state))
|
||||
| Some c when f c -> advance_while f (snd (next state))
|
||||
| _ -> state (* EOF or no match *)
|
||||
|
||||
let append_token (pos : code_pos) (token_type : token_type) (state : state) : state =
|
||||
|
|
@ -124,16 +128,16 @@ module State = struct
|
|||
let tt = lexeme |> Hashtbl.find_opt keywords |> Option.value ~default:(Identifier lexeme) in
|
||||
append_token code_pos tt state
|
||||
|
||||
let rec parse_block_commend (state : state) : state =
|
||||
let rec parse_block_comment (state : state) : state =
|
||||
(* "- 2" since we already consumed the "/*" *)
|
||||
let pos = { line = state.line; col = state.col - 2 } in
|
||||
let found, state = advance_until '*' state in
|
||||
if not found then append_error pos "Unterminated block commend" state
|
||||
if not found then append_error pos "Unterminated block comment" state
|
||||
else if peek state = Some '/' then
|
||||
let state = snd @@ advance state in
|
||||
let state = advance state in
|
||||
let lexeme = get_lexeme state (state.start_pos + 2) (state.cur_pos - 2) in
|
||||
append_token pos (Comment lexeme) state
|
||||
else parse_block_commend state
|
||||
else parse_block_comment state
|
||||
|
||||
let rec tokenize_rec (state : state) : state =
|
||||
let pos = { line = state.line; col = state.col } in
|
||||
|
|
@ -142,7 +146,7 @@ module State = struct
|
|||
if is_at_end state then append_token Eof state
|
||||
else
|
||||
let state = { state with start_pos = state.cur_pos } in
|
||||
let c, state = advance state in
|
||||
let c, state = next state in
|
||||
let state =
|
||||
state
|
||||
|>
|
||||
|
|
@ -181,7 +185,7 @@ module State = struct
|
|||
let _, state = advance_until '\n' state in
|
||||
let lexeme = String.trim @@ get_lexeme state start_pos state.cur_pos in
|
||||
append_token (Comment lexeme) state
|
||||
| Some '*' -> parse_block_commend (snd @@ advance state)
|
||||
| Some '*' -> parse_block_comment (advance state)
|
||||
| _ -> append_token Slash state)
|
||||
| '"' ->
|
||||
fun state ->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue