Skip to content

Instantly share code, notes, and snippets.

@alexbevi
Created November 9, 2011 14:03
Show Gist options
  • Save alexbevi/1351521 to your computer and use it in GitHub Desktop.
Save alexbevi/1351521 to your computer and use it in GitHub Desktop.
Ruby GOTO
require 'goto'
def test
frame_start
label(:start) { goto :b }
label(:a) { print "world!\n"; goto :c }
label(:b) { print "hello "; goto :a }
label(:c)
frame_end
end
frame_start
label(:a) { test }
label(:b) { goto :a }
frame_end
STACK = []
class Label
attr_accessor :name;
attr_accessor :block;
def initialize(name, block);
@name = name
@block = block
end
def ==(sym)
@name == sym
end
end
class Goto < Exception;
attr_accessor :label
def initialize(label); @label = label; end
end
def label(sym, &block)
STACK.last << Label.new(sym, block)
end
def frame_start
STACK << []
end
def frame_end
frame = STACK.pop
idx = 0
begin
for i in (idx...frame.size)
frame[i].block.call if frame[i].block
end
rescue Goto => g
idx = frame.index(g.label)
retry
end
end
def goto(label)
raise Goto.new(label)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment