4 import mal_types
as types
5 from mal_types
import (MalType
, nil
, true
, false
,
6 MalInt
, MalSym
, MalStr
,
7 MalList
, MalVector
, MalHashMap
)
17 def do_equal(args
): return wrap_tf(types
._equal
_Q
(args
[0], args
[1]))
21 raise types
.MalException(args
[0])
24 def nil_Q(args
): return wrap_tf(types
._nil
_Q
(args
[0]))
25 def true_Q(args
): return wrap_tf(types
._true
_Q
(args
[0]))
26 def false_Q(args
): return wrap_tf(types
._false
_Q
(args
[0]))
29 if isinstance(a0
, MalStr
):
30 return types
._symbol
(a0
.value
)
31 elif isinstance(a0
, MalSym
):
34 types
.throw_str("symbol called on non-string/non-symbol")
35 def symbol_Q(args
): return wrap_tf(types
._symbol
_Q
(args
[0]))
36 def keyword(args
): return types
._keyword
(args
[0])
37 def keyword_Q(args
): return wrap_tf(types
._keyword
_Q
(args
[0]))
43 for exp
in args
.values
: parts
.append(printer
._pr
_str
(exp
, True))
44 return MalStr(u
" ".join(parts
))
48 for exp
in args
.values
: parts
.append(printer
._pr
_str
(exp
, False))
49 return MalStr(u
"".join(parts
))
53 for exp
in args
.values
: parts
.append(printer
._pr
_str
(exp
, True))
54 print(u
" ".join(parts
))
59 for exp
in args
.values
: parts
.append(printer
._pr
_str
(exp
, False))
60 print(u
" ".join(parts
))
63 def do_readline(args
):
65 assert isinstance(prompt
, MalStr
)
66 return MalStr(unicode(mal_readline
.readline(str(prompt
.value
))))
70 assert isinstance(a0
, MalStr
)
71 return reader
.read_str(str(a0
.value
))
75 assert isinstance(a0
, MalStr
)
76 return MalStr(unicode(open(str(a0
.value
)).read()))
80 a
, b
= args
[0], args
[1]
81 assert isinstance(a
, MalInt
)
82 assert isinstance(b
, MalInt
)
83 return wrap_tf(a
.value
< b
.value
)
85 a
, b
= args
[0], args
[1]
86 assert isinstance(a
, MalInt
)
87 assert isinstance(b
, MalInt
)
88 return wrap_tf(a
.value
<= b
.value
)
90 a
, b
= args
[0], args
[1]
91 assert isinstance(a
, MalInt
)
92 assert isinstance(b
, MalInt
)
93 return wrap_tf(a
.value
> b
.value
)
95 a
, b
= args
[0], args
[1]
96 assert isinstance(a
, MalInt
)
97 assert isinstance(b
, MalInt
)
98 return wrap_tf(a
.value
>= b
.value
)
101 a
, b
= args
[0], args
[1]
102 assert isinstance(a
, MalInt
)
103 assert isinstance(b
, MalInt
)
104 return MalInt(a
.value
+b
.value
)
106 a
, b
= args
[0], args
[1]
107 assert isinstance(a
, MalInt
)
108 assert isinstance(b
, MalInt
)
109 return MalInt(a
.value
-b
.value
)
111 a
, b
= args
[0], args
[1]
112 assert isinstance(a
, MalInt
)
113 assert isinstance(b
, MalInt
)
114 return MalInt(a
.value
*b
.value
)
116 a
, b
= args
[0], args
[1]
117 assert isinstance(a
, MalInt
)
118 assert isinstance(b
, MalInt
)
119 return MalInt(int(a
.value
/b
.value
))
124 assert isinstance(ml
, MalList
)
125 return types
._hash
_mapl
(ml
.values
)
127 def hash_map_Q(args
):
128 return wrap_tf(types
._hash
_map
_Q
(args
[0]))
131 src_hm
, key_vals
= args
[0], args
.rest()
132 #new_dct = copy.copy(src_hm.dct)
133 new_dct
= src_hm
.dct
.copy()
134 for i
in range(0,len(key_vals
),2):
136 assert isinstance(k
, MalStr
)
137 new_dct
[k
.value
] = key_vals
[i
+1]
138 return MalHashMap(new_dct
)
141 src_hm
, keys
= args
[0], args
.rest()
142 #new_dct = copy.copy(src_hm.dct)
143 new_dct
= src_hm
.dct
.copy()
144 for k
in keys
.values
:
145 assert isinstance(k
, MalStr
)
146 if k
.value
in new_dct
:
148 return MalHashMap(new_dct
)
151 obj
, key
= args
[0], args
[1]
154 elif isinstance(obj
, MalHashMap
):
155 assert isinstance(key
, MalStr
)
156 if obj
and key
.value
in obj
.dct
:
157 return obj
.dct
[key
.value
]
160 elif isinstance(obj
, MalList
):
161 assert isinstance(key
, MalInt
)
162 return obj
.values
[key
.value
]
164 raise Exception("get called on invalid type")
166 def contains_Q(args
):
167 hm
, key
= args
[0], args
[1]
168 assert isinstance(key
, MalStr
)
169 return wrap_tf(key
.value
in hm
.dct
)
174 for k
in hm
.dct
.keys(): keys
.append(MalStr(k
))
179 return MalList(hm
.dct
.values())
184 assert isinstance(ml
, MalList
)
188 return wrap_tf(types
._list
_Q
(args
[0]))
191 assert isinstance(ml
, MalList
)
192 return MalVector(ml
.values
)
195 return wrap_tf(types
._vector
_Q
(args
[0]))
198 assert isinstance(args
, MalType
)
200 if isinstance(seq
, MalList
):
201 return wrap_tf(len(seq
) == 0)
205 types
.throw_str("empty? called on non-sequence")
208 assert isinstance(args
, MalType
)
210 if isinstance(seq
, MalList
):
211 return MalInt(len(seq
))
215 types
.throw_str("count called on non-sequence")
217 #def coll_Q(coll): return sequential_Q(coll) or hash_map_Q(coll)
219 def sequential_Q(args
):
220 return wrap_tf(types
._sequential
_Q
(args
[0]))
223 x
, seq
= args
[0], args
[1]
224 assert isinstance(seq
, MalList
)
225 return MalList([x
] + seq
.values
)
229 for l
in args
.values
:
230 assert isinstance(l
, MalList
)
231 new_lst
= new_lst
+ l
.values
232 return MalList(new_lst
)
235 lst
, idx
= args
[0], args
[1]
236 assert isinstance(lst
, MalList
)
237 assert isinstance(idx
, MalInt
)
238 if idx
.value
< len(lst
): return lst
[idx
.value
]
239 else: types
.throw_str("nth: index out of range")
243 assert isinstance(a0
, MalList
)
244 if len(a0
) == 0: return nil
249 assert isinstance(a0
, MalList
)
250 if len(a0
) == 0: return MalList([])
251 else: return a0
.rest()
254 #def conj(lst, *args):
255 # if types._list_Q(lst):
256 # new_lst = List(list(reversed(list(args))) + lst)
258 # new_lst = Vector(lst + list(args))
259 # if hasattr(lst, "__meta__"):
260 # new_lst.__meta__ = lst.__meta__
264 f
, fargs
= args
[0], args
.rest()
265 last_arg
= fargs
.values
[-1]
266 assert isinstance(last_arg
, MalList
)
267 all_args
= fargs
.values
[0:-1] + last_arg
.values
268 return f
.apply(MalList(all_args
))
271 f
, lst
= args
[0], args
[1]
272 assert isinstance(lst
, MalList
)
275 res
.append(f
.apply(MalList([a
])))
279 ## Metadata functions
280 #def with_meta(obj, meta):
281 # new_obj = types._clone(obj)
282 # new_obj.__meta__ = meta
286 # if hasattr(obj, "__meta__"): return obj.__meta__
291 #def deref(atm): return atm.val
292 #def reset_BANG(atm,val):
295 #def swap_BANG(atm,f,*args):
296 # atm.val = f(atm.val,*args)
309 'keyword?': keyword_Q
,
315 'readline': do_readline
,
316 'read-string': read_str
,
326 # 'time-ms': lambda : int(time.time() * 1000),
332 'hash-map': do_hash_map
,
337 'contains?': contains_Q
,
341 'sequential?': sequential_Q
,
353 # 'with-meta': with_meta,
355 # 'atom': types._atom,
356 # 'atom?': types._atom_Q,
358 # 'reset!': reset_BANG,