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/nthref.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,
:block ]
@@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
35
# File 'lib/ruby2js/converter.rb', line 21

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

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

Instance Attribute Details

#binding ⇒ Object

Returns the value of attribute binding.



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

def binding
  @binding
end

#ivars ⇒ Object

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



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

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_whitespace ⇒ Object



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

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

#group(ast) ⇒ Object



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

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

#operator_index(op) ⇒ Object



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

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

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



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

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



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

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

#scope(ast, args = nil) ⇒ Object



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

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

#to_js ⇒ Object



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

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



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

def width=(width)
  @width = width
end