minjs 0.2.2 → 0.3.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/exe/minjs +12 -2
- data/lib/minjs.rb +0 -1
- data/lib/minjs/compressor.rb +24 -21
- data/lib/minjs/ctype.rb +1239 -836
- data/lib/minjs/ecma262/base.rb +1 -1
- data/lib/minjs/ecma262/exp.rb +31 -2
- data/lib/minjs/ecma262/lit.rb +103 -56
- data/lib/minjs/ecma262/punc.rb +6 -2
- data/lib/minjs/ecma262/st.rb +7 -3
- data/lib/minjs/exceptions.rb +3 -3
- data/lib/minjs/expression.rb +597 -496
- data/lib/minjs/func.rb +80 -66
- data/lib/minjs/lex.rb +629 -407
- data/lib/minjs/program.rb +16 -12
- data/lib/minjs/statement.rb +321 -309
- data/lib/minjs/version.rb +1 -1
- metadata +2 -3
- data/lib/minjs/literal.rb +0 -45
data/lib/minjs/program.rb
CHANGED
@@ -3,25 +3,29 @@ module Minjs
|
|
3
3
|
# 14 Program
|
4
4
|
#
|
5
5
|
module Program
|
6
|
+
def program(lex, context)
|
7
|
+
prog = source_elements(@lex, @global_context)
|
8
|
+
if lex.eof?
|
9
|
+
return prog
|
10
|
+
else
|
11
|
+
raise ParseError.new("unexpceted token", lex)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
6
15
|
def source_elements(lex, context, options = {})
|
7
16
|
prog = []
|
8
|
-
while
|
9
|
-
t
|
10
|
-
if t
|
11
|
-
prog.push(t)
|
12
|
-
else
|
13
|
-
break
|
14
|
-
end
|
17
|
+
while t = source_element(lex, context)
|
18
|
+
prog.push(t)
|
15
19
|
end
|
16
20
|
ECMA262::Prog.new(context, ECMA262::SourceElements.new(prog))
|
17
21
|
end
|
18
22
|
|
19
23
|
def source_element(lex, context)
|
20
|
-
lex.eval_lit{
|
21
|
-
|
22
|
-
} or lex.eval_lit{
|
23
|
-
|
24
|
-
}
|
24
|
+
#lex.eval_lit{
|
25
|
+
statement(lex, context)
|
26
|
+
#} or lex.eval_lit{ => statement
|
27
|
+
# func_declaration(lex, context)
|
28
|
+
#}
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/minjs/statement.rb
CHANGED
@@ -7,85 +7,75 @@ module Minjs
|
|
7
7
|
# check next literal is ';' or '}' or LT
|
8
8
|
#
|
9
9
|
def semicolon(lex, context)
|
10
|
-
lex.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
10
|
+
a = lex.peek_lit_nolt(nil)
|
11
|
+
# ; ?
|
12
|
+
if a == ECMA262::PUNC_SEMICOLON
|
13
|
+
lex.fwd_after_peek
|
14
|
+
a
|
15
|
+
# } ?
|
16
|
+
elsif a == ECMA262::PUNC_RCURLYBRAC
|
17
|
+
a
|
18
|
+
# line feed?
|
19
|
+
elsif a == ECMA262::LIT_LINE_FEED
|
20
|
+
lex.fwd_after_peek
|
21
|
+
a
|
22
|
+
# end of program
|
23
|
+
elsif a.nil?
|
24
|
+
lex.fwd_after_peek
|
25
|
+
ECMA262::LIT_LINE_FEED
|
26
|
+
# line terminator?
|
27
|
+
elsif a.lt?
|
28
|
+
lex.fwd_after_peek
|
29
|
+
a
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
27
33
|
end
|
28
34
|
|
29
35
|
#12
|
30
36
|
def statement(lex, context)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
:func_declaration,
|
50
|
-
:empty_statement,
|
51
|
-
].each do |f|
|
52
|
-
t = lex.eval_lit {
|
53
|
-
__send__(f, lex, context)
|
54
|
-
}
|
55
|
-
return t if t
|
56
|
-
end
|
57
|
-
nil
|
37
|
+
(
|
38
|
+
block(lex, context) or #12.1
|
39
|
+
var_statement(lex, context) or #12.2
|
40
|
+
if_statement(lex, context) or #12.5
|
41
|
+
iteration_statement(lex, context) or #12.6
|
42
|
+
continue_statement(lex, context) or #12.7
|
43
|
+
break_statement(lex, context) or #12.8
|
44
|
+
return_statement(lex, context) or #12.9
|
45
|
+
with_statement(lex, context) or #12.10
|
46
|
+
switch_statement(lex, context) or #12.11
|
47
|
+
labelled_statement(lex, context) or #12.12
|
48
|
+
throw_statement(lex, context) or #12.13
|
49
|
+
try_statement(lex, context) or #12.14
|
50
|
+
debugger_statement(lex, context) or #12.15
|
51
|
+
func_declaration(lex, context) or #13 => func.rb
|
52
|
+
exp_statement(lex, context) or #12.4
|
53
|
+
empty_statement(lex, context) #12.3
|
54
|
+
)
|
58
55
|
end
|
59
56
|
#
|
60
57
|
#12.1
|
61
58
|
# block
|
62
59
|
def block(lex, context)
|
63
60
|
pos0 = lex.pos
|
64
|
-
return nil unless lex.
|
65
|
-
if lex.
|
61
|
+
return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
|
62
|
+
if lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
|
66
63
|
return ECMA262::StBlock.new(ECMA262::StatementList.new([]))
|
67
64
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
}
|
65
|
+
|
66
|
+
if s = statement_list(lex, context) and lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
|
67
|
+
ECMA262::StBlock.new(s)
|
68
|
+
else
|
69
|
+
raise ParseError.new('no "}" end of block', lex)
|
70
|
+
end
|
75
71
|
end
|
76
72
|
|
77
73
|
def statement_list(lex, context)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
else
|
84
|
-
break
|
85
|
-
end
|
86
|
-
end
|
87
|
-
ECMA262::StatementList.new(t)
|
88
|
-
}
|
74
|
+
t = []
|
75
|
+
while !lex.eof? and s = statement(lex, context)
|
76
|
+
t.push(s)
|
77
|
+
end
|
78
|
+
ECMA262::StatementList.new(t)
|
89
79
|
end
|
90
80
|
#
|
91
81
|
#12.2
|
@@ -93,111 +83,119 @@ module Minjs
|
|
93
83
|
#
|
94
84
|
def var_statement(lex, context)
|
95
85
|
raise 'internal error' if context.nil?
|
96
|
-
return nil unless lex.
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
ECMA262::StVar.new(context, vl)
|
108
|
-
else
|
109
|
-
raise Minjs::ParseError.new("var_statement", lex)
|
86
|
+
return nil unless lex.eql_lit?(ECMA262::ID_VAR)
|
87
|
+
|
88
|
+
if vl = var_decl_list(lex, context, {}) and semicolon(lex, context)
|
89
|
+
#10.5
|
90
|
+
vl.each do |v|
|
91
|
+
dn = v[0]
|
92
|
+
context.var_env.record.create_mutable_binding(dn, nil)
|
93
|
+
context.var_env.record.set_mutable_binding(dn, :undefined, nil)
|
94
|
+
context.lex_env.record.create_mutable_binding(dn, nil)
|
95
|
+
context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
|
110
96
|
end
|
111
|
-
|
97
|
+
ECMA262::StVar.new(context, vl)
|
98
|
+
else
|
99
|
+
raise Minjs::ParseError.new("unexpected token", lex)
|
100
|
+
end
|
112
101
|
end
|
113
|
-
|
102
|
+
# 12.2
|
103
|
+
#
|
104
|
+
# VariableDeclarationList :
|
105
|
+
# VariableDeclaration
|
106
|
+
# VariableDeclarationList , VariableDeclaration
|
107
|
+
#
|
114
108
|
def var_decl_list(lex, context, options)
|
115
|
-
|
116
|
-
|
117
|
-
next nil if !a
|
109
|
+
list = []
|
110
|
+
list.push(var_decl(lex, context, options))
|
118
111
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
end
|
124
|
-
}
|
112
|
+
while lex.eql_lit?(ECMA262::PUNC_COMMA) and b = var_decl(lex, context, options)
|
113
|
+
list.push(b)
|
114
|
+
end
|
115
|
+
list
|
125
116
|
end
|
126
117
|
|
118
|
+
# 12.2
|
119
|
+
#
|
120
|
+
# VariableDeclaration :
|
121
|
+
# Identifier Initialiser[opt]
|
122
|
+
#
|
123
|
+
# return tuple of [name, initialiser]
|
124
|
+
#
|
127
125
|
def var_decl(lex, context, options)
|
128
|
-
lex
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
end
|
136
|
-
}
|
126
|
+
a = identifier(lex, context)
|
127
|
+
if !a
|
128
|
+
raise ParseError.new("bad identifier", lex);
|
129
|
+
else
|
130
|
+
b = initialiser(lex, context, options)
|
131
|
+
[a, b]
|
132
|
+
end
|
137
133
|
end
|
138
134
|
|
135
|
+
# 12.2
|
136
|
+
#
|
137
|
+
# Initialiser :
|
138
|
+
# = AssignmentExpression
|
139
|
+
#
|
139
140
|
def initialiser(lex, context, options)
|
140
|
-
if lex.
|
141
|
-
|
141
|
+
if lex.eql_lit?(ECMA262::PUNC_LET)
|
142
|
+
if a = assignment_exp(lex, context, options)
|
143
|
+
return a
|
144
|
+
else
|
145
|
+
raise ParseError.new("unexpceted token", lex);
|
146
|
+
end
|
142
147
|
end
|
143
|
-
|
144
148
|
nil
|
145
149
|
end
|
146
150
|
#
|
147
151
|
#12.3
|
148
152
|
#
|
149
153
|
def empty_statement(lex, context)
|
150
|
-
lex.
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
}# || lex.eval_lit {
|
158
|
-
# a = lex.fwd_lit(:nolt => true)
|
159
|
-
# if a == ECMA262::LIT_LINE_FEED
|
160
|
-
# ECMA262::StEmpty.new
|
161
|
-
# elsif a.lt?
|
162
|
-
# ECMA262::StEmpty.new
|
163
|
-
# else
|
164
|
-
# nil
|
165
|
-
# end
|
166
|
-
# }
|
154
|
+
a = lex.peek_lit(nil)
|
155
|
+
if a == ECMA262::PUNC_SEMICOLON
|
156
|
+
lex.fwd_after_peek
|
157
|
+
ECMA262::StEmpty.new
|
158
|
+
else
|
159
|
+
nil
|
160
|
+
end
|
167
161
|
end
|
168
162
|
#
|
169
163
|
#12.4
|
170
164
|
#
|
171
165
|
def exp_statement(lex, context)
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
166
|
+
if (a = lex.peek_lit(nil)).eql? ECMA262::PUNC_LCURLYBRAC
|
167
|
+
return block(lex, context)
|
168
|
+
end
|
169
|
+
if a.eql? ECMA262::ID_FUNCTION
|
170
|
+
return func_declaration(lex, context)
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
if a = exp(lex, context, {})
|
175
|
+
if semicolon(lex, context)
|
176
176
|
ECMA262::StExp.new(a)
|
177
|
+
# There is a possibility of labelled statemet if
|
178
|
+
# exp_statement call before labelled_statement
|
177
179
|
else
|
178
|
-
|
179
|
-
raise ParseError.new("no semicolon at end of expression statement", lex)
|
180
|
-
else
|
181
|
-
nil
|
182
|
-
end
|
180
|
+
raise ParseError.new("no semicolon at end of expression statement", lex)
|
183
181
|
end
|
184
|
-
|
182
|
+
else
|
183
|
+
nil
|
184
|
+
end
|
185
185
|
end
|
186
186
|
#
|
187
187
|
#12.5
|
188
188
|
#
|
189
189
|
def if_statement(lex, context)
|
190
|
-
return nil unless lex.
|
191
|
-
lex.
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
end
|
200
|
-
}
|
190
|
+
return nil unless lex.eql_lit?(ECMA262::ID_IF)
|
191
|
+
unless lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and cond=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
192
|
+
raise ParseError.new("unexpected token", lex)
|
193
|
+
end
|
194
|
+
if lex.eql_lit?(ECMA262::ID_ELSE) and e=statement(lex, context)
|
195
|
+
ECMA262::StIf.new(cond, s, e)
|
196
|
+
else
|
197
|
+
ECMA262::StIf.new(cond, s, nil)
|
198
|
+
end
|
201
199
|
end
|
202
200
|
#
|
203
201
|
# 12.6
|
@@ -207,74 +205,94 @@ module Minjs
|
|
207
205
|
end
|
208
206
|
|
209
207
|
def while_statement(lex, context)
|
210
|
-
return nil unless lex.
|
211
|
-
if lex.
|
208
|
+
return nil unless lex.eql_lit?(ECMA262::ID_WHILE)
|
209
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
212
210
|
ECMA262::StWhile.new(e, s)
|
213
211
|
else
|
214
|
-
raise ParseError.new("
|
212
|
+
raise ParseError.new("unexpected token", lex)
|
215
213
|
end
|
216
214
|
end
|
217
215
|
|
218
216
|
def do_while_statement(lex, context)
|
219
|
-
return nil unless lex.
|
220
|
-
if s=statement(lex, context) and lex.
|
217
|
+
return nil unless lex.eql_lit?(ECMA262::ID_DO)
|
218
|
+
if s=statement(lex, context) and lex.eql_lit?(ECMA262::ID_WHILE) and lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and semicolon(lex, context)
|
221
219
|
ECMA262::StDoWhile.new(e, s)
|
222
220
|
else
|
223
|
-
raise ParseError.new("
|
221
|
+
raise ParseError.new("unexpected token", lex)
|
224
222
|
end
|
225
223
|
end
|
226
224
|
|
225
|
+
#12.6
|
226
|
+
#
|
227
|
+
# for ( ExpressionNoInopt ; Expressionopt ; Expressionopt ) Statement
|
228
|
+
# for ( var VariableDeclarationListNoIn ; Expressionopt ; Expressionopt ) Statement
|
229
|
+
# for ( LeftHandSideExpression in Expression ) Statement
|
230
|
+
# for ( var VariableDeclarationNoIn in Expression ) Statement
|
231
|
+
#
|
227
232
|
def for_statement(lex, context)
|
228
|
-
return nil unless lex.
|
233
|
+
return nil unless lex.eql_lit?(ECMA262::ID_FOR)
|
234
|
+
raise ParseError('unexpected token', lex) unless lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS)
|
229
235
|
lex.eval_lit{
|
230
236
|
# for(var i in a)
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
# for(i ; cond; exp)
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
237
|
+
if lex.eql_lit?(ECMA262::ID_VAR)
|
238
|
+
lex.eval_lit{
|
239
|
+
if v=var_decl(lex, context, :no_in => true) and lex.eql_lit?(ECMA262::ID_IN)
|
240
|
+
if e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
241
|
+
#10.5
|
242
|
+
context.var_env.record.create_mutable_binding(v[0], nil)
|
243
|
+
context.var_env.record.set_mutable_binding(v[0], :undefined, nil)
|
244
|
+
context.lex_env.record.create_mutable_binding(v[0], nil)
|
245
|
+
context.lex_env.record.set_mutable_binding(v[0], :undefined, nil)
|
246
|
+
ECMA262::StForInVar.new(context, v, e, s)
|
247
|
+
else
|
248
|
+
raise ParseError.new("unexpected token", lex)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
} or lex.eval_lit {
|
252
|
+
# for(var i ; cond ; exp)
|
253
|
+
if vl=var_decl_list(lex, context, :no_in =>true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {})||true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
254
|
+
e = nil if e == true
|
255
|
+
e2 = nil if e2 == true
|
256
|
+
#10.5
|
257
|
+
vl.each do |v|
|
258
|
+
dn = v[0]
|
259
|
+
context.var_env.record.create_mutable_binding(dn, nil)
|
260
|
+
context.var_env.record.set_mutable_binding(dn, :undefined, nil)
|
261
|
+
context.lex_env.record.create_mutable_binding(dn, nil)
|
262
|
+
context.lex_env.record.set_mutable_binding(dn, :undefined, nil)
|
263
|
+
end
|
264
|
+
ECMA262::StForVar.new(context, vl, e, e2, s)
|
265
|
+
else
|
266
|
+
if !s1
|
267
|
+
raise ParseError.new("no semicolon", lex)
|
268
|
+
elsif !s2
|
269
|
+
raise ParseError.new("no semicolon", lex)
|
270
|
+
else
|
271
|
+
raise ParseError.new("unexpected token", lex)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
}
|
275
|
+
else # => for(i in exp) / for(i ; cond; exp)
|
276
|
+
lex.eval_lit{
|
277
|
+
# for(i in exp)
|
278
|
+
if v=left_hand_side_exp(lex, context, {}) and lex.eql_lit?(ECMA262::ID_IN)
|
279
|
+
if e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
280
|
+
ECMA262::StForIn.new(v, e, s)
|
281
|
+
else
|
282
|
+
raise ParseError.new("unexpected token", lex)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
} or lex.eval_lit{
|
286
|
+
# for(i ; cond; exp)
|
287
|
+
if (v=exp(lex, context, :no_in => true) || true) and s1=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {}) || true) and s2=lex.eql_lit?(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
288
|
+
v = nil if v == true
|
289
|
+
e = nil if e == true
|
290
|
+
e2 = nil if e2 == true
|
291
|
+
ECMA262::StFor.new(v, e, e2, s)
|
292
|
+
else
|
293
|
+
raise ParseError.new("unexpected token", lex)
|
294
|
+
end
|
295
|
+
}
|
278
296
|
end
|
279
297
|
}
|
280
298
|
end
|
@@ -282,99 +300,99 @@ module Minjs
|
|
282
300
|
# 12.7
|
283
301
|
#
|
284
302
|
def continue_statement(lex, context)
|
285
|
-
return nil unless lex.
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
303
|
+
return nil unless lex.eql_lit?(ECMA262::ID_CONTINUE)
|
304
|
+
|
305
|
+
if semicolon(lex, context)
|
306
|
+
ECMA262::StContinue.new
|
307
|
+
elsif e=identifier(lex, context) and semicolon(lex, context)
|
308
|
+
ECMA262::StContinue.new(e)
|
309
|
+
else
|
310
|
+
if e
|
311
|
+
raise ParseError.new("no semicolon at end of continue statement", lex)
|
291
312
|
else
|
292
|
-
|
293
|
-
raise ParseError.new("no semicolon at end of continue statement", lex)
|
294
|
-
else
|
295
|
-
raise ParseError.new("bad continue statement", lex)
|
296
|
-
end
|
313
|
+
raise ParseError.new("unexpected token", lex)
|
297
314
|
end
|
298
|
-
|
315
|
+
end
|
299
316
|
end
|
300
317
|
#
|
301
318
|
# 12.8
|
302
319
|
#
|
303
320
|
def break_statement(lex, context)
|
304
|
-
return nil unless lex.
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
321
|
+
return nil unless lex.eql_lit?(ECMA262::ID_BREAK)
|
322
|
+
|
323
|
+
if semicolon(lex, context)
|
324
|
+
ECMA262::StBreak.new
|
325
|
+
elsif e=identifier(lex, context) and semicolon(lex, context)
|
326
|
+
ECMA262::StBreak.new(e)
|
327
|
+
else
|
328
|
+
if e
|
329
|
+
raise ParseError.new("no semicolon at end of break statement", lex)
|
310
330
|
else
|
311
|
-
|
312
|
-
raise ParseError.new("no semicolon at end of break statement", lex)
|
313
|
-
else
|
314
|
-
raise ParseError.new("bad break statement", lex)
|
315
|
-
end
|
331
|
+
raise ParseError.new("unexpected token", lex)
|
316
332
|
end
|
317
|
-
|
333
|
+
end
|
318
334
|
end
|
319
335
|
#
|
320
336
|
# 12.9
|
321
337
|
#
|
322
338
|
def return_statement(lex, context)
|
323
|
-
return nil unless lex.
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
}
|
339
|
+
return nil unless lex.eql_lit?(ECMA262::ID_RETURN)
|
340
|
+
|
341
|
+
if semicolon(lex, context)
|
342
|
+
ECMA262::StReturn.new
|
343
|
+
elsif e=exp(lex, context, {}) and semicolon(lex, context)
|
344
|
+
ECMA262::StReturn.new(e)
|
345
|
+
else
|
346
|
+
raise ParseError.new("unexpected token", lex)
|
347
|
+
end
|
333
348
|
end
|
334
349
|
#
|
335
350
|
# 12.10
|
336
351
|
#
|
337
352
|
def with_statement(lex, context)
|
338
|
-
return nil unless lex.
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
}
|
353
|
+
return nil unless lex.eql_lit?(ECMA262::ID_WITH)
|
354
|
+
|
355
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
356
|
+
ECMA262::StWith.new(context, e, s)
|
357
|
+
else
|
358
|
+
raise ParseError.new("unexpected token", lex)
|
359
|
+
end
|
346
360
|
end
|
347
361
|
#
|
348
362
|
# 12.11
|
349
363
|
#
|
350
364
|
def switch_statement(lex, context)
|
351
|
-
return nil unless lex.
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
}
|
365
|
+
return nil unless lex.eql_lit?(ECMA262::ID_SWITCH)
|
366
|
+
|
367
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and c = case_block(lex, context)
|
368
|
+
ECMA262::StSwitch.new(e, c)
|
369
|
+
else
|
370
|
+
raise ParseError.new("unexpected token", lex)
|
371
|
+
end
|
359
372
|
end
|
360
373
|
|
361
374
|
def case_block(lex, context)
|
362
|
-
return nil unless lex.
|
375
|
+
return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
|
363
376
|
_case_block = []
|
364
377
|
while true
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
378
|
+
if lex.eql_lit?(ECMA262::ID_CASE)
|
379
|
+
if e = exp(lex, context, {}) and lex.eql_lit?(ECMA262::PUNC_COLON)
|
380
|
+
sl = statement_list(lex, context)
|
381
|
+
_case_block.push [e, sl]
|
382
|
+
else
|
383
|
+
raise ParseError.new("unexpected token", lex)
|
384
|
+
end
|
385
|
+
elsif lex.eql_lit?(ECMA262::ID_DEFAULT)
|
386
|
+
if lex.eql_lit?(ECMA262::PUNC_COLON)
|
387
|
+
sl = statement_list(lex, context)
|
388
|
+
_case_block.push [nil, sl]
|
389
|
+
else
|
390
|
+
raise ParseError.new("unexpected token", lex)
|
391
|
+
end
|
392
|
+
elsif lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
|
393
|
+
break
|
394
|
+
end
|
376
395
|
end
|
377
|
-
return nil unless lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
|
378
396
|
_case_block
|
379
397
|
end
|
380
398
|
#
|
@@ -382,8 +400,12 @@ module Minjs
|
|
382
400
|
#
|
383
401
|
def labelled_statement(lex, context)
|
384
402
|
lex.eval_lit {
|
385
|
-
if i=identifier(lex, context) and lex.
|
386
|
-
|
403
|
+
if i=identifier(lex, context) and s1=lex.eql_lit?(ECMA262::PUNC_COLON)
|
404
|
+
if s=statement(lex, context)
|
405
|
+
ECMA262::StLabelled.new(i, s)
|
406
|
+
else
|
407
|
+
raise ParseError.new("unexpected token", lex)
|
408
|
+
end
|
387
409
|
else
|
388
410
|
nil
|
389
411
|
end
|
@@ -393,79 +415,69 @@ module Minjs
|
|
393
415
|
# 12.13
|
394
416
|
#
|
395
417
|
def throw_statement(lex, context)
|
396
|
-
return nil unless lex.
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
418
|
+
return nil unless lex.eql_lit?(ECMA262::ID_THROW)
|
419
|
+
|
420
|
+
if semicolon(lex, context)
|
421
|
+
raise ParseError.new("no line terminator here", lex)
|
422
|
+
elsif e=exp(lex, context, {}) and semi = semicolon(lex, context)
|
423
|
+
ECMA262::StThrow.new(e)
|
424
|
+
else
|
425
|
+
if e
|
426
|
+
raise ParseError.new("no semicolon at end of throw statement", lex)
|
402
427
|
else
|
403
|
-
|
404
|
-
raise ParseError.new("no semicolon at end of throw statement", lex)
|
405
|
-
else
|
406
|
-
raise ParseError.new("bad throw statement", lex)
|
407
|
-
end
|
428
|
+
raise ParseError.new("unexpected token", lex)
|
408
429
|
end
|
409
|
-
|
430
|
+
end
|
410
431
|
end
|
411
432
|
#
|
412
433
|
# 12.14
|
413
434
|
#
|
414
435
|
def try_statement(lex, context)
|
415
|
-
return nil unless lex.
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
#catch_context.lex_env = context.lex_env
|
423
|
-
#catch_context.var_env = context.var_env
|
424
|
-
catch_context = context
|
436
|
+
return nil unless lex.eql_lit?(ECMA262::ID_TRY)
|
437
|
+
#
|
438
|
+
# The catch argument context must be executable lexical environment.
|
439
|
+
# See compress_var
|
440
|
+
#
|
441
|
+
t = block(lex, context)
|
442
|
+
return nil unless t
|
425
443
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
lex.eval_lit{
|
430
|
-
c = try_catch(lex, catch_context)
|
431
|
-
break nil unless c
|
432
|
-
|
433
|
-
f = try_finally(lex, context)
|
434
|
-
ECMA262::StTry.new(context, t, c, f)
|
435
|
-
} || lex.eval_lit{
|
436
|
-
f = try_finally(lex, context)
|
437
|
-
break nil unless f
|
438
|
-
ECMA262::StTry.new(context, t, nil, f)
|
439
|
-
}
|
440
|
-
}
|
444
|
+
c = try_catch(lex, context)
|
445
|
+
f = try_finally(lex, context)
|
446
|
+
ECMA262::StTry.new(context, t, c, f)
|
441
447
|
end
|
442
|
-
|
443
|
-
|
448
|
+
# 12.14
|
449
|
+
#
|
450
|
+
# Catch :
|
451
|
+
# catch ( Identifier ) Block
|
452
|
+
#
|
453
|
+
# return [identigier, block]
|
454
|
+
#
|
455
|
+
def try_catch(lex, context)
|
456
|
+
return nil unless lex.eql_lit?(ECMA262::ID_CATCH)
|
444
457
|
|
445
|
-
if lex.
|
446
|
-
# catch_context.lex_env.record.create_mutable_binding(i, nil)
|
447
|
-
# catch_context.lex_env.record.set_mutable_binding(i, :undefined, nil, {:_parameter_list => true})
|
448
|
-
# catch_context.var_env.record.create_mutable_binding(i, nil)
|
449
|
-
# catch_context.var_env.record.set_mutable_binding(i, :undefined, nil, {:_parameter_list => true})
|
450
|
-
# catch_context.var_env.record.binding.each do|k, v|
|
451
|
-
# end
|
458
|
+
if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS) and i=identifier(lex, context) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS) and b=block(lex, context)
|
452
459
|
[i, b]
|
453
460
|
else
|
454
|
-
|
461
|
+
raise ParseError.new("unexpected token", lex)
|
455
462
|
end
|
456
463
|
end
|
457
464
|
|
458
465
|
def try_finally(lex, context)
|
459
|
-
return nil unless lex.
|
460
|
-
block(lex, context)
|
466
|
+
return nil unless lex.eql_lit?(ECMA262::ID_FINALLY)
|
467
|
+
b = block(lex, context)
|
468
|
+
raise ParseError.new("unexpected token", lex) if b.nil?
|
469
|
+
b
|
461
470
|
end
|
462
471
|
|
463
472
|
#
|
464
473
|
# 12.15
|
465
474
|
#
|
466
475
|
def debugger_statement(lex, context)
|
467
|
-
|
468
|
-
|
476
|
+
return nil unless lex.eql_lit?(ECMA262::ID_DEBUGGER)
|
477
|
+
if semicolon(lex, context)
|
478
|
+
ECMA262::StDebugger.new
|
479
|
+
else
|
480
|
+
raise ParseError.new("no semicolon at end of debugger statement", lex)
|
469
481
|
end
|
470
482
|
end
|
471
483
|
|