minjs 0.1.2 → 0.1.3

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.
@@ -13,6 +13,10 @@ module Minjs
13
13
  def to_exp?
14
14
  false
15
15
  end
16
+
17
+ def priority(exp)
18
+ 10
19
+ end
16
20
  end
17
21
 
18
22
  class DivOrRegexpLiteral < Literal
@@ -169,10 +173,9 @@ module Minjs
169
173
  end
170
174
 
171
175
  class ECMA262Numeric < Literal
172
- attr_reader :integer, :decimal, :exp, :raw
176
+ attr_reader :integer, :decimal, :exp
173
177
 
174
- def initialize(raw, integer, decimal = nil, exp = nil)
175
- @raw = raw
178
+ def initialize(integer, decimal = nil, exp = nil)
176
179
  if integer == :nan
177
180
  integer = nil
178
181
  @nan = true
@@ -187,10 +190,11 @@ module Minjs
187
190
  if decimal
188
191
  @decimal = decimal.to_s
189
192
  end
190
- @exp = exp
193
+ if exp
194
+ @exp = exp.to_i
195
+ end
191
196
  end
192
197
  @decimal = nil if @decimal == 0
193
- @exp = nil if @exp == 1
194
198
  end
195
199
 
196
200
  def traverse(parent, &block)
@@ -242,120 +246,52 @@ module Minjs
242
246
  end
243
247
 
244
248
  def to_f
245
- "#{@integer}.#{@decimal}e#{@exp}".to_f
249
+ d = @decimal
250
+ if d.to_s == ''
251
+ d = '0'
252
+ end
253
+ "#{@integer}.#{d}e#{@exp}".to_f
246
254
  end
247
- =begin
248
- TODO
249
255
  #
250
256
  # 9.8.1
251
257
  #
252
258
  def to_ecma262_string
253
259
  if @nan
254
260
  "NaN"
255
- elsif @integer == 0 and @decimal.nil? and @exp.nil?
261
+ elsif @integer == '0' and @decimal.nil? and @exp.nil?
256
262
  "0"
257
- elsif @integer.to_i < 0
258
- ECMA262Numeric.new(-@integer, @decimal, @exp).to_string
259
263
  elsif @intinify
260
264
  "Infinity"
261
265
  else
262
- #puts "to_f:"
263
- #puts to_f
264
- _i = @integer
265
- _d = @decimal
266
- _e = @exp.to_i || 0
267
-
268
- if _d
269
- _e -= _d.length
270
- _i += _d
271
- _d = nil
272
- end
273
-
274
- if _i.match(/^0/) and _i != '0'
275
- _i = _i.sub(/^0/, '')
276
- end
277
- #puts "i,d,e:"
278
- #p _i
279
- #p _d
280
- #p _e
281
-
282
- while(_i % 10 == 0)
283
- _i /= 10
284
- _e += 1
285
- end
286
- k = _i.to_s.length
287
- s = _i
288
- n = k + _e
289
- #
290
- # Otherwise, let n, k, and s be integers such that k ≥ 1,
291
- # 10k−1 ≤ s < 10k, the Number value for s × 10n−k is m,
292
- # and k is as small as possible. Note that k is the number
293
- # of digits in the decimal representation of s, that s is
294
- # not divisible by 10, and that the least significant digit
295
- # of s is not necessarily uniquely determined by these
296
- # criteria.
297
- #
298
- #puts "k=#{k}"
299
- #puts "s=#{s}"
300
- #puts "n=#{n}"
301
- #puts "#{s}e#{n-k}"
302
- #puts eval("#{s}e#{n-k}")
303
- #
304
- # If k ≤ n ≤ 21, return the String consisting of the k digits
305
- # of the decimal representation of s (in order, with no
306
- # leading zeroes), followed by n−k occurrences of the
307
- # character ‘0’.
308
- #
309
- if k <= n and n <= 21
310
- "#{s * 10 ** (n-k)}"
311
- #
312
- # If 0 < n ≤ 21, return the String consisting of the most
313
- # significant n digits of the decimal representation of s,
314
- # followed by a decimal point ‘.’, followed by the
315
- # remaining k−n digits of the decimal representation of s.
316
- #
317
- elsif 0 < n and n <= 21
318
- "#{s[0...n]}.#{s[n..-1]}"
319
- #
320
- # If −6 < n ≤ 0, return the String consisting of the
321
- # character ‘0’, followed by a decimal point ‘.’,
322
- # followed by −n occurrences of the character ‘0’,
323
- # followed by the k digits of the decimal representation of
324
- # s.
325
- #
326
- elsif -6 < n and n <= 0
327
- to_f.to_s #TODO
328
- #"0.#{'0' * -n}#{s}"
329
- #
330
- # Otherwise, if k = 1, return the String consisting of the
331
- # single digit of s, followed by lowercase character ‘e’,
332
- # followed by a plus sign ‘+’ or minus sign ‘−’
333
- # according to whether n−1 is positive or negative,
334
- # followed by the decimal representation of the integer
335
- # abs(n−1) (with no leading zeroes).
336
- #
337
- elsif k == 1
338
- to_f.to_s #TODO
339
- #"#{s}e#{n-1 > 0 ? '+' : '-'}#{(n-1).abs}"
340
- #
341
- # Return the String consisting of the most significant digit
342
- # of the decimal representation of s, followed by a decimal
343
- # point ‘.’, followed by the remaining k−1 digits of the
344
- # decimal representation of s, followed by the lowercase
345
- # character ‘e’, followed by a plus sign ‘+’ or minus
346
- # sign ‘−’ according to whether n−1 is positive or
347
- # negative, followed by the decimal representation of the
348
- # integer abs(n−1) (with no leading zeroes).
349
- #
266
+ f = to_f.to_s
267
+ _n, _e = f.split('e')
268
+ _i, _d = _n.split('.')
269
+
270
+ e = _e.to_i
271
+ if(e == 0)
272
+ if _d.to_i != 0
273
+ return _n
274
+ else
275
+ return _i
276
+ end
277
+ elsif(e > 0 && e < 21)
278
+ _n = _i + _d
279
+ _n += '0' * (21 - _n.length)
280
+ return _n
281
+ elsif(e < 0 && e >= -6)
282
+ _n = "0." + ('0' * (-e-1)) + _i + _d
283
+ return _n
350
284
  else
351
- to_f.to_s #TODO
285
+ if e<0
286
+ return "#{_i}.#{_d}e#{e}"
287
+ else
288
+ return "#{_i}.#{_d}e+#{e}"
289
+ end
352
290
  end
353
291
  end
354
292
  end
355
- =end
356
-
357
- NUMERIC_NAN = ECMA262Numeric.new('NaN', :nan)
358
293
  end
294
+ NUMERIC_NAN = ECMA262Numeric.new(:nan)
359
295
 
360
296
  class ECMA262RegExp < Literal
361
297
  def initialize(body, flags)
@@ -417,12 +353,27 @@ TODO
417
353
  end
418
354
  def to_js(options = {})
419
355
  "{" + @val.collect{|x, y|
420
- if x.kind_of? ECMA262Numeric
421
- "#{x.raw}:#{y.to_js(options)}"
422
- elsif idname?(x.val.to_s)
423
- "#{x.val.to_s}:#{y.to_js(options)}"
356
+ if y.kind_of? StFunc and (y.getter? || y.setter?)
357
+ if y.name.val == :get
358
+ t = "get #{x.val.to_s}(){#{y.statements.to_js(options)}}"
359
+ else
360
+ t = "set #{x.val.to_s}(#{y.args[0].to_js(options)}){#{y.statements.to_js(options)}}"
361
+ end
424
362
  else
425
- "#{x.to_js(options)}:#{y.to_js(options)}"
363
+ if x.kind_of? ECMA262Numeric
364
+ a = "#{x.to_ecma262_string}"
365
+ b = "#{x.to_js}"
366
+ if a.length <= b.length || a == "Infinity"
367
+ t = a
368
+ else
369
+ t = b
370
+ end
371
+ elsif idname?(x.val.to_s)
372
+ t = "#{x.val.to_s}"
373
+ else
374
+ t = "#{x.to_js(options)}"
375
+ end
376
+ t << ":#{y.to_js(options)}"
426
377
  end
427
378
  }.join(",") + "}"
428
379
  end
@@ -5,8 +5,12 @@ module Minjs
5
5
  false
6
6
  end
7
7
 
8
- def replace(from, to)
9
- puts "warning: not implement"
8
+ def to_return?
9
+ false
10
+ end
11
+
12
+ def priority(exp)
13
+ 999
10
14
  end
11
15
  end
12
16
 
@@ -60,6 +64,12 @@ module Minjs
60
64
  @statement_list.delete(st)
61
65
  end
62
66
 
67
+ def remove_empty_statement
68
+ @statement_list.reject!{|x|
69
+ x.class == StEmpty
70
+ }
71
+ end
72
+
63
73
  def traverse(parent, &block)
64
74
  @statement_list.each do|st|
65
75
  st.traverse(self, &block)
@@ -114,9 +124,6 @@ module Minjs
114
124
 
115
125
  #statement_list:StList
116
126
  def initialize(statement_list)
117
- if statement_list.class == Array
118
- raise 'bad class'
119
- end
120
127
  @statement_list = statement_list
121
128
  end
122
129
 
@@ -136,6 +143,17 @@ module Minjs
136
143
  def to_exp(options)
137
144
  @statement_list[0].to_exp({})
138
145
  end
146
+
147
+ def to_statement?
148
+ @statement_list.statement_list.select{|s|
149
+ s.class != StEmpty
150
+ }.length == 1
151
+ end
152
+
153
+ def to_statement
154
+ statement_list.remove_empty_statement
155
+ @statement_list[0]
156
+ end
139
157
  end
140
158
  #
141
159
  # 12.2
@@ -223,10 +241,18 @@ module Minjs
223
241
  def initialize(exp)
224
242
  @exp = exp
225
243
  end
244
+
245
+ def replace(from, to)
246
+ if @exp == from
247
+ @exp = to
248
+ end
249
+ end
250
+
226
251
  def traverse(parent, &block)
227
252
  @exp.traverse(self, &block)
228
253
  yield self, parent
229
254
  end
255
+
230
256
  def to_js(options = {})
231
257
  concat(options, @exp, ";")
232
258
  end
@@ -275,9 +301,35 @@ module Minjs
275
301
  end
276
302
  end
277
303
 
304
+ def to_return?
305
+ if !@else_st
306
+ return true if @then_st.class == StReturn
307
+ else
308
+ return true if @then_st.class == StReturn and @else_st.class == StReturn
309
+ end
310
+ end
311
+
312
+ def to_return
313
+ if !@else_st
314
+ cond = ExpParen.new(@cond)
315
+ then_exp = ExpParen.new(then_st.exp)
316
+ else_exp = ExpVoid.new(ECMA262Numeric.new('0'))
317
+ StReturn.new(ExpCond.new(cond, then_exp, else_exp))
318
+ else
319
+ cond = ExpParen.new(@cond)
320
+ then_exp = ExpParen.new(then_st.exp)
321
+ else_exp = ExpParen.new(else_st.exp)
322
+ StReturn.new(ExpCond.new(cond, then_exp, else_exp))
323
+ end
324
+ end
325
+
278
326
  def to_exp?
279
- return false if @then_st.to_exp? == false
280
- return false if @else_st and @else_st.to_exp? == false
327
+ if !@else_st
328
+ return false if @then_st.to_exp? == false
329
+ else
330
+ return false if @then_st.to_exp? == false
331
+ return false if @else_st.to_exp? == false
332
+ end
281
333
  return true
282
334
  end
283
335
 
@@ -288,7 +340,6 @@ module Minjs
288
340
  else_exp = @else_st.to_exp(options)
289
341
  else
290
342
  then_exp = @then_st.to_exp(options)
291
- #else_exp = ECMA262Numeric.new(0)
292
343
  return ExpLogicalAnd.new(ExpParen.new(@cond), ExpParen.new(then_exp))
293
344
  end
294
345
  if then_exp.kind_of? ExpComma
@@ -365,6 +416,9 @@ module Minjs
365
416
  end
366
417
  end
367
418
 
419
+ #
420
+ # for(var i=0,... ; ; )
421
+ #
368
422
  class StForVar < St
369
423
  attr_reader :context
370
424
 
@@ -433,11 +487,7 @@ module Minjs
433
487
  concat options, x[0]
434
488
  end
435
489
  }.join(",")
436
- # if options[:compress_var]
437
- # t = concat({:for_args => true}.merge(options), :for, "(", _var_decl_list, ";", @exp2, ";", @exp3, ")")
438
- # else
439
- t = concat({:for_args => true}.merge(options), :for, "(", _var_decl_list, ";", @exp2, ";", @exp3, ")")
440
- # end
490
+ t = concat({:for_args => true}.merge(options), :for, "(var", _var_decl_list, ";", @exp2, ";", @exp3, ")")
441
491
  concat options, t, statement
442
492
  end
443
493
  end
@@ -637,7 +687,7 @@ module Minjs
637
687
  end
638
688
 
639
689
  def to_js(options = {})
640
- concat options, :with, "(", @exp, ")","{", @statement, "}"
690
+ concat options, :with, "(", @exp, ")", @statement
641
691
  end
642
692
  end
643
693
  #12.11
@@ -740,8 +790,6 @@ module Minjs
740
790
  @catch[1] = to
741
791
  elsif from == @finally
742
792
  @finally = to
743
- else
744
- raise 'unknown'
745
793
  end
746
794
  end
747
795
 
@@ -778,16 +826,21 @@ module Minjs
778
826
  class StFunc < St
779
827
  attr_reader :name
780
828
  attr_reader :args
781
- attr_reader :statement
829
+ attr_reader :statements
782
830
  attr_reader :context
783
- attr_reader :decl
784
831
 
785
- def initialize(context, name, args, statements, decl = false)
832
+ def initialize(context, name, args, statements, options = {})
786
833
  @name = name
787
- @args = args
834
+ @args = args #=> array
788
835
  @statements = statements #=> Prog
789
836
  @context = context
790
- @decl = decl
837
+ @decl = options[:decl]
838
+ @getter = options[:getter]
839
+ @setter = options[:setter]
840
+ end
841
+
842
+ def priority(exp)
843
+ 10
791
844
  end
792
845
 
793
846
  def traverse(parent, &block)
@@ -801,7 +854,25 @@ module Minjs
801
854
 
802
855
  def to_js(options = {})
803
856
  _args = @args.collect{|x|x.to_js(options)}.join(",")
804
- concat options, :function, @name, '(', _args, ")", "{", @statements, "}"
857
+ if @getter
858
+ concat options, :get, @name, '(', _args, ")", "{", @statements, "}"
859
+ elsif @setter
860
+ concat options, :set, @name, '(', _args, ")", "{", @statements, "}"
861
+ else
862
+ concat options, :function, @name, '(', _args, ")", "{", @statements, "}"
863
+ end
864
+ end
865
+
866
+ def getter?
867
+ @getter
868
+ end
869
+
870
+ def setter?
871
+ @setter
872
+ end
873
+
874
+ def decl?
875
+ @decl
805
876
  end
806
877
  end
807
878
  end
@@ -2,14 +2,22 @@ module Minjs
2
2
  class ParseError < StandardError
3
3
  def initialize(error_message = nil, lex = nil)
4
4
  super(error_message)
5
- @lex = lex
5
+ if lex
6
+ @lex = lex
7
+ @lex_pos = lex.pos
8
+ end
6
9
  end
7
10
 
8
11
  def to_s
9
12
  t = ''
10
13
  t << super
11
14
  t << "\n"
12
- t << @lex.debug_str if @lex
15
+ if @lex
16
+ line, col = @lex.line_col(@lex_pos)
17
+ t << "line: #{line}, col: #{col}\n"
18
+ t << @lex.debug_str(@lex_pos)
19
+ end
20
+ t
13
21
  end
14
22
  end
15
23
  end
@@ -19,7 +19,7 @@ module Minjs
19
19
  STDERR.puts "*** primary_exp => ()" if @debug
20
20
  return ECMA262::ExpParen.new(a)
21
21
  else
22
- raise 'error'
22
+ raise ParseError.new("no `)' at end of expression", lex)
23
23
  end
24
24
  end
25
25
 
@@ -103,18 +103,17 @@ module Minjs
103
103
  break
104
104
  end
105
105
  lex.eval_lit{
106
+ if lex.match_lit(ECMA262::ID_GET) and a=property_name(lex, context) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and b=func_body(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
107
+ h.push([a, ECMA262::StFunc.new(context, ECMA262::ID_GET, [], b, :getter => true)])
108
+ elsif lex.match_lit(ECMA262::ID_SET) and a=property_name(lex, context) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and arg=property_set_parameter_list(lex, context) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and b=func_body(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
109
+ h.push([a, ECMA262::StFunc.new(context, ECMA262::ID_SET, arg, b, :setter => true)])
110
+ else
111
+ nil
112
+ end
113
+ } or lex.eval_lit{
106
114
  a=property_name(lex, context) and lex.match_lit(ECMA262::PUNC_COLON) and b=assignment_exp(lex, context, options)
107
115
  h.push([a, b])
108
116
  }
109
- # or lex.eval_lit{
110
- # if lex.match_lit(ECMA262::ID_GET) and a=property_name(lex, context) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and func_body(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
111
- # h[a] = "getter" #TODO
112
- # elsif lex.match_lit(ECMA262::ID_SET) and a=property_name(lex, context) and lex.match_lit(ECMA262::PUNC_LPARENTHESIS) and property_set_parameter_list(lex, context) and lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and func_body(lex, context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
113
- # h[a] = "setter" #TODO
114
- # else
115
- # return nil
116
- # end
117
- # }
118
117
 
119
118
  if lex.match_lit(ECMA262::PUNC_COMMA)
120
119
  break if lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
@@ -138,7 +137,7 @@ module Minjs
138
137
  elsif a.kind_of?(ECMA262::ECMA262Numeric)
139
138
  a
140
139
  else
141
- raise ParseError.new("The Property name must be kind_of ItentiferName or String", lex)
140
+ nil
142
141
  end
143
142
  }
144
143
  end
@@ -147,7 +146,7 @@ module Minjs
147
146
  lex.eval_lit {
148
147
  a = lex.fwd_lit
149
148
  if a.kind_of?(ECMA262::IdentifierName) and !a.reserved?
150
- a
149
+ [a]
151
150
  else
152
151
  nil
153
152
  end
@@ -292,12 +291,11 @@ module Minjs
292
291
  STDERR.puts "*** postfix_exp" if @debug
293
292
  lex.debug_lit if @debug
294
293
 
295
- next_exp = :left_hand_side_exp
296
294
  t = lex.eval_lit{
297
- a = __send__(next_exp, lex, context, options)
295
+ a = left_hand_side_exp(lex, context, options)
298
296
  return nil if a.nil?
299
- if punc = (lex.match_lit(ECMA262::PUNC_INC) ||
300
- lex.match_lit(ECMA262::PUNC_DEC))
297
+ if punc = (lex.match_lit(ECMA262::PUNC_INC, :nolt => true) ||
298
+ lex.match_lit(ECMA262::PUNC_DEC, :nolt => true))
301
299
  if punc == ECMA262::PUNC_INC
302
300
  ECMA262::ExpPostInc.new(a)
303
301
  else
@@ -683,7 +681,7 @@ module Minjs
683
681
  when ECMA262::PUNC_XORLET
684
682
  ECMA262::ExpXorAssign.new(left_hand, b)
685
683
  else
686
- raise "not implement"
684
+ raise "internal error"
687
685
  end
688
686
  else # some assignment operator presents but no assignment_expression => fail
689
687
  return nil
data/lib/minjs/func.rb CHANGED
@@ -17,13 +17,17 @@ module Minjs
17
17
  lex.match_lit(ECMA262::PUNC_RPARENTHESIS) and
18
18
  lex.match_lit(ECMA262::PUNC_LCURLYBRAC) and
19
19
  b=func_body(lex, new_context) and lex.match_lit(ECMA262::PUNC_RCURLYBRAC)
20
- f = ECMA262::StFunc.new(new_context, id, args, b, true)
20
+ f = ECMA262::StFunc.new(new_context, id, args, b, {:decl => true})
21
21
 
22
22
  context.var_env.record.create_mutable_binding(id, nil)
23
23
  context.var_env.record.set_mutable_binding(id, f, nil)
24
24
  f
25
25
  else
26
- nil
26
+ if b
27
+ raise ParseError.new("No `}' at end of function", lex)
28
+ else
29
+ raise ParseError.new("Bad function declaration", lex)
30
+ end
27
31
  end
28
32
  }
29
33
  end
@@ -53,8 +57,11 @@ module Minjs
53
57
  end
54
58
  f
55
59
  else
56
- lex.debug_lit
57
- raise 'error'
60
+ if b
61
+ raise ParseError.new("No `}' at end of function", lex)
62
+ else
63
+ raise ParseError.new("Bad function declaration", lex)
64
+ end
58
65
  end
59
66
  }
60
67
  end