2015-02-08 10:13:41 +03:00
|
|
|
classdef core
|
|
|
|
methods(Static)
|
2015-02-09 08:50:12 +03:00
|
|
|
function ret = throw(obj)
|
|
|
|
ret = types.nil;
|
|
|
|
throw(types.MalException(obj));
|
|
|
|
end
|
|
|
|
|
2015-02-08 22:18:08 +03:00
|
|
|
function str = pr_str(varargin)
|
|
|
|
strs = cellfun(@(s) printer.pr_str(s,true), varargin, ...
|
|
|
|
'UniformOutput', false);
|
|
|
|
str = strjoin(strs, ' ');
|
|
|
|
end
|
|
|
|
function str = do_str(varargin)
|
|
|
|
strs = cellfun(@(s) printer.pr_str(s,false), varargin, ...
|
|
|
|
'UniformOutput', false);
|
|
|
|
str = strjoin(strs, '');
|
|
|
|
end
|
|
|
|
function ret = prn(varargin)
|
|
|
|
strs = cellfun(@(s) printer.pr_str(s,true), varargin, ...
|
|
|
|
'UniformOutput', false);
|
|
|
|
fprintf('%s\n', strjoin(strs, ' '));
|
|
|
|
ret = types.nil;
|
|
|
|
end
|
|
|
|
function ret = println(varargin)
|
|
|
|
strs = cellfun(@(s) printer.pr_str(s,false), varargin, ...
|
|
|
|
'UniformOutput', false);
|
|
|
|
fprintf('%s\n', strjoin(strs, ' '));
|
|
|
|
ret = types.nil;
|
|
|
|
end
|
|
|
|
|
2015-02-09 09:23:10 +03:00
|
|
|
function ret = time_ms()
|
|
|
|
secs = now-repmat(datenum('1970-1-1 00:00:00'),size(now));
|
|
|
|
ret = floor(secs.*repmat(24*3600.0*1000,size(now)));
|
|
|
|
end
|
|
|
|
|
2015-02-10 08:20:23 +03:00
|
|
|
function new_hm = assoc(hm, varargin)
|
|
|
|
new_hm = clone(hm);
|
|
|
|
for i=1:2:length(varargin)
|
|
|
|
new_hm.set(varargin{i}, varargin{i+1});
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function new_hm = dissoc(hm, varargin)
|
|
|
|
new_hm = clone(hm);
|
|
|
|
ks = intersect(hm.keys(),varargin);
|
|
|
|
remove(new_hm.data, ks);
|
|
|
|
end
|
|
|
|
|
|
|
|
function ret = get(hm, key)
|
|
|
|
if hm == types.nil
|
|
|
|
ret = types.nil;
|
|
|
|
else
|
|
|
|
if hm.data.isKey(key)
|
|
|
|
ret = hm.data(key);
|
|
|
|
else
|
|
|
|
ret = types.nil;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function ret = keys(hm)
|
|
|
|
ks = hm.keys();
|
|
|
|
ret = types.List(ks{:});
|
|
|
|
end
|
|
|
|
|
|
|
|
function ret = vals(hm)
|
|
|
|
vs = hm.values();
|
|
|
|
ret = types.List(vs{:});
|
|
|
|
end
|
|
|
|
|
|
|
|
function ret = cons(a, seq)
|
|
|
|
cella = [{a}, seq.data];
|
|
|
|
ret = types.List(cella{:});
|
|
|
|
end
|
|
|
|
|
2015-02-09 04:23:49 +03:00
|
|
|
function ret = concat(varargin)
|
|
|
|
if nargin == 0
|
2015-02-10 08:20:23 +03:00
|
|
|
cella = {};
|
2015-02-09 04:23:49 +03:00
|
|
|
else
|
2015-02-10 08:20:23 +03:00
|
|
|
cells = cellfun(@(x) x.data, varargin, ...
|
|
|
|
'UniformOutput', false);
|
|
|
|
cella = cat(2,cells{:});
|
2015-02-09 04:23:49 +03:00
|
|
|
end
|
2015-02-10 08:20:23 +03:00
|
|
|
ret = types.List(cella{:});
|
2015-02-09 04:23:49 +03:00
|
|
|
end
|
|
|
|
|
2015-02-09 05:35:44 +03:00
|
|
|
function ret = first(seq)
|
|
|
|
if length(seq) < 1
|
|
|
|
ret = types.nil;
|
|
|
|
else
|
2015-02-10 08:20:23 +03:00
|
|
|
ret = seq.get(1);
|
2015-02-09 05:35:44 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-10 08:20:23 +03:00
|
|
|
function ret = rest(seq)
|
|
|
|
cella = seq.data(2:end);
|
|
|
|
ret = types.List(cella{:});
|
|
|
|
end
|
|
|
|
|
2015-02-09 05:35:44 +03:00
|
|
|
function ret = nth(seq, idx)
|
|
|
|
if idx+1 > length(seq)
|
|
|
|
throw(MException('Range:nth', ...
|
|
|
|
'nth: index out of range'))
|
|
|
|
end
|
2015-02-10 08:20:23 +03:00
|
|
|
ret = seq.get(idx+1);
|
2015-02-09 05:35:44 +03:00
|
|
|
end
|
|
|
|
|
2015-02-09 08:50:12 +03:00
|
|
|
function ret = apply(varargin)
|
|
|
|
f = varargin{1};
|
|
|
|
if isa(f, 'types.Function')
|
|
|
|
f = f.fn;
|
|
|
|
end
|
|
|
|
first_args = varargin(2:end-1);
|
2015-02-10 08:20:23 +03:00
|
|
|
rest_args = varargin{end}.data;
|
2015-02-09 08:50:12 +03:00
|
|
|
args = [first_args rest_args];
|
|
|
|
ret = f(args{:});
|
|
|
|
end
|
|
|
|
|
|
|
|
function ret = map(f, lst)
|
|
|
|
if isa(f, 'types.Function')
|
|
|
|
f = f.fn;
|
|
|
|
end
|
2015-02-10 08:20:23 +03:00
|
|
|
cells = cellfun(@(x) f(x), lst.data, 'UniformOutput', false);
|
|
|
|
ret = types.List(cells{:});
|
2015-02-09 08:50:12 +03:00
|
|
|
end
|
|
|
|
|
2015-02-10 10:34:56 +03:00
|
|
|
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
|
|
|
|
|
2015-02-08 10:13:41 +03:00
|
|
|
function n = ns()
|
|
|
|
n = containers.Map();
|
2015-02-08 22:18:08 +03:00
|
|
|
n('=') = @types.equal;
|
2015-02-09 08:50:12 +03:00
|
|
|
n('throw') = @core.throw;
|
|
|
|
n('nil?') = @(a) isa(a, 'types.Nil');
|
|
|
|
n('true?') = @(a) isa(a, 'logical') && a == true;
|
|
|
|
n('false?') = @(a) isa(a, 'logical') && a == false;
|
|
|
|
n('symbol') = @(a) types.Symbol(a);
|
|
|
|
n('symbol?') = @(a) isa(a, 'types.Symbol');
|
2015-02-10 08:20:23 +03:00
|
|
|
n('keyword') = @types.keyword;
|
|
|
|
n('keyword?') = @types.keyword_Q;
|
2015-02-08 22:18:08 +03:00
|
|
|
|
|
|
|
n('pr-str') = @core.pr_str;
|
|
|
|
n('str') = @core.do_str;
|
|
|
|
n('prn') = @core.prn;
|
|
|
|
n('println') = @core.println;
|
2015-02-09 03:56:13 +03:00
|
|
|
n('read-string') = @reader.read_str;
|
2015-02-09 08:50:12 +03:00
|
|
|
n('readline') = @(p) input(p, 's');
|
2015-02-09 03:56:13 +03:00
|
|
|
n('slurp') = @fileread;
|
|
|
|
|
2015-02-08 10:13:41 +03:00
|
|
|
n('<') = @(a,b) a<b;
|
|
|
|
n('<=') = @(a,b) a<=b;
|
|
|
|
n('>') = @(a,b) a>b;
|
|
|
|
n('>=') = @(a,b) a>=b;
|
2015-02-08 22:18:08 +03:00
|
|
|
n('+') = @(a,b) a+b;
|
|
|
|
n('-') = @(a,b) a-b;
|
|
|
|
n('*') = @(a,b) a*b;
|
|
|
|
n('/') = @(a,b) floor(a/b);
|
2015-02-09 09:23:10 +03:00
|
|
|
n('time-ms') = @core.time_ms;
|
2015-02-08 10:13:41 +03:00
|
|
|
|
2015-02-10 08:20:23 +03:00
|
|
|
n('list') = @(varargin) types.List(varargin{:});
|
|
|
|
n('list?') = @types.list_Q;
|
|
|
|
n('vector') = @(varargin) types.Vector(varargin{:});
|
|
|
|
n('vector?') = @types.vector_Q;
|
|
|
|
n('hash-map') = @(varargin) types.HashMap(varargin{:});
|
|
|
|
n('map?') = @types.hash_map_Q;
|
|
|
|
n('assoc') = @core.assoc;
|
|
|
|
n('dissoc') = @core.dissoc;
|
|
|
|
n('get') = @core.get;
|
|
|
|
n('contains?') = @(a,b) a.data.isKey(b);
|
|
|
|
n('keys') = @core.keys;
|
|
|
|
n('vals') = @core.vals;
|
2015-02-09 04:23:49 +03:00
|
|
|
|
2015-02-10 08:20:23 +03:00
|
|
|
n('sequential?') = @types.sequential_Q;
|
|
|
|
n('cons') = @core.cons;
|
2015-02-09 04:23:49 +03:00
|
|
|
n('concat') = @core.concat;
|
2015-02-09 05:35:44 +03:00
|
|
|
n('nth') = @core.nth;
|
|
|
|
n('first') = @core.first;
|
2015-02-10 08:20:23 +03:00
|
|
|
n('rest') = @core.rest;
|
2015-02-08 10:13:41 +03:00
|
|
|
n('empty?') = @(a) length(a) == 0;
|
|
|
|
n('count') = @(a) length(a);
|
2015-02-09 08:50:12 +03:00
|
|
|
n('apply') = @core.apply;
|
|
|
|
n('map') = @core.map;
|
2015-02-10 10:51:28 +03:00
|
|
|
n('conj') = @(x) disp('not implemented yet');
|
2015-02-10 10:34:56 +03:00
|
|
|
|
|
|
|
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;
|
2015-02-08 10:13:41 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|