2 from mal_types
import (_symbol
, _keyword
, _list
, _vector
, _hash_map
)
4 class Blank(Exception): pass
7 def __init__(self
, tokens
, position
=0):
9 self
.position
= position
13 return self
.tokens
[self
.position
-1]
16 if len(self
.tokens
) > self
.position
:
17 return self
.tokens
[self
.position
]
22 tre
= re
.compile(r
"""[\s,]*(~@|[\[\]{}()'`~^@]|"(?:[\\].|[^\\"])*"|;.*|[^\s\[\]{}()'"`@,;]+)""");
23 return [t
for t
in re
.findall(tre
, str) if t
[0] != ';']
25 def read_atom(reader
):
26 int_re
= re
.compile(r
"-?[0-9]+$")
27 float_re
= re
.compile(r
"-?[0-9][0-9.]*$")
29 if re
.match(int_re
, token
): return int(token
)
30 elif re
.match(float_re
, token
): return int(token
)
31 elif token
[0] == '"': return token
[1:-1].replace('\\"', '"')
32 elif token
[0] == ':': return _keyword(token
[1:])
33 elif token
== "nil": return None
34 elif token
== "true": return True
35 elif token
== "false": return False
36 else: return _symbol(token
)
38 def read_sequence(reader
, typ
=list, start
='(', end
=')'):
41 if token
!= start
: raise Exception("expected '" + start
+ "'")
45 if not token
: raise Exception("expected '" + end
+ "', got EOF")
46 ast
.append(read_form(reader
))
51 def read_hash_map(reader
):
52 lst
= read_sequence(reader
, list, '{', '}')
53 return _hash_map(*lst
)
55 def read_list(reader
):
56 return read_sequence(reader
, _list
, '(', ')')
58 def read_vector(reader
):
59 return read_sequence(reader
, _vector
, '[', ']')
61 def read_form(reader
):
63 # reader macros/transforms
69 return _list(_symbol('quote'), read_form(reader
))
72 return _list(_symbol('quasiquote'), read_form(reader
))
75 return _list(_symbol('unquote'), read_form(reader
))
78 return _list(_symbol('splice-unquote'), read_form(reader
))
81 meta
= read_form(reader
)
82 return _list(_symbol('with-meta'), read_form(reader
), meta
)
85 return _list(_symbol('deref'), read_form(reader
))
88 elif token
== ')': raise Exception("unexpected ')'")
89 elif token
== '(': return read_list(reader
)
92 elif token
== ']': raise Exception("unexpected ']'");
93 elif token
== '[': return read_vector(reader
);
96 elif token
== '}': raise Exception("unexpected '}'");
97 elif token
== '{': return read_hash_map(reader
);
100 else: return read_atom(reader
);
103 tokens
= tokenize(str)
104 if len(tokens
) == 0: raise Blank("Blank Line")
105 return read_form(Reader(tokens
))