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