Skip to content

Instantly share code, notes, and snippets.

@deciode
Created August 28, 2013 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deciode/cacdfe88e45b3b43e2bb to your computer and use it in GitHub Desktop.
Save deciode/cacdfe88e45b3b43e2bb to your computer and use it in GitHub Desktop.
# These arrays (stacks, essentially) are for tracking the current state while walking the terms.
ifs, whiles = [], []
# These hashes store the jumps.
@ifs, @whiles = {}, {}
# This bit is pretty obvious.
@terms.each_with_index do |term, offset|
case term
# Handling if and while is pretty simple. Their offsets simply get pushed onto the relevant stack.
# Notice that a single-element array is pushed in the case of if.
when :if
ifs << [offset]
when :while
whiles << offset
# On else, we append two copies of the current offset to the most recently pushed if.
when :else
ifs[-1].concat [offset, offset]
# Then, on endif, everything comes together. If the array had a single element, then the jump
# from an if to its endif gets stored; if it had three, the if links up with its else, and that
# else gets paired with its endif.
when :endif
@ifs.update Hash[*ifs.pop << offset]
# endwhile is easier; whenever we encounter an endwhile, it's obviously related to the most
# recently opened while, whose offset will always be the one at the top of the stack.
when :endwhile
@whiles[offset] = whiles.pop
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment