diff options
| author | Joel Martin <github@martintribe.org> | 2015-02-08 01:13:41 -0600 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2015-02-08 23:51:08 -0600 |
| commit | d6624158bdf41e047ad8d0a9942238dc80649901 (patch) | |
| tree | 4138b0e5c597b65a690adbc933748dc0c1271b7a | |
| parent | ab6e6fae4e8935fca5fb33bd8645fe9cece18bb9 (diff) | |
| download | mal-d6624158bdf41e047ad8d0a9942238dc80649901.tar.gz mal-d6624158bdf41e047ad8d0a9942238dc80649901.zip | |
matlab: start of step4
| -rw-r--r-- | matlab/+types/Nil.m | 2 | ||||
| -rw-r--r-- | matlab/Env.m | 16 | ||||
| -rw-r--r-- | matlab/core.m | 22 | ||||
| -rw-r--r-- | matlab/printer.m | 2 | ||||
| -rw-r--r-- | matlab/reader.m | 3 | ||||
| -rw-r--r-- | matlab/step4_if_fn_do.m | 98 | ||||
| -rw-r--r-- | matlab/types.m | 6 |
7 files changed, 147 insertions, 2 deletions
diff --git a/matlab/+types/Nil.m b/matlab/+types/Nil.m new file mode 100644 index 0000000..d7573f0 --- /dev/null +++ b/matlab/+types/Nil.m @@ -0,0 +1,2 @@ +classdef Nil +end diff --git a/matlab/Env.m b/matlab/Env.m index 1d080a3..1a7b3fc 100644 --- a/matlab/Env.m +++ b/matlab/Env.m @@ -4,10 +4,24 @@ classdef Env < handle outer end methods - function env = Env(outer) + function env = Env(outer, binds, exprs) env.data = containers.Map(); env.outer = outer; + + if nargin > 1 + env = Env(outer); + for i=1:length(binds) + k = binds{i}.name; + if strcmp(k, '&') + env.data(binds{i+1}.name) = exprs(i:end); + break; + else + env.data(k) = exprs{i}; + end + end + end end + function ret = set(env, k, v) env.data(k.name) = v; ret = v; diff --git a/matlab/core.m b/matlab/core.m new file mode 100644 index 0000000..968b9a4 --- /dev/null +++ b/matlab/core.m @@ -0,0 +1,22 @@ +classdef core + methods(Static) + function n = ns() + n = containers.Map(); + n('=') = @(a,b) a==b; + n('<') = @(a,b) a<b; + n('<=') = @(a,b) a<=b; + n('>') = @(a,b) a>b; + n('>=') = @(a,b) a>=b; + n('+') = @(a,b) a+b; + n('-') = @(a,b) a-b; + n('*') = @(a,b) a*b; + n('/') = @(a,b) floor(a/b); + + n('list') = @(varargin) varargin; + n('list?') = @iscell; + n('empty?') = @(a) length(a) == 0; + n('count') = @(a) length(a); + end + end +end + diff --git a/matlab/printer.m b/matlab/printer.m index b164093..9308a96 100644 --- a/matlab/printer.m +++ b/matlab/printer.m @@ -13,6 +13,8 @@ classdef printer strs = cellfun(@(x) printer.pr_str(x, print_readably), ... obj, 'UniformOutput', false); str = strcat('(', strjoin(strs, ' '), ')'); + case 'types.Nil' + str = 'nil'; case 'logical' if eq(obj, true) str = 'true'; diff --git a/matlab/reader.m b/matlab/reader.m index 8c752c9..77dae07 100644 --- a/matlab/reader.m +++ b/matlab/reader.m @@ -14,7 +14,8 @@ classdef reader atm = str2double(token); elseif strcmp(token(1), '"') atm = token(2:length(token)-1); - %else if token eq 'nil' + elseif strcmp(token, 'nil') + atm = types.nil; elseif strcmp(token, 'true') atm = true; elseif strcmp(token, 'false') diff --git a/matlab/step4_if_fn_do.m b/matlab/step4_if_fn_do.m new file mode 100644 index 0000000..4f73da7 --- /dev/null +++ b/matlab/step4_if_fn_do.m @@ -0,0 +1,98 @@ +function step4_if_fn_do(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) + 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)); + 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 + ret = EVAL(ast{3}, let_env); + case 'do' + el = eval_ast(ast(2:end), env); + ret = el{end}; + case 'if' + cond = EVAL(ast{2}, env); + if strcmp(class(cond), 'types.Nil') || ... + (islogical(cond) && cond == false) + if length(ast) > 3 + ret = EVAL(ast{4}, env); + else + ret = types.nil; + end + else + ret = EVAL(ast{3}, env); + end + case 'fn*' + ret = @(varargin) EVAL(ast{3}, Env(env, ast{2}, varargin)); + otherwise + el = eval_ast(ast, env); + f = el{1}; + args = el(2:end); + ret = f(args{:}); + 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); + ns = core.ns(); ks = ns.keys(); + for i=1:length(ks) + k = ks{i}; + repl_env.set(types.Symbol(k), ns(k)); + 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 diff --git a/matlab/types.m b/matlab/types.m new file mode 100644 index 0000000..cb3bf8f --- /dev/null +++ b/matlab/types.m @@ -0,0 +1,6 @@ +classdef types + properties (Constant = true) + nil = types.Nil(); + end +end + |
