diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..496ee2c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/parse_tree.rb b/parse_tree.rb new file mode 100644 index 0000000..54a785c --- /dev/null +++ b/parse_tree.rb @@ -0,0 +1,33 @@ +# make an "e" method to evaluate a parse tree +# make a "q" method to quote a parse tree +# make a "p" method to create a new parse tree + +class ParseTree + def initialize(nodes) + @nodes = nodes + end + attr_accessor :nodes + def evaluate(array = nodes) + node_method = array.first.keys.first.to_sym + node_object = if array.first.values.first.is_a?(Array) + evaluate(array.first.values.first) + else + array.first.values.first + end + node_arguments = [] + array.rest.each do |element| + node_arguments << if element.is_a?(Array) + evaluate(element) + else + element + end + end + node_object.send( *([node_method] + node_arguments) ) + end +end + +class Array + def rest + self[1..size] + end +end \ No newline at end of file diff --git a/spec/parse_tree_spec.rb b/spec/parse_tree_spec.rb new file mode 100644 index 0000000..8b0e89c --- /dev/null +++ b/spec/parse_tree_spec.rb @@ -0,0 +1,70 @@ +require File.join(File.dirname(__FILE__), "..", "parse_tree") + +describe ParseTree, "#nodes" do + it "should raise an Exception if not initialized" do + lambda {ParseTree.new}.should raise_error + end + + it "should return an arary of nodes when initialized" do + ParseTree.new([{:+ => 1}, 2]).nodes.should == [{:+ => 1}, 2] + end + + it "should be able to add nodes" do + parse_tree = ParseTree.new([{:+ => 1}]) + parse_tree.nodes << 2 + parse_tree.nodes.should == [{:+ => 1}, 2] + end +end + +describe ParseTree, "#evaluate, with terminal parameters and objects" do + it "should be able to evaluate an expression for a parse tree with no parameters" do + parse_tree = ParseTree.new( [{:to_s => 1}] ) + parse_tree.evaluate.should == "1" + end + + it "should be able to evaluate an expression for a parse tree with a parameter" do + parse_tree = ParseTree.new( [{:+ => 1}, 2] ) + parse_tree.evaluate.should == 3 + end + + it "should be able to evaluate an expression for a parse tree with multiple parameters" do + parse_tree = ParseTree.new( [{:new => Array}, 2, 1] ) + parse_tree.evaluate.should == [1, 1] + end +end + +describe ParseTree, "#evaluate, with function parameters" do + it "should be able to evaluate an expression for a simple parse tree" do + parse_tree = ParseTree.new( [ {:+ => 1}, [{:* => 2}, 2] ] ) + parse_tree.evaluate.should == 5 + end + + it "should be able to evaluate an expression for a complex parse tree" do + parse_tree = ParseTree.new( [ {:+ => 2}, [{:+ => 1}, [{:* => 2}, 2]] ] ) + parse_tree.evaluate.should == 7 + end +end + +describe ParseTree, "#evaluate, with function objects" do + it "should be able to evaluate an expression for a simple parse tree" do + parse_tree = ParseTree.new( [ {:+ => 1}, [{:* => 2}, 2] ] ) + parse_tree.evaluate.should == 5 + end + + it "should be able to evaluate an expression for a complex parse tree" do + parse_tree = ParseTree.new( [ {:+ => 2}, [{:+ => 1}, [{:* => 2}, 2]] ] ) + parse_tree.evaluate.should == 7 + end +end + +describe ParseTree, "#evaluate, for complex mixed parameters" do + it "should be able to evaluate" do + parse_tree = ParseTree.new( + [{:+ => [{:+ => 1}, 2]}, + [{:+ => [{:+ => 1}, 2]}, + [{:* => [{:+ => 1}, 2]}, + [{:+ => 1}, 2]]]] + ) + parse_tree.evaluate.should == 15 + end +end \ No newline at end of file