class CodeTools::AST::When

Attributes

body[RW]
conditions[RW]
single[RW]
splat[RW]

Public Class Methods

new(line, conditions, body) click to toggle source
# File lib/rubinius/code/ast/control_flow.rb, line 85
def initialize(line, conditions, body)
  @line = line
  @body = body || NilLiteral.new(line)
  @splat = nil
  @single = nil

  case conditions
  when ArrayLiteral
    if conditions.body.last.kind_of? When
      last = conditions.body.pop
      if last.conditions.kind_of? ArrayLiteral
        conditions.body.concat last.conditions.body
      elsif last.single
        @splat = SplatWhen.new line, last.single
      else
        @splat = SplatWhen.new line, last.conditions
      end
    end

    if conditions.body.size == 1 and !@splat
      @single = conditions.body.first
    else
      @conditions = conditions
    end
  when SplatValue, ConcatArgs, PushArgs
    @splat = SplatWhen.new line, conditions
    @conditions = nil
  else
    @conditions = conditions
  end
end

Public Instance Methods

bytecode(g, done) click to toggle source
# File lib/rubinius/code/ast/control_flow.rb, line 153
def bytecode(g, done)
  pos(g)

  nxt = g.new_label
  body = g.new_label

  if @single
    @single.bytecode(g)
    g.goto_if_false nxt
  else
    if @conditions
      @conditions.body.each do |condition|
        condition.bytecode(g)
        g.goto_if_true body
      end
    end

    @splat.bytecode(g, body, nxt) if @splat
    g.goto nxt

    body.set!
  end

  @body.bytecode(g)
  g.goto done

  nxt.set!
end
condition_bytecode(g, condition) click to toggle source
# File lib/rubinius/code/ast/control_flow.rb, line 117
def condition_bytecode(g, condition)
  condition.pos(g)
  g.dup
  condition.bytecode(g)
  g.swap
  g.send :===, 1
end
receiver_bytecode(g, done) click to toggle source
# File lib/rubinius/code/ast/control_flow.rb, line 125
def receiver_bytecode(g, done)
  body = g.new_label
  nxt = g.new_label

  if @single
    condition_bytecode(g, @single)
    g.goto_if_false nxt
  else
    if @conditions
      @conditions.body.each do |c|
        condition_bytecode(g, c)
        g.goto_if_true body
      end
    end

    @splat.receiver_bytecode(g, body, nxt) if @splat
    g.goto nxt

    body.set!
  end

  g.pop
  @body.bytecode(g)
  g.goto done

  nxt.set!
end
to_sexp() click to toggle source
# File lib/rubinius/code/ast/control_flow.rb, line 182
def to_sexp
  if @single
    conditions_sexp = [:array, @single.to_sexp]
  else
    conditions_sexp = @conditions ? @conditions.to_sexp : []
    conditions_sexp << @splat.to_sexp if @splat
  end
  [:when, conditions_sexp, @body.to_sexp]
end