mirror of
https://github.com/MorizzG/MLox.git
synced 2025-12-06 04:22:41 +00:00
in environment made globals ref to easier share
This commit is contained in:
parent
8f4b95a137
commit
8735cc5023
1 changed files with 14 additions and 12 deletions
|
|
@ -1,36 +1,38 @@
|
||||||
open Value
|
open Value
|
||||||
|
|
||||||
type env_table = (string, lox_value) Hashtbl.t
|
|
||||||
type environment = { globals : env_table; locals : env_table list }
|
|
||||||
|
|
||||||
module Hashtbl = struct
|
module Hashtbl = struct
|
||||||
include Stdlib.Hashtbl
|
include Stdlib.Hashtbl
|
||||||
|
|
||||||
let contains tbl key = find_opt tbl key |> Option.is_some
|
let contains tbl key = find_opt tbl key |> Option.is_some
|
||||||
end
|
end
|
||||||
|
|
||||||
|
type env_table = (string, lox_value) Hashtbl.t
|
||||||
|
type environment = { globals : env_table ref; locals : env_table list }
|
||||||
|
|
||||||
module Env = struct
|
module Env = struct
|
||||||
type t = environment
|
type t = environment
|
||||||
|
|
||||||
let make () : t = { globals = Hashtbl.create 0; locals = [] }
|
let make () : t = { globals = ref (Hashtbl.create 0); locals = [] }
|
||||||
|
|
||||||
let enter (env : t) : t =
|
let enter (env : t) : t =
|
||||||
let tbl = Hashtbl.create 0 in
|
let tbl = Hashtbl.create 0 in
|
||||||
{ env with locals = tbl :: env.locals }
|
{ env with locals = tbl :: env.locals }
|
||||||
|
|
||||||
let exit (env : t) : t =
|
let push_frame (env : t) : t = { env with locals = [] } |> enter
|
||||||
assert (not (List.is_empty env.locals));
|
|
||||||
{ env with locals = List.tl env.locals }
|
(* let exit (env : t) : t =
|
||||||
|
assert (not (List.is_empty env.locals));
|
||||||
|
{ env with locals = List.tl env.locals } *)
|
||||||
|
|
||||||
let define_global (env : t) (name : string) (value : lox_value) =
|
let define_global (env : t) (name : string) (value : lox_value) =
|
||||||
Hashtbl.replace env.globals name value
|
Hashtbl.replace !(env.globals) name value
|
||||||
|
|
||||||
let get_global (env : t) (name : string) : lox_value option = Hashtbl.find_opt env.globals name
|
let get_global (env : t) (name : string) : lox_value option = Hashtbl.find_opt !(env.globals) name
|
||||||
|
|
||||||
(* Check if `name` is defined in either locals or globals *)
|
(* Check if `name` is defined in either locals or globals *)
|
||||||
let is_defined (env : t) (name : string) : bool =
|
let is_defined (env : t) (name : string) : bool =
|
||||||
let _is_defined tbl = Hashtbl.contains tbl name in
|
let _is_defined tbl = Hashtbl.contains tbl name in
|
||||||
List.fold_left (fun acc tbl -> acc || _is_defined tbl) false (env.globals :: env.locals)
|
List.fold_left (fun acc tbl -> acc || _is_defined tbl) false (!(env.globals) :: env.locals)
|
||||||
|
|
||||||
let define (env : t) (name : string) (value : lox_value) : bool =
|
let define (env : t) (name : string) (value : lox_value) : bool =
|
||||||
if List.is_empty env.locals then (
|
if List.is_empty env.locals then (
|
||||||
|
|
@ -53,7 +55,7 @@ module Env = struct
|
||||||
true)
|
true)
|
||||||
else _update tail
|
else _update tail
|
||||||
in
|
in
|
||||||
if _update env.locals then () else Hashtbl.replace env.globals name value
|
if _update env.locals then () else Hashtbl.replace !(env.globals) name value
|
||||||
|
|
||||||
let get (env : t) (name : string) : lox_value option =
|
let get (env : t) (name : string) : lox_value option =
|
||||||
let rec _get tbls =
|
let rec _get tbls =
|
||||||
|
|
@ -63,5 +65,5 @@ module Env = struct
|
||||||
match Hashtbl.find_opt tbl name with Some x -> Some x | None -> _get tail)
|
match Hashtbl.find_opt tbl name with Some x -> Some x | None -> _get tail)
|
||||||
in
|
in
|
||||||
let val_opt = _get env.locals in
|
let val_opt = _get env.locals in
|
||||||
match val_opt with Some x -> Some x | None -> Hashtbl.find_opt env.globals name
|
match val_opt with Some x -> Some x | None -> Hashtbl.find_opt !(env.globals) name
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue