Merge pull request #138 from dubek/js-fix-quasiquote-nil
[jackhill/mal.git] / matlab / core.m
CommitLineData
d6624158
JM
1classdef core
2 methods(Static)
b550d8b7
JM
3 function ret = throw(obj)
4 ret = types.nil;
5 throw(types.MalException(obj));
6 end
7
6d12affa
JM
8 function str = pr_str(varargin)
9 strs = cellfun(@(s) printer.pr_str(s,true), varargin, ...
10 'UniformOutput', false);
11 str = strjoin(strs, ' ');
12 end
13 function str = do_str(varargin)
14 strs = cellfun(@(s) printer.pr_str(s,false), varargin, ...
15 'UniformOutput', false);
16 str = strjoin(strs, '');
17 end
18 function ret = prn(varargin)
19 strs = cellfun(@(s) printer.pr_str(s,true), varargin, ...
20 'UniformOutput', false);
21 fprintf('%s\n', strjoin(strs, ' '));
22 ret = types.nil;
23 end
24 function ret = println(varargin)
25 strs = cellfun(@(s) printer.pr_str(s,false), varargin, ...
26 'UniformOutput', false);
27 fprintf('%s\n', strjoin(strs, ' '));
28 ret = types.nil;
29 end
30
7f567f36
JM
31 function ret = time_ms()
32 secs = now-repmat(datenum('1970-1-1 00:00:00'),size(now));
33 ret = floor(secs.*repmat(24*3600.0*1000,size(now)));
34 end
35
6a572dff
JM
36 function new_hm = assoc(hm, varargin)
37 new_hm = clone(hm);
38 for i=1:2:length(varargin)
39 new_hm.set(varargin{i}, varargin{i+1});
40 end
41 end
42
43 function new_hm = dissoc(hm, varargin)
44 new_hm = clone(hm);
45 ks = intersect(hm.keys(),varargin);
46 remove(new_hm.data, ks);
47 end
48
49 function ret = get(hm, key)
50 if hm == types.nil
51 ret = types.nil;
52 else
53 if hm.data.isKey(key)
54 ret = hm.data(key);
55 else
56 ret = types.nil;
57 end
58 end
59 end
60
61 function ret = keys(hm)
62 ks = hm.keys();
63 ret = types.List(ks{:});
64 end
65
66 function ret = vals(hm)
67 vs = hm.values();
68 ret = types.List(vs{:});
69 end
70
71 function ret = cons(a, seq)
72 cella = [{a}, seq.data];
73 ret = types.List(cella{:});
74 end
75
c3023f26
JM
76 function ret = concat(varargin)
77 if nargin == 0
6a572dff 78 cella = {};
c3023f26 79 else
6a572dff
JM
80 cells = cellfun(@(x) x.data, varargin, ...
81 'UniformOutput', false);
82 cella = cat(2,cells{:});
c3023f26 83 end
6a572dff 84 ret = types.List(cella{:});
c3023f26
JM
85 end
86
c4033aab
JM
87 function ret = first(seq)
88 if length(seq) < 1
89 ret = types.nil;
90 else
6a572dff 91 ret = seq.get(1);
c4033aab
JM
92 end
93 end
94
6a572dff
JM
95 function ret = rest(seq)
96 cella = seq.data(2:end);
97 ret = types.List(cella{:});
98 end
99
c4033aab
JM
100 function ret = nth(seq, idx)
101 if idx+1 > length(seq)
102 throw(MException('Range:nth', ...
103 'nth: index out of range'))
104 end
6a572dff 105 ret = seq.get(idx+1);
c4033aab
JM
106 end
107
b550d8b7
JM
108 function ret = apply(varargin)
109 f = varargin{1};
110 if isa(f, 'types.Function')
111 f = f.fn;
112 end
113 first_args = varargin(2:end-1);
6a572dff 114 rest_args = varargin{end}.data;
b550d8b7
JM
115 args = [first_args rest_args];
116 ret = f(args{:});
117 end
118
119 function ret = map(f, lst)
120 if isa(f, 'types.Function')
121 f = f.fn;
122 end
6a572dff
JM
123 cells = cellfun(@(x) f(x), lst.data, 'UniformOutput', false);
124 ret = types.List(cells{:});
b550d8b7
JM
125 end
126
53942f88
JM
127 function new_obj = with_meta(obj, meta)
128 new_obj = clone(obj);
129 new_obj.meta = meta;
130 end
131
132 function meta = meta(obj)
133 switch class(obj)
134 case {'types.List', 'types.Vector',
135 'types.HashMap', 'types.Function'}
136 meta = obj.meta;
137 otherwise
138 meta = types.nil;
139 end
140 end
141
142 function ret = reset_BANG(atm, val)
143 atm.val = val;
144 ret = val;
145 end
146
147 function ret = swap_BANG(atm, f, varargin)
148 args = [{atm.val} varargin];
149 if isa(f, 'types.Function')
150 f = f.fn;
151 end
152 atm.val = f(args{:});
153 ret = atm.val;
154 end
155
d6624158
JM
156 function n = ns()
157 n = containers.Map();
6d12affa 158 n('=') = @types.equal;
b550d8b7
JM
159 n('throw') = @core.throw;
160 n('nil?') = @(a) isa(a, 'types.Nil');
161 n('true?') = @(a) isa(a, 'logical') && a == true;
162 n('false?') = @(a) isa(a, 'logical') && a == false;
163 n('symbol') = @(a) types.Symbol(a);
164 n('symbol?') = @(a) isa(a, 'types.Symbol');
6a572dff
JM
165 n('keyword') = @types.keyword;
166 n('keyword?') = @types.keyword_Q;
6d12affa
JM
167
168 n('pr-str') = @core.pr_str;
169 n('str') = @core.do_str;
170 n('prn') = @core.prn;
171 n('println') = @core.println;
9831bce7 172 n('read-string') = @reader.read_str;
b550d8b7 173 n('readline') = @(p) input(p, 's');
9831bce7
JM
174 n('slurp') = @fileread;
175
d6624158
JM
176 n('<') = @(a,b) a<b;
177 n('<=') = @(a,b) a<=b;
178 n('>') = @(a,b) a>b;
179 n('>=') = @(a,b) a>=b;
6d12affa
JM
180 n('+') = @(a,b) a+b;
181 n('-') = @(a,b) a-b;
182 n('*') = @(a,b) a*b;
183 n('/') = @(a,b) floor(a/b);
7f567f36 184 n('time-ms') = @core.time_ms;
d6624158 185
6a572dff
JM
186 n('list') = @(varargin) types.List(varargin{:});
187 n('list?') = @types.list_Q;
188 n('vector') = @(varargin) types.Vector(varargin{:});
189 n('vector?') = @types.vector_Q;
190 n('hash-map') = @(varargin) types.HashMap(varargin{:});
191 n('map?') = @types.hash_map_Q;
192 n('assoc') = @core.assoc;
193 n('dissoc') = @core.dissoc;
194 n('get') = @core.get;
195 n('contains?') = @(a,b) a.data.isKey(b);
196 n('keys') = @core.keys;
197 n('vals') = @core.vals;
c3023f26 198
6a572dff
JM
199 n('sequential?') = @types.sequential_Q;
200 n('cons') = @core.cons;
c3023f26 201 n('concat') = @core.concat;
c4033aab
JM
202 n('nth') = @core.nth;
203 n('first') = @core.first;
6a572dff 204 n('rest') = @core.rest;
d6624158
JM
205 n('empty?') = @(a) length(a) == 0;
206 n('count') = @(a) length(a);
b550d8b7
JM
207 n('apply') = @core.apply;
208 n('map') = @core.map;
0b234e13 209 n('conj') = @(x) disp('not implemented yet');
53942f88
JM
210
211 n('with-meta') = @core.with_meta;
212 n('meta') = @core.meta;
213 n('atom') = @types.Atom;
214 n('atom?') = @(a) isa(a, 'types.Atom');
215 n('deref') = @(a) a.val;
216 n('reset!') = @core.reset_BANG;
217 n('swap!') = @core.swap_BANG;
d6624158
JM
218 end
219 end
220end
221