Commit | Line | Data |
---|---|---|
0067158f JM |
1 | unit mal_env; |
2 | ||
3 | {$H+} // Use AnsiString | |
4 | ||
5 | interface | |
6 | ||
7 | Uses sysutils, | |
8 | fgl, | |
9 | mal_types; | |
10 | ||
11 | type TEnv = class(TObject) | |
12 | public | |
13 | Data : TMalDict; | |
14 | Outer : TEnv; | |
15 | ||
16 | constructor Create; | |
17 | constructor Create(_Outer : TEnv); | |
18 | constructor Create(_Outer : TEnv; | |
19 | Binds : TMalList; | |
20 | Exprs : TMalArray); | |
21 | ||
22 | function Add(Key : TMalSymbol; Val : TMal) : TMal; | |
23 | function Find(Key : TMalSymbol) : TEnv; | |
24 | function Get(Key : TMalSymbol) : TMal; | |
25 | end; | |
26 | ||
27 | //////////////////////////////////////////////////////////// | |
28 | ||
29 | implementation | |
30 | ||
31 | constructor TEnv.Create(); | |
32 | begin | |
33 | inherited Create(); | |
34 | Self.Data := TMalDict.Create; | |
35 | Self.Outer := nil; | |
36 | end; | |
37 | ||
38 | constructor TEnv.Create(_Outer: TEnv); | |
39 | begin | |
40 | Self.Create(); | |
41 | Self.Outer := _Outer; | |
42 | end; | |
43 | ||
44 | constructor TEnv.Create(_Outer : TEnv; | |
45 | Binds : TMalList; | |
46 | Exprs : TMalArray); | |
47 | var | |
48 | I : longint; | |
49 | Bind : TMalSymbol; | |
50 | Rest : TMalList; | |
51 | begin | |
52 | Self.Create(_Outer); | |
53 | for I := 0 to Length(Binds.Val)-1 do | |
54 | begin | |
55 | Bind := (Binds.Val[I] as TMalSymbol); | |
56 | if Bind.Val = '&' then | |
57 | begin | |
58 | if I < Length(Exprs) then | |
59 | Rest := TMalList.Create(copy(Exprs, I, Length(Exprs)-I)) | |
60 | else | |
61 | Rest := TMalList.Create; | |
62 | Self.Data[(Binds.Val[I+1] as TMalSymbol).Val] := Rest; | |
63 | break; | |
64 | end; | |
65 | Self.Data[Bind.Val] := Exprs[I]; | |
66 | end; | |
67 | end; | |
68 | ||
69 | function TEnv.Add(Key : TMalSymbol; Val : TMal) : TMal; | |
70 | begin | |
71 | Self.Data[Key.Val] := Val; | |
72 | Add := Val; | |
73 | end; | |
74 | ||
75 | function TEnv.Find(Key : TMalSymbol) : TEnv; | |
76 | var | |
77 | Sym : string; | |
78 | begin | |
79 | Sym := (Key as TMalSymbol).Val; | |
80 | if Data.IndexOf(Sym) >= 0 then | |
81 | Find := Self | |
82 | else if Outer <> nil then | |
83 | Find := Outer.Find(Key) | |
84 | else | |
85 | Find := nil; | |
86 | end; | |
87 | ||
88 | function TEnv.Get(Key : TMalSymbol) : TMal; | |
89 | var | |
90 | Sym : string; | |
91 | Env : TEnv; | |
92 | begin | |
93 | Sym := (Key as TMalSymbol).Val; | |
94 | Env := Self.Find(Key); | |
95 | if Env <> nil then | |
96 | Get := Env.Data[Sym] | |
97 | else | |
98 | raise Exception.Create('''' + Sym + ''' not found'); | |
99 | end; | |
100 | ||
101 | end. |