Skip to content

Instantly share code, notes, and snippets.

@wvanbergen
Created October 3, 2009 11:50
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 wvanbergen/200607 to your computer and use it in GitHub Desktop.
Save wvanbergen/200607 to your computer and use it in GitHub Desktop.
A method to evaluate static parts of a ParseTree syntax tree.
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