1 import sys
, copy
, types
as pytypes
3 # python 3.0 differences
4 if sys
.hexversion
> 0x3000000:
9 _u
= lambda x
: codecs
.unicode_escape_decode(x
)[0]
10 _s2u
= lambda x
: unicode(x
)
12 if sys
.version_info
[0] >= 3:
15 str_types
= [str, unicode]
20 ota
, otb
= type(a
), type(b
)
21 if _string_Q(a
) and _string_Q(b
):
23 if not (ota
== otb
or (_sequential_Q(a
) and _sequential_Q(b
))):
27 elif _list_Q(a
) or _vector_Q(a
):
28 if len(a
) != len(b
): return False
29 for i
in range(len(a
)):
30 if not _equal_Q(a
[i
], b
[i
]): return False
33 akeys
= sorted(a
.keys())
34 bkeys
= sorted(b
.keys())
35 if len(akeys
) != len(bkeys
): return False
36 for i
in range(len(akeys
)):
37 if akeys
[i
] != bkeys
[i
]: return False
38 if not _equal_Q(a
[akeys
[i
]], b
[bkeys
[i
]]): return False
43 def _sequential_Q(seq
): return _list_Q(seq
) or _vector_Q(seq
)
46 #if type(obj) == type(lambda x:x):
47 if type(obj
) == pytypes
.FunctionType
:
49 return pytypes
.FunctionType(
50 obj
.__code
__, obj
.__globals
__, name
= obj
.__name
__,
51 argdefs
= obj
.__defaults
__, closure
= obj
.__closure
__)
53 return pytypes
.FunctionType(
54 obj
.func_code
, obj
.func_globals
, name
= obj
.func_name
,
55 argdefs
= obj
.func_defaults
, closure
= obj
.func_closure
)
63 class MalException(Exception):
64 def __init__(self
, object):
68 def _nil_Q(exp
): return exp
is None
69 def _true_Q(exp
): return exp
is True
70 def _false_Q(exp
): return exp
is False
72 if type(exp
) in str_types
:
73 return len(exp
) == 0 or exp
[0] != _u("\u029e")
76 def _number_Q(exp
): return type(exp
) == int
79 class Symbol(str): pass
80 def _symbol(str): return Symbol(str)
81 def _symbol_Q(exp
): return type(exp
) == Symbol
84 # A specially prefixed string
86 if str[0] == _u("\u029e"): return str
87 else: return _u("\u029e") + str
89 if type(exp
) in str_types
:
90 return len(exp
) != 0 and exp
[0] == _u("\u029e")
95 def _function(Eval
, Env
, ast
, env
, params
):
97 return Eval(ast
, Env(env
, params
, List(args
)))
100 fn
.__gen
_env
__ = lambda args
: Env(env
, params
, args
)
107 def __add__(self
, rhs
): return List(list.__add
__(self
, rhs
))
108 def __getitem__(self
, i
):
109 if type(i
) == slice: return List(list.__getitem
__(self
, i
))
110 elif i
>= len(self
): return None
111 else: return list.__getitem
__(self
, i
)
112 def __getslice__(self
, *a
): return List(list.__getslice
__(self
, *a
))
113 def _list(*vals
): return List(vals
)
114 def _list_Q(exp
): return type(exp
) == List
119 def __add__(self
, rhs
): return Vector(list.__add
__(self
, rhs
))
120 def __getitem__(self
, i
):
121 if type(i
) == slice: return Vector(list.__getitem
__(self
, i
))
122 elif i
>= len(self
): return None
123 else: return list.__getitem
__(self
, i
)
124 def __getslice__(self
, *a
): return Vector(list.__getslice
__(self
, *a
))
125 def _vector(*vals
): return Vector(vals
)
126 def _vector_Q(exp
): return type(exp
) == Vector
129 class Hash_Map(dict): pass
130 def _hash_map(*key_vals
):
132 for i
in range(0,len(key_vals
),2): hm
[key_vals
[i
]] = key_vals
[i
+1]
134 def _hash_map_Q(exp
): return type(exp
) == Hash_Map
138 def __init__(self
, val
):
140 def _atom(val
): return Atom(val
)
141 def _atom_Q(exp
): return type(exp
) == Atom
144 if type(obj
) == list: return List(obj
)
145 if type(obj
) == tuple: return List(obj
)
146 elif type(obj
) == dict: return Hash_Map(obj
)