2 from itertools
import chain
4 import mal_types
as types
5 from mal_types
import List
, Vector
11 def throw(exc
): raise Exception(exc
)
16 return " ".join(map(lambda exp
: printer
._pr
_str
(exp
, True), args
))
19 return "".join(map(lambda exp
: printer
._pr
_str
(exp
, False), args
))
22 print(" ".join(map(lambda exp
: printer
._pr
_str
(exp
, True), args
)))
26 line
= " ".join(map(lambda exp
: printer
._pr
_str
(exp
, False), args
))
27 print(line
.replace('\\n', '\n'))
32 def assoc(src_hm
, *key_vals
):
33 hm
= copy
.copy(src_hm
)
34 for i
in range(0,len(key_vals
),2): hm
[key_vals
[i
]] = key_vals
[i
+1]
37 def dissoc(src_hm
, *keys
):
38 hm
= copy
.copy(src_hm
)
40 if key
in hm
: del hm
[key
]
49 def contains_Q(hm
, key
): return key
in hm
51 def keys(hm
): return types
._list
(*hm
.keys())
53 def vals(hm
): return types
._list
(*hm
.values())
57 def coll_Q(coll
): return sequential_Q(coll
) or hash_map_Q(coll
)
59 def cons(x
, seq
): return List([x
]) + List(seq
)
61 def concat(*lsts
): return List(chain(*lsts
))
64 if idx
< len(lst
): return lst
[idx
]
65 else: throw("nth: index out of range")
67 def first(lst
): return lst
[0]
69 def rest(lst
): return List(lst
[1:])
71 def empty_Q(lst
): return len(lst
) == 0
74 if types
._nil
_Q
(lst
): return 0
79 if types
._list
_Q
(lst
):
80 new_lst
= List(list(reversed(list(args
))) + lst
)
82 new_lst
= Vector(lst
+ list(args
))
83 if hasattr(lst
, "__meta__"):
84 new_lst
.__meta
__ = lst
.__meta
__
87 def apply(f
, *args
): return f(*(list(args
[0:-1])+args
[-1]))
89 def mapf(f
, lst
): return List(map(f
, lst
))
93 def with_meta(obj
, meta
):
94 new_obj
= types
._clone
(obj
)
95 new_obj
.__meta
__ = meta
99 if hasattr(obj
, "__meta__"): return obj
.__meta
__
104 def deref(atm
): return atm
.val
105 def reset_BANG(atm
,val
):
108 def swap_BANG(atm
,f
,*args
):
109 atm
.val
= f(atm
.val
,*args
)
116 'nil?': types
._nil
_Q
,
117 'true?': types
._true
_Q
,
118 'false?': types
._false
_Q
,
119 'symbol': types
._symbol
,
120 'symbol?': types
._symbol
_Q
,
121 'keyword': types
._keyword
,
122 'keyword?': types
._keyword
_Q
,
128 'readline': lambda prompt
: mal_readline
.readline(prompt
),
129 'read-string': reader
.read_str
,
130 'slurp': lambda file: open(file).read(),
131 '<': lambda a
,b
: a
<b
,
132 '<=': lambda a
,b
: a
<=b
,
133 '>': lambda a
,b
: a
>b
,
134 '>=': lambda a
,b
: a
>=b
,
135 '+': lambda a
,b
: a
+b
,
136 '-': lambda a
,b
: a
-b
,
137 '*': lambda a
,b
: a
*b
,
138 '/': lambda a
,b
: int(a
/b
),
139 'time-ms': lambda : int(time
.time() * 1000),
142 'list?': types
._list
_Q
,
143 'vector': types
._vector
,
144 'vector?': types
._vector
_Q
,
145 'hash-map': types
._hash
_map
,
146 'map?': types
._hash
_map
_Q
,
150 'contains?': contains_Q
,
154 'sequential?': types
._sequential
_Q
,
166 'with-meta': with_meta
,
169 'atom?': types
._atom
_Q
,
171 'reset!': reset_BANG
,