diff options
| author | Joel Martin <github@martintribe.org> | 2015-02-08 18:56:13 -0600 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2015-02-08 23:51:38 -0600 |
| commit | 9831bce71071b1db9391ef77d450199c6bc76990 (patch) | |
| tree | 32812e9cf0c7ceef42c5f274fbde9c49591535b2 | |
| parent | 23c5aa440a0d21934bc16407cf0312ac95734738 (diff) | |
| download | mal-9831bce71071b1db9391ef77d450199c6bc76990.tar.gz mal-9831bce71071b1db9391ef77d450199c6bc76990.zip | |
matlab: add step6
| -rw-r--r-- | matlab/core.m | 3 | ||||
| -rw-r--r-- | matlab/step6_file.m | 124 |
2 files changed, 127 insertions, 0 deletions
diff --git a/matlab/core.m b/matlab/core.m index 8a64934..fb6e456 100644 --- a/matlab/core.m +++ b/matlab/core.m @@ -31,6 +31,9 @@ classdef core n('str') = @core.do_str; n('prn') = @core.prn; n('println') = @core.println; + n('read-string') = @reader.read_str; + n('slurp') = @fileread; + n('<') = @(a,b) a<b; n('<=') = @(a,b) a<=b; n('>') = @(a,b) a>b; diff --git a/matlab/step6_file.m b/matlab/step6_file.m new file mode 100644 index 0000000..63fd84a --- /dev/null +++ b/matlab/step6_file.m @@ -0,0 +1,124 @@ +function step6_file(varargin), main(varargin), end + +% read +function ret = READ(str) + ret = reader.read_str(str); +end + +% eval +function ret = eval_ast(ast, env) + switch class(ast) + case 'types.Symbol' + ret = env.get(ast); + case 'cell' + ret = {}; + for i=1:length(ast) + ret{end+1} = EVAL(ast{i}, env); + end + otherwise + ret = ast; + end +end + +function ret = EVAL(ast, env) + while true + if ~iscell(ast), + ret = eval_ast(ast, env); + return; + end + + % apply + if isa(ast{1},'types.Symbol') + a1sym = ast{1}.name; + else + a1sym = '_@$fn$@_'; + end + switch (a1sym) + case 'def!' + ret = env.set(ast{2}, EVAL(ast{3}, env)); + return; + case 'let*' + let_env = Env(env); + for i=1:2:length(ast{2}) + let_env.set(ast{2}{i}, EVAL(ast{2}{i+1}, let_env)); + end + env = let_env; + ast = ast{3}; % TCO + case 'do' + el = eval_ast(ast(2:end-1), env); + ast = ast{end}; % TCO + case 'if' + cond = EVAL(ast{2}, env); + if strcmp(class(cond), 'types.Nil') || ... + (islogical(cond) && cond == false) + if length(ast) > 3 + ast = ast{4}; % TCO + else + ret = types.nil; + return; + end + else + ast = ast{3}; % TCO + end + case 'fn*' + fn = @(varargin) EVAL(ast{3}, Env(env, ast{2}, varargin)); + ret = Function(fn, ast{3}, env, ast{2}); + return; + otherwise + el = eval_ast(ast, env); + f = el{1}; + args = el(2:end); + if isa(f, 'Function') + env = Env(f.env, f.params, args); + ast = f.ast; % TCO + else + ret = f(args{:}); + return + end + end + end +end + +% print +function ret = PRINT(ast) + ret = printer.pr_str(ast, true); +end + +% REPL +function ret = rep(str, env) + ret = PRINT(EVAL(READ(str), env)); +end + +function main(args) + repl_env = Env(false); + + % core.m: defined using matlab + ns = core.ns(); ks = ns.keys(); + for i=1:length(ks) + k = ks{i}; + repl_env.set(types.Symbol(k), ns(k)); + end + repl_env.set(types.Symbol('eval'), @(a) EVAL(a, repl_env)); + repl_env.set(types.Symbol('*ARGV*'), args(2:end)); + + % core.mal: defined using the langauge itself + rep('(def! not (fn* (a) (if a false true)))', repl_env); + rep('(def! load-file (fn* (f) (eval (read-string (str "(do " (slurp f) ")")))))"', repl_env); + + if ~isempty(args) + rep(strcat('(load-file "', args{1}, '")'), repl_env); + quit; + end + + %cleanObj = onCleanup(@() disp('*** here1 ***')); + while (true) + line = input('user> ', 's'); + if strcmp(strtrim(line),''), continue, end + try + fprintf('%s\n', rep(line, repl_env)); + catch err + fprintf('Error: %s\n', err.message); + fprintf('%s\n', getReport(err, 'extended')); + end + end +end |
