e5a1e80898c0c0401a653495c001a519f27276df
3 {$H+} // Use AnsiString
8 Readline
in 'pas-readline/src/readline.pas',
9 History
in 'pas-readline/src/history.pas',
16 TEnv
= specialize TFPGMap
<string,TMal
>;
23 function READ(const Str
: string) : TMal
;
25 READ
:= read_str(Str
);
29 // Forward declation since eval_ast call it
30 function EVAL(Ast
: TMal
; Env
: TEnv
) : TMal
; forward;
32 function eval_ast(Ast
: TMal
; Env
: TEnv
) : TMal
;
35 OldArr
, NewArr
: TMalArray
;
36 OldDict
, NewDict
: TMalDict
;
39 if Ast
is TMalSymbol
then
41 Sym
:= (Ast
as TMalSymbol
).Val
;
42 if Env
.IndexOf(Sym
) < 0 then
43 raise Exception
.Create('''' + Sym
+ ''' not found')
47 else if Ast
is TMalList
then
49 OldArr
:= (Ast
as TMalList
).Val
;
50 SetLength(NewArr
, Length(OldArr
));
51 for I
:= 0 to Length(OldArr
)-1 do
53 NewArr
[I
] := EVAL(OldArr
[I
], Env
);
55 if Ast
is TMalVector
then
56 eval_ast
:= TMalVector
.Create(NewArr
)
58 eval_ast
:= TMalList
.Create(NewArr
);
60 else if Ast
is TMalHashMap
then
62 OldDict
:= (Ast
as TMalHashMap
).Val
;
63 NewDict
:= TMalDict
.Create
;
65 while I
< OldDict
.Count
do
67 NewDict
[OldDict
.Keys
[I
]] := EVAL(OldDict
[OldDict
.Keys
[I
]], Env
);
70 eval_ast
:= TMalHashMap
.Create(NewDict
);
76 function EVAL(Ast
: TMal
; Env
: TEnv
) : TMal
;
81 if Ast
.ClassType
<> TMalList
then
82 Exit(eval_ast(Ast
, Env
));
85 Arr
:= (eval_ast(Ast
, Env
) as TMalList
).Val
;
86 if Arr
[0] is TMalFunc
then
88 Fn
:= (Arr
[0] as TMalFunc
).Val
;
89 EVAL
:= Fn(copy(Arr
, 1, Length(Arr
)-1));
92 raise Exception
.Create('invalid apply');
96 function PRINT(Exp
: TMal
) : string;
98 PRINT
:= pr_str(Exp
, True);
102 function REP(Str
: string) : string;
104 REP
:= PRINT(EVAL(READ(Str
), Repl_Env
));
107 function add(Args
: TMalArray
) : TMal
;
109 add
:= TMalInt
.Create((Args
[0] as TMalInt
).Val
+
110 (Args
[1] as TMalInt
).Val
);
112 function subtract(Args
: TMalArray
) : TMal
;
114 subtract
:= TMalInt
.Create((Args
[0] as TMalInt
).Val
-
115 (Args
[1] as TMalInt
).Val
);
117 function multiply(Args
: TMalArray
) : TMal
;
119 multiply
:= TMalInt
.Create((Args
[0] as TMalInt
).Val
*
120 (Args
[1] as TMalInt
).Val
);
122 function divide(Args
: TMalArray
) : TMal
;
124 divide
:= TMalInt
.Create((Args
[0] as TMalInt
).Val
div
125 (Args
[1] as TMalInt
).Val
);
129 Repl_Env
:= TEnv
.Create
;
130 Repl_Env
.Add('+', TMalFunc
.Create(@add
));
131 Repl_Env
.Add('-', TMalFunc
.Create(@subtract
));
132 Repl_Env
.Add('*', TMalFunc
.Create(@multiply
));
133 Repl_Env
.Add('/', TMalFunc
.Create(@divide
));
136 Line
:= Readline
.readline('user> ');
148 WriteLn('Error: ' + E
.message);
149 WriteLn('Backtrace:');
150 WriteLn(GetBacktrace(E
));