Commit | Line | Data |
---|---|---|
37bb752e PS |
1 | module Env |
2 | ||
3 | open Types | |
4 | ||
5 | type Env = System.Collections.Generic.Dictionary<string, Node> | |
6 | type EnvChain = Env list | |
7 | ||
8 | let errSymbolNotFound s = EvalError(sprintf "'%s' not found" s) | |
9 | let errNoEnvironment () = EvalError("no environment") | |
10 | ||
11 | let makeEmpty () = Env() | |
12 | ||
13 | let ofList lst = | |
14 | let env = makeEmpty () | |
15 | let accumulate (e : Env) (k, v) = e.Add(k, v); e | |
16 | List.fold accumulate env lst | |
17 | ||
18 | let set (env : EnvChain) key node = | |
19 | match env with | |
20 | | head::_ -> head.[key] <- node | |
21 | | _ -> raise <| errNoEnvironment () | |
22 | ||
23 | let rec find (chain : EnvChain) key = | |
24 | match chain with | |
25 | | [] -> None | |
26 | | env::rest -> | |
27 | match env.TryGetValue(key) with | |
28 | | true, v -> Some(v) | |
29 | | false, _ -> find rest key | |
30 | ||
31 | let get chain key = | |
32 | match find chain key with | |
33 | | Some(v) -> v | |
34 | | None -> raise <| errSymbolNotFound key | |
35 | ||
36 | let makeRootEnv () = | |
37 | let wrap tag name func = name, Func({ Tag = tag; Name = name; F = func }) | |
38 | let env = | |
39 | [ wrap 1 "+" Core.add; | |
40 | wrap 2 "-" Core.subtract; | |
41 | wrap 3 "*" Core.multiply; | |
42 | wrap 4 "/" Core.divide ] | |
43 | |> ofList | |
44 | [ env ] | |
45 |