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