minjs 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +7 -0
- data/exe/minjs +2 -1
- data/lib/minjs.rb +1 -5
- data/lib/minjs/compressor.rb +3 -1140
- data/lib/minjs/compressor/compressor.rb +1146 -0
- data/lib/minjs/ctype.rb +71 -28
- data/lib/minjs/ecma262.rb +9 -4
- data/lib/minjs/ecma262/base.rb +89 -8
- data/lib/minjs/ecma262/env.rb +39 -16
- data/lib/minjs/ecma262/{exp.rb → expression.rb} +988 -281
- data/lib/minjs/ecma262/{lit.rb → literal.rb} +429 -48
- data/lib/minjs/ecma262/punctuator.rb +141 -0
- data/lib/minjs/ecma262/{st.rb → statement.rb} +328 -76
- data/lib/minjs/lex.rb +8 -1009
- data/lib/minjs/{exceptions.rb → lex/exceptions.rb} +3 -1
- data/lib/minjs/lex/expression.rb +1092 -0
- data/lib/minjs/{func.rb → lex/function.rb} +43 -23
- data/lib/minjs/lex/parser.rb +1147 -0
- data/lib/minjs/lex/program.rb +56 -0
- data/lib/minjs/{statement.rb → lex/statement.rb} +136 -126
- data/lib/minjs/minjs_compressor.rb +1 -1
- data/lib/minjs/version.rb +2 -1
- data/minjs.gemspec +1 -1
- metadata +28 -11
- data/lib/minjs/ecma262/punc.rb +0 -92
- data/lib/minjs/expression.rb +0 -833
- data/lib/minjs/program.rb +0 -32
@@ -0,0 +1,56 @@
|
|
1
|
+
module Minjs::Lex
|
2
|
+
#
|
3
|
+
# 14 Program
|
4
|
+
#
|
5
|
+
module Program
|
6
|
+
include Minjs
|
7
|
+
|
8
|
+
# Tests next literals sequence is Program or not.
|
9
|
+
#
|
10
|
+
# If sequence is Program
|
11
|
+
# return ECMA262::Prog object and
|
12
|
+
# forward lexical parser position.
|
13
|
+
# Otherwise return nil and position is not changed.
|
14
|
+
#
|
15
|
+
# @return [ECMA262::Prog] element
|
16
|
+
#
|
17
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 14
|
18
|
+
def program(context)
|
19
|
+
prog = source_elements(context)
|
20
|
+
if lex.eof?
|
21
|
+
return prog
|
22
|
+
else
|
23
|
+
raise ParseError.new("unexpceted token", lex)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Tests next literals sequence is SourceElements or not.
|
28
|
+
#
|
29
|
+
# If sequence is SourceElements
|
30
|
+
# return ECMA262::SourceElements object and
|
31
|
+
# forward lexical parser position.
|
32
|
+
# Otherwise return nil and position is not changed.
|
33
|
+
#
|
34
|
+
# @return [ECMA262::SourceElements] element
|
35
|
+
#
|
36
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 14
|
37
|
+
def source_elements(context)
|
38
|
+
prog = []
|
39
|
+
while t = source_element(context)
|
40
|
+
prog.push(t)
|
41
|
+
end
|
42
|
+
ECMA262::Prog.new(context, ECMA262::SourceElements.new(prog))
|
43
|
+
end
|
44
|
+
|
45
|
+
def source_element(context)
|
46
|
+
#lex.eval_lit{
|
47
|
+
statement(context)
|
48
|
+
#} or lex.eval_lit{ => statement
|
49
|
+
# func_declaration(context)
|
50
|
+
#}
|
51
|
+
end
|
52
|
+
|
53
|
+
private :source_element
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -1,12 +1,11 @@
|
|
1
|
-
module Minjs
|
1
|
+
module Minjs::Lex
|
2
2
|
#
|
3
3
|
# 12
|
4
4
|
#
|
5
5
|
module Statement
|
6
|
-
|
7
|
-
#
|
8
|
-
|
9
|
-
def semicolon(lex, context)
|
6
|
+
include Minjs
|
7
|
+
# Tests next literal is ';' or '}' or LT
|
8
|
+
def semicolon(context)
|
10
9
|
a = lex.peek_lit_nolt(nil)
|
11
10
|
# ; ?
|
12
11
|
if a == ECMA262::PUNC_SEMICOLON
|
@@ -16,13 +15,13 @@ module Minjs
|
|
16
15
|
elsif a == ECMA262::PUNC_RCURLYBRAC
|
17
16
|
a
|
18
17
|
# line feed?
|
19
|
-
elsif a == ECMA262::
|
18
|
+
elsif a == ECMA262::LIT_LINE_TERMINATOR
|
20
19
|
lex.fwd_after_peek
|
21
20
|
a
|
22
21
|
# end of program
|
23
22
|
elsif a.nil?
|
24
23
|
lex.fwd_after_peek
|
25
|
-
ECMA262::
|
24
|
+
ECMA262::LIT_LINE_TERMINATOR
|
26
25
|
# line terminator?
|
27
26
|
elsif a.lt?
|
28
27
|
lex.fwd_after_peek
|
@@ -32,60 +31,61 @@ module Minjs
|
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
|
-
#
|
36
|
-
def statement(
|
34
|
+
# Tests next literals sequence is Statement or not.
|
35
|
+
def statement(context)
|
37
36
|
(
|
38
|
-
block(
|
39
|
-
var_statement(
|
40
|
-
if_statement(
|
41
|
-
iteration_statement(
|
42
|
-
continue_statement(
|
43
|
-
break_statement(
|
44
|
-
return_statement(
|
45
|
-
with_statement(
|
46
|
-
switch_statement(
|
47
|
-
labelled_statement(
|
48
|
-
throw_statement(
|
49
|
-
try_statement(
|
50
|
-
debugger_statement(
|
51
|
-
func_declaration(
|
52
|
-
exp_statement(
|
53
|
-
empty_statement(
|
37
|
+
block(context) or #12.1
|
38
|
+
var_statement(context) or #12.2
|
39
|
+
if_statement(context) or #12.5
|
40
|
+
iteration_statement(context) or #12.6
|
41
|
+
continue_statement(context) or #12.7
|
42
|
+
break_statement(context) or #12.8
|
43
|
+
return_statement(context) or #12.9
|
44
|
+
with_statement(context) or #12.10
|
45
|
+
switch_statement(context) or #12.11
|
46
|
+
labelled_statement(context) or #12.12
|
47
|
+
throw_statement(context) or #12.13
|
48
|
+
try_statement(context) or #12.14
|
49
|
+
debugger_statement(context) or #12.15
|
50
|
+
func_declaration(context) or #13 => func.rb
|
51
|
+
exp_statement(context) or #12.4
|
52
|
+
empty_statement(context) #12.3
|
54
53
|
)
|
55
54
|
end
|
55
|
+
# Tests next literals sequence is Block or not.
|
56
56
|
#
|
57
|
-
#12.1
|
58
|
-
|
59
|
-
def block(lex, context)
|
57
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.1
|
58
|
+
def block(context)
|
60
59
|
pos0 = lex.pos
|
61
60
|
return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
|
62
61
|
if lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
|
63
62
|
return ECMA262::StBlock.new(ECMA262::StatementList.new([]))
|
64
63
|
end
|
65
64
|
|
66
|
-
if s = statement_list(
|
65
|
+
if s = statement_list(context) and lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
|
67
66
|
ECMA262::StBlock.new(s)
|
68
67
|
else
|
69
68
|
raise ParseError.new('no "}" end of block', lex)
|
70
69
|
end
|
71
70
|
end
|
72
71
|
|
73
|
-
def statement_list(
|
72
|
+
def statement_list(context)
|
74
73
|
t = []
|
75
|
-
while !lex.eof? and s = statement(
|
74
|
+
while !lex.eof? and s = statement(context)
|
76
75
|
t.push(s)
|
77
76
|
end
|
78
77
|
ECMA262::StatementList.new(t)
|
79
78
|
end
|
79
|
+
private :statement_list
|
80
|
+
|
81
|
+
# Tests next literals sequence is VariableStatement or not.
|
80
82
|
#
|
81
|
-
#12.2
|
82
|
-
|
83
|
-
#
|
84
|
-
def var_statement(lex, context)
|
83
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.2
|
84
|
+
def var_statement(context)
|
85
85
|
raise 'internal error' if context.nil?
|
86
86
|
return nil unless lex.eql_lit?(ECMA262::ID_VAR)
|
87
87
|
|
88
|
-
if vl = var_decl_list(
|
88
|
+
if vl = var_decl_list(context, {}) and semicolon(context)
|
89
89
|
#10.5
|
90
90
|
vl.each do |v|
|
91
91
|
dn = v[0]
|
@@ -105,11 +105,11 @@ module Minjs
|
|
105
105
|
# VariableDeclaration
|
106
106
|
# VariableDeclarationList , VariableDeclaration
|
107
107
|
#
|
108
|
-
def var_decl_list(
|
108
|
+
def var_decl_list(context, options)
|
109
109
|
list = []
|
110
|
-
list.push(var_decl(
|
110
|
+
list.push(var_decl(context, options))
|
111
111
|
|
112
|
-
while lex.eql_lit?(ECMA262::PUNC_COMMA) and b = var_decl(
|
112
|
+
while lex.eql_lit?(ECMA262::PUNC_COMMA) and b = var_decl(context, options)
|
113
113
|
list.push(b)
|
114
114
|
end
|
115
115
|
list
|
@@ -122,12 +122,12 @@ module Minjs
|
|
122
122
|
#
|
123
123
|
# return tuple of [name, initialiser]
|
124
124
|
#
|
125
|
-
def var_decl(
|
126
|
-
a = identifier(
|
125
|
+
def var_decl(context, options)
|
126
|
+
a = identifier(context)
|
127
127
|
if !a
|
128
128
|
raise ParseError.new("bad identifier", lex);
|
129
129
|
else
|
130
|
-
b = initialiser(
|
130
|
+
b = initialiser(context, options)
|
131
131
|
[a, b]
|
132
132
|
end
|
133
133
|
end
|
@@ -137,9 +137,9 @@ module Minjs
|
|
137
137
|
# Initialiser :
|
138
138
|
# = AssignmentExpression
|
139
139
|
#
|
140
|
-
def initialiser(
|
141
|
-
if lex.eql_lit?(ECMA262::
|
142
|
-
if a = assignment_exp(
|
140
|
+
def initialiser(context, options)
|
141
|
+
if lex.eql_lit?(ECMA262::PUNC_ASSIGN)
|
142
|
+
if a = assignment_exp(context, options)
|
143
143
|
return a
|
144
144
|
else
|
145
145
|
raise ParseError.new("unexpceted token", lex);
|
@@ -147,10 +147,12 @@ module Minjs
|
|
147
147
|
end
|
148
148
|
nil
|
149
149
|
end
|
150
|
+
private :var_decl_list, :var_decl, :initialiser
|
151
|
+
|
152
|
+
# Tests next literals sequence is EmptyStatement or not.
|
150
153
|
#
|
151
|
-
#12.3
|
152
|
-
|
153
|
-
def empty_statement(lex, context)
|
154
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.3
|
155
|
+
def empty_statement(context)
|
154
156
|
a = lex.peek_lit(nil)
|
155
157
|
if a == ECMA262::PUNC_SEMICOLON
|
156
158
|
lex.fwd_after_peek
|
@@ -159,20 +161,20 @@ module Minjs
|
|
159
161
|
nil
|
160
162
|
end
|
161
163
|
end
|
164
|
+
# Tests next literals sequence is ExpressionStatement or not.
|
162
165
|
#
|
163
|
-
#12.4
|
164
|
-
|
165
|
-
def exp_statement(lex, context)
|
166
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.4
|
167
|
+
def exp_statement(context)
|
166
168
|
if (a = lex.peek_lit(nil)).eql? ECMA262::PUNC_LCURLYBRAC
|
167
|
-
return block(
|
169
|
+
return block(context)
|
168
170
|
end
|
169
171
|
if a.eql? ECMA262::ID_FUNCTION
|
170
|
-
return func_declaration(
|
172
|
+
return func_declaration(context)
|
171
173
|
end
|
172
174
|
|
173
175
|
|
174
|
-
if a = exp(
|
175
|
-
if semicolon(
|
176
|
+
if a = exp(context, {})
|
177
|
+
if semicolon(context)
|
176
178
|
ECMA262::StExp.new(a)
|
177
179
|
# There is a possibility of labelled statemet if
|
178
180
|
# exp_statement call before labelled_statement
|
@@ -183,39 +185,40 @@ module Minjs
|
|
183
185
|
nil
|
184
186
|
end
|
185
187
|
end
|
188
|
+
# Tests next literals sequence is IfStatement or not.
|
186
189
|
#
|
187
|
-
#12.5
|
188
|
-
|
189
|
-
def if_statement(lex, context)
|
190
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.5
|
191
|
+
def if_statement(context)
|
190
192
|
return nil unless lex.eql_lit?(ECMA262::ID_IF)
|
191
|
-
unless
|
193
|
+
unless(lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and cond=exp(context, {}) and
|
194
|
+
lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s = statement(context))
|
192
195
|
raise ParseError.new("unexpected token", lex)
|
193
196
|
end
|
194
|
-
if
|
197
|
+
if(lex.eql_lit?(ECMA262::ID_ELSE) and e = statement(context))
|
195
198
|
ECMA262::StIf.new(cond, s, e)
|
196
199
|
else
|
197
200
|
ECMA262::StIf.new(cond, s, nil)
|
198
201
|
end
|
199
202
|
end
|
203
|
+
# Tests next literals sequence is IterationStatement or not.
|
200
204
|
#
|
201
|
-
# 12.6
|
202
|
-
|
203
|
-
|
204
|
-
for_statement(lex, context) or while_statement(lex, context) or do_while_statement(lex, context)
|
205
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.6
|
206
|
+
def iteration_statement(context)
|
207
|
+
for_statement(context) or while_statement(context) or do_while_statement(context)
|
205
208
|
end
|
206
209
|
|
207
|
-
def while_statement(
|
210
|
+
def while_statement(context)
|
208
211
|
return nil unless lex.eql_lit?(ECMA262::ID_WHILE)
|
209
|
-
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(
|
212
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(context)
|
210
213
|
ECMA262::StWhile.new(e, s)
|
211
214
|
else
|
212
215
|
raise ParseError.new("unexpected token", lex)
|
213
216
|
end
|
214
217
|
end
|
215
218
|
|
216
|
-
def do_while_statement(
|
219
|
+
def do_while_statement(context)
|
217
220
|
return nil unless lex.eql_lit?(ECMA262::ID_DO)
|
218
|
-
if s=statement(
|
221
|
+
if s=statement(context) and lex.eql_lit?(ECMA262::ID_WHILE) and lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and semicolon(context)
|
219
222
|
ECMA262::StDoWhile.new(e, s)
|
220
223
|
else
|
221
224
|
raise ParseError.new("unexpected token", lex)
|
@@ -229,15 +232,15 @@ module Minjs
|
|
229
232
|
# for ( LeftHandSideExpression in Expression ) Statement
|
230
233
|
# for ( var VariableDeclarationNoIn in Expression ) Statement
|
231
234
|
#
|
232
|
-
def for_statement(
|
235
|
+
def for_statement(context)
|
233
236
|
return nil unless lex.eql_lit?(ECMA262::ID_FOR)
|
234
237
|
raise ParseError('unexpected token', lex) unless lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS)
|
235
238
|
lex.eval_lit{
|
236
239
|
# for(var i in a)
|
237
240
|
if lex.eql_lit?(ECMA262::ID_VAR)
|
238
241
|
lex.eval_lit{
|
239
|
-
if v=var_decl(
|
240
|
-
if e=exp(
|
242
|
+
if v=var_decl(context, :no_in => true) and lex.eql_lit?(ECMA262::ID_IN)
|
243
|
+
if e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s = statement(context)
|
241
244
|
#10.5
|
242
245
|
context.var_env.record.create_mutable_binding(v[0], nil)
|
243
246
|
context.var_env.record.set_mutable_binding(v[0], :undefined, nil)
|
@@ -250,7 +253,7 @@ module Minjs
|
|
250
253
|
end
|
251
254
|
} or lex.eval_lit {
|
252
255
|
# for(var i ; cond ; exp)
|
253
|
-
if vl=var_decl_list(
|
256
|
+
if vl=var_decl_list(context, :no_in =>true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(context, {})||true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(context)
|
254
257
|
e = nil if e == true
|
255
258
|
e2 = nil if e2 == true
|
256
259
|
#10.5
|
@@ -275,8 +278,8 @@ module Minjs
|
|
275
278
|
else # => for(i in exp) / for(i ; cond; exp)
|
276
279
|
lex.eval_lit{
|
277
280
|
# for(i in exp)
|
278
|
-
if v=left_hand_side_exp(
|
279
|
-
if e=exp(
|
281
|
+
if v=left_hand_side_exp(context) and lex.eql_lit?(ECMA262::ID_IN)
|
282
|
+
if e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(context)
|
280
283
|
ECMA262::StForIn.new(v, e, s)
|
281
284
|
else
|
282
285
|
raise ParseError.new("unexpected token", lex)
|
@@ -284,7 +287,7 @@ module Minjs
|
|
284
287
|
end
|
285
288
|
} or lex.eval_lit{
|
286
289
|
# for(i ; cond; exp)
|
287
|
-
if (v=exp(
|
290
|
+
if (v=exp(context, :no_in => true) || true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(context, {}) || true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(context)
|
288
291
|
v = nil if v == true
|
289
292
|
e = nil if e == true
|
290
293
|
e2 = nil if e2 == true
|
@@ -296,15 +299,17 @@ module Minjs
|
|
296
299
|
end
|
297
300
|
}
|
298
301
|
end
|
302
|
+
private :while_statement, :do_while_statement, :for_statement
|
303
|
+
|
304
|
+
# Tests next literals sequence is ContinueStatement or not.
|
299
305
|
#
|
300
|
-
# 12.7
|
301
|
-
|
302
|
-
def continue_statement(lex, context)
|
306
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.7
|
307
|
+
def continue_statement(context)
|
303
308
|
return nil unless lex.eql_lit?(ECMA262::ID_CONTINUE)
|
304
309
|
|
305
|
-
if semicolon(
|
310
|
+
if semicolon(context)
|
306
311
|
ECMA262::StContinue.new
|
307
|
-
elsif e=identifier(
|
312
|
+
elsif e=identifier(context) and semicolon(context)
|
308
313
|
ECMA262::StContinue.new(e)
|
309
314
|
else
|
310
315
|
if e
|
@@ -314,15 +319,16 @@ module Minjs
|
|
314
319
|
end
|
315
320
|
end
|
316
321
|
end
|
322
|
+
|
323
|
+
# Tests next literals sequence is BreakStatement or not.
|
317
324
|
#
|
318
|
-
# 12.8
|
319
|
-
|
320
|
-
def break_statement(lex, context)
|
325
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.8
|
326
|
+
def break_statement(context)
|
321
327
|
return nil unless lex.eql_lit?(ECMA262::ID_BREAK)
|
322
328
|
|
323
|
-
if semicolon(
|
329
|
+
if semicolon(context)
|
324
330
|
ECMA262::StBreak.new
|
325
|
-
elsif e=identifier(
|
331
|
+
elsif e=identifier(context) and semicolon(context)
|
326
332
|
ECMA262::StBreak.new(e)
|
327
333
|
else
|
328
334
|
if e
|
@@ -332,59 +338,59 @@ module Minjs
|
|
332
338
|
end
|
333
339
|
end
|
334
340
|
end
|
341
|
+
# Tests next literals sequence is ReturnStatement or not.
|
335
342
|
#
|
336
|
-
# 12.9
|
337
|
-
|
338
|
-
def return_statement(lex, context)
|
343
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.9
|
344
|
+
def return_statement(context)
|
339
345
|
return nil unless lex.eql_lit?(ECMA262::ID_RETURN)
|
340
346
|
|
341
|
-
if semicolon(
|
347
|
+
if semicolon(context)
|
342
348
|
ECMA262::StReturn.new
|
343
|
-
elsif e=exp(
|
349
|
+
elsif e=exp(context, {}) and semicolon(context)
|
344
350
|
ECMA262::StReturn.new(e)
|
345
351
|
else
|
346
352
|
raise ParseError.new("unexpected token", lex)
|
347
353
|
end
|
348
354
|
end
|
355
|
+
# Tests next literals sequence is WithStatement or not.
|
349
356
|
#
|
350
|
-
# 12.10
|
351
|
-
|
352
|
-
def with_statement(lex, context)
|
357
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.10
|
358
|
+
def with_statement(context)
|
353
359
|
return nil unless lex.eql_lit?(ECMA262::ID_WITH)
|
354
360
|
|
355
|
-
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(
|
361
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(context)
|
356
362
|
ECMA262::StWith.new(context, e, s)
|
357
363
|
else
|
358
364
|
raise ParseError.new("unexpected token", lex)
|
359
365
|
end
|
360
366
|
end
|
367
|
+
# Tests next literals sequence is SwitchStatement or not.
|
361
368
|
#
|
362
|
-
# 12.11
|
363
|
-
|
364
|
-
def switch_statement(lex, context)
|
369
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.11
|
370
|
+
def switch_statement(context)
|
365
371
|
return nil unless lex.eql_lit?(ECMA262::ID_SWITCH)
|
366
372
|
|
367
|
-
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(
|
373
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and c = case_block(context)
|
368
374
|
ECMA262::StSwitch.new(e, c)
|
369
375
|
else
|
370
376
|
raise ParseError.new("unexpected token", lex)
|
371
377
|
end
|
372
378
|
end
|
373
379
|
|
374
|
-
def case_block(
|
380
|
+
def case_block(context)
|
375
381
|
return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
|
376
382
|
_case_block = []
|
377
383
|
while true
|
378
384
|
if lex.eql_lit?(ECMA262::ID_CASE)
|
379
|
-
if e = exp(
|
380
|
-
sl = statement_list(
|
385
|
+
if e = exp(context, {}) and lex.eql_lit?(ECMA262::PUNC_COLON)
|
386
|
+
sl = statement_list(context)
|
381
387
|
_case_block.push [e, sl]
|
382
388
|
else
|
383
389
|
raise ParseError.new("unexpected token", lex)
|
384
390
|
end
|
385
391
|
elsif lex.eql_lit?(ECMA262::ID_DEFAULT)
|
386
392
|
if lex.eql_lit?(ECMA262::PUNC_COLON)
|
387
|
-
sl = statement_list(
|
393
|
+
sl = statement_list(context)
|
388
394
|
_case_block.push [nil, sl]
|
389
395
|
else
|
390
396
|
raise ParseError.new("unexpected token", lex)
|
@@ -395,13 +401,15 @@ module Minjs
|
|
395
401
|
end
|
396
402
|
_case_block
|
397
403
|
end
|
404
|
+
private :case_block
|
405
|
+
|
406
|
+
# Tests next literals sequence is LabelledStatement or not.
|
398
407
|
#
|
399
|
-
# 12.12
|
400
|
-
|
401
|
-
def labelled_statement(lex, context)
|
408
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.12
|
409
|
+
def labelled_statement(context)
|
402
410
|
lex.eval_lit {
|
403
|
-
if i=identifier(
|
404
|
-
if s=statement(
|
411
|
+
if i=identifier(context) and s1=lex.eql_lit?(ECMA262::PUNC_COLON)
|
412
|
+
if s=statement(context)
|
405
413
|
ECMA262::StLabelled.new(i, s)
|
406
414
|
else
|
407
415
|
raise ParseError.new("unexpected token", lex)
|
@@ -411,15 +419,15 @@ module Minjs
|
|
411
419
|
end
|
412
420
|
}
|
413
421
|
end
|
422
|
+
# Tests next literals sequence is ThrowStatement or not.
|
414
423
|
#
|
415
|
-
# 12.13
|
416
|
-
|
417
|
-
def throw_statement(lex, context)
|
424
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.13
|
425
|
+
def throw_statement(context)
|
418
426
|
return nil unless lex.eql_lit?(ECMA262::ID_THROW)
|
419
427
|
|
420
|
-
if semicolon(
|
428
|
+
if semicolon(context)
|
421
429
|
raise ParseError.new("no line terminator here", lex)
|
422
|
-
elsif e=exp(
|
430
|
+
elsif e=exp(context, {}) and semi = semicolon(context)
|
423
431
|
ECMA262::StThrow.new(e)
|
424
432
|
else
|
425
433
|
if e
|
@@ -429,20 +437,20 @@ module Minjs
|
|
429
437
|
end
|
430
438
|
end
|
431
439
|
end
|
440
|
+
# Tests next literals sequence is TryStatement or not.
|
432
441
|
#
|
433
|
-
# 12.14
|
434
|
-
|
435
|
-
def try_statement(lex, context)
|
442
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.14
|
443
|
+
def try_statement(context)
|
436
444
|
return nil unless lex.eql_lit?(ECMA262::ID_TRY)
|
437
445
|
#
|
438
446
|
# The catch argument context must be executable lexical environment.
|
439
447
|
# See compress_var
|
440
448
|
#
|
441
|
-
t = block(
|
449
|
+
t = block(context)
|
442
450
|
return nil unless t
|
443
451
|
|
444
|
-
c = try_catch(
|
445
|
-
f = try_finally(
|
452
|
+
c = try_catch(context)
|
453
|
+
f = try_finally(context)
|
446
454
|
ECMA262::StTry.new(context, t, c, f)
|
447
455
|
end
|
448
456
|
# 12.14
|
@@ -452,29 +460,31 @@ module Minjs
|
|
452
460
|
#
|
453
461
|
# return [identigier, block]
|
454
462
|
#
|
455
|
-
def try_catch(
|
463
|
+
def try_catch(context)
|
456
464
|
return nil unless lex.eql_lit?(ECMA262::ID_CATCH)
|
457
465
|
|
458
|
-
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and i=identifier(
|
466
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and i=identifier(context) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and b=block(context)
|
459
467
|
[i, b]
|
460
468
|
else
|
461
469
|
raise ParseError.new("unexpected token", lex)
|
462
470
|
end
|
463
471
|
end
|
464
472
|
|
465
|
-
def try_finally(
|
473
|
+
def try_finally(context)
|
466
474
|
return nil unless lex.eql_lit?(ECMA262::ID_FINALLY)
|
467
|
-
b = block(
|
475
|
+
b = block(context)
|
468
476
|
raise ParseError.new("unexpected token", lex) if b.nil?
|
469
477
|
b
|
470
478
|
end
|
471
479
|
|
480
|
+
private :try_catch, :try_finally
|
481
|
+
|
482
|
+
# Tests next literals sequence is DebuggerStatement or not.
|
472
483
|
#
|
473
|
-
# 12.15
|
474
|
-
|
475
|
-
def debugger_statement(lex, context)
|
484
|
+
# @see http://www.ecma-international.org/ecma-262 ECMA262 12.15
|
485
|
+
def debugger_statement(context)
|
476
486
|
return nil unless lex.eql_lit?(ECMA262::ID_DEBUGGER)
|
477
|
-
if semicolon(
|
487
|
+
if semicolon(context)
|
478
488
|
ECMA262::StDebugger.new
|
479
489
|
else
|
480
490
|
raise ParseError.new("no semicolon at end of debugger statement", lex)
|