Skip to content

Commit

Permalink
matlab: merge eval and eval_ast
Browse files Browse the repository at this point in the history
  • Loading branch information
asarhaddon committed Oct 9, 2024
1 parent 8dd059c commit 2764f89
Show file tree
Hide file tree
Showing 10 changed files with 276 additions and 265 deletions.
28 changes: 7 additions & 21 deletions impls/matlab/Env.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,16 @@
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
if exist('OCTAVE_VERSION', 'builtin') ~= 0
error('ENV:notfound', ...
sprintf('''%s'' not found', k.name));
else
throw(MException('ENV:notfound', ...
sprintf('''%s'' not found', k.name)));
while ~env.data.isKey(k)
env = env.outer;
if islogical(env)
ret = {};
return;
end
end
ret = env.data(k);
end
end
end
32 changes: 16 additions & 16 deletions impls/matlab/step2_eval.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,32 @@ function step2_eval(varargin), main(varargin), end
end

% eval
function ret = eval_ast(ast, env)
function ret = EVAL(ast, env)

% fprintf('EVAL: %s\n', printer.pr_str(ast, true));

switch class(ast)
case 'types.Symbol'
ret = env(ast.name);
return;
case 'types.List'
ret = types.List();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
end
% Proceed after this switch.
case 'types.Vector'
ret = types.Vector();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
end
return;
case 'types.HashMap'
ret = types.HashMap();
ks = ast.keys();
for i=1:length(ks)
k = ks{i};
ret.set(k, EVAL(ast.get(k), env));
end
return;
otherwise
ret = ast;
end
end

function ret = EVAL(ast, env)
%fprintf('EVAL: %s\n', printer.pr_str(ast, true));
if ~type_utils.list_Q(ast)
ret = eval_ast(ast, env);
return;
end

Expand All @@ -44,10 +40,14 @@ function step2_eval(varargin), main(varargin), end
ret = ast;
return;
end
el = eval_ast(ast, env);
f = el.get(1);
args = el.data(2:end);
ret = f(args{:});

f = EVAL(ast.get(1), env);
args = types.List();
for i=2:length(ast)
args.append(EVAL(ast.get(i), env));
end
ret = f(args.data{:});

end

% print
Expand Down
46 changes: 29 additions & 17 deletions impls/matlab/step3_env.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,45 @@ function step3_env(varargin), main(varargin), end
end

% eval
function ret = eval_ast(ast, env)
function ret = EVAL(ast, env)

dbgeval = env.get('DEBUG-EVAL');
if ~isequal(dbgeval, {}) ...
&& ~strcmp(class(dbgeval), 'types.Nil') ...
&& (~islogical(dbgeval) || dbgeval)
fprintf('EVAL: %s\n', printer.pr_str(ast, true));
end

switch class(ast)
case 'types.Symbol'
ret = env.get(ast);
case 'types.List'
ret = types.List();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
ret = env.get(ast.name);
if isequal(ret, {})
msg = sprintf('''%s'' not found', ast.name);
if exist('OCTAVE_VERSION', 'builtin') ~= 0
error('ENV:notfound', msg);
else
throw(MException('ENV:notfound', msg));
end
end
return;
case 'types.List'
% Proceed after this switch.
case 'types.Vector'
ret = types.Vector();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
end
return;
case 'types.HashMap'
ret = types.HashMap();
ks = ast.keys();
for i=1:length(ks)
k = ks{i};
ret.set(k, EVAL(ast.get(k), env));
end
return;
otherwise
ret = ast;
end
end

function ret = EVAL(ast, env)
%fprintf('EVAL: %s\n', printer.pr_str(ast, true));
if ~type_utils.list_Q(ast)
ret = eval_ast(ast, env);
return;
end

Expand All @@ -44,6 +53,7 @@ function step3_env(varargin), main(varargin), end
ret = ast;
return;
end

if isa(ast.get(1),'types.Symbol')
a1sym = ast.get(1).name;
else
Expand All @@ -59,10 +69,12 @@ function step3_env(varargin), main(varargin), end
end
ret = EVAL(ast.get(3), let_env);
otherwise
el = eval_ast(ast, env);
f = el.get(1);
args = el.data(2:end);
ret = f(args{:});
f = EVAL(ast.get(1), env);
args = types.List();
for i=2:length(ast)
args.append(EVAL(ast.get(i), env));
end
ret = f(args.data{:});
end
end

Expand Down
51 changes: 32 additions & 19 deletions impls/matlab/step4_if_fn_do.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,45 @@ function step4_if_fn_do(varargin), main(varargin), end
end

% eval
function ret = eval_ast(ast, env)
function ret = EVAL(ast, env)

dbgeval = env.get('DEBUG-EVAL');
if ~isequal(dbgeval, {}) ...
&& ~strcmp(class(dbgeval), 'types.Nil') ...
&& (~islogical(dbgeval) || dbgeval)
fprintf('EVAL: %s\n', printer.pr_str(ast, true));
end

switch class(ast)
case 'types.Symbol'
ret = env.get(ast);
case 'types.List'
ret = types.List();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
ret = env.get(ast.name);
if isequal(ret, {})
msg = sprintf('''%s'' not found', ast.name);
if exist('OCTAVE_VERSION', 'builtin') ~= 0
error('ENV:notfound', msg);
else
throw(MException('ENV:notfound', msg));
end
end
return;
case 'types.List'
% Proceed after this switch.
case 'types.Vector'
ret = types.Vector();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
end
return;
case 'types.HashMap'
ret = types.HashMap();
ks = ast.keys();
for i=1:length(ks)
k = ks{i};
ret.set(k, EVAL(ast.get(k), env));
end
return;
otherwise
ret = ast;
end
end

function ret = EVAL(ast, env)
%fprintf('EVAL: %s\n', printer.pr_str(ast, true));
if ~type_utils.list_Q(ast)
ret = eval_ast(ast, env);
return;
end

Expand All @@ -44,6 +53,7 @@ function step4_if_fn_do(varargin), main(varargin), end
ret = ast;
return;
end

if isa(ast.get(1),'types.Symbol')
a1sym = ast.get(1).name;
else
Expand All @@ -59,8 +69,9 @@ function step4_if_fn_do(varargin), main(varargin), end
end
ret = EVAL(ast.get(3), let_env);
case 'do'
el = eval_ast(ast.slice(2), env);
ret = el.get(length(el));
for i=2:length(ast)
ret = EVAL(ast.get(i), env);
end
case 'if'
cond = EVAL(ast.get(2), env);
if strcmp(class(cond), 'types.Nil') || ...
Expand All @@ -77,10 +88,12 @@ function step4_if_fn_do(varargin), main(varargin), end
ret = @(varargin) EVAL(ast.get(3), Env({env}, ast.get(2), ...
types.List(varargin{:})));
otherwise
el = eval_ast(ast, env);
f = el.get(1);
args = el.data(2:end);
ret = f(args{:});
f = EVAL(ast.get(1), env);
args = types.List();
for i=2:length(ast)
args.append(EVAL(ast.get(i), env));
end
ret = f(args.data{:});
end
end

Expand Down
50 changes: 32 additions & 18 deletions impls/matlab/step5_tco.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,46 @@ function step5_tco(varargin), main(varargin), end
end

% eval
function ret = eval_ast(ast, env)
function ret = EVAL(ast, env)
while true

dbgeval = env.get('DEBUG-EVAL');
if ~isequal(dbgeval, {}) ...
&& ~strcmp(class(dbgeval), 'types.Nil') ...
&& (~islogical(dbgeval) || dbgeval)
fprintf('EVAL: %s\n', printer.pr_str(ast, true));
end

switch class(ast)
case 'types.Symbol'
ret = env.get(ast);
case 'types.List'
ret = types.List();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
ret = env.get(ast.name);
if isequal(ret, {})
msg = sprintf('''%s'' not found', ast.name);
if exist('OCTAVE_VERSION', 'builtin') ~= 0
error('ENV:notfound', msg);
else
throw(MException('ENV:notfound', msg));
end
end
return;
case 'types.List'
% Proceed after this switch.
case 'types.Vector'
ret = types.Vector();
for i=1:length(ast)
ret.append(EVAL(ast.get(i), env));
end
return;
case 'types.HashMap'
ret = types.HashMap();
ks = ast.keys();
for i=1:length(ks)
k = ks{i};
ret.set(k, EVAL(ast.get(k), env));
end
return;
otherwise
ret = ast;
end
end

function ret = EVAL(ast, env)
while true
%fprintf('EVAL: %s\n', printer.pr_str(ast, true));
if ~type_utils.list_Q(ast)
ret = eval_ast(ast, env);
return;
end

Expand All @@ -45,6 +54,7 @@ function step5_tco(varargin), main(varargin), end
ret = ast;
return;
end

if isa(ast.get(1),'types.Symbol')
a1sym = ast.get(1).name;
else
Expand All @@ -62,7 +72,9 @@ function step5_tco(varargin), main(varargin), end
env = let_env;
ast = ast.get(3); % TCO
case 'do'
el = eval_ast(ast.slice(2,length(ast)-1), env);
for i=2:(length(ast) -1)
ret = EVAL(ast.get(i), env);
end
ast = ast.get(length(ast)); % TCO
case 'if'
cond = EVAL(ast.get(2), env);
Expand All @@ -83,9 +95,11 @@ function step5_tco(varargin), main(varargin), end
ret = types.Function(fn, ast.get(3), env, ast.get(2));
return;
otherwise
el = eval_ast(ast, env);
f = el.get(1);
args = el.slice(2);
f = EVAL(ast.get(1), env);
args = types.List();
for i=2:length(ast)
args.append(EVAL(ast.get(i), env));
end
if isa(f, 'types.Function')
env = Env({f.env}, f.params, args);
ast = f.ast; % TCO
Expand Down
Loading

0 comments on commit 2764f89

Please sign in to comment.