clj 0.0.5.3 → 0.0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/clj/parser.rb +61 -48
- metadata +6 -6
data/lib/clj/parser.rb
CHANGED
@@ -15,6 +15,10 @@ class Clojure
|
|
15
15
|
class Parser
|
16
16
|
NUMBERS = '0' .. '9'
|
17
17
|
|
18
|
+
STRING_REGEX = %r((?:\\[\\bfnrt"/]|(?:\\u(?:[A-Fa-f\d]{4}))+|\\[\x20-\xff]))n
|
19
|
+
UNICODE_REGEX = /u([0-9|a-f|A-F]{4})/
|
20
|
+
OCTAL_REGEX = /o([0-3][0-7]?[0-7]?)/
|
21
|
+
|
18
22
|
# Unescape characters in strings.
|
19
23
|
UNESCAPE_MAP = Hash.new { |h, k| h[k] = k.chr }
|
20
24
|
UNESCAPE_MAP.update({
|
@@ -81,7 +85,7 @@ private
|
|
81
85
|
def read_nil (ch)
|
82
86
|
check = @source.read(2)
|
83
87
|
|
84
|
-
if check.
|
88
|
+
if check.length != 2
|
85
89
|
raise SyntaxError, 'unexpected EOF'
|
86
90
|
elsif check != 'il'
|
87
91
|
raise SyntaxError, "expected nil, found n#{check}"
|
@@ -94,7 +98,7 @@ private
|
|
94
98
|
if ch == 't'
|
95
99
|
check = @source.read(3)
|
96
100
|
|
97
|
-
if check.
|
101
|
+
if check.length != 3
|
98
102
|
raise SyntaxError, 'unexpected EOF'
|
99
103
|
elsif check != 'rue'
|
100
104
|
raise SyntaxError, "expected true, found t#{check}"
|
@@ -104,7 +108,7 @@ private
|
|
104
108
|
else
|
105
109
|
check = @source.read(4)
|
106
110
|
|
107
|
-
if check.
|
111
|
+
if check.length != 4
|
108
112
|
raise SyntaxError, 'unexpected EOF'
|
109
113
|
elsif check != 'alse'
|
110
114
|
raise SyntaxError, "expected false, found f#{check}"
|
@@ -121,15 +125,15 @@ private
|
|
121
125
|
piece << ch
|
122
126
|
end
|
123
127
|
|
124
|
-
revert
|
128
|
+
revert if ch
|
125
129
|
|
126
130
|
if piece.include? '/'
|
127
131
|
Rational(piece)
|
128
|
-
elsif piece.include? 'r'
|
129
|
-
base, number = piece.split(
|
132
|
+
elsif piece.include? 'r' or piece.include? 'R'
|
133
|
+
base, number = piece.split(/r/i, 2)
|
130
134
|
|
131
135
|
number.to_i(base.to_i)
|
132
|
-
elsif piece.include? '.' or piece.include? 'e' or piece.end_with? 'M'
|
136
|
+
elsif piece.include? '.' or piece.include? 'e' or piece.include? 'E' or piece.end_with? 'M'
|
133
137
|
if piece.end_with? 'M'
|
134
138
|
piece[-1] = ''
|
135
139
|
|
@@ -147,13 +151,27 @@ private
|
|
147
151
|
end
|
148
152
|
|
149
153
|
def read_char (ch)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
+
if (ahead = lookahead(2)) && (!ahead[1] || both?(ahead[1]))
|
155
|
+
@source.read(1)
|
156
|
+
elsif (ahead = lookahead(8)) && ahead[0, 7] == 'newline' && (!ahead[7] || both?(ahead[7]))
|
157
|
+
@source.read(7) and "\n"
|
158
|
+
elsif (ahead = lookahead(6)) && ahead[0, 5] == 'space' && (!ahead[5] || both?(ahead[5]))
|
159
|
+
@source.read(5) and ' '
|
160
|
+
elsif (ahead = lookahead(4)) && ahead[0, 3] == 'tab' && (!ahead[3] || both?(ahead[3]))
|
161
|
+
@source.read(3) and "\t"
|
162
|
+
elsif (ahead = lookahead(10)) && ahead[0, 9] == 'backspace' && (!ahead[9] || both?(ahead[9]))
|
163
|
+
@source.read(9) and "\b"
|
164
|
+
elsif (ahead = lookahead(9)) && ahead[0, 8] == 'formfeed' && (!ahead[8] || both?(ahead[8]))
|
165
|
+
@source.read(8) and "\f"
|
166
|
+
elsif (ahead = lookahead(7)) && ahead[0, 6] == 'return' && (!ahead[6] || both?(ahead[6]))
|
167
|
+
@source.read(6) and "\r"
|
168
|
+
elsif (ahead = lookahead(6)) && ahead[0, 5] =~ UNICODE_REGEX && (!ahead[5] || both?(ahead[5]))
|
169
|
+
[@source.read(5)[1, 4].to_i(16)].pack('U')
|
170
|
+
elsif (ahead = lookahead(5)) && ahead[0, 4] =~ OCTAL_REGEX && (!ahead[4] || both?(ahead[4]))
|
171
|
+
@source.read(4)[1, 3].to_i(8).chr
|
154
172
|
else
|
155
|
-
|
156
|
-
end
|
173
|
+
raise SyntaxError, 'unknown character type'
|
174
|
+
end
|
157
175
|
end
|
158
176
|
|
159
177
|
def read_keyword (ch)
|
@@ -163,7 +181,7 @@ private
|
|
163
181
|
result << ch
|
164
182
|
end
|
165
183
|
|
166
|
-
revert
|
184
|
+
revert if ch
|
167
185
|
|
168
186
|
result.to_sym
|
169
187
|
end
|
@@ -181,7 +199,27 @@ private
|
|
181
199
|
end
|
182
200
|
end
|
183
201
|
|
184
|
-
|
202
|
+
result.gsub(STRING_REGEX) {|escape|
|
203
|
+
if u = UNESCAPE_MAP[$&[1]]
|
204
|
+
next u
|
205
|
+
end
|
206
|
+
|
207
|
+
bytes = EMPTY_8BIT_STRING.dup
|
208
|
+
|
209
|
+
i = 0
|
210
|
+
while escape[6 * i] == ?\\ && escape[6 * i + 1] == ?u
|
211
|
+
bytes << escape[6 * i + 2, 2].to_i(16) << escape[6 * i + 4, 2].to_i(16)
|
212
|
+
|
213
|
+
i += 1
|
214
|
+
end
|
215
|
+
|
216
|
+
if bytes.respond_to? :force_encoding
|
217
|
+
bytes.force_encoding 'UTF-16be'
|
218
|
+
bytes.encode 'UTF-8'
|
219
|
+
else
|
220
|
+
bytes
|
221
|
+
end
|
222
|
+
}
|
185
223
|
end
|
186
224
|
|
187
225
|
def read_instant (ch)
|
@@ -274,50 +312,25 @@ private
|
|
274
312
|
end
|
275
313
|
|
276
314
|
def unescape (string)
|
277
|
-
string
|
278
|
-
if u = UNESCAPE_MAP[$&[1]]
|
279
|
-
next u
|
280
|
-
end
|
281
|
-
|
282
|
-
bytes = EMPTY_8BIT_STRING.dup
|
283
|
-
|
284
|
-
i = 0
|
285
|
-
while escape[6 * i] == ?\\ && escape[6 * i + 1] == ?u
|
286
|
-
bytes << escape[6 * i + 2, 2].to_i(16) << escape[6 * i + 4, 2].to_i(16)
|
287
|
-
|
288
|
-
i += 1
|
289
|
-
end
|
290
|
-
|
291
|
-
if bytes.respond_to? :force_encoding
|
292
|
-
bytes.force_encoding 'UTF-16be'
|
293
|
-
bytes.encode 'UTF-8'
|
294
|
-
else
|
295
|
-
bytes
|
296
|
-
end
|
297
|
-
}
|
315
|
+
string
|
298
316
|
end
|
299
317
|
|
300
|
-
def lookahead (length
|
301
|
-
|
302
|
-
result = @source.read(length)
|
318
|
+
def lookahead (length)
|
319
|
+
result = @source.read(length)
|
303
320
|
|
304
|
-
@source.seek(
|
321
|
+
@source.seek(-result.length, IO::SEEK_CUR)
|
305
322
|
|
306
323
|
result
|
307
324
|
end
|
308
325
|
|
309
|
-
def ignore (
|
326
|
+
def ignore (rev = true)
|
310
327
|
while ignore?(ch = @source.read(1)); end
|
311
328
|
|
312
|
-
|
313
|
-
|
314
|
-
ungetc ? revert(ch) : ch
|
329
|
+
rev ? revert : ch if ch
|
315
330
|
end
|
316
331
|
|
317
|
-
def revert (
|
318
|
-
|
319
|
-
|
320
|
-
@source.seek -1, IO::SEEK_CUR
|
332
|
+
def revert (n = 1)
|
333
|
+
@source.seek -n, IO::SEEK_CUR
|
321
334
|
end
|
322
335
|
|
323
336
|
def ignore? (ch)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.5.
|
4
|
+
version: 0.0.5.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &13013480 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *13013480
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &13012980 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *13012980
|
36
36
|
description:
|
37
37
|
email: meh@paranoici.org
|
38
38
|
executables: []
|