Class: Ruby2JS::Converter

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby2js/converter.rb,
lib/ruby2js/converter/if.rb,
lib/ruby2js/converter/arg.rb,
lib/ruby2js/converter/def.rb,
lib/ruby2js/converter/for.rb,
lib/ruby2js/converter/nil.rb,
lib/ruby2js/converter/sym.rb,
lib/ruby2js/converter/var.rb,
lib/ruby2js/converter/args.rb,
lib/ruby2js/converter/case.rb,
lib/ruby2js/converter/cvar.rb,
lib/ruby2js/converter/defs.rb,
lib/ruby2js/converter/dstr.rb,
lib/ruby2js/converter/hash.rb,
lib/ruby2js/converter/ivar.rb,
lib/ruby2js/converter/next.rb,
lib/ruby2js/converter/self.rb,
lib/ruby2js/converter/send.rb,
lib/ruby2js/converter/xstr.rb,
lib/ruby2js/converter/array.rb,
lib/ruby2js/converter/begin.rb,
lib/ruby2js/converter/block.rb,
lib/ruby2js/converter/break.rb,
lib/ruby2js/converter/casgn.rb,
lib/ruby2js/converter/class.rb,
lib/ruby2js/converter/const.rb,
lib/ruby2js/converter/masgn.rb,
lib/ruby2js/converter/super.rb,
lib/ruby2js/converter/undef.rb,
lib/ruby2js/converter/until.rb,
lib/ruby2js/converter/vasgn.rb,
lib/ruby2js/converter/while.rb,
lib/ruby2js/converter/cvasgn.rb,
lib/ruby2js/converter/ivasgn.rb,
lib/ruby2js/converter/module.rb,
lib/ruby2js/converter/opasgn.rb,
lib/ruby2js/converter/regexp.rb,
lib/ruby2js/converter/return.rb,
lib/ruby2js/converter/boolean.rb,
lib/ruby2js/converter/defined.rb,
lib/ruby2js/converter/kwbegin.rb,
lib/ruby2js/converter/literal.rb,
lib/ruby2js/converter/logical.rb,
lib/ruby2js/converter/blockpass.rb,
lib/ruby2js/converter/prototype.rb,
lib/ruby2js/converter/untilpost.rb,
lib/ruby2js/converter/whilepost.rb

Constant Summary collapse

LOGICAL =
:and, :not, :or
OPERATORS =
[:[], :[]=], [:not, :!], [:*, :/, :%], [:+, :-], [:>>, :<<], 
[:<=, :<, :>, :>=], [:==, :!=, :===, :"!=="], [:and, :or]
INVERT_OP =
{
  :<  => :>=,
  :<= => :>,
  :== => :!=,
  :!= => :==,
  :>  => :<=,
  :>= => :<,
  :=== => :'!=='
}
EXPRESSIONS =
[ :array, :float, :hash, :int, :lvar, :nil, :send, :attr,
:str, :sym, :dstr, :dsym, :cvar, :ivar, :zsuper, :super, :or, :and ]
@@handlers =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(ast, vars = {}) ⇒ Converter

Returns a new instance of Converter.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/ruby2js/converter.rb', line 21

def initialize( ast, vars = {} )
  @ast, @vars = ast, vars.dup
  @sep = '; '
  @nl = ''
  @ws = ' '
  @varstack = []
  @width = 80
  @next_token = :return

  @handlers = {}
  @@handlers.each do |name|
    @handlers[name] = method("on_#{name}")
  end
end

Instance Attribute Details

#bindingObject

Returns the value of attribute binding.



19
20
21
# File 'lib/ruby2js/converter.rb', line 19

def binding
  @binding
end

#ivarsObject

Returns the value of attribute ivars.



19
20
21
# File 'lib/ruby2js/converter.rb', line 19

def ivars
  @ivars
end

Class Method Details

.handle(*types, &block) ⇒ Object



71
72
73
74
75
76
# File 'lib/ruby2js/converter.rb', line 71

def self.handle(*types, &block)
  types.each do |type| 
    define_method("on_#{type}", block)
    @@handlers << type
  end
end

Instance Method Details

#combine_properties(body) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ruby2js/converter/begin.rb', line 34

def combine_properties(body)
  for i in 0...body.length-1
    next unless body[i] and body[i].type == :prop
    for j in i+1...body.length
      break unless body[j] and body[j].type == :prop
      if body[i].children[0] == body[j].children[0]
        merge = Hash[(body[i].children[1].to_a+body[j].children[1].to_a).
          group_by {|name, value| name.to_s}.map {|name, values|
          [name, values.map(&:last).reduce(:merge)]}]
        body[j] = s(:prop, body[j].children[0], merge)
        body[i] = nil
        break
      end
    end
  end
end

#enable_vertical_whitespaceObject



36
37
38
39
40
# File 'lib/ruby2js/converter.rb', line 36

def enable_vertical_whitespace
  @sep = ";\n"
  @nl = "\n"
  @ws = @nl
end

#group(ast) ⇒ Object



92
93
94
# File 'lib/ruby2js/converter.rb', line 92

def group( ast )
  "(#{ parse ast })"
end

#operator_index(op) ⇒ Object



54
55
56
# File 'lib/ruby2js/converter.rb', line 54

def operator_index op
  OPERATORS.index( OPERATORS.find{ |el| el.include? op } ) || -1
end

#parse(ast, state = :expression) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ruby2js/converter.rb', line 78

def parse(ast, state=:expression)
  return ast unless ast

  @state = state
  @ast = ast
  handler = @handlers[ast.type]

  unless handler
    raise NotImplementedError, "unknown AST type #{ ast.type }"
  end

  handler.call(*ast.children) if handler
end

#s(type, *args) ⇒ Object



66
67
68
# File 'lib/ruby2js/converter.rb', line 66

def s(type, *args)
  Parser::AST::Node.new(type, args)
end

#scope(ast, args = nil) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/ruby2js/converter.rb', line 58

def scope( ast, args=nil )
  @varstack.push @vars.dup
  @vars = args if args
  parse( ast, :statement )
ensure
  @vars = @varstack.pop
end

#to_jsObject



50
51
52
# File 'lib/ruby2js/converter.rb', line 50

def to_js
  parse( @ast, :statement )
end

#transform_defs(target, method, args, body) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ruby2js/converter/defs.rb', line 14

def transform_defs(target, method, args, body)
  if not @ast.is_method? or @ast.type == :defp
    s(:prop, target, method.to_s => 
      {enumerable: s(:true), configurable: s(:true),
      get: s(:block, s(:send, nil, :proc), args,
      s(:autoreturn, body))})
  elsif method =~ /=$/
    s(:prop, target, method.to_s.sub('=', '') => 
      {enumerable: s(:true), configurable: s(:true),
      set: s(:block, s(:send, nil, :proc), args,
      body)})
  else
    s(:send, target, "#{method}=", 
      s(:block, s(:send, nil, :lambda), args, body))
  end
end

#width=(width) ⇒ Object



46
47
48
# File 'lib/ruby2js/converter.rb', line 46

def width=(width)
  @width = width
end