class Rubinius Generator {
  def ip: @ip
  def ip {
    @ip
  }
}

class Fancy AST {
  class Label : Node {
    @@registry = <[]>
    def Label [name] {
      @@registry[name]
    }
    def Label [name]: pos {
      @@registry[name]: pos
    }

    def initialize: @line name: @name
    def bytecode: g {
      pos(g)
      Label[@name]: $ g ip
      g push_nil() # needed
    }
  }

  class Goto : Node {
    def initialize: @line label_name: @label_name
    def bytecode: g {
      pos(g)
      pos = Label[@label_name]
      { "Label not found: #{@label_name}" raise! } unless: pos
      tmp_ip = g ip
      g ip: pos
      label = g new_label()
      label set!()
      g ip: tmp_ip
      g goto(label)
    }
  }
}

Allow forward references of labels and skip push_nil weirdness (+2)
class Rubinius Generator {
  def ip: @ip
  def ip {
    @ip
  }
}

class Fancy AST {
  class Label : Node {
    @@registry = <[]>
    def Label [name] {
      @@registry[name]
    }
    def Label [name]: label {
      @@registry[name]: label
    }

    def initialize: @line name: @name
    def bytecode: g {
      pos(g)
      label = Label[@name]
      unless: label do: {
        label = g new_label()
        Label[@name]: label
      }
      tmp = g ip
      g ip: (tmp + 2)
      label set!()
      g ip: tmp
      g push_nil()
    }
  }

  class Goto : Node {
    def initialize: @line label_name: @label_name
    def bytecode: g {
      pos(g)
      label = Label[@label_name]
      unless: label do: {
        label = g new_label()
        Label[@label_name]: label
      }
      g goto(label)
    }
  }
}