minjs 0.1.2
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 +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/exe/minjs +12 -0
- data/lib/minjs/compressor.rb +418 -0
- data/lib/minjs/ctype.rb +846 -0
- data/lib/minjs/ecma262/base.rb +128 -0
- data/lib/minjs/ecma262/env.rb +78 -0
- data/lib/minjs/ecma262/exp.rb +630 -0
- data/lib/minjs/ecma262/lit.rb +552 -0
- data/lib/minjs/ecma262/punc.rb +84 -0
- data/lib/minjs/ecma262/st.rb +808 -0
- data/lib/minjs/ecma262.rb +6 -0
- data/lib/minjs/exceptions.rb +15 -0
- data/lib/minjs/expression.rb +714 -0
- data/lib/minjs/func.rb +86 -0
- data/lib/minjs/lex.rb +745 -0
- data/lib/minjs/literal.rb +45 -0
- data/lib/minjs/minjs_compressor.rb +47 -0
- data/lib/minjs/program.rb +32 -0
- data/lib/minjs/statement.rb +438 -0
- data/lib/minjs/version.rb +3 -0
- data/lib/minjs.rb +16 -0
- data/minjs.gemspec +31 -0
- metadata +132 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module Minjs
|
2
|
+
module Literal
|
3
|
+
#
|
4
|
+
# 7.8
|
5
|
+
#
|
6
|
+
def literal(lex, context)
|
7
|
+
lex.eval_lit{
|
8
|
+
a = lex.fwd_lit(:hint => :regexp)
|
9
|
+
if a.kind_of?(ECMA262::ECMA262Numeric) || a.kind_of?(ECMA262::ECMA262String) || a.kind_of?(ECMA262::ECMA262RegExp)
|
10
|
+
a
|
11
|
+
else
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
} or lex.eval_lit{
|
15
|
+
null_literal(lex, context)
|
16
|
+
} or lex.eval_lit{
|
17
|
+
boolean_literal(lex, context)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# 7.8.1
|
23
|
+
#
|
24
|
+
def null_literal(lex, context)
|
25
|
+
if lex.match_lit(ECMA262::ID_NULL)
|
26
|
+
ECMA262::Null.get
|
27
|
+
else
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# 7.8.2
|
34
|
+
#
|
35
|
+
def boolean_literal(lex, context)
|
36
|
+
if lex.match_lit(ECMA262::ID_TRUE)
|
37
|
+
ECMA262::Boolean.new(:true)
|
38
|
+
elsif lex.match_lit(ECMA262::ID_FALSE)
|
39
|
+
ECMA262::Boolean.new(:false)
|
40
|
+
else
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
|
3
|
+
module Minjs
|
4
|
+
class MinjsCompressor < Tilt::Template
|
5
|
+
DEBUG = false
|
6
|
+
|
7
|
+
def self.engine_initialized?
|
8
|
+
defined?(::Minjs)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_engine
|
12
|
+
end
|
13
|
+
|
14
|
+
def prepare
|
15
|
+
end
|
16
|
+
|
17
|
+
def evaluate(context, locals, &block)
|
18
|
+
case context.content_type
|
19
|
+
when 'application/javascript'
|
20
|
+
if DEBUG
|
21
|
+
@@c = 0 unless defined?(@@c)
|
22
|
+
puts "start: compressing"
|
23
|
+
file = "tmp#{@@c}.js"
|
24
|
+
output = "tmp#{@@c}.js.min"
|
25
|
+
@@c += 1
|
26
|
+
puts "source: #{file}"
|
27
|
+
puts "output: #{output}"
|
28
|
+
tmp = open(file, "w")
|
29
|
+
tmp.write(data)
|
30
|
+
tmp.close
|
31
|
+
end
|
32
|
+
t = Minjs::Compressor.new.compress(data)
|
33
|
+
if DEBUG
|
34
|
+
tmp = open(output, "w")
|
35
|
+
tmp.write(t)
|
36
|
+
tmp.close
|
37
|
+
end
|
38
|
+
t
|
39
|
+
else
|
40
|
+
data
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Minjs
|
2
|
+
#
|
3
|
+
# 14 Program
|
4
|
+
#
|
5
|
+
module Program
|
6
|
+
def source_elements(lex, context, options = {})
|
7
|
+
prog = []
|
8
|
+
while !lex.eof?
|
9
|
+
t = source_element(lex, context)
|
10
|
+
if t
|
11
|
+
prog.push(t)
|
12
|
+
# elsif !options[:no_exception]
|
13
|
+
# lex.debug_lit
|
14
|
+
# raise 'error'
|
15
|
+
# return nil
|
16
|
+
else
|
17
|
+
break
|
18
|
+
end
|
19
|
+
end
|
20
|
+
ECMA262::Prog.new(context, prog)
|
21
|
+
end
|
22
|
+
|
23
|
+
def source_element(lex, context)
|
24
|
+
lex.eval_lit{
|
25
|
+
statement(lex, context)
|
26
|
+
} or lex.eval_lit{
|
27
|
+
func_declaration(lex, context)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,438 @@
|
|
1
|
+
module Minjs
|
2
|
+
#
|
3
|
+
# 12
|
4
|
+
#
|
5
|
+
module Statement
|
6
|
+
#
|
7
|
+
# check next literal is ';' or '}' or LT
|
8
|
+
#
|
9
|
+
def semicolon(lex, context)
|
10
|
+
lex.eval_lit{
|
11
|
+
a = lex.fwd_lit(:nolt => true)
|
12
|
+
if a == ECMA262::PUNC_SEMICOLON
|
13
|
+
a
|
14
|
+
elsif a == ECMA262::PUNC_RCURLYBRAC
|
15
|
+
lex.rewind_pos
|
16
|
+
a
|
17
|
+
elsif a == ECMA262::LIT_LINE_FEED
|
18
|
+
a
|
19
|
+
elsif a.lt?
|
20
|
+
a
|
21
|
+
else
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
#12
|
28
|
+
def statement(lex, context)
|
29
|
+
[:block,
|
30
|
+
:var_statement,
|
31
|
+
:exp_statement,
|
32
|
+
:if_statement,
|
33
|
+
:iteration_statement,
|
34
|
+
:continue_statement,
|
35
|
+
:break_statement,
|
36
|
+
:return_statement,
|
37
|
+
:with_statement,
|
38
|
+
:labelled_statement,
|
39
|
+
:switch_statement,
|
40
|
+
:throw_statement,
|
41
|
+
:try_statement,
|
42
|
+
:debugger_statement,
|
43
|
+
#
|
44
|
+
# function declaration in statement(block) is not permitted by ECMA262.
|
45
|
+
# however, almost all implementation permit it.
|
46
|
+
#
|
47
|
+
:func_declaration,
|
48
|
+
:empty_statement,
|
49
|
+
].each do |f|
|
50
|
+
puts "* checking #{f.to_s}" if @debug
|
51
|
+
t = lex.eval_lit {
|
52
|
+
__send__(f, lex, context)
|
53
|
+
}
|
54
|
+
return t if t
|
55
|
+
end
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
#
|
59
|
+
#12.1
|
60
|
+
# block
|
61
|
+
def block(lex, context)
|
62
|
+
pos0 = lex.pos
|
63
|
+
return nil unless lex.match_lit(ECMA262::PUNC_LCURLYBRAC)
|
64
|
+
if lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
|
65
|
+
return ECMA262::StBlock.new(ECMA262::StList.new([]))
|
66
|
+
end
|
67
|
+
lex.eval_lit {
|
68
|
+
if s = statement_list(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
|
69
|
+
ECMA262::StBlock.new(s)
|
70
|
+
else
|
71
|
+
if s
|
72
|
+
lex.debug_lit
|
73
|
+
puts lex.debug_code(pos0, lex.pos)
|
74
|
+
raise 'no "}" end of block'
|
75
|
+
else
|
76
|
+
lex.debug_lit
|
77
|
+
raise "bad block"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def statement_list(lex, context)
|
84
|
+
lex.eval_lit {
|
85
|
+
t = []
|
86
|
+
while !lex.eof?
|
87
|
+
if s = statement(lex, context)
|
88
|
+
t.push(s)
|
89
|
+
else
|
90
|
+
break
|
91
|
+
end
|
92
|
+
end
|
93
|
+
ECMA262::StList.new(t)
|
94
|
+
}
|
95
|
+
end
|
96
|
+
#
|
97
|
+
#12.2
|
98
|
+
# variable_statement
|
99
|
+
#
|
100
|
+
def var_statement(lex, context)
|
101
|
+
raise 'error' if context.nil?
|
102
|
+
return nil unless lex.match_lit(ECMA262::ID_VAR)
|
103
|
+
lex.eval_lit {
|
104
|
+
if vl = var_decl_list(lex, context, {}) and semicolon(lex, context)
|
105
|
+
#10.5
|
106
|
+
vl.each do |v|
|
107
|
+
dn = v[0]
|
108
|
+
context.var_env.record.create_mutable_binding(dn, nil)
|
109
|
+
context.var_env.record.set_mutable_binding(dn, :undefined, nil)
|
110
|
+
end
|
111
|
+
ECMA262::StVar.new(context, vl)
|
112
|
+
else
|
113
|
+
lex.debug_lit
|
114
|
+
raise Minjs::ParseError.new("var_statement")
|
115
|
+
end
|
116
|
+
}
|
117
|
+
end
|
118
|
+
|
119
|
+
def var_decl_list(lex, context, options)
|
120
|
+
lex.eval_lit {
|
121
|
+
a = var_decl(lex, context, options)
|
122
|
+
next nil if !a
|
123
|
+
|
124
|
+
if lex.match_lit(ECMA262::PUNC_COMMA) and b = var_decl_list(lex, context, options)
|
125
|
+
next [a] + b
|
126
|
+
else
|
127
|
+
next [a]
|
128
|
+
end
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
132
|
+
def var_decl(lex, context, options)
|
133
|
+
lex.eval_lit {
|
134
|
+
a = lex.fwd_lit
|
135
|
+
if !a
|
136
|
+
nil
|
137
|
+
elsif !a.kind_of?(ECMA262::IdentifierName)
|
138
|
+
nil
|
139
|
+
else
|
140
|
+
b = initialiser(lex, context, options)
|
141
|
+
[a, b]
|
142
|
+
end
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
def initialiser(lex, context, options)
|
147
|
+
if lex.match_lit(ECMA262::PUNC_LET) and a = assignment_exp(lex, context, options)
|
148
|
+
return a
|
149
|
+
end
|
150
|
+
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
#
|
154
|
+
#12.3
|
155
|
+
#
|
156
|
+
def empty_statement(lex, context)
|
157
|
+
lex.eval_lit{
|
158
|
+
a = lex.fwd_lit(:nolt => true)
|
159
|
+
if a == ECMA262::PUNC_SEMICOLON
|
160
|
+
ECMA262::StEmpty.new
|
161
|
+
elsif a == ECMA262::LIT_LINE_FEED
|
162
|
+
ECMA262::StEmpty.new
|
163
|
+
elsif a.lt?
|
164
|
+
ECMA262::StEmpty.new
|
165
|
+
else
|
166
|
+
nil
|
167
|
+
end
|
168
|
+
}
|
169
|
+
end
|
170
|
+
#
|
171
|
+
#12.4
|
172
|
+
#
|
173
|
+
def exp_statement(lex, context)
|
174
|
+
return false if lex.next_lit == ECMA262::PUNC_LCURLYBRAC
|
175
|
+
return false if lex.next_lit == ECMA262::ID_FUNCTION
|
176
|
+
lex.eval_lit{
|
177
|
+
if a=exp(lex, context, {}) and semicolon(lex, context)
|
178
|
+
ECMA262::StExp.new(a)
|
179
|
+
else
|
180
|
+
nil
|
181
|
+
end
|
182
|
+
}
|
183
|
+
end
|
184
|
+
#
|
185
|
+
#12.5
|
186
|
+
#
|
187
|
+
def if_statement(lex, context)
|
188
|
+
lex.eval_lit {
|
189
|
+
unless lex.match_lit(ECMA262::ID_IF) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and cond=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
190
|
+
next nil
|
191
|
+
end
|
192
|
+
if lex.match_lit(ECMA262::ID_ELSE) and e=statement(lex, context)
|
193
|
+
ECMA262::StIf.new(cond, s, e)
|
194
|
+
else
|
195
|
+
ECMA262::StIf.new(cond, s, nil)
|
196
|
+
end
|
197
|
+
}
|
198
|
+
end
|
199
|
+
#
|
200
|
+
# 12.6
|
201
|
+
#
|
202
|
+
def iteration_statement(lex, context)
|
203
|
+
for_statement(lex, context) or while_statement(lex, context) or do_while_statement(lex, context)
|
204
|
+
end
|
205
|
+
|
206
|
+
def while_statement(lex, context)
|
207
|
+
return nil unless lex.match_lit(ECMA262::ID_WHILE)
|
208
|
+
if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
209
|
+
ECMA262::StWhile.new(e, s)
|
210
|
+
else
|
211
|
+
lex.debug_lit
|
212
|
+
raise ParseError.new("while_statement")
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def do_while_statement(lex, context)
|
217
|
+
return nil unless lex.match_lit(ECMA262::ID_DO)
|
218
|
+
if s=statement(lex, context) and lex.match_lit(ECMA262::ID_WHILE) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and semicolon(lex, context)
|
219
|
+
ECMA262::StDoWhile.new(e, s)
|
220
|
+
else
|
221
|
+
lex.debug_lit
|
222
|
+
raise ParseError.new("do_while_statement")
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def for_statement(lex, context)
|
227
|
+
return nil unless lex.match_lit(ECMA262::ID_FOR)
|
228
|
+
lex.eval_lit{
|
229
|
+
# for(var i in a)
|
230
|
+
next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
|
231
|
+
if lex.match_lit(ECMA262::ID_VAR) and v=var_decl(lex, context, :no_in => true) and lex.match_lit(ECMA262::ID_IN) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
232
|
+
#10.5
|
233
|
+
context.var_env.record.create_mutable_binding(v[0], nil)
|
234
|
+
context.var_env.record.set_mutable_binding(v[0], :undefined, nil)
|
235
|
+
ECMA262::StForInVar.new(context, v, e, s)
|
236
|
+
else
|
237
|
+
nil
|
238
|
+
end
|
239
|
+
} or lex.eval_lit {
|
240
|
+
# for(var i ; cond ; exp)
|
241
|
+
next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
|
242
|
+
if lex.match_lit(ECMA262::ID_VAR) and vl=var_decl_list(lex, context, :no_in =>true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
243
|
+
e = ECMA262::ExpEmpty.new if e == true
|
244
|
+
e2 = ECMA262::ExpEmpty.new if e2 == true
|
245
|
+
#10.5
|
246
|
+
vl.each do |v|
|
247
|
+
dn = v[0]
|
248
|
+
context.var_env.record.create_mutable_binding(dn, nil)
|
249
|
+
context.var_env.record.set_mutable_binding(dn, :undefined, nil)
|
250
|
+
end
|
251
|
+
ECMA262::StForVar.new(context, vl, e, e2, s)
|
252
|
+
else
|
253
|
+
nil
|
254
|
+
end
|
255
|
+
} or lex.eval_lit{
|
256
|
+
# for(i in exp)
|
257
|
+
next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
|
258
|
+
if v=left_hand_side_exp(lex, context, {}) and lex.match_lit(ECMA262::ID_IN) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
259
|
+
ECMA262::StForIn.new(v, e, s)
|
260
|
+
else
|
261
|
+
nil
|
262
|
+
end
|
263
|
+
} or lex.eval_lit{
|
264
|
+
# for(i ; cond; exp)
|
265
|
+
next nil unless lex.match_lit(ECMA262::PUNC_LPARENTHESIS)
|
266
|
+
if (v=exp(lex, context, :no_in => true) || true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e=exp(lex, context, {}) || true) and lex.match_lit(ECMA262::PUNC_SEMICOLON) and (e2=exp(lex, context, {})||true) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
267
|
+
v = ECMA262::ExpEmpty.new if v == true
|
268
|
+
e = ECMA262::ExpEmpty.new if e == true
|
269
|
+
e2 = ECMA262::ExpEmpty.new if e2 == true
|
270
|
+
ECMA262::StFor.new(v, e, e2, s)
|
271
|
+
else
|
272
|
+
nil
|
273
|
+
end
|
274
|
+
}
|
275
|
+
end
|
276
|
+
#
|
277
|
+
# 12.7
|
278
|
+
#
|
279
|
+
def continue_statement(lex, context)
|
280
|
+
return nil unless lex.match_lit(ECMA262::ID_CONTINUE)
|
281
|
+
lex.eval_lit {
|
282
|
+
if semicolon(lex, context)
|
283
|
+
ECMA262::StContinue.new
|
284
|
+
elsif e=exp(lex, context, {}) and semicolon(lex, context)
|
285
|
+
ECMA262::StContinue.new(e)
|
286
|
+
end
|
287
|
+
}
|
288
|
+
end
|
289
|
+
#
|
290
|
+
# 12.8
|
291
|
+
#
|
292
|
+
def break_statement(lex, context)
|
293
|
+
return nil unless lex.match_lit(ECMA262::ID_BREAK)
|
294
|
+
lex.eval_lit {
|
295
|
+
if semicolon(lex, context)
|
296
|
+
ECMA262::StBreak.new
|
297
|
+
elsif e=exp(lex, context, {}) and semicolon(lex, context)
|
298
|
+
ECMA262::StBreak.new(e)
|
299
|
+
end
|
300
|
+
}
|
301
|
+
end
|
302
|
+
#
|
303
|
+
# 12.9
|
304
|
+
#
|
305
|
+
def return_statement(lex, context)
|
306
|
+
return nil unless lex.match_lit(ECMA262::ID_RETURN)
|
307
|
+
lex.eval_lit {
|
308
|
+
if semicolon(lex, context)
|
309
|
+
ECMA262::StReturn.new
|
310
|
+
elsif e=exp(lex, context, {}) and semicolon(lex, context)
|
311
|
+
ECMA262::StReturn.new(e)
|
312
|
+
else
|
313
|
+
nil
|
314
|
+
end
|
315
|
+
}
|
316
|
+
end
|
317
|
+
#
|
318
|
+
# 12.10
|
319
|
+
#
|
320
|
+
def with_statement(lex, context)
|
321
|
+
return nil unless lex.match_lit(ECMA262::ID_WITH)
|
322
|
+
lex.eval_lit {
|
323
|
+
if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and s=statement(lex, context)
|
324
|
+
ECMA262::StWith.new(e, s)
|
325
|
+
else
|
326
|
+
lex.debug_lit
|
327
|
+
raise ParseError.new("switch_statement")
|
328
|
+
end
|
329
|
+
}
|
330
|
+
end
|
331
|
+
#
|
332
|
+
# 12.11
|
333
|
+
#
|
334
|
+
def switch_statement(lex, context)
|
335
|
+
return nil unless lex.match_lit(ECMA262::ID_SWITCH)
|
336
|
+
lex.eval_lit {
|
337
|
+
if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and c = case_block(lex, context)
|
338
|
+
ECMA262::StSwitch.new(e, c)
|
339
|
+
else
|
340
|
+
lex.debug_lit
|
341
|
+
raise ParseError.new("switch_statement")
|
342
|
+
end
|
343
|
+
}
|
344
|
+
end
|
345
|
+
|
346
|
+
def case_block(lex, context)
|
347
|
+
return nil unless lex.match_lit(ECMA262::PUNC_LCURLYBRAC)
|
348
|
+
_case_block = []
|
349
|
+
while true
|
350
|
+
t = lex.eval_lit{
|
351
|
+
break unless lex.match_lit(ECMA262::ID_CASE) and e=exp(lex, context, {}) and lex.match_lit(ECMA262::PUNC_COLON)
|
352
|
+
sl = statement_list(lex, context)
|
353
|
+
[e, sl]
|
354
|
+
} || lex.eval_lit{
|
355
|
+
break unless lex.match_lit(ECMA262::ID_DEFAULT) and lex.match_lit(ECMA262::PUNC_COLON)
|
356
|
+
sl = statement_list(lex, context)
|
357
|
+
[nil, sl]
|
358
|
+
}
|
359
|
+
break if t.nil?
|
360
|
+
_case_block.push(t)
|
361
|
+
end
|
362
|
+
return nil unless lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
|
363
|
+
_case_block
|
364
|
+
end
|
365
|
+
#
|
366
|
+
# 12.12
|
367
|
+
#
|
368
|
+
def labelled_statement(lex, context)
|
369
|
+
lex.eval_lit {
|
370
|
+
if i=identifier(lex, context) and lex.match_lit(ECMA262::PUNC_COLON) and s=statement(lex, context)
|
371
|
+
ECMA262::StLabelled.new(i, s)
|
372
|
+
else
|
373
|
+
nil
|
374
|
+
end
|
375
|
+
}
|
376
|
+
end
|
377
|
+
#
|
378
|
+
# 12.13
|
379
|
+
#
|
380
|
+
def throw_statement(lex, context)
|
381
|
+
return nil unless lex.match_lit(ECMA262::ID_THROW)
|
382
|
+
lex.eval_lit{
|
383
|
+
if e=exp(lex, context, {}) and semicolon(lex, context)
|
384
|
+
ECMA262::StThrow.new(e)
|
385
|
+
else
|
386
|
+
lex.debug_lit
|
387
|
+
raise ParseError.new("throw_statement")
|
388
|
+
end
|
389
|
+
}
|
390
|
+
end
|
391
|
+
#
|
392
|
+
# 12.14
|
393
|
+
#
|
394
|
+
def try_statement(lex, context)
|
395
|
+
return nil unless lex.match_lit(ECMA262::ID_TRY)
|
396
|
+
lex.eval_lit {
|
397
|
+
t = block(lex, context)
|
398
|
+
break nil unless t
|
399
|
+
|
400
|
+
lex.eval_lit{
|
401
|
+
c = try_catch(lex, context)
|
402
|
+
break nil unless c
|
403
|
+
|
404
|
+
f = try_finally(lex, context)
|
405
|
+
ECMA262::StTry.new(t, c, f)
|
406
|
+
} || lex.eval_lit{
|
407
|
+
f = try_finally(lex, context)
|
408
|
+
break nil unless f
|
409
|
+
ECMA262::StTry.new(t, nil, f)
|
410
|
+
}
|
411
|
+
}
|
412
|
+
end
|
413
|
+
def try_catch(lex, context)
|
414
|
+
return nil unless lex.match_lit(ECMA262::ID_CATCH)
|
415
|
+
if lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and i=identifier(lex, context) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and b=block(lex, context)
|
416
|
+
[i, b]
|
417
|
+
else
|
418
|
+
nil
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
def try_finally(lex, context)
|
423
|
+
return nil unless lex.match_lit(ECMA262::ID_FINALLY)
|
424
|
+
block(lex, context)
|
425
|
+
end
|
426
|
+
|
427
|
+
#
|
428
|
+
# 12.15
|
429
|
+
#
|
430
|
+
def debugger_statement(lex, context)
|
431
|
+
if lex.match_lit(ECMA262::ID_DEBUGGER) and semicolon(lex, context)
|
432
|
+
t = ECMA262::StDebugger.new
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
data/lib/minjs.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "minjs/version"
|
2
|
+
require "minjs/expression"
|
3
|
+
require "minjs/func"
|
4
|
+
require "minjs/lex"
|
5
|
+
require "minjs/literal"
|
6
|
+
require "minjs/program"
|
7
|
+
require "minjs/statement"
|
8
|
+
require "minjs/compressor"
|
9
|
+
require "minjs/ecma262"
|
10
|
+
require "minjs/minjs_compressor"
|
11
|
+
require "minjs/ctype"
|
12
|
+
require "minjs/exceptions"
|
13
|
+
|
14
|
+
module Minjs
|
15
|
+
# Your code goes here...
|
16
|
+
end
|
data/minjs.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'minjs/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "minjs"
|
8
|
+
spec.version = Minjs::VERSION
|
9
|
+
spec.authors = ["Issei Numata"]
|
10
|
+
spec.email = ["issei@heart-s.com"]
|
11
|
+
|
12
|
+
# if spec.respond_to?(:metadata)
|
13
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
|
14
|
+
# end
|
15
|
+
|
16
|
+
spec.summary = %q{JavaScript compressor in pure Ruby}
|
17
|
+
spec.description = %q{Minjs is a JavaScript compressor written in pure Ruby}
|
18
|
+
spec.homepage = "https://github.com/i10a/minjs"
|
19
|
+
spec.license = "MIT"
|
20
|
+
|
21
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
|
+
spec.bindir = "exe"
|
23
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.8"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
#spec.add_dependency 'sprockets', '~> 3.0.0'
|
30
|
+
spec.add_dependency 'tilt', '~> 1.4.0'
|
31
|
+
end
|