diff options
| -rw-r--r-- | matlab/+types/Atom.m | 10 | ||||
| -rw-r--r-- | matlab/+types/Function.m | 7 | ||||
| -rw-r--r-- | matlab/+types/List.m | 6 | ||||
| -rw-r--r-- | matlab/+types/Vector.m | 5 | ||||
| -rw-r--r-- | matlab/core.m | 37 | ||||
| -rw-r--r-- | matlab/printer.m | 2 | ||||
| -rw-r--r-- | matlab/reader.m | 10 |
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 '(' |
