Created
August 28, 2013 22:49
-
-
Save deciode/cacdfe88e45b3b43e2bb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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