Created
October 3, 2009 11:50
-
-
Save wvanbergen/200607 to your computer and use it in GitHub Desktop.
A method to evaluate static parts of a ParseTree syntax tree.
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
class ParseTree | |
# Evaluates a static part of the tree that ParseTree.translate returns. | |
# You can pas a block that will be used to get a value that is not static. | |
# A simple example: | |
# | |
# >> code = '{ :array => ["str", 123, 4.5], :dynamic => method_call }' | |
# >> tree = ParseTree.translate(code) | |
# => [:hash, [:lit, :array], [:array, [:str, "str"], [:lit, 123], [:lit, 4.5]], | |
# [:lit, :dynamic], [:vcall, :method_call]] | |
# >> ParseTree.eval_static_tree(tree) | |
# RuntimeError: tree is not static: :vcall ... | |
# >> ParseTree.eval_static_tree(tree) { nil } | |
# => {:dynamic=>nil, :array=>["str", 123, 4.5]} | |
# | |
# <tt>tree</tt>:: The (sub)tree to evaluate. Should be (a part of) the | |
# array ParseTree.translate(str) returns | |
# <tt>&block</tt>:: A handler block for non-static elements. | |
def self.eval_static_tree(tree, &block) | |
case node_type = tree.shift | |
when :lit, :str then tree.last | |
when :array then tree.map { |child| eval_static_tree(child, &block) } | |
when :hash | |
hash = {} | |
hash[eval_static_tree(tree.shift, &block)] = eval_static_tree(tree.shift, &block) until tree.empty? | |
return hash | |
else | |
if block_given? | |
yield(tree.unshift(node_type)) | |
else | |
raise "Tree node is not static: #{node_type.inspect}" | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment