e7575d21b09ef45d483593a13bc45a9b8aa70b5e
6 Readline
in 'pas-readline/src/readline.pas',
7 History
in 'pas-readline/src/history.pas',
22 function READ(const Str
: string) : TMal
;
24 READ
:= read_str(Str
);
28 // Forward declation since eval_ast call it
29 function EVAL(Ast
: TMal
; Env
: TEnv
) : TMal
; forward;
31 function eval_ast(Ast
: TMal
; Env
: TEnv
) : TMal
;
33 OldArr
, NewArr
: TMalArray
;
34 OldDict
, NewDict
: TMalDict
;
37 if Ast
is TMalSymbol
then
39 eval_ast
:= Env
.Get((Ast
as TMalSymbol
));
41 else if Ast
is TMalList
then
43 OldArr
:= (Ast
as TMalList
).Val
;
44 SetLength(NewArr
, Length(OldArr
));
45 for I
:= 0 to Length(OldArr
)-1 do
47 NewArr
[I
] := EVAL(OldArr
[I
], Env
);
49 if Ast
is TMalVector
then
50 eval_ast
:= TMalVector
.Create(NewArr
)
52 eval_ast
:= TMalList
.Create(NewArr
);
54 else if Ast
is TMalHashMap
then
56 OldDict
:= (Ast
as TMalHashMap
).Val
;
57 NewDict
:= TMalDict
.Create
;
59 while I
< OldDict
.Count
do
61 NewDict
[OldDict
.Keys
[I
]] := EVAL(OldDict
[OldDict
.Keys
[I
]], Env
);
64 eval_ast
:= TMalHashMap
.Create(NewDict
);
70 function EVAL(Ast
: TMal
; Env
: TEnv
) : TMal
;
84 if Ast
.ClassType
<> TMalList
then
85 Exit(eval_ast(Ast
, Env
));
88 Lst
:= (Ast
as TMalList
);
90 if Arr
[0] is TMalSymbol
then
91 A0Sym
:= (Arr
[0] as TMalSymbol
).Val
93 A0Sym
:= '__<*fn*>__';
97 Exit(Env
.Add((Arr
[1] as TMalSymbol
), EVAL(Arr
[2], ENV
)));
100 LetEnv
:= TEnv
.Create(Env
);
101 Arr1
:= (Arr
[1] as TMalList
).Val
;
103 while I
< Length(Arr1
) do
105 LetEnv
.Add((Arr1
[I
] as TMalSymbol
), EVAL(Arr1
[I
+1], LetEnv
));
109 Ast
:= Arr
[2]; // TCO
113 eval_ast(TMalList
.Create(copy(Arr
,1, Length(Arr
)-2)), Env
);
114 Ast
:= Arr
[Length(Arr
)-1]; // TCO
118 Cond
:= EVAL(Arr
[1], Env
);
119 if (Cond
is TMalNil
) or (Cond
is TMalFalse
) then
120 if Length(Arr
) > 3 then
125 Ast
:= Arr
[2]; // TCO
129 Exit(TMalFunc
.Create(Arr
[2], Env
, (Arr
[1] as TMalList
)));
133 Arr
:= (eval_ast(Ast
, Env
) as TMalList
).Val
;
134 if Arr
[0] is TMalFunc
then
136 Fn
:= Arr
[0] as TMalFunc
;
137 if Length(Arr
) < 2 then
140 Args
:= copy(Arr
, 1, Length(Arr
)-1);
145 Env
:= TEnv
.Create(Fn
.Env
, Fn
.Params
, Args
);
146 Ast
:= Fn
.Ast
; // TCO
151 raise Exception
.Create('invalid apply');
158 function PRINT(Exp
: TMal
) : string;
160 PRINT
:= pr_str(Exp
, True);
164 function REP(Str
: string) : string;
166 REP
:= PRINT(EVAL(READ(Str
), Repl_Env
));
170 Repl_Env
:= TEnv
.Create
;
172 // core.pas: defined using Pascal
173 for I
:= 0 to core
.NS
.Count
-1 do
175 Key
:= core
.NS
.Keys
[I
];
176 Repl_Env
.Add(TMalSymbol
.Create(Key
),
177 TMalFunc
.Create(core
.NS
[Key
]));
180 // core.mal: defined using language itself
181 REP('(def! not (fn* (a) (if a false true)))');
185 Line
:= Readline
.readline('user> ');
197 WriteLn('Error: ' + E
.message);
198 WriteLn('Backtrace:');
199 WriteLn(GetBacktrace(E
));