RPython: step9 basics.
[jackhill/mal.git] / rpython / core.py
CommitLineData
b0a9121d 1import copy, time
b0a9121d
JM
2
3import mal_types as types
4from mal_types import (MalType, nil, true, false,
9be6d5a6 5 MalInt, MalSym, MalStr, MalList)
b0a9121d
JM
6import mal_readline
7import reader
8import printer
9
10# General functions
9be6d5a6
JM
11def wrap_tf(tf):
12 if tf: return true
13 else: return false
b0a9121d 14
9be6d5a6
JM
15def do_equal(args): return wrap_tf(types._equal_Q(args[0], args[1]))
16
17# Errors/Exceptions
18def throw(args):
19 raise types.MalException(args[0])
20
21# Scalar functions
22def nil_Q(args): return wrap_tf(types._nil_Q(args[0]))
23def true_Q(args): return wrap_tf(types._true_Q(args[0]))
24def false_Q(args): return wrap_tf(types._false_Q(args[0]))
25def symbol(args):
26 a0 = args[0]
27 if isinstance(a0, MalStr):
28 return types._symbol(a0.value)
29 elif isinstance(a0, MalSym):
30 return a0
31 else:
32 types.throw_str("symbol called on non-string/non-symbol")
33def symbol_Q(args): return wrap_tf(types._symbol_Q(args[0]))
34def keyword(args): return types._keyword(args[0])
35def keyword_Q(args): return wrap_tf(types._keyword_Q(args[0]))
c9fe67a8 36
b0a9121d
JM
37
38# String functions
39def pr_str(args):
40 parts = []
41 for exp in args.values: parts.append(printer._pr_str(exp, True))
42 return MalStr(u" ".join(parts))
43
44def do_str(args):
45 parts = []
46 for exp in args.values: parts.append(printer._pr_str(exp, False))
47 return MalStr(u"".join(parts))
48
49def prn(args):
50 parts = []
51 for exp in args.values: parts.append(printer._pr_str(exp, True))
52 print(u" ".join(parts))
53 return nil
54
55def println(args):
56 parts = []
57 for exp in args.values: parts.append(printer._pr_str(exp, False))
58 print(u" ".join(parts))
59 return nil
60
219f5239
JM
61def read_str(args):
62 a0 = args[0]
63 assert isinstance(a0, MalStr)
64 return reader.read_str(str(a0.value))
65
66def slurp(args):
67 a0 = args[0]
68 assert isinstance(a0, MalStr)
69 return MalStr(unicode(open(str(a0.value)).read()))
70
b0a9121d
JM
71# Number functions
72def lt(args):
73 a, b = args[0], args[1]
74 assert isinstance(a, MalInt)
75 assert isinstance(b, MalInt)
9be6d5a6 76 return wrap_tf(a.value < b.value)
b0a9121d
JM
77def lte(args):
78 a, b = args[0], args[1]
79 assert isinstance(a, MalInt)
80 assert isinstance(b, MalInt)
9be6d5a6 81 return wrap_tf(a.value <= b.value)
b0a9121d
JM
82def gt(args):
83 a, b = args[0], args[1]
84 assert isinstance(a, MalInt)
85 assert isinstance(b, MalInt)
9be6d5a6 86 return wrap_tf(a.value > b.value)
b0a9121d
JM
87def gte(args):
88 a, b = args[0], args[1]
89 assert isinstance(a, MalInt)
90 assert isinstance(b, MalInt)
9be6d5a6 91 return wrap_tf(a.value >= b.value)
b0a9121d
JM
92
93def plus(args):
94 a, b = args[0], args[1]
95 assert isinstance(a, MalInt)
96 assert isinstance(b, MalInt)
97 return MalInt(a.value+b.value)
98def minus(args):
99 a, b = args[0], args[1]
100 assert isinstance(a, MalInt)
101 assert isinstance(b, MalInt)
102 return MalInt(a.value-b.value)
103def multiply(args):
104 a, b = args[0], args[1]
105 assert isinstance(a, MalInt)
106 assert isinstance(b, MalInt)
107 return MalInt(a.value*b.value)
108def divide(args):
109 a, b = args[0], args[1]
110 assert isinstance(a, MalInt)
111 assert isinstance(b, MalInt)
112 return MalInt(int(a.value/b.value))
113
114
115## Hash map functions
116#def assoc(src_hm, *key_vals):
117# hm = copy.copy(src_hm)
118# for i in range(0,len(key_vals),2): hm[key_vals[i]] = key_vals[i+1]
119# return hm
120#
121#def dissoc(src_hm, *keys):
122# hm = copy.copy(src_hm)
123# for key in keys:
124# if key in hm: del hm[key]
125# return hm
126#
127#def get(hm, key):
128# if hm and key in hm:
129# return hm[key]
130# else:
131# return None
132#
133#def contains_Q(hm, key): return key in hm
134#
135#def keys(hm): return types._list(*hm.keys())
136#
137#def vals(hm): return types._list(*hm.values())
138#
139
140# Sequence functions
141def do_list(ml):
142 assert isinstance(ml, MalList)
143 return ml
144
145def list_Q(args):
9be6d5a6 146 return wrap_tf(isinstance(args[0], MalList))
b0a9121d
JM
147
148def empty_Q(args):
149 assert isinstance(args, MalType)
150 seq = args[0]
151 if isinstance(seq, MalList):
9be6d5a6 152 return wrap_tf(len(seq) == 0)
b0a9121d
JM
153 elif seq is nil:
154 return true
155 else:
9be6d5a6 156 types.throw_str("empty? called on non-sequence")
b0a9121d
JM
157
158def count(args):
159 assert isinstance(args, MalType)
160 seq = args[0]
161 if isinstance(seq, MalList):
162 return MalInt(len(seq))
163 elif seq is nil:
164 return MalInt(0)
165 else:
9be6d5a6 166 types.throw_str("count called on non-sequence")
b0a9121d
JM
167
168#def coll_Q(coll): return sequential_Q(coll) or hash_map_Q(coll)
169#
0096b107
JM
170def cons(args):
171 x, seq = args[0], args[1]
172 assert isinstance(seq, MalList)
173 return MalList([x] + seq.values)
174
175def concat(args):
176 new_lst = []
177 for l in args.values:
178 assert isinstance(l, MalList)
179 new_lst = new_lst + l.values
180 return MalList(new_lst)
181
c9fe67a8
JM
182def nth(args):
183 lst, idx = args[0], args[1]
184 assert isinstance(lst, MalList)
185 assert isinstance(idx, MalInt)
186 if idx.value < len(lst): return lst[idx.value]
9be6d5a6 187 else: types.throw_str("nth: index out of range")
c9fe67a8
JM
188
189def first(args):
190 a0 = args[0]
191 assert isinstance(a0, MalList)
192 if len(a0) == 0: return nil
193 else: return a0[0]
194
195def rest(args):
196 a0 = args[0]
197 assert isinstance(a0, MalList)
198 if len(a0) == 0: return MalList([])
199 else: return a0.rest()
200
b0a9121d
JM
201## retains metadata
202#def conj(lst, *args):
203# if types._list_Q(lst):
204# new_lst = List(list(reversed(list(args))) + lst)
205# else:
206# new_lst = Vector(lst + list(args))
207# if hasattr(lst, "__meta__"):
208# new_lst.__meta__ = lst.__meta__
209# return new_lst
9be6d5a6
JM
210
211def apply(args):
212 f, fargs = args[0], args.rest()
213 last_arg = fargs.values[-1]
214 assert isinstance(last_arg, MalList)
215 all_args = fargs.values[0:-1] + last_arg.values
216 return f.apply(MalList(all_args))
217
218def mapf(args):
219 f, lst = args[0], args[1]
220 assert isinstance(lst, MalList)
221 res = []
222 for a in lst.values:
223 res.append(f.apply(MalList([a])))
224 return MalList(res)
225
226
b0a9121d
JM
227## Metadata functions
228#def with_meta(obj, meta):
229# new_obj = types._clone(obj)
230# new_obj.__meta__ = meta
231# return new_obj
232#
233#def meta(obj):
234# if hasattr(obj, "__meta__"): return obj.__meta__
235# else: return None
236#
237#
238## Atoms functions
239#def deref(atm): return atm.val
240#def reset_BANG(atm,val):
241# atm.val = val
242# return atm.val
243#def swap_BANG(atm,f,*args):
244# atm.val = f(atm.val,*args)
245# return atm.val
246
247
248ns = {
249 '=': do_equal,
9be6d5a6
JM
250 'throw': throw,
251 'nil?': nil_Q,
252 'true?': true_Q,
253 'false?': false_Q,
254 'symbol': symbol,
255 'symbol?': symbol_Q,
256 'keyword': keyword,
257 'keyword?': keyword_Q,
258
b0a9121d
JM
259 'pr-str': pr_str,
260 'str': do_str,
261 'prn': prn,
262 'println': println,
263# 'readline': lambda prompt: mal_readline.readline(prompt),
219f5239
JM
264 'read-string': read_str,
265 'slurp': slurp,
b0a9121d
JM
266 '<': lt,
267 '<=': lte,
268 '>': gt,
269 '>=': gte,
270 '+': plus,
271 '-': minus,
272 '*': multiply,
273 '/': divide,
274# 'time-ms': lambda : int(time.time() * 1000),
275#
276 'list': do_list,
277 'list?': list_Q,
278# 'vector': types._vector,
279# 'vector?': types._vector_Q,
280# 'hash-map': types._hash_map,
281# 'map?': types._hash_map_Q,
282# 'assoc': assoc,
283# 'dissoc': dissoc,
284# 'get': get,
285# 'contains?': contains_Q,
286# 'keys': keys,
287# 'vals': vals,
288#
289# 'sequential?': types._sequential_Q,
0096b107
JM
290 'cons': cons,
291 'concat': concat,
c9fe67a8
JM
292 'nth': nth,
293 'first': first,
294 'rest': rest,
b0a9121d
JM
295 'empty?': empty_Q,
296 'count': count,
297# 'conj': conj,
9be6d5a6
JM
298 'apply': apply,
299 'map': mapf,
b0a9121d
JM
300#
301# 'with-meta': with_meta,
302# 'meta': meta,
303# 'atom': types._atom,
304# 'atom?': types._atom_Q,
305# 'deref': deref,
306# 'reset!': reset_BANG,
307# 'swap!': swap_BANG
308 }
309