From ab6e6fae4e8935fca5fb33bd8645fe9cece18bb9 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Sat, 7 Feb 2015 22:07:16 -0600 Subject: matlab: step3 --- matlab/Env.m | 36 ++++++++++++++++++++++++ matlab/step2_eval.m | 10 ++++--- matlab/step3_env.m | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 matlab/Env.m create mode 100644 matlab/step3_env.m diff --git a/matlab/Env.m b/matlab/Env.m new file mode 100644 index 0000000..1d080a3 --- /dev/null +++ b/matlab/Env.m @@ -0,0 +1,36 @@ +classdef Env < handle + properties + data + outer + end + methods + function env = Env(outer) + env.data = containers.Map(); + env.outer = outer; + end + function ret = set(env, k, v) + env.data(k.name) = v; + ret = v; + end + function ret = find(env, k) + if env.data.isKey(k.name) + ret = env; + else + if ~islogical(env.outer) + ret = env.outer.find(k); + else + ret = false; + end + end + end + function ret = get(env, k) + fenv = env.find(k); + if ~islogical(fenv) + ret = fenv.data(k.name); + else + throw(MException('ENV:notfound', ... + strcat('''', k.name, ''' not found'))); + end + end + end +end diff --git a/matlab/step2_eval.m b/matlab/step2_eval.m index 418bb84..4ce13fb 100644 --- a/matlab/step2_eval.m +++ b/matlab/step2_eval.m @@ -1,4 +1,4 @@ -function step1_read_print(varargin), main(varargin), end +function step2_eval(varargin), main(varargin), end % read function ret = READ(str) @@ -44,9 +44,11 @@ function ret = rep(str, env) end function main(args) - repl_env = containers.Map( ... - {'+', '-', '*', '/'}, ... - {@(a,b) a+b, @(a,b) a-b, @(a,b) a*b, @(a,b) floor(a/b)}); + repl_env = containers.Map(); + repl_env('+') = @(a,b) a+b; + repl_env('-') = @(a,b) a-b; + repl_env('*') = @(a,b) a*b; + repl_env('/') = @(a,b) floor(a/b); %cleanObj = onCleanup(@() disp('*** here1 ***')); while (true) diff --git a/matlab/step3_env.m b/matlab/step3_env.m new file mode 100644 index 0000000..6ac6426 --- /dev/null +++ b/matlab/step3_env.m @@ -0,0 +1,80 @@ +function step3_env(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); + 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); + repl_env.set(types.Symbol('+'), @(a,b) a+b); + repl_env.set(types.Symbol('-'), @(a,b) a-b); + repl_env.set(types.Symbol('*'), @(a,b) a*b); + repl_env.set(types.Symbol('/'), @(a,b) floor(a/b)); + + %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 -- cgit v1.2.3