<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,9 +1,11 @@
 == 1.0.4 / 2008-11-17
 
-* 3 minor enhancements
+* 4 minor enhancements
   * Updated array traversal code to be recursive by default
   * Updated visitor code to use class instances instead of class-level methods for greater flexibility
   * Updated error handling to include parsing context in error message
+  * Added clone method for deep copy of AST
+  * Updated node building to set node parents for easier traversal of the AST
 
 == 1.0.0 / 2008-06-29
 </diff>
      <filename>History.txt</filename>
    </modified>
    <modified>
      <diff>@@ -31,6 +31,8 @@ module TireSwing
       @attribute_mapping ||= {}
     end
 
+    attr_accessor :parent
+
     # Instantiate a node.
     #
     # Values can either be a hash of values to set the values of this node's attributes, or a Treetop syntax node
@@ -57,15 +59,7 @@ module TireSwing
     def build_from_parsed_node(parsed_node)
       attributes.each do |attrib|
         if handler = mapping(attrib)
-          if handler.kind_of?(Proc)
-            value = handler.call(parsed_node)
-          else
-            if parsed_node.respond_to?(handler)
-              value = parsed_node.send(handler)
-            else
-              value = parsed_node.text_value.send(handler)
-            end
-          end
+          value = apply_mapping(handler, parsed_node)
         else
           value = parsed_node.send(attrib)
         end
@@ -80,9 +74,25 @@ module TireSwing
       end
     end
 
+    def apply_mapping(handler, parsed_node)
+      # TODO add in handler for arrays of methods to call in order
+      if handler.kind_of?(Proc)
+        value = handler.call(parsed_node)
+      else
+        # TODO need to add more error checking
+        if parsed_node.respond_to?(handler)
+          value = parsed_node.send(handler)
+        else
+          value = parsed_node.text_value.send(handler)
+        end
+      end
+    end
+
     def extract_value(value)
       if value.respond_to?(:build)
-        value.build
+        node = value.build
+        node.parent = self if node.kind_of?(Node)
+        node
       elsif value.kind_of?(Treetop::Runtime::SyntaxNode)
         value.text_value
       else</diff>
      <filename>lib/tire_swing/node.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,15 +2,16 @@ module TireSwing::NodeDefinition
 
   module ModuleMethods
 
-    # Returns a NodeCreator to act as a stand-in for a normal node class definition.
+    # Returns a NodeCreator to act as a stand-in for a node class in the treetop parser.
     # According to the treetop metagrammar, node class definitions can have more than just a class in them.
-    # For example:
+    #
+    # Given the initial grammar,
     #
     #   rule variable
     #     [a-z]+ &lt;Variable&gt;
     #   end
     #
-    # Instead, use this method to use AST node auto-build functionality. Given
+    # you might instead use use the AST node auto-build functionality. Given
     #
     #   node :variable, :value =&gt; :text_value
     #
@@ -20,6 +21,8 @@ module TireSwing::NodeDefinition
     #     [a-z]+ &lt;node(:variable)&gt;
     #   end
     #
+    # and voila, you'll magically have a Variable node with a #value attribute containing the text value.
+    #
     # Also note that you can specify alternate namespaces:
     #
     #   module AST
@@ -28,15 +31,15 @@ module TireSwing::NodeDefinition
     #
     #   &lt;AST.create_node(:variable)&gt;
     #
-    # When you're using the parser extension:
+    # and when you're using the parser extension, tell the parser about the namespace
     #
     #   TireSwing.parses_grammar(Grammar, AST)
     #
-    # you can use
+    # and then you can use the shortest possible syntax,
     #
     #   &lt;node(...)&gt;
     #
-    # Which is an instance method wrapper for the create_node class method.
+    # which is an instance method wrapper for the create_node class method.
     #
     def create_node(name)
       TireSwing::NodeCreator.new(name, const_get(name.to_s.camelize))</diff>
      <filename>lib/tire_swing/node_definition.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2,6 +2,13 @@ require File.join(File.dirname(__FILE__), %w[spec_helper])
 
 describe TireSwing::Node do
 
+  it &quot;has a parent accessor&quot; do
+    node = TireSwing::Node.new
+    node.parent.should be_nil
+    node.parent = :parent
+    node.parent.should == :parent
+  end
+
   describe &quot;.create&quot; do
     it &quot;returns a class that inherits from TireSwing::Node&quot; do
       klass = TireSwing::Node.create
@@ -120,6 +127,16 @@ describe TireSwing::Node do
           TireSwing::Node.create(:foo =&gt; :children).new(@top).foo.should == [&quot;foo&quot;, 1, &quot;child&quot;]
         end
 
+        it &quot;assigns the parent node if the child node is also a TireSwing node&quot; do
+          @top.should_receive(:child).and_return(@child)
+          node = TireSwing::Node.create(:foo =&gt; :child)
+          child_node = TireSwing::Node.new
+          @child.should_receive(:build).and_return(child_node)
+          new_top = node.new(@top)
+          new_top.foo.should == child_node
+          child_node.parent.should == new_top
+        end
+
       end
 
       it &quot;yields the syntax node instance if a named attribute is a lambda&quot; do
@@ -141,7 +158,7 @@ describe TireSwing::Node do
 
   describe &quot;#clone&quot; do
     it &quot;does a deep copy of a node&quot; do
-      # can't leave this as an anonymous class, marshal dump/load don't like it
+      # can't leave this as an anonymous class, marshal dump/load doesn't like it
       MyNode = TireSwing::Node.create
       node = MyNode.new
       node.clone.should_not eql node</diff>
      <filename>spec/node_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>b3850b22cb77f2bccc959ce43136481eb78a7f5b</id>
    </parent>
  </parents>
  <author>
    <name>Nathan Witmer</name>
    <email>nwitmer@gmail.com</email>
  </author>
  <url>http://github.com/aniero/tire_swing/commit/0da39edd937c82769b7a8d075ccb63a011c13d5a</url>
  <id>0da39edd937c82769b7a8d075ccb63a011c13d5a</id>
  <committed-date>2008-11-18T16:21:57-08:00</committed-date>
  <authored-date>2008-11-18T07:33:30-08:00</authored-date>
  <message>Added parent tracking for nodes</message>
  <tree>f64f45692c8eccc41e61c4901d99f99311cc522b</tree>
  <committer>
    <name>Nathan Witmer</name>
    <email>nwitmer@gmail.com</email>
  </committer>
</commit>
