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.
@@ -33,7 +33,7 @@ module Minjs
33
33
  tmp.close
34
34
  end
35
35
  #TODO
36
- t = Minjs::Compressor.new(:logger => logger).compress(data).to_js
36
+ t = Minjs::Compressor::Compressor.new(:logger => logger).compress(data).to_js
37
37
  if logger.info?
38
38
  tmp = open(output, "w")
39
39
  tmp.write(t)
@@ -1,3 +1,4 @@
1
1
  module Minjs
2
- VERSION = "0.3.0"
2
+ # Version of minjs
3
+ VERSION = "0.4.0"
3
4
  end
@@ -26,6 +26,6 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "bundler", "~> 1.8"
27
27
  spec.add_development_dependency "rake", "~> 10.0"
28
28
  spec.add_development_dependency "rspec"
29
- #spec.add_dependency 'sprockets', '~> 3.0.0'
29
+ spec.add_development_dependency "yard"
30
30
  spec.add_dependency 'tilt', '~> 1.4.0'
31
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Issei Numata
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-06-05 00:00:00.000000000 Z
11
+ date: 2015-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: tilt
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -87,21 +101,23 @@ files:
87
101
  - exe/minjs
88
102
  - lib/minjs.rb
89
103
  - lib/minjs/compressor.rb
104
+ - lib/minjs/compressor/compressor.rb
90
105
  - lib/minjs/ctype.rb
91
106
  - lib/minjs/ecma262.rb
92
107
  - lib/minjs/ecma262/base.rb
93
108
  - lib/minjs/ecma262/env.rb
94
- - lib/minjs/ecma262/exp.rb
95
- - lib/minjs/ecma262/lit.rb
96
- - lib/minjs/ecma262/punc.rb
97
- - lib/minjs/ecma262/st.rb
98
- - lib/minjs/exceptions.rb
99
- - lib/minjs/expression.rb
100
- - lib/minjs/func.rb
109
+ - lib/minjs/ecma262/expression.rb
110
+ - lib/minjs/ecma262/literal.rb
111
+ - lib/minjs/ecma262/punctuator.rb
112
+ - lib/minjs/ecma262/statement.rb
101
113
  - lib/minjs/lex.rb
114
+ - lib/minjs/lex/exceptions.rb
115
+ - lib/minjs/lex/expression.rb
116
+ - lib/minjs/lex/function.rb
117
+ - lib/minjs/lex/parser.rb
118
+ - lib/minjs/lex/program.rb
119
+ - lib/minjs/lex/statement.rb
102
120
  - lib/minjs/minjs_compressor.rb
103
- - lib/minjs/program.rb
104
- - lib/minjs/statement.rb
105
121
  - lib/minjs/version.rb
106
122
  - minjs.gemspec
107
123
  homepage: https://github.com/i10a/minjs
@@ -129,3 +145,4 @@ signing_key:
129
145
  specification_version: 4
130
146
  summary: JavaScript compressor in pure Ruby
131
147
  test_files: []
148
+ has_rdoc:
@@ -1,92 +0,0 @@
1
- module Minjs
2
- module ECMA262
3
- class Punctuator < Literal
4
- attr_reader :val
5
-
6
- @@sym = {}
7
- def initialize(val)
8
- @val = val.to_sym
9
- end
10
-
11
- def self.get(val)
12
- @@sym[val] ||= self.new(val)
13
- end
14
-
15
- def self.punctuator?(val)
16
- val = val.to_s
17
- if val == ">>>=" ||
18
- val == "===" || val == "!==" || val == ">>>" || val == "<<=" || val == ">>=" ||
19
- val == ">>" || val == "<=" || val == ">=" || val == "== " || val == "!=" ||
20
- val == "++" || val == "--" || val == "<<" || val == ">>" || val == "&&" ||
21
- val == "||" || val == "+=" || val == "-=" || val == "*=" || val == "%=" ||
22
- val == "&=" || val == "|=" || val == "^=" || val == "/="
23
- val.match(/\A[\{\}\(\)\[\]\.\;\,\<\>\+\-\*\%\&\|\^\!\~\?\:\=\/]/)
24
- true
25
- else
26
- false
27
- end
28
- end
29
-
30
- def to_s
31
- val.to_s
32
- end
33
-
34
- def to_js
35
- val.to_s
36
- end
37
-
38
- def ==(obj)
39
- self.class == obj.class and self.val == obj.val
40
- end
41
- end
42
- PUNC_CONDIF = Punctuator.get('?')
43
- #PUNC_CONDELSE = Punctuator.get(':')
44
- PUNC_LET = Punctuator.get('=')
45
- PUNC_DIVLET = Punctuator.get('/=')
46
- PUNC_MULLET = Punctuator.get('*=')
47
- PUNC_MODLET = Punctuator.get('%=')
48
- PUNC_ADDLET = Punctuator.get('+=')
49
- PUNC_SUBLET = Punctuator.get('-=')
50
- PUNC_LSHIFTLET = Punctuator.get('<<=')
51
- PUNC_RSHIFTLET = Punctuator.get('>>=')
52
- PUNC_URSHIFTLET = Punctuator.get('>>>=')
53
- PUNC_ANDLET = Punctuator.get('&=')
54
- PUNC_XORLET = Punctuator.get('^=')
55
- PUNC_ORLET = Punctuator.get('|=')
56
- PUNC_LOR = Punctuator.get('||')
57
- PUNC_LAND = Punctuator.get('&&')
58
- PUNC_OR = Punctuator.get('|')
59
- PUNC_XOR = Punctuator.get('^')
60
- PUNC_AND = Punctuator.get('&')
61
- PUNC_EQ = Punctuator.get('==')
62
- PUNC_NEQ = Punctuator.get('!=')
63
- PUNC_SEQ = Punctuator.get('===')
64
- PUNC_SNEQ = Punctuator.get('!==')
65
- PUNC_LT = Punctuator.get('<')
66
- PUNC_GT = Punctuator.get('>')
67
- PUNC_LTEQ = Punctuator.get('<=')
68
- PUNC_GTEQ = Punctuator.get('>=')
69
- PUNC_LSHIFT = Punctuator.get('<<')
70
- PUNC_RSHIFT = Punctuator.get('>>')
71
- PUNC_URSHIFT = Punctuator.get('>>>')
72
- PUNC_ADD = Punctuator.get('+')
73
- PUNC_SUB = Punctuator.get('-')
74
- PUNC_MUL = Punctuator.get('*')
75
- PUNC_DIV = Punctuator.get('/')
76
- PUNC_MOD = Punctuator.get('%')
77
- PUNC_INC = Punctuator.get('++')
78
- PUNC_DEC = Punctuator.get('--')
79
- PUNC_NOT = Punctuator.get('~')
80
- PUNC_LNOT = Punctuator.get('!')
81
- PUNC_LPARENTHESIS = Punctuator.get('(')
82
- PUNC_RPARENTHESIS = Punctuator.get(')')
83
- PUNC_LSQBRAC = Punctuator.get('[')
84
- PUNC_RSQBRAC = Punctuator.get(']')
85
- PUNC_LCURLYBRAC = Punctuator.get('{')
86
- PUNC_RCURLYBRAC = Punctuator.get('}')
87
- PUNC_COMMA = Punctuator.get(',')
88
- PUNC_COLON = Punctuator.get(':') #= same as PUNC_CONDELSE
89
- PUNC_SEMICOLON = Punctuator.get(';')
90
- PUNC_PERIOD = Punctuator.get('.')
91
- end
92
- end
@@ -1,833 +0,0 @@
1
- # coding: utf-8
2
- module Minjs
3
- module Exp
4
- #
5
- # Primary Expressions
6
- # 11.1
7
- #
8
- def primary_exp(lex, context, options)
9
- @logger.debug "*** primary_exp"
10
-
11
- if lex.eql_lit?(ECMA262::ID_THIS)
12
- @logger.debug "*** primary_exp => this"
13
- return ECMA262::This.new(context)
14
- end
15
- # (exp)
16
- if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS)
17
- if a=exp(lex, context, options) and lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS)
18
- @logger.debug "*** primary_exp => ()"
19
- return ECMA262::ExpParen.new(a)
20
- else
21
- raise ParseError.new("no `)' at end of expression", lex)
22
- end
23
- end
24
-
25
- t = identifier(lex, context) ||
26
- literal(lex, context) ||
27
- array_literal(lex, context, options) ||
28
- object_literal(lex, context, options)
29
-
30
- @logger.debug {
31
- "*** primary_exp => #{t ? t.to_js : t}"
32
- }
33
- t
34
- end
35
-
36
- # 7.8
37
- # 7.8.1
38
- # 7.8.2
39
- #
40
- # Literal ::
41
- # NullLiteral
42
- # BooleanLiteral
43
- # NumericLiteral
44
- # StringLiteral
45
- # RegularExpressionLiteral
46
- #
47
- def literal(lex, context)
48
- a = lex.peek_lit(:regexp)
49
- if a.kind_of? ECMA262::ECMA262Numeric or a.kind_of? ECMA262::ECMA262String or a.kind_of? ECMA262::ECMA262RegExp
50
- lex.fwd_after_peek
51
- a
52
- elsif a.eql? ECMA262::ID_NULL
53
- lex.fwd_after_peek
54
- ECMA262::Null.get
55
- elsif a.eql? ECMA262::ID_TRUE
56
- lex.fwd_after_peek
57
- ECMA262::Boolean.get(:true)
58
- elsif a.eql? ECMA262::ID_FALSE
59
- lex.fwd_after_peek
60
- ECMA262::Boolean.get(:false)
61
- else
62
- nil
63
- end
64
- end
65
-
66
- #
67
- # 11.1.2
68
- #
69
- def identifier(lex, context)
70
- a = lex.peek_lit(:regexp)
71
- if a.kind_of? ECMA262::IdentifierName and !a.reserved?
72
- lex.fwd_after_peek
73
- a.context = context
74
- a
75
- else
76
- nil
77
- end
78
- end
79
- #
80
- # 11.1.4
81
- #
82
- def array_literal(lex, context, options)
83
- return nil unless lex.eql_lit?(ECMA262::PUNC_LSQBRAC)
84
- t = []
85
- while true
86
- if lex.eql_lit?(ECMA262::PUNC_COMMA)
87
- t.push(nil)
88
- elsif lex.eql_lit?(ECMA262::PUNC_RSQBRAC)
89
- break
90
- elsif a = assignment_exp(lex, context, {})
91
- t.push(a)
92
- lex.eql_lit?(ECMA262::PUNC_COMMA)
93
- else
94
- raise ParseError.new("no `]' end of array", lex)
95
- end
96
- end
97
- ECMA262::ECMA262Array.new(t)
98
- end
99
- #
100
- # 11.1.5
101
- #
102
- # ObjectLiteral :
103
- # { }
104
- # { PropertyNameAndValueList }
105
- # { PropertyNameAndValueList , }
106
- #
107
- def object_literal(lex, context, options)
108
- return nil unless lex.eql_lit?(ECMA262::PUNC_LCURLYBRAC)
109
- #{}
110
- if lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
111
- ECMA262::ECMA262Object.new([])
112
- else
113
- ECMA262::ECMA262Object.new(property_name_and_value_list(lex, context, options))
114
- end
115
- end
116
-
117
- # 11.1.5
118
- #
119
- # PropertyNameAndValueList :
120
- # PropertyAssignment
121
- # PropertyNameAndValueList , PropertyAssignment
122
- #
123
- # PropertyAssignment :
124
- # PropertyName : AssignmentExpression
125
- # get PropertyName ( ) { FunctionBody }
126
- # set PropertyName ( PropertySetParameterList ) { FunctionBody }
127
- #
128
- #
129
- # name: exp
130
- # get name(){funcbody}
131
- # set name(args){funcbody}
132
- #
133
- def property_name_and_value_list(lex, context, options)
134
- h = []
135
- while !lex.eof?
136
- #get
137
- if lex.match_lit? ECMA262::ID_GET
138
- # {get : val}
139
- if lex.eql_lit? ECMA262::PUNC_COLON
140
- b = assignment_exp(lex, context, options)
141
- h.push([ECMA262::ID_GET, b])
142
- # {get name(){}}
143
- else
144
- new_context = ECMA262::Context.new
145
- new_context.lex_env = context.lex_env.new_declarative_env()
146
- new_context.var_env = context.var_env.new_declarative_env()
147
- if(a = property_name(lex, context) and
148
- lex.eql_lit? ECMA262::PUNC_LPARENTHESIS and
149
- lex.eql_lit? ECMA262::PUNC_RPARENTHESIS and
150
- lex.eql_lit? ECMA262::PUNC_LCURLYBRAC and
151
- b = func_body(lex, new_context) and
152
- lex.eql_lit? ECMA262::PUNC_RCURLYBRAC)
153
- h.push([a, ECMA262::StFunc.new(new_context, ECMA262::ID_GET, [], b, :getter => true)])
154
- else
155
- raise ParseError.new("unexpceted token", lex)
156
- end
157
- end
158
- #set
159
- elsif lex.match_lit?(ECMA262::ID_SET)
160
- # {set : val}
161
- if lex.eql_lit? ECMA262::PUNC_COLON
162
- b = assignment_exp(lex, context, options)
163
- h.push([ECMA262::ID_SET, b])
164
- # {set name(arg){}}
165
- else
166
- new_context = ECMA262::Context.new
167
- new_context.lex_env = context.lex_env.new_declarative_env()
168
- new_context.var_env = context.var_env.new_declarative_env()
169
- if(a = property_name(lex, context) and
170
- lex.eql_lit? ECMA262::PUNC_LPARENTHESIS and
171
- arg = property_set_parameter_list(lex, new_context) and
172
- lex.eql_lit? ECMA262::PUNC_RPARENTHESIS and
173
- lex.eql_lit? ECMA262::PUNC_LCURLYBRAC and
174
- b = func_body(lex, new_context) and
175
- lex.eql_lit? ECMA262::PUNC_RCURLYBRAC)
176
- h.push([a, ECMA262::StFunc.new(new_context, ECMA262::ID_SET, arg, b, :setter => true)])
177
- else
178
- raise ParseError.new("unexpceted token", lex)
179
- end
180
- end
181
- #property
182
- elsif(a = property_name(lex, context) and
183
- lex.eql_lit? ECMA262::PUNC_COLON and
184
- b = assignment_exp(lex, context, options))
185
- h.push([a, b])
186
- else
187
- raise ParseError.new("unexpceted token", lex)
188
- end
189
-
190
- if lex.eql_lit?(ECMA262::PUNC_COMMA)
191
- break if lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
192
- elsif lex.eql_lit?(ECMA262::PUNC_RCURLYBRAC)
193
- break
194
- else
195
- raise ParseError.new("no `}' end of object", lex)
196
- end
197
- end
198
- h
199
- end
200
-
201
- # 11.1.5
202
- #
203
- # PropertyName :
204
- # IdentifierName
205
- # StringLiteral
206
- # NumericLiteral
207
- #
208
- def property_name(lex, context)
209
- a = lex.fwd_lit(nil)
210
- if a.kind_of?(ECMA262::ECMA262String)
211
- a
212
- elsif a.kind_of?(ECMA262::IdentifierName)
213
- ECMA262::ECMA262String.new(a.to_js)
214
- elsif a.kind_of?(ECMA262::ECMA262Numeric)
215
- a
216
- elsif a.eql?(ECMA262::PUNC_COLON)
217
- nil
218
- else
219
- raise ParseError.new("unexpceted token", lex)
220
- end
221
- end
222
-
223
- # 11.1.5
224
- #
225
- # PropertySetParameterList :
226
- # Identifier
227
- #
228
- def property_set_parameter_list(lex, context)
229
- argName = identifier(lex, context)
230
- context.var_env.record.create_mutable_binding(argName, nil)
231
- context.var_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true})
232
- context.lex_env.record.create_mutable_binding(argName, nil)
233
- context.lex_env.record.set_mutable_binding(argName, :undefined, nil, {:_parameter_list => true})
234
- [argName]
235
- end
236
-
237
- # 11.2
238
- #
239
- # LeftHandSideExpression :
240
- # NewExpression
241
- # CallExpression
242
- #
243
- def left_hand_side_exp(lex, context, options)
244
- @logger.debug "*** left_hand_side_exp"
245
-
246
- t = call_exp(lex, context, options) || new_exp(lex, context, options)
247
- #t = new_exp(lex, context, options) || call_exp(lex, context, options)
248
-
249
- @logger.debug{
250
- "*** left_hand_side_exp => #{t ? t.to_js: t}"
251
- }
252
- t
253
- end
254
-
255
- # 11.2
256
- #
257
- # NewExpression :
258
- # MemberExpression
259
- # new NewExpression
260
- #
261
- # NOTE:
262
- #
263
- # The NewExpression only matchs no-arguments-constructor because
264
- # member expression also has "new MemberExpression Arguments"
265
- #
266
- # For example,
267
- #
268
- # 1. new A;
269
- # 2. new A[B];
270
- # 3. new A.B;
271
- # 4. new A.B();
272
- # 5. new new B();
273
- # 6. A();
274
- #
275
- # 1 to 3 are NewExpression.
276
- # 4 is MemberExpression.
277
- # 5 's first new is NewExpression and second one is MemberExpression.
278
- # 6 is CallExpression
279
- #
280
- # NewExpression can be rewritten as follows:
281
- #
282
- # NewExpression:
283
- # MemberExpression [lookahead ∉ {(}]
284
- # new NewExpression [lookahead ∉ {(}]
285
- #
286
- def new_exp(lex, context, options)
287
- lex.eval_lit {
288
- if lex.eql_lit?(ECMA262::ID_NEW)
289
- if a = new_exp(lex, context, options)
290
- if lex.eql_lit? ECMA262::PUNC_LPARENTHESIS
291
- # minjs evaluate CallExpression first, so
292
- # program never falls to here.
293
- next nil # this is not NewExpression, may be MemberExpression.
294
- end
295
- #puts "new_exp> #{a.to_js}"
296
- ECMA262::ExpNew.new(a, nil)
297
- else
298
- # minjs evaluate CallExpression first, so
299
- # raise exception when program falls to here.
300
- raise ParseError.new("unexpceted token", lex)
301
- #nil
302
- end
303
- end
304
- } || member_exp(lex, context, options)
305
- # minjs evaluate CallExpression first, so
306
- # there is no reason to check parenthesis.
307
- #
308
- # lex.eval_lit{
309
- # t = member_exp(lex, context, options)
310
- # if lex.eql_lit? ECMA262::PUNC_LPARENTHESIS
311
- # break nil
312
- # end
313
- # t
314
- # }
315
- end
316
- # 11.2
317
- #
318
- # CallExpression :
319
- # MemberExpression Arguments
320
- # CallExpression Arguments
321
- # CallExpression [ Expression ]
322
- # CallExpression . IdentifierName
323
- #
324
- def call_exp(lex, context, options)
325
- if a = member_exp(lex, context, options)
326
- if b = arguments(lex, context, options)
327
- t = ECMA262::ExpCall.new(a, b)
328
- # if b is nil, this may be MemberExpression of NewExpression
329
- else
330
- return a
331
- end
332
- else
333
- return nil
334
- end
335
-
336
- while true
337
- if b = arguments(lex, context, options)
338
- t = ECMA262::ExpCall.new(t, b)
339
- elsif lex.eql_lit?(ECMA262::PUNC_LSQBRAC)
340
- if b=exp(lex, context, options) and lex.eql_lit?(ECMA262::PUNC_RSQBRAC)
341
- t = ECMA262::ExpPropBrac.new(t, b)
342
- else
343
- raise ParseError.new("unexpceted token", lex)
344
- end
345
- elsif lex.eql_lit?(ECMA262::PUNC_PERIOD)
346
- if (b=lex.fwd_lit(nil)).kind_of?(ECMA262::IdentifierName)
347
- t = ECMA262::ExpProp.new(t, b)
348
- else
349
- raise ParseError.new("unexpceted token", lex)
350
- end
351
- else
352
- break
353
- end
354
- end
355
- t
356
- end
357
-
358
- # 11.2
359
- #
360
- # MemberExpression :
361
- # PrimaryExpression
362
- # FunctionExpression
363
- # MemberExpression [ Expression ]
364
- # MemberExpression . IdentifierName
365
- # new MemberExpression Arguments
366
- #
367
- def member_exp(lex, context, options)
368
- t = lex.eval_lit{
369
- if lex.eql_lit? ECMA262::ID_NEW
370
- if a = member_exp(lex, context, options)
371
- b = arguments(lex, context, options)
372
- # if b is nil, this may be NewExpression
373
- if b
374
- s = b.collect{|x| x.to_js}.join(',');
375
- #puts "member_exp> [new] #{a.to_js} (#{s})"
376
- next ECMA262::ExpNew.new(a, b)
377
- else
378
- return nil
379
- end
380
- else
381
- return nil
382
- end
383
- end
384
- } || primary_exp(lex, context, options) || func_exp(lex, context)
385
- return nil if t.nil?
386
-
387
- while true
388
- if lex.eql_lit?(ECMA262::PUNC_LSQBRAC)
389
- if b=exp(lex, context, options) and lex.eql_lit?(ECMA262::PUNC_RSQBRAC)
390
- t = ECMA262::ExpPropBrac.new(t, b)
391
- else
392
- raise ParseError.new("unexpceted token", lex)
393
- end
394
- elsif lex.eql_lit?(ECMA262::PUNC_PERIOD)
395
- if (b=lex.fwd_lit(nil)).kind_of?(ECMA262::IdentifierName)
396
- t = ECMA262::ExpProp.new(t, b)
397
- else
398
- raise ParseError.new("unexpceted token", lex)
399
- end
400
- else
401
- break
402
- end
403
- end
404
- t
405
- end
406
- # 11.2
407
- # Arguments :
408
- # ( )
409
- # ( ArgumentList )
410
- #
411
- def arguments(lex, context, options)
412
- return nil if lex.eql_lit?(ECMA262::PUNC_LPARENTHESIS).nil?
413
- return [] if lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS)
414
-
415
- args = []
416
- while true
417
- if t = assignment_exp(lex, context, options)
418
- args.push(t)
419
- else
420
- raise ParseError.new("unexpected token", lex)
421
- end
422
- if lex.eql_lit?(ECMA262::PUNC_COMMA)
423
- ;
424
- elsif lex.eql_lit?(ECMA262::PUNC_RPARENTHESIS)
425
- break
426
- else
427
- raise ParseError.new("unexpected token", lex)
428
- end
429
- end
430
- args
431
- end
432
- #
433
- # 11.3
434
- #
435
- def postfix_exp(lex, context, options)
436
- exp = left_hand_side_exp(lex, context, options)
437
- return nil if exp.nil?
438
- if punc = (lex.eql_lit_nolt?(ECMA262::PUNC_INC) ||
439
- lex.eql_lit_nolt?(ECMA262::PUNC_DEC))
440
- if punc == ECMA262::PUNC_INC
441
- ECMA262::ExpPostInc.new(exp)
442
- else
443
- ECMA262::ExpPostDec.new(exp)
444
- end
445
- else
446
- exp
447
- end
448
- end
449
-
450
- #
451
- # 11.4
452
- #
453
- def unary_exp(lex, context, options)
454
- if punc = (lex.eql_lit?(ECMA262::ID_DELETE) ||
455
- lex.eql_lit?(ECMA262::ID_VOID) ||
456
- lex.eql_lit?(ECMA262::ID_TYPEOF) ||
457
- lex.eql_lit?(ECMA262::PUNC_INC) ||
458
- lex.eql_lit?(ECMA262::PUNC_DEC) ||
459
- lex.eql_lit?(ECMA262::PUNC_ADD) ||
460
- lex.eql_lit?(ECMA262::PUNC_SUB) ||
461
- lex.eql_lit?(ECMA262::PUNC_NOT) ||
462
- lex.eql_lit?(ECMA262::PUNC_LNOT))
463
- exp = unary_exp(lex, context, options)
464
- if exp.nil?
465
- raise ParseError.new("unexpceted token", lex)
466
- elsif punc == ECMA262::PUNC_INC
467
- ECMA262::ExpPreInc.new(exp)
468
- elsif punc == ECMA262::PUNC_DEC
469
- ECMA262::ExpPreDec.new(exp)
470
- elsif punc == ECMA262::PUNC_ADD
471
- ECMA262::ExpPositive.new(exp)
472
- elsif punc == ECMA262::PUNC_SUB
473
- ECMA262::ExpNegative.new(exp)
474
- elsif punc == ECMA262::PUNC_NOT
475
- ECMA262::ExpBitwiseNot.new(exp)
476
- elsif punc == ECMA262::PUNC_LNOT
477
- ECMA262::ExpLogicalNot.new(exp)
478
- elsif punc.respond_to?(:val)
479
- if punc.val == :delete
480
- ECMA262::ExpDelete.new(exp)
481
- elsif punc.val == :void
482
- ECMA262::ExpVoid.new(exp)
483
- elsif punc.val == :typeof
484
- ECMA262::ExpTypeof.new(exp)
485
- end
486
- end
487
- else
488
- postfix_exp(lex, context, options)
489
- end
490
- end
491
-
492
- #
493
- # 11.5
494
- #
495
- def multiplicative_exp(lex, context, options)
496
- a = unary_exp(lex, context, options)
497
- return nil if !a
498
- t = a
499
- while punc = lex.eql_lit?(ECMA262::PUNC_MUL) ||
500
- lex.eql_lit?(ECMA262::PUNC_DIV, :div) ||
501
- lex.eql_lit?(ECMA262::PUNC_MOD)
502
-
503
- if b = unary_exp(lex, context, options)
504
- if punc == ECMA262::PUNC_MUL
505
- t = ECMA262::ExpMul.new(t, b)
506
- elsif punc == ECMA262::PUNC_DIV
507
- t = ECMA262::ExpDiv.new(t, b)
508
- else
509
- t = ECMA262::ExpMod.new(t, b)
510
- end
511
- else
512
- raise ParseError.new("unexpceted token", lex)
513
- end
514
- end
515
- t
516
- end
517
-
518
- #
519
- # 11.6
520
- #
521
- def additive_exp(lex, context, options)
522
- a = multiplicative_exp(lex, context, options)
523
- return nil if !a
524
-
525
- t = a
526
- while punc = lex.eql_lit?(ECMA262::PUNC_ADD) || lex.eql_lit?(ECMA262::PUNC_SUB)
527
- if b = multiplicative_exp(lex, context, options)
528
- if punc == ECMA262::PUNC_ADD
529
- t = ECMA262::ExpAdd.new(t, b)
530
- else
531
- t = ECMA262::ExpSub.new(t, b)
532
- end
533
- else
534
- raise ParseError.new("unexpceted token", lex)
535
- end
536
- end
537
- t
538
- end
539
- #
540
- # 11.7
541
- def shift_exp(lex, context, options)
542
- a = additive_exp(lex, context, options)
543
- return nil if !a
544
-
545
- t = a
546
- while punc = lex.eql_lit?(ECMA262::PUNC_LSHIFT) ||
547
- lex.eql_lit?(ECMA262::PUNC_RSHIFT) ||
548
- lex.eql_lit?(ECMA262::PUNC_URSHIFT)
549
- if b = additive_exp(lex, context, options)
550
- if punc == ECMA262::PUNC_LSHIFT
551
- t = ECMA262::ExpLShift.new(t, b)
552
- elsif punc == ECMA262::PUNC_RSHIFT
553
- t = ECMA262::ExpRShift.new(t, b)
554
- elsif punc == ECMA262::PUNC_URSHIFT
555
- t = ECMA262::ExpURShift.new(t, b)
556
- end
557
- else
558
- raise ParseError.new("unexpceted token", lex)
559
- end
560
- end
561
- t
562
- end
563
- #
564
- #
565
- # 11.8
566
- #
567
- def relational_exp(lex, context, options)
568
- a = shift_exp(lex, context, options)
569
- return nil if !a
570
-
571
- t = a
572
- while (punc = lex.eql_lit?(ECMA262::PUNC_LT) || lex.eql_lit?(ECMA262::PUNC_GT) ||
573
- lex.eql_lit?(ECMA262::PUNC_LTEQ) || lex.eql_lit?(ECMA262::PUNC_GTEQ) ||
574
- lex.eql_lit?(ECMA262::ID_INSTANCEOF) || (!options[:no_in] && lex.eql_lit?(ECMA262::ID_IN)))
575
- if b = shift_exp(lex, context, options)
576
- if punc == ECMA262::PUNC_LT
577
- t = ECMA262::ExpLt.new(t, b)
578
- elsif punc == ECMA262::PUNC_GT
579
- t = ECMA262::ExpGt.new(t, b)
580
- elsif punc == ECMA262::PUNC_LTEQ
581
- t = ECMA262::ExpLtEq.new(t, b)
582
- elsif punc == ECMA262::PUNC_GTEQ
583
- t = ECMA262::ExpGtEq.new(t, b)
584
- elsif punc.val == :instanceof
585
- t = ECMA262::ExpInstanceOf.new(t, b)
586
- elsif !options[:no_in] and punc.val == :in
587
- t = ECMA262::ExpIn.new(t, b)
588
- else
589
- end
590
- else
591
- raise ParseError.new("unexpceted token", lex)
592
- end
593
- end
594
- t
595
- end
596
- #
597
- #
598
- # 11.9
599
- # a == b
600
- # a != b
601
- # a === b
602
- # a !== b
603
- #
604
- def equality_exp(lex, context, options)
605
- a = relational_exp(lex, context, options)
606
- return nil if !a
607
-
608
- t = a
609
- while punc = lex.eql_lit?(ECMA262::PUNC_EQ) ||
610
- lex.eql_lit?(ECMA262::PUNC_NEQ) ||
611
- lex.eql_lit?(ECMA262::PUNC_SEQ) ||
612
- lex.eql_lit?(ECMA262::PUNC_SNEQ)
613
- if b = relational_exp(lex, context, options)
614
- if punc == ECMA262::PUNC_EQ
615
- t = ECMA262::ExpEq.new(t, b)
616
- elsif punc == ECMA262::PUNC_NEQ
617
- t = ECMA262::ExpNotEq.new(t, b)
618
- elsif punc == ECMA262::PUNC_SEQ
619
- t = ECMA262::ExpStrictEq.new(t, b)
620
- elsif punc == ECMA262::PUNC_SNEQ
621
- t = ECMA262::ExpStrictNotEq.new(t, b)
622
- end
623
- else
624
- raise ParseError.new("unexpceted token", lex)
625
- end
626
- end
627
- t
628
- end
629
-
630
- #
631
- # 11.10
632
- # a & b
633
- #
634
- def bitwise_and_exp(lex, context, options)
635
- a = equality_exp(lex, context, options)
636
- return nil if !a
637
-
638
- t = a
639
- while punc = lex.eql_lit?(ECMA262::PUNC_AND)
640
- if b = equality_exp(lex, context, options)
641
- t = ECMA262::ExpAnd.new(t, b)
642
- else
643
- raise ParseError.new("unexpceted token", lex)
644
- end
645
- end
646
- t
647
- end
648
-
649
- #
650
- # a ^ b
651
- #
652
- def bitwise_xor_exp(lex, context, options)
653
- a = bitwise_and_exp(lex, context, options)
654
- return nil if !a
655
-
656
- t = a
657
- while punc = lex.eql_lit?(ECMA262::PUNC_XOR)
658
- if b = bitwise_and_exp(lex, context, options)
659
- t = ECMA262::ExpXor.new(t, b)
660
- else
661
- raise ParseError.new("unexpceted token", lex)
662
- end
663
- end
664
-
665
- t
666
- end
667
-
668
- #
669
- # a | b
670
- #
671
- def bitwise_or_exp(lex, context, options)
672
- a = bitwise_xor_exp(lex, context, options)
673
- return nil if !a
674
-
675
- t = a
676
- while punc = lex.eql_lit?(ECMA262::PUNC_OR)
677
- if b = bitwise_xor_exp(lex, context, options)
678
- t = ECMA262::ExpOr.new(t, b)
679
- else
680
- raise ParseError.new("unexpceted token", lex)
681
- end
682
- end
683
- t
684
- end
685
- #
686
- # 11.11
687
- # a && b
688
- #
689
- def logical_and_exp(lex, context, options)
690
- a = bitwise_or_exp(lex, context, options)
691
- return nil if !a
692
-
693
- t = a
694
- while punc = lex.eql_lit?(ECMA262::PUNC_LAND)
695
- if b = bitwise_or_exp(lex, context, options)
696
- t = ECMA262::ExpLogicalAnd.new(t, b)
697
- else
698
- raise ParseError.new("unexpceted token", lex)
699
- end
700
- end
701
-
702
- t
703
- end
704
-
705
- def logical_or_exp(lex, context, options)
706
- a = logical_and_exp(lex, context, options)
707
- return nil if !a
708
-
709
- t = a
710
- while punc = lex.eql_lit?(ECMA262::PUNC_LOR)
711
- if b = logical_and_exp(lex, context, options)
712
- t = ECMA262::ExpLogicalOr.new(t, b)
713
- else
714
- raise ParseError.new("unexpceted token", lex)
715
- end
716
- end
717
-
718
- t
719
- end
720
- #
721
- # 11.12
722
- # a ? b : c
723
- #
724
- def cond_exp(lex, context, options)
725
- a = logical_or_exp(lex, context, options)
726
- return nil if !a
727
-
728
- if lex.eql_lit?(ECMA262::PUNC_CONDIF)
729
- if b=assignment_exp(lex, context, options) and lex.eql_lit?(ECMA262::PUNC_COLON) and c=assignment_exp(lex, context, options)
730
- ECMA262::ExpCond.new(a, b, c)
731
- else
732
- raise ParseError.new("unexpceted token", lex)
733
- end
734
- else
735
- a
736
- end
737
- end
738
- #
739
- #11.13
740
- # AssignmentExpression :
741
- # ConditionalExpression
742
- # LeftHandSideExpression = AssignmentExpression
743
- # LeftHandSideExpression AssignmentOperator AssignmentExpression
744
- #
745
- def assignment_exp(lex, context, options)
746
- @logger.debug "*** assignment_exp"
747
-
748
- t = cond_exp(lex, context, options)
749
- return nil if t.nil?
750
-
751
- if !t.left_hand_side_exp?
752
- return t
753
- end
754
- left_hand = t
755
- punc = lex.peek_lit(:div)
756
- if punc == ECMA262::PUNC_LET ||
757
- punc == ECMA262::PUNC_DIVLET ||
758
- punc == ECMA262::PUNC_MULLET ||
759
- punc == ECMA262::PUNC_MODLET ||
760
- punc == ECMA262::PUNC_ADDLET ||
761
- punc == ECMA262::PUNC_SUBLET ||
762
- punc == ECMA262::PUNC_LSHIFTLET ||
763
- punc == ECMA262::PUNC_RSHIFTLET ||
764
- punc == ECMA262::PUNC_URSHIFTLET ||
765
- punc == ECMA262::PUNC_ANDLET ||
766
- punc == ECMA262::PUNC_ORLET ||
767
- punc == ECMA262::PUNC_XORLET
768
- lex.fwd_after_peek
769
- if b = assignment_exp(lex, context, options)
770
- case punc
771
- when ECMA262::PUNC_LET
772
- ECMA262::ExpAssign.new(left_hand, b)
773
- when ECMA262::PUNC_DIVLET
774
- ECMA262::ExpDivAssign.new(left_hand, b)
775
- when ECMA262::PUNC_MULLET
776
- ECMA262::ExpMulAssign.new(left_hand, b)
777
- when ECMA262::PUNC_MODLET
778
- ECMA262::ExpModAssign.new(left_hand, b)
779
- when ECMA262::PUNC_ADDLET
780
- ECMA262::ExpAddAssign.new(left_hand, b)
781
- when ECMA262::PUNC_SUBLET
782
- ECMA262::ExpSubAssign.new(left_hand, b)
783
- when ECMA262::PUNC_LSHIFTLET
784
- ECMA262::ExpLShiftAssign.new(left_hand, b)
785
- when ECMA262::PUNC_RSHIFTLET
786
- ECMA262::ExpRShiftAssign.new(left_hand, b)
787
- when ECMA262::PUNC_URSHIFTLET
788
- ECMA262::ExpURShiftAssign.new(left_hand, b)
789
- when ECMA262::PUNC_ANDLET
790
- ECMA262::ExpAndAssign.new(left_hand, b)
791
- when ECMA262::PUNC_ORLET
792
- ECMA262::ExpOrAssign.new(left_hand, b)
793
- when ECMA262::PUNC_XORLET
794
- ECMA262::ExpXorAssign.new(left_hand, b)
795
- else
796
- raise "internal error"
797
- end
798
- else
799
- raise ParseError.new("unexpceted token", lex)
800
- end
801
- else
802
- @logger.debug {
803
- "*** assignment_exp => #{t ? t.to_js : t}"
804
- }
805
- t
806
- end
807
- end
808
-
809
- #
810
- # 11.14
811
- # Expression :
812
- # AssignmentExpression
813
- # Expression , AssignmentExpression
814
- #
815
- def exp(lex, context, options)
816
- @logger.debug "*** expression"
817
-
818
- t = assignment_exp(lex, context, options)
819
- return nil if t.nil?
820
- while punc = lex.eql_lit?(ECMA262::PUNC_COMMA)
821
- if b = assignment_exp(lex,context, options)
822
- t = ECMA262::ExpComma.new(t, b)
823
- else
824
- raise ParseError.new("unexpceted token", lex)
825
- end
826
- end
827
- @logger.debug{
828
- "*** expression => #{t ? t.to_js : t}"
829
- }
830
- t
831
- end
832
- end
833
- end