aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--matlab/+types/Atom.m10
-rw-r--r--matlab/+types/Function.m7
-rw-r--r--matlab/+types/List.m6
-rw-r--r--matlab/+types/Vector.m5
-rw-r--r--matlab/core.m37
-rw-r--r--matlab/printer.m2
-rw-r--r--matlab/reader.m10
7 files changed, 77 insertions, 0 deletions
diff --git a/matlab/+types/Atom.m b/matlab/+types/Atom.m
new file mode 100644
index 0000000..7338ce2
--- /dev/null
+++ b/matlab/+types/Atom.m
@@ -0,0 +1,10 @@
+classdef Atom < handle
+ properties
+ val
+ end
+ methods
+ function atm = Atom(val)
+ atm.val = val;
+ end
+ end
+end
diff --git a/matlab/+types/Function.m b/matlab/+types/Function.m
index 2f28368..9270ed1 100644
--- a/matlab/+types/Function.m
+++ b/matlab/+types/Function.m
@@ -5,6 +5,7 @@ classdef Function < handle
env
params
is_macro = false
+ meta = types.nil;
end
methods
function f = Function(fn, ast, env, params)
@@ -13,5 +14,11 @@ classdef Function < handle
f.env = env;
f.params = params;
end
+
+ function ret = clone(obj)
+ ret = types.Function(obj.fn, obj.ast, obj.env, obj.params);
+ ret.is_macro = obj.is_macro;
+ ret.meta = obj.meta;
+ end
end
end
diff --git a/matlab/+types/List.m b/matlab/+types/List.m
index fd27cb4..3fc1429 100644
--- a/matlab/+types/List.m
+++ b/matlab/+types/List.m
@@ -33,6 +33,12 @@ classdef List < handle
ret = types.List(obj.data{start:end});
end
+ function ret = clone(obj)
+ ret = types.List();
+ ret.data = obj.data;
+ ret.meta = obj.meta;
+ end
+
% function varargout = subsref(vec, S)
% % This doesn't work for ranges
% [varargout{1:nargout}] = builtin('subsref', vec.data, S);
diff --git a/matlab/+types/Vector.m b/matlab/+types/Vector.m
index 3f854fb..f5dea9c 100644
--- a/matlab/+types/Vector.m
+++ b/matlab/+types/Vector.m
@@ -11,5 +11,10 @@ classdef Vector < types.List
ret = types.Vector(obj.data{2:end});
end
+ function ret = clone(obj)
+ ret = types.Vector();
+ ret.data = obj.data;
+ ret.meta = obj.meta;
+ end
end
end
diff --git a/matlab/core.m b/matlab/core.m
index 5947c2d..ef3848e 100644
--- a/matlab/core.m
+++ b/matlab/core.m
@@ -124,6 +124,35 @@ classdef core
ret = types.List(cells{:});
end
+ function new_obj = with_meta(obj, meta)
+ new_obj = clone(obj);
+ new_obj.meta = meta;
+ end
+
+ function meta = meta(obj)
+ switch class(obj)
+ case {'types.List', 'types.Vector',
+ 'types.HashMap', 'types.Function'}
+ meta = obj.meta;
+ otherwise
+ meta = types.nil;
+ end
+ end
+
+ function ret = reset_BANG(atm, val)
+ atm.val = val;
+ ret = val;
+ end
+
+ function ret = swap_BANG(atm, f, varargin)
+ args = [{atm.val} varargin];
+ if isa(f, 'types.Function')
+ f = f.fn;
+ end
+ atm.val = f(args{:});
+ ret = atm.val;
+ end
+
function n = ns()
n = containers.Map();
n('=') = @types.equal;
@@ -177,6 +206,14 @@ classdef core
n('count') = @(a) length(a);
n('apply') = @core.apply;
n('map') = @core.map;
+
+ n('with-meta') = @core.with_meta;
+ n('meta') = @core.meta;
+ n('atom') = @types.Atom;
+ n('atom?') = @(a) isa(a, 'types.Atom');
+ n('deref') = @(a) a.val;
+ n('reset!') = @core.reset_BANG;
+ n('swap!') = @core.swap_BANG;
end
end
end
diff --git a/matlab/printer.m b/matlab/printer.m
index fa55e06..0642e7b 100644
--- a/matlab/printer.m
+++ b/matlab/printer.m
@@ -45,6 +45,8 @@ classdef printer
else
str = 'false';
end
+ case 'types.Atom'
+ str = sprintf('(atom %s)', printer.pr_str(obj.val,true));
otherwise
str = '#<unknown>';
end
diff --git a/matlab/reader.m b/matlab/reader.m
index 7265ab3..fc72ac5 100644
--- a/matlab/reader.m
+++ b/matlab/reader.m
@@ -85,6 +85,16 @@ classdef reader
rdr.next();
ast = types.List(types.Symbol('splice-unquote'), ...
reader.read_form(rdr));
+ case '^'
+ rdr.next();
+ meta = reader.read_form(rdr);
+ ast = types.List(types.Symbol('with-meta'), ...
+ reader.read_form(rdr), meta);
+ case '@'
+ rdr.next();
+ ast = types.List(types.Symbol('deref'), ...
+ reader.read_form(rdr));
+
case ')'
error('unexpected '')''');
case '('