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