2 IS_RPYTHON
= sys
.argv
[0].endswith('rpython')
5 from rpython
.rlib
.rsre
import rsre_re
as re
9 import mal_types
as types
10 from mal_types
import (MalSym
, MalInt
, MalStr
, _keywordu
,
11 _list
, _listl
, _vectorl
, _hash_mapl
)
13 class Blank(Exception): pass
16 def __init__(self
, tokens
, position
=0):
18 self
.position
= position
22 return self
.tokens
[self
.position
-1]
25 if len(self
.tokens
) > self
.position
:
26 return self
.tokens
[self
.position
]
31 re_str
= "[\s,]*(~@|[\[\]{}()'`~^@]|\"(?:[\\\\].|[^\\\\\"])*\"?|;.*|[^\s\[\]{}()'\"`@,;]+)"
35 tok_re
= re
.compile(re_str
)
36 return [t
for t
in re
.findall(tok_re
, str) if t
[0] != ';']
38 def read_atom(reader
):
41 float_re
= '-?[0-9][0-9.]*$'
42 str_re
= '"(?:[\\\\].|[^\\\\"])*"'
44 int_re
= re
.compile('-?[0-9]+$')
45 float_re
= re
.compile('-?[0-9][0-9.]*$')
46 str_re
= re
.compile('"(?:[\\\\].|[^\\\\"])*"')
48 if re
.match(int_re
, token
): return MalInt(int(token
))
49 ## elif re.match(float_re, token): return int(token)
50 elif re
.match(str_re
, token
):
55 s
= unicode(token
[1:end
])
56 s
= types
._replace
(u
'\\\\', u
"\u029e", s
)
57 s
= types
._replace
(u
'\\"', u
'"', s
)
58 s
= types
._replace
(u
'\\n', u
"\n", s
)
59 s
= types
._replace
(u
"\u029e", u
"\\", s
)
62 types
.throw_str("expected '\"', got EOF")
63 elif token
[0] == ':': return _keywordu(unicode(token
[1:]))
64 elif token
== "nil": return types
.nil
65 elif token
== "true": return types
.true
66 elif token
== "false": return types
.false
67 else: return MalSym(unicode(token
))
69 def read_sequence(reader
, start
='(', end
=')'):
72 if token
!= start
: types
.throw_str("expected '" + start
+ "'")
76 if not token
: types
.throw_str("expected '" + end
+ "', got EOF")
77 ast
.append(read_form(reader
))
82 def read_list(reader
):
83 lst
= read_sequence(reader
, '(', ')')
86 def read_vector(reader
):
87 lst
= read_sequence(reader
, '[', ']')
90 def read_hash_map(reader
):
91 lst
= read_sequence(reader
, '{', '}')
92 return _hash_mapl(lst
)
94 def read_form(reader
):
96 # reader macros/transforms
102 return _list(MalSym(u
'quote'), read_form(reader
))
105 return _list(MalSym(u
'quasiquote'), read_form(reader
))
108 return _list(MalSym(u
'unquote'), read_form(reader
))
111 return _list(MalSym(u
'splice-unquote'), read_form(reader
))
114 meta
= read_form(reader
)
115 return _list(MalSym(u
'with-meta'), read_form(reader
), meta
)
118 return _list(MalSym(u
'deref'), read_form(reader
))
121 elif token
== ')': types
.throw_str("unexpected ')'")
122 elif token
== '(': return read_list(reader
)
125 elif token
== ']': types
.throw_str("unexpected ']'");
126 elif token
== '[': return read_vector(reader
);
129 elif token
== '}': types
.throw_str("unexpected '}'");
130 elif token
== '{': return read_hash_map(reader
);
133 else: return read_atom(reader
);
136 tokens
= tokenize(str)
137 if len(tokens
) == 0: raise Blank("Blank Line")
138 return read_form(Reader(tokens
))