lib/minjs/ecma262/lit.rb in minjs-0.2.2 vs lib/minjs/ecma262/lit.rb in minjs-0.3.0
- old
+ new
@@ -84,10 +84,42 @@
end
end
LIT_LINE_FEED = LineFeed.get
+ class This < Literal
+ attr_reader :context
+
+ def initialize(context)
+ @context = context
+ end
+
+ def deep_dup
+ self.class.new(@context)
+ end
+
+ def traverse(parent, &block)
+ yield self, parent
+ end
+
+ def to_s
+ "this"
+ end
+
+ def ==(obj)
+ self.class == obj.class
+ end
+
+ def to_js(options = {})
+ "this"
+ end
+
+ def left_hand_side_exp?
+ true
+ end
+ end
+
class Null < Literal
def initialize(val)
@val = :null
end
@@ -109,10 +141,14 @@
def to_js(options = {})
"null"
end
+ def left_hand_side_exp?
+ true
+ end
+
@@instance = self.new(nil)
def self.get
@@instance
end
@@ -159,10 +195,14 @@
def to_js(options = {})
@val.to_s
end
+ def left_hand_side_exp?
+ true
+ end
+
def true?
@val == :true
end
def to_ecma262_string
@@ -267,10 +307,14 @@
else
t << "\'"
end
end
+ def left_hand_side_exp?
+ true
+ end
+
def to_ecma262_boolean
if @val.length == 0
false
else
true
@@ -292,17 +336,17 @@
else
break
end
end
#hex
- if v[pos] == 0x30 and (v[pos+1] == 0x78 || v[pos+1] == 0x58) and hex_number?(v[pos+2])
+ if v[pos] == 0x30 and (v[pos+1] == 0x78 || v[pos+1] == 0x58) and hex_digit?(v[pos+2])
base = 16
pos += 2
pos0 = pos
while true
break if v[pos].nil?
- if hex_number?(v[pos])
+ if hex_digit?(v[pos])
pos += 1
else
break
end
end
@@ -497,10 +541,12 @@
return "Infinity"
elsif @number == -Float::INFINITY
return "-Infinity"
end
t0 = to_ecma262_string
+ t0.sub!(/^0\./, '.')
+
t = @integer.nil? ? "" : @integer.dup.to_s
d = @decimal.to_s
if d == '0'
d = ''
@@ -524,10 +570,14 @@
t0.sub!(/e\+/, 'e')
t.length <= t0.length ? t : t0
end
+ def left_hand_side_exp?
+ true
+ end
+
def to_i
to_ecma262_string.to_i
end
def to_f
@@ -647,10 +697,14 @@
end
def to_js(options = {})
"/#{@body}/#{@flags}"
end
+
+ def left_hand_side_exp?
+ true
+ end
end
LITERAL_TRUE = Boolean.new(:true)
LITERAL_FALSE = Boolean.new(:false)
@@ -677,10 +731,15 @@
end
def to_js(options = {})
"[" + @val.collect{|x| x.to_s}.join(",") + "]"
end
+
+ def left_hand_side_exp?
+ true
+ end
+
def to_ecma262_boolean
true
end
end
@@ -691,22 +750,10 @@
#val is tupple [[k,v],[k,v],...]
def initialize(val)
@val = val
end
-#=>Ctype
-# def idname?(name)
-# return false if name.length == 0
-# s = name.codepoints
-# return false unless identifier_start?(s[0])
-# s.unshift
-# s.each do |code|
-# return false unless identifier_part?(code)
-# end
-# return true
-# end
-
def deep_dup
self.class.new(@val.collect{|x, y| [x.deep_dup, y ? y.deep_dup : y]})
end
def traverse(parent, &block)
@@ -720,42 +767,36 @@
def ==(obj)
self.class == obj.class and @val == obj.val
end
def to_js(options = {})
- "{" + @val.collect{|x, y|
- if y.kind_of? StFunc and (y.getter? || y.setter?)
- if y.name.val == :get
- t = "get #{x.val.to_s}(){#{y.statements.to_js(options)}}"
- else
- t = "set #{x.val.to_s}(#{y.args[0].to_js(options)}){#{y.statements.to_js(options)}}"
- end
- else
- if x.kind_of? ECMA262Numeric
- a = "#{x.to_ecma262_string}"
- t = a
- elsif idname?(x.val.to_s)
- t = "#{x.val.to_s}"
- else
- t = "#{x.to_js(options)}"
- end
- t << ":#{y.to_js(options)}"
- end
- }.join(",") + "}"
+ concat(options, "{" + @val.collect{|x, y|
+ if y.kind_of? StFunc and (y.getter? || y.setter?)
+ if y.name.val == :get
+ t = concat options, "get", x.val, "()", "{", y.statements, "}"
+ else
+ t = concat options, "set", x.val, "(", y.args[0], ")", "{", y.statements, "}"
+ end
+ else
+ if x.kind_of? ECMA262Numeric
+ t = concat options, x.to_ecma262_string, ":", y
+ elsif idname?(x.val.to_s)
+ t = concat options, x.val, ":", y
+ else
+ t = concat options, x, ":", y
+ end
+ end
+ }.join(","), "}")
end
+
+ def left_hand_side_exp?
+ true
+ end
+
def to_ecma262_boolean
true
end
-# def ecma262_eval(type)
-#
-# case type
-# when :boolean
-# to_ecma262_boolean
-# else
-# nil
-# end
-# end
end
class SingleLineComment < Literal
def initialize(comment)
@comment = comment
@@ -778,39 +819,36 @@
end
end
class MultiLineComment < Literal
attr_reader :comment, :has_lf
+ include Ctype
- def initialize(comment, has_lf)
+ def initialize(comment)
@comment = comment
- @has_lf = has_lf
end
def traverse(parent, &block)
end
def ==(obj)
- self.class == obj.class and
- @comment == obj.comment and
- @has_lf == obj.has_lf
+ self.class == obj.class and @comment == obj.comment
end
def to_js(options)
- if lt?
- "/*#{@comment}*/"
- else
- "/*#{@comment}*/"
- end
+ "/*#{@comment}*/"
end
def ws?
!lt?
end
def lt?
- @has_lf ? true : false
+ @comment.codepoints.each{|char|
+ return true if line_terminator?(char)
+ }
+ false
end
end
class IdentifierName < Literal
attr_accessor :context
@@ -822,11 +860,15 @@
@context = context
@val = val.to_sym
end
def self.get(context, val)
- @@sym[val] ||= self.new(context, val)
+ if reserved?(val)
+ @@sym[val] ||= self.new(context, val)
+ else
+ self.new(context, val)
+ end
end
RESERVED_WORD = Set.new [
:break, :do, :instanceof, :typeof, :case, :else,
:new, :var, :catch, :finally, :return, :void, :continue,
@@ -859,10 +901,14 @@
def to_js(options = {})
val.to_s
end
+ def left_hand_side_exp?
+ true
+ end
+
def binding_env(type = :var)
return nil if context.nil?
if type == :var
v = context.var_env
else
@@ -905,12 +951,13 @@
ID_THROW = IdentifierName.get(nil, :throw)
ID_TRY = IdentifierName.get(nil, :try)
ID_CATCH = IdentifierName.get(nil, :catch)
ID_FINALLY = IdentifierName.get(nil, :finally)
ID_DEBUGGER = IdentifierName.get(nil, :debugger)
- ID_GET = IdentifierName.get(nil, :get)
- ID_SET = IdentifierName.get(nil, :set)
ID_CASE = IdentifierName.get(nil, :case)
ID_DEFAULT = IdentifierName.get(nil, :default)
+ # Note: get and set are not reserved word
+ ID_GET = IdentifierName.get(nil, :get)
+ ID_SET = IdentifierName.get(nil, :set)
end
end