1 require_relative
"types"
9 return @tokens[@position]
13 return @tokens[@position-1]
19 re
= /[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}('"`,;)]*)/
20 return str
.scan(re
).map
{|m
| m
[0]}.select
{ |t
|
21 t
!= "" && t
[0..0] != ";"
25 def parse_str(t
) # trim and unescape
26 return t
[1..-2].gsub(/\\./, {"\\\\" => "\\", "\\n" => "\n", "\\\"" => '"'})
32 when /^-?[0-9]+$/ then token
.to_i
# integer
33 when /^-?[0-9][0-9.]*$/ then token
.to_f
# float
34 when /^".*"$/ then parse_str(token
) # string
35 when /^".*$/ then raise "expected '\"', got EOF"
36 when /^:/ then "\u029e" + token
[1..-1] # keyword
39 when "false" then false
40 else token
.to_sym
# symbol
44 def read_list(rdr
, klass
, start
="(", last
=")")
48 raise "expected '" + start
+ "'"
50 while (token
= rdr
.peek
) != last
52 raise "expected '" + last
+ "', got EOF"
54 ast
.push(read_form(rdr
))
63 when "'" then rdr
.next; List
.new
[:quote, read_form(rdr
)]
64 when "`" then rdr
.next; List
.new
[:quasiquote, read_form(rdr
)]
65 when "~" then rdr
.next; List
.new
[:unquote, read_form(rdr
)]
66 when "~@" then rdr
.next; List
.new
[:"splice-unquote", read_form(rdr
)]
67 when "^" then rdr
.next; meta
= read_form(rdr
);
68 List
.new
[:"with-meta", read_form(rdr
), meta
]
69 when "@" then rdr
.next; List
.new
[:deref, read_form(rdr
)]
71 when "(" then read_list(rdr
, List
, "(", ")")
72 when ")" then raise "unexpected ')'"
73 when "[" then read_list(rdr
, Vector
, "[", "]")
74 when "]" then raise "unexpected ']'"
75 when "{" then Hash
[read_list(rdr
, List
, "{", "}").each_slice(2).to_a
]
76 when "}" then raise "unexpected '}'"
82 tokens
= tokenize(str
)
83 return nil if tokens
.size
== 0
84 return read_form(Reader
.new(tokens
))