1 function stepA_mal
(varargin), main
(varargin), end
4 function ret
= READ
(str
)
5 ret
= reader.read_str
(str
);
9 function ret
= is_pair
(ast
)
10 ret
= type_utils.sequential_Q
(ast
) && length(ast
) > 0;
13 function ret
= quasiquote
(ast
)
15 ret
= types.List
(types.Symbol
('quote'), ast
);
16 elseif isa(ast.
get(1),'types.Symbol') && ...
17 strcmp(ast.
get(1).name
, 'unquote')
19 elseif is_pair
(ast.
get(1)) && ...
20 isa(ast.
get(1).
get(1),'types.Symbol') && ...
21 strcmp(ast.
get(1).
get(1).name
, 'splice-unquote')
22 ret
= types.List
(types.Symbol
('concat'), ...
23 ast.
get(1).
get(2), ...
24 quasiquote
(ast.
slice(2)));
26 ret
= types.List
(types.Symbol
('cons'), ...
27 quasiquote
(ast.
get(1)), ...
28 quasiquote
(ast.
slice(2)));
32 function ret
= is_macro_call
(ast
, env
)
33 if type_utils.list_Q
(ast
) && isa(ast.
get(1), 'types.Symbol') && ...
34 ~islogical
(env.
find(ast.
get(1)))
35 f
= env.
get(ast.
get(1));
36 ret
= isa(f
,'types.Function') && f.is_macro
;
42 function ret
= macroexpand
(ast
, env
)
43 while is_macro_call
(ast
, env
)
44 mac
= env.
get(ast.
get(1));
46 ast
= mac.fn
(args.data
{:});
51 function ret
= eval_ast
(ast
, env
)
58 ret.append
(EVAL(ast.
get(i
), env
));
63 ret.append
(EVAL(ast.
get(i
), env
));
66 ret
= types.HashMap
();
70 ret.
set(EVAL(k
, env
), EVAL(ast.
get(k
), env
));
77 function ret
= EVAL(ast
, env
)
79 %fprintf('EVAL: %s\n', printer.pr_str(ast, true));
80 if ~type_utils.list_Q
(ast
)
81 ret
= eval_ast
(ast
, env
);
90 ast
= macroexpand
(ast
, env
);
91 if ~type_utils.list_Q
(ast
)
92 ret
= eval_ast
(ast
, env
);
96 if isa(ast.
get(1),'types.Symbol')
97 a1sym
= ast.
get(1).name
;
103 ret
= env.
set(ast.
get(2), EVAL(ast.
get(3), env
));
106 let_env
= Env
({env
});
107 for i
=1:2:length(ast.
get(2))
108 let_env.
set(ast.
get(2).
get(i
), EVAL(ast.
get(2).
get(i
+1), let_env
));
111 ast
= ast.
get(3); % TCO
116 ast
= quasiquote
(ast.
get(2)); % TCO
118 ret
= env.
set(ast.
get(2), EVAL(ast.
get(3), env
));
122 ret
= macroexpand
(ast.
get(2), env
);
126 ret
= EVAL(ast.
get(2), env
);
129 if length(ast
) > 2 && strcmp(ast.
get(3).
get(1).name
, 'catch*')
130 if strcmp(e.identifier
, 'MalException:object')
131 if exist('OCTAVE_VERSION', 'builtin') ~
= 0
140 catch_env
= Env
({env
}, types.List
(ast.
get(3).
get(2)), ...
142 ret
= EVAL(ast.
get(3).
get(3), catch_env
);
149 el
= eval_ast
(ast.
slice(2,length(ast
)-1), env
);
150 ast
= ast.
get(length(ast
)); % TCO
152 cond = EVAL(ast.
get(2), env
);
153 if strcmp(class(cond), 'types.Nil') || ...
154 (islogical
(cond) && cond == false
)
156 ast
= ast.
get(4); % TCO
158 ret
= type_utils.nil
;
162 ast
= ast.
get(3); % TCO
165 fn
= @
(varargin) EVAL(ast.
get(3), Env
({env
}, ast.
get(2), ...
166 types.List
(varargin{:})));
167 ret
= types.
Function(fn
, ast.
get(3), env
, ast.
get(2));
170 el
= eval_ast
(ast
, env
);
173 if isa(f
, 'types.Function')
174 env
= Env
({f.env
}, f.params
, args
);
177 ret
= f
(args.data
{:});
185 function ret
= PRINT(ast
)
186 ret
= printer.pr_str
(ast
, true
);
190 function ret
= rep
(str
, env
)
191 ret
= PRINT(EVAL(READ
(str
), env
));
197 % core.m: defined using matlab
198 ns
= core.ns
(); ks
= ns.keys
();
201 repl_env.
set(types.Symbol
(k
), ns
(k
));
203 repl_env.
set(types.Symbol
('eval'), @
(a
) EVAL(a
, repl_env
));
204 rest_args
= args
(2:end);
205 repl_env.
set(types.Symbol
('*ARGV*'), types.List
(rest_args
{:}));
207 % core.mal: defined using the langauge itself
208 rep
('(def! *host-language* "matlab")', repl_env
);
209 rep
('(def! not (fn* (a) (if a false true)))', repl_env
);
210 rep
('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))"', repl_env
);
211 rep
('(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list ''if (first xs) (if (> (count xs) 1) (nth xs 1) (throw "odd number of forms to cond")) (cons ''cond (rest (rest xs)))))))', repl_env
);
212 rep
('(def! *gensym-counter* (atom 0))', repl_env
);
213 rep
('(def! gensym (fn* [] (symbol (str "G__" (swap! *gensym-counter* (fn* [x] (+ 1 x)))))))', repl_env
);
214 rep
('(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) (let* (condvar (gensym)) `(let* (~condvar ~(first xs)) (if ~condvar ~condvar (or ~@(rest xs)))))))))', repl_env
);
217 rep
(sprintf('(load-file "%s")', args
{1}), repl_env
);
221 %cleanObj = onCleanup(@() disp('*** here1 ***'));
222 rep
('(println (str "Mal [" *host-language* "]"))', repl_env
);
225 line = input('user> ', 's');
229 if strcmp(strtrim
(line),''), continue
, end
231 fprintf('%s\n', rep
(line, repl_env
));
233 if strcmp('MalException:object', err.identifier
)
234 if exist('OCTAVE_VERSION', 'builtin') ~
= 0
236 fprintf('Error: %s\n', printer.pr_str
(error_object
, true
));
238 fprintf('Error: %s\n', printer.pr_str
(err.obj
, true
));
241 fprintf('Error: %s\n', err.message
);
243 type_utils.print_stack
(err
);