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.
@@ -0,0 +1,552 @@
1
+ # coding: utf-8
2
+ module Minjs
3
+ module ECMA262
4
+ class Literal < Base
5
+ def ws?
6
+ false
7
+ end
8
+
9
+ def lt?
10
+ false
11
+ end
12
+
13
+ def to_exp?
14
+ false
15
+ end
16
+ end
17
+
18
+ class DivOrRegexpLiteral < Literal
19
+ def traverse(parent, &block)
20
+ end
21
+
22
+ def to_js(options = {})
23
+ "??"
24
+ end
25
+
26
+ @@instance = self.new()
27
+ def self.get
28
+ @@instance
29
+ end
30
+ end
31
+
32
+ LIT_DIV_OR_REGEXP_LITERAL = DivOrRegexpLiteral.get
33
+
34
+ class WhiteSpace < Literal
35
+ def traverse(parent, &block)
36
+ end
37
+
38
+ def ws?
39
+ true
40
+ end
41
+
42
+ def to_js(options = {})
43
+ " "
44
+ end
45
+
46
+ @@instance = self.new()
47
+ def self.get
48
+ @@instance
49
+ end
50
+ end
51
+
52
+ class LineFeed < Literal
53
+ def traverse(parent, &block)
54
+ end
55
+
56
+ def lt?
57
+ true
58
+ end
59
+
60
+ def to_js(options = {})
61
+ "\n"
62
+ end
63
+
64
+ @@instance = self.new()
65
+ def self.get
66
+ @@instance
67
+ end
68
+ end
69
+
70
+ LIT_LINE_FEED = LineFeed.get
71
+
72
+ class Null < Literal
73
+ def initialize(val)
74
+ @val = :null
75
+ end
76
+
77
+ def traverse(parent, &block)
78
+ yield self, parent
79
+ end
80
+
81
+ def to_s
82
+ "null"
83
+ end
84
+
85
+ def to_js(options = {})
86
+ "null"
87
+ end
88
+
89
+ @@instance = self.new(nil)
90
+ def self.get
91
+ @@instance
92
+ end
93
+ end
94
+
95
+ class Boolean < Literal
96
+ attr_reader :val
97
+
98
+ def initialize(val)
99
+ if val.to_s == "true"
100
+ @val = :"true"
101
+ else
102
+ @val = :"false"
103
+ end
104
+ end
105
+
106
+ def traverse(parent, &block)
107
+ yield self, parent
108
+ end
109
+
110
+ def to_js(options = {})
111
+ @val.to_s
112
+ end
113
+
114
+ def true?
115
+ @val == :true
116
+ end
117
+
118
+ @@true = self.new(:true)
119
+ @@false = self.new(:false)
120
+ def self.get(val)
121
+ if val.to_sym == :true
122
+ @@true
123
+ else
124
+ @@false
125
+ end
126
+ end
127
+ end
128
+
129
+ class ECMA262String < Literal
130
+ attr_reader :val
131
+
132
+ def initialize(val)
133
+ @val = val
134
+ end
135
+ def traverse(parent)
136
+ yield self, parent
137
+ end
138
+ def to_js(options = {})
139
+ t = "\""
140
+ @val.to_s.each_codepoint do |c|
141
+ if c == 0x5c
142
+ t << ('\\\\')
143
+ elsif c == 0x22
144
+ t << ('\"')
145
+ elsif c >= 0x20 and c <= 0x7f
146
+ t << ("%c" % c)
147
+ elsif c == 8
148
+ t << '\\b'
149
+ elsif c == 9
150
+ t << '\\t'
151
+ elsif c == 0xa
152
+ t << '\\n'
153
+ elsif c == 0xb
154
+ t << '\\v'
155
+ elsif c == 0xc
156
+ t << '\\v'
157
+ elsif c == 0xd
158
+ t << '\\r'
159
+ elsif c == 0
160
+ t << '\\0'
161
+ elsif c < 0x20
162
+ t << "\\x#{"%02x" % c}"
163
+ else
164
+ t << [c].pack("U*")
165
+ end
166
+ end
167
+ t << "\""
168
+ end
169
+ end
170
+
171
+ class ECMA262Numeric < Literal
172
+ attr_reader :integer, :decimal, :exp, :raw
173
+
174
+ def initialize(raw, integer, decimal = nil, exp = nil)
175
+ @raw = raw
176
+ if integer == :nan
177
+ integer = nil
178
+ @nan = true
179
+ elsif integer == :infinity
180
+ integer = nil
181
+ @infinity = true
182
+ elsif integer.kind_of? Float
183
+ @integer, @decimal = integer.to_i.to_s
184
+ @decimal = (integer - @integer).to_s.sub(/^.*0\./, '')
185
+ else
186
+ @integer = integer.to_s
187
+ if decimal
188
+ @decimal = decimal.to_s
189
+ end
190
+ @exp = exp
191
+ end
192
+ @decimal = nil if @decimal == 0
193
+ @exp = nil if @exp == 1
194
+ end
195
+
196
+ def traverse(parent, &block)
197
+ yield self, parent
198
+ end
199
+
200
+ def to_js(options = {})
201
+ if @nan
202
+ return "NaN"
203
+ end
204
+ t = @integer.dup.to_s
205
+
206
+ if @decimal
207
+ if @integer == '0'
208
+ t = ".#{@decimal}"
209
+ else
210
+ t << ".#{@decimal}"
211
+ end
212
+ end
213
+ if @exp
214
+ t << "e#{@exp}"
215
+ end
216
+
217
+ if @decimal.nil? and @exp.nil? and t.match(/0{3,}$/)
218
+ len = $&.length
219
+ t.sub!(/0+$/, "e#{len}")
220
+ end
221
+ t
222
+ end
223
+
224
+ def integer?
225
+ @decimal.nil?
226
+ end
227
+
228
+ def to_num
229
+ if @decimal
230
+ to_f
231
+ else
232
+ to_i
233
+ end
234
+ end
235
+
236
+ def to_i
237
+ if @exp
238
+ @integer.to_i * (10 ** @exp.to_i)
239
+ else
240
+ @integer.to_i
241
+ end
242
+ end
243
+
244
+ def to_f
245
+ "#{@integer}.#{@decimal}e#{@exp}".to_f
246
+ end
247
+ =begin
248
+ TODO
249
+ #
250
+ # 9.8.1
251
+ #
252
+ def to_ecma262_string
253
+ if @nan
254
+ "NaN"
255
+ elsif @integer == 0 and @decimal.nil? and @exp.nil?
256
+ "0"
257
+ elsif @integer.to_i < 0
258
+ ECMA262Numeric.new(-@integer, @decimal, @exp).to_string
259
+ elsif @intinify
260
+ "Infinity"
261
+ 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
+ #
350
+ else
351
+ to_f.to_s #TODO
352
+ end
353
+ end
354
+ end
355
+ =end
356
+
357
+ NUMERIC_NAN = ECMA262Numeric.new('NaN', :nan)
358
+ end
359
+
360
+ class ECMA262RegExp < Literal
361
+ def initialize(body, flags)
362
+ @body = body
363
+ @flags = flags
364
+ end
365
+
366
+ def traverse(parent)
367
+ yield self, parent
368
+ end
369
+
370
+ def to_js(options = {})
371
+ "/#{@body}/#{@flags}"
372
+ end
373
+ end
374
+
375
+ LITERAL_TRUE = Boolean.new(:true)
376
+ LITERAL_FALSE = Boolean.new(:false)
377
+
378
+ class ECMA262Array < Literal
379
+ def initialize(val)
380
+ @val = val
381
+ end
382
+ def traverse(parent, &block)
383
+ yield self, parent
384
+ @val.each do |k|
385
+ k.traverse(parent, &block)
386
+ end
387
+ end
388
+ def to_js(options = {})
389
+ "[" + @val.collect{|x| x.to_s}.join(",") + "]"
390
+ end
391
+ end
392
+
393
+ class ECMA262Object < Literal
394
+ include Ctype
395
+ private
396
+ def idname?(name)
397
+ return false if name.length == 0
398
+ s = name.codepoints
399
+ return false unless identifier_start?(s[0])
400
+ s.unshift
401
+ s.each do |code|
402
+ return false unless identifier_part?(code)
403
+ end
404
+ return true
405
+ end
406
+
407
+ public
408
+ def initialize(val)
409
+ @val = val
410
+ end
411
+ def traverse(parent, &block)
412
+ yield self, parent
413
+ @val.each do |k, v|
414
+ k.traverse(parent, &block)
415
+ v.traverse(parent, &block)
416
+ end
417
+ end
418
+ def to_js(options = {})
419
+ "{" + @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)}"
424
+ else
425
+ "#{x.to_js(options)}:#{y.to_js(options)}"
426
+ end
427
+ }.join(",") + "}"
428
+ end
429
+ end
430
+
431
+ class SingleLineComment < Literal
432
+ def initialize(comment)
433
+ @comment = comment
434
+ end
435
+
436
+ def traverse(parent, &block)
437
+ end
438
+
439
+ def to_js(options)
440
+ "//#{@comment}"
441
+ end
442
+
443
+ def ws?
444
+ true
445
+ end
446
+ end
447
+
448
+ class MultiLineComment < Literal
449
+ def initialize(comment, has_lf)
450
+ @comment = comment
451
+ @has_lf = has_lf
452
+ end
453
+
454
+ def traverse(parent, &block)
455
+ end
456
+
457
+ def to_js(options)
458
+ if lt?
459
+ "/*#{@comment}*/"
460
+ else
461
+ "/*#{@comment}*/"
462
+ end
463
+ end
464
+
465
+ def ws?
466
+ !lt?
467
+ end
468
+
469
+ def lt?
470
+ @has_lf ? true : false
471
+ end
472
+ end
473
+
474
+ class IdentifierName < Literal
475
+ attr_accessor :context
476
+ attr_accessor :val
477
+
478
+ @@sym = {}
479
+
480
+ def initialize(context, val)
481
+ @val = val.to_sym
482
+ end
483
+
484
+ def self.get(context, val)
485
+ @@sym[val] ||= self.new(context, val)
486
+ end
487
+
488
+ RESERVED_WORD = [
489
+ :break, :do, :instanceof, :typeof, :case, :else,
490
+ :new, :var, :catch, :finally, :return, :void, :continue,
491
+ :for, :switch, :while,:debugger, :function, :this, :with,
492
+ :default, :if, :throw, :delete, :in, :try,
493
+ :class, :enum, :extends, :super, :const, :export, :import,
494
+ :implements, :let, :private, :public, :yield,
495
+ :interface, :package, :protected, :static,
496
+ :null, :false, :true
497
+ ]
498
+ def reserved?
499
+ RESERVED_WORD.index(val)
500
+ end
501
+
502
+ def self.reserved?(val)
503
+ RESERVED_WORD.index(val)
504
+ end
505
+
506
+ def traverse(parent)
507
+ yield self, parent
508
+ end
509
+
510
+ def to_js(options = {})
511
+ val.to_s
512
+ end
513
+
514
+ def ==(obj)
515
+ self.class == obj.class and self.val == obj.val
516
+ end
517
+ end
518
+
519
+ ID_THIS = IdentifierName.get(nil, :this)
520
+ ID_VAR = IdentifierName.get(nil, :var)
521
+ ID_IN = IdentifierName.get(nil, :in)
522
+ ID_INSTANCEOF = IdentifierName.get(nil, :instanceof)
523
+ ID_FUNCTION = IdentifierName.get(nil, :function)
524
+ ID_NULL = IdentifierName.get(nil, :null)
525
+ ID_TRUE = IdentifierName.get(nil, :true)
526
+ ID_FALSE = IdentifierName.get(nil, :false)
527
+ ID_NEW = IdentifierName.get(nil, :new)
528
+ ID_DELETE = IdentifierName.get(nil, :delete)
529
+ ID_VOID = IdentifierName.get(nil, :void)
530
+ ID_TYPEOF = IdentifierName.get(nil, :typeof)
531
+ ID_IF = IdentifierName.get(nil, :if)
532
+ ID_ELSE = IdentifierName.get(nil, :else)
533
+ ID_FOR = IdentifierName.get(nil, :for)
534
+ ID_WHILE = IdentifierName.get(nil, :while)
535
+ ID_DO = IdentifierName.get(nil, :do)
536
+ ID_CONTINUE = IdentifierName.get(nil, :continue)
537
+ ID_BREAK = IdentifierName.get(nil, :break)
538
+ ID_RETURN = IdentifierName.get(nil, :return)
539
+ ID_WITH = IdentifierName.get(nil, :with)
540
+ ID_SWITCH = IdentifierName.get(nil, :switch)
541
+ ID_THROW = IdentifierName.get(nil, :throw)
542
+ ID_TRY = IdentifierName.get(nil, :try)
543
+ ID_CATCH = IdentifierName.get(nil, :catch)
544
+ ID_FINALLY = IdentifierName.get(nil, :finally)
545
+ ID_DEBUGGER = IdentifierName.get(nil, :debugger)
546
+ ID_GET = IdentifierName.get(nil, :get)
547
+ ID_SET = IdentifierName.get(nil, :set)
548
+ ID_CASE = IdentifierName.get(nil, :case)
549
+ ID_DEFAULT = IdentifierName.get(nil, :default)
550
+
551
+ end
552
+ end
@@ -0,0 +1,84 @@
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
+ end
34
+ PUNC_CONDIF = Punctuator.get('?')
35
+ PUNC_CONDELSE = Punctuator.get(':')
36
+ PUNC_LET = Punctuator.get('=')
37
+ PUNC_DIVLET = Punctuator.get('/=')
38
+ PUNC_MULLET = Punctuator.get('*=')
39
+ PUNC_MODLET = Punctuator.get('%=')
40
+ PUNC_ADDLET = Punctuator.get('+=')
41
+ PUNC_SUBLET = Punctuator.get('-=')
42
+ PUNC_LSHIFTLET = Punctuator.get('<<=')
43
+ PUNC_RSHIFTLET = Punctuator.get('>>=')
44
+ PUNC_URSHIFTLET = Punctuator.get('>>>=')
45
+ PUNC_ANDLET = Punctuator.get('&=')
46
+ PUNC_XORLET = Punctuator.get('^=')
47
+ PUNC_ORLET = Punctuator.get('|=')
48
+ PUNC_LOR = Punctuator.get('||')
49
+ PUNC_LAND = Punctuator.get('&&')
50
+ PUNC_OR = Punctuator.get('|')
51
+ PUNC_XOR = Punctuator.get('^')
52
+ PUNC_AND = Punctuator.get('&')
53
+ PUNC_EQ = Punctuator.get('==')
54
+ PUNC_NEQ = Punctuator.get('!=')
55
+ PUNC_SEQ = Punctuator.get('===')
56
+ PUNC_SNEQ = Punctuator.get('!==')
57
+ PUNC_LT = Punctuator.get('<')
58
+ PUNC_GT = Punctuator.get('>')
59
+ PUNC_LTEQ = Punctuator.get('<=')
60
+ PUNC_GTEQ = Punctuator.get('>=')
61
+ PUNC_LSHIFT = Punctuator.get('<<')
62
+ PUNC_RSHIFT = Punctuator.get('>>')
63
+ PUNC_URSHIFT = Punctuator.get('>>>')
64
+ PUNC_ADD = Punctuator.get('+')
65
+ PUNC_SUB = Punctuator.get('-')
66
+ PUNC_MUL = Punctuator.get('*')
67
+ PUNC_DIV = Punctuator.get('/')
68
+ PUNC_MOD = Punctuator.get('%')
69
+ PUNC_INC = Punctuator.get('++')
70
+ PUNC_DEC = Punctuator.get('--')
71
+ PUNC_NOT = Punctuator.get('~')
72
+ PUNC_LNOT = Punctuator.get('!')
73
+ PUNC_LPARENTHESIS = Punctuator.get('(')
74
+ PUNC_RPARENTHESIS = Punctuator.get(')')
75
+ PUNC_LSQBRAC = Punctuator.get('[')
76
+ PUNC_RSQBRAC = Punctuator.get(']')
77
+ PUNC_LCURLYBRAC = Punctuator.get('{')
78
+ PUNC_RCURLYBRAC = Punctuator.get('}')
79
+ PUNC_COMMA = Punctuator.get(',')
80
+ PUNC_COLON = Punctuator.get(':')
81
+ PUNC_SEMICOLON = Punctuator.get(';')
82
+ PUNC_PERIOD = Punctuator.get('.')
83
+ end
84
+ end