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.]*$'
43 int_re
= re
.compile('-?[0-9]+$')
44 float_re
= re
.compile('-?[0-9][0-9.]*$')
46 if re
.match(int_re
, token
): return MalInt(int(token
))
47 ## elif re.match(float_re, token): return int(token)
53 s
= unicode(token
[1:end
])
54 s
= types
._replace
(u
'\\"', u
'"', s
)
55 s
= types
._replace
(u
'\\n', u
"\n", s
)
56 s
= types
._replace
(u
'\\\\', u
"\\", s
)
58 elif token
[0] == ':': return _keywordu(unicode(token
[1:]))
59 elif token
== "nil": return types
.nil
60 elif token
== "true": return types
.true
61 elif token
== "false": return types
.false
62 else: return MalSym(unicode(token
))
64 def read_sequence(reader
, start
='(', end
=')'):
67 if token
!= start
: types
.throw_str("expected '" + start
+ "'")
71 if not token
: types
.throw_str("expected '" + end
+ "', got EOF")
72 ast
.append(read_form(reader
))
77 def read_list(reader
):
78 lst
= read_sequence(reader
, '(', ')')
81 def read_vector(reader
):
82 lst
= read_sequence(reader
, '[', ']')
85 def read_hash_map(reader
):
86 lst
= read_sequence(reader
, '{', '}')
87 return _hash_mapl(lst
)
89 def read_form(reader
):
91 # reader macros/transforms
97 return _list(MalSym(u
'quote'), read_form(reader
))
100 return _list(MalSym(u
'quasiquote'), read_form(reader
))
103 return _list(MalSym(u
'unquote'), read_form(reader
))
106 return _list(MalSym(u
'splice-unquote'), read_form(reader
))
109 meta
= read_form(reader
)
110 return _list(MalSym(u
'with-meta'), read_form(reader
), meta
)
113 return _list(MalSym(u
'deref'), read_form(reader
))
116 elif token
== ')': types
.throw_str("unexpected ')'")
117 elif token
== '(': return read_list(reader
)
120 elif token
== ']': types
.throw_str("unexpected ']'");
121 elif token
== '[': return read_vector(reader
);
124 elif token
== '}': types
.throw_str("unexpected '}'");
125 elif token
== '{': return read_hash_map(reader
);
128 else: return read_atom(reader
);
131 tokens
= tokenize(str)
132 if len(tokens
) == 0: raise Blank("Blank Line")
133 return read_form(Reader(tokens
))