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
, _list
)
12 class Blank(Exception): pass
15 def __init__(self
, tokens
, position
=0):
17 self
.position
= position
21 return self
.tokens
[self
.position
-1]
24 if len(self
.tokens
) > self
.position
:
25 return self
.tokens
[self
.position
]
30 re_str
= "[\s,]*(~@|[\[\]{}()'`~^@]|\"(?:[\\\\].|[^\\\\\"])*\"|;.*|[^\s\[\]{}()'\"`@,;]+)"
34 tok_re
= re
.compile(re_str
)
35 return [t
for t
in re
.findall(tok_re
, str) if t
[0] != ';']
37 def read_atom(reader
):
40 float_re
= '-?[0-9][0-9.]*$'
42 int_re
= re
.compile('-?[0-9]+$')
43 float_re
= re
.compile('-?[0-9][0-9.]*$')
45 if re
.match(int_re
, token
): return MalInt(int(token
))
46 ## elif re.match(float_re, token): return int(token)
52 return MalStr(types
._replace
(u
'\\"', u
'"', unicode(token
[1:end
])))
53 elif token
[0] == ':': return _keywordu(unicode(token
[1:]))
54 elif token
== "nil": return types
.nil
55 elif token
== "true": return types
.true
56 elif token
== "false": return types
.false
57 else: return MalSym(unicode(token
))
59 def read_sequence(reader
, typ
, start
='(', end
=')'):
62 if token
!= start
: raise Exception("expected '" + start
+ "'")
66 if not token
: raise Exception("expected '" + end
+ "', got EOF")
67 ast
.append(read_form(reader
))
72 ##def read_hash_map(reader):
73 ## lst = read_sequence(reader, list, '{', '}')
74 ## return _hash_map(*lst)
76 def read_list(reader
):
77 return read_sequence(reader
, _list
, '(', ')')
79 ##def read_vector(reader):
80 ## return read_sequence(reader, _vector, '[', ']')
82 def read_form(reader
):
84 # reader macros/transforms
90 return _list(MalSym(u
'quote'), read_form(reader
))
93 return _list(MalSym(u
'quasiquote'), read_form(reader
))
96 return _list(MalSym(u
'unquote'), read_form(reader
))
99 return _list(MalSym(u
'splice-unquote'), read_form(reader
))
102 meta
= read_form(reader
)
103 return _list(MalSym(u
'with-meta'), read_form(reader
), meta
)
106 return _list(MalSym(u
'deref'), read_form(reader
))
109 elif token
== ')': raise Exception("unexpected ')'")
110 elif token
== '(': return read_list(reader
)
113 ## elif token == ']': raise Exception("unexpected ']'");
114 ## elif token == '[': return read_vector(reader);
117 ## elif token == '}': raise Exception("unexpected '}'");
118 ## elif token == '{': return read_hash_map(reader);
121 else: return read_atom(reader
);
124 tokens
= tokenize(str)
125 if len(tokens
) == 0: raise Blank("Blank Line")
126 return read_form(Reader(tokens
))