[phc-internals] svn commit by edsko

svn at phpcompiler.org svn at phpcompiler.org
Thu Nov 17 14:59:47 GMT 2005


Implemented the children_xxx methods in the TreeTransform interface.

# Changed
U   phc/doc/website/doc/index.html
U   phc/doc/website/doc/tutorial4.html
U   phc/doc/website/doc/tutorial5.html
U   phc/src/parsing/ast.cpp
U   phc/src/parsing/ast.h
U   phc/src/translation/transform.cpp
U   phc/src/translation/transform.h

# Diff
Modified: phc/doc/website/doc/index.html
===================================================================
--- phc/doc/website/doc/index.html	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/doc/website/doc/index.html	2005-11-17 14:59:45 UTC (rev 396)
@@ -86,6 +86,13 @@
 			that renames all functions <code>foo</code> in a script to
 			<code>db_foo</code>, if there are calls to a database engine within
 			<code>foo</code>.
+			
+			<h3>Tutorial 5: Modifying the Traversal Order</h3>
+			
+			<a href="tutorial5.html">Tuturial 5</a> explains how to modify in
+			which order the children of a node are visited, make sure they do not
+			get visited at all, or simply execute some code in between visiting
+			two children. 
 		
 			<h3>What's in Store?</h3>
 

Modified: phc/doc/website/doc/tutorial4.html
===================================================================
--- phc/doc/website/doc/tutorial4.html	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/doc/website/doc/tutorial4.html	2005-11-17 14:59:45 UTC (rev 396)
@@ -142,9 +142,11 @@
 
 			<h2> What's Next? </h2>
 
-			<p> <a href="tutorial5.html">Tuturial 5</a> explains how to implement
-			transforms that cannot (directly) be implemented using the
-			TreeTransform API. </p>
+			<p> <a href="tutorial5.html">Tuturial 5</a> explains how to modify in
+			which order the children of a node are visited, to make sure they do
+			not get visited at all, or simply execute some code in between
+			visiting two children. </p>
+
 		</td></tr>
 		<tr>
 			<td style="border-top: solid #8a7640 1px; font-size: 8pt; background-color: #efdca5;">

Modified: phc/doc/website/doc/tutorial5.html
===================================================================
--- phc/doc/website/doc/tutorial5.html	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/doc/website/doc/tutorial5.html	2005-11-17 14:59:45 UTC (rev 396)
@@ -20,13 +20,17 @@
 			</td>
 		</tr>
 		<tr><td style="padding: 5px;">
-			<h1>Tutorial 5: More Complicated Transforms</h1>
+			<h1>Tutorial 5: Modifying the Traversal Order</h1>
 
-			<p> In this tutorial we show how to customize tree transforms if the
-			standard tree transform does not provide the functionality you need.
-			As an example, we are going to write a transform that automatically
-			adds comments to the <i>true</i> and <i>false</i> branches of an
-			<i>if</i>-statement. I.e., the following example </p>
+			<p> As explained in the previous tutorials (in particular, <a
+			href="tutorial1.html">Tutorial 1</a>), when the TreeTransform walks
+			over a tree, it first calls <code>pre_xxx</code> for a node of type
+			<i>xxx</i>, it then visits all the children of the node, and finally
+			it calls <code>post_xxx</code> on the node.  For many transforms, this
+			is sufficient &mdash; but not for all.  Consider the following
+			transform. Suppose we want to add comments  to the <i>true</i> and
+			<i>false</i> branches of an <i>if</i>-statement, so that the following
+			example </p>
 
 <pre>
 &lt;?<b>php</b>
@@ -58,170 +62,80 @@
 ?&gt;
 </pre>
 
-			<h2>First Attempt</h2>
+			<p> This appears to be a simple transform. One way to do implement it
+			would be to introduce a flag <code>comment</code> that is set to
+			<code>true</code> when we encounter an <code>AST_if</code> (i.e., in
+			<code>pre_if</code>). Then in <code>post_statement</code> we could
+			check for this flag, and if it is set, we could add the required
+			comment to the statement, and reset the flag to <code>false</code>.
+			</p>
+			
+			<p> However, this will only add a comment to the first statement in
+			the <i>true</i> branch. By rights, we should set the flag to
+			<code>true</code> in between visiting the children of the <i>true</i>
+			branch and visiting the children of the <i>false</i> branch. To be
+			able to do this, we need to modify <code>children_if</code>, as
+			explained in the next section. </p>
 
-			<p> As a first attempt, we write the following transform. </p>
+			<h2> The Solution </h2>
 
-<pre>
-<b>static</b> AST_statement* comment = <b>NULL</b>;
+			<p> For every AST node type <i>xxx</i>, the TreeTransform API defines
+			a method called <code>children_xxx</code>. This method is responsible
+			for visiting all the children of the node. The default implementation
+			for <code>AST_if</code> is: </p>
 
-<b>class</b> CommentIfs : <b>public</b> TreeTransform
-{
-<b>public</b>:
-   <b>void</b> pre_if(AST_if* in, AST_statement** out)
-   {
-      comment = in;   
-   }
-
-   <b>void</b> post_if(AST_if* in, AST_statement** out)
-   {
-      comment = <b>NULL</b>;
-   }
-
-   <b>void</b> pre_statement(AST_statement* in, AST_statement** out)
-   {
-      <b>if</b>(comment &amp;&amp; comment != in)
-      {
-         <b>if</b>(in-&gt;comments-&gt;empty())
-            in-&gt;comments-&gt;push_back(<b>new</b> String("/* TODO: Insert comment */"));
-            
-         comment = <b>NULL</b>;
-      }
-   }
-};
-</pre>
-
-			<p> The basic idea of this transform is that we set a flag
-			<code>comment</code> at the start of every <code>if</code>. Then, for
-			any statement, we check if this flag is set, and if it is set, we add
-			a comment <i>&ldquo;TODO: Insert comment&rdquo;</i> to the statement
-			(if it does not already have a comment). </p>
-
-			<p> There is one complication we have to deal with: the
-			<code>if</code> <i>itself</i> is also a statement. Recall from <a
-			href="tutorial1.html">tutorial 1</a> that <code>pre_statement</code>
-			gets invoked for every statement <i>after</i> the transform for the
-			specific type of statement. For the current example, this means that
-			<code>pre_statement</code> will be invoked on the <code>if</code>
-			statement <i>itself</i>, after <code>pre_if</code>. Thus, if we add
-			the comment to the first statement we see, we will add it to the
-			<code>if</code> statement itself, rather than the first statement
-			<i>in</i> the <code>if</code>. This is why we implement the flag
-			<code>comment</code> as a pointer; when we set the flag, we set the
-			pointer to the <code>if</code> statement, and when we check the flag,
-			we check whether it has been set, and is not equal to the statement we
-			are currently considering &mdash; thus, we will never add the comment
-			to the <code>if</code> statement itself. </p>
-
-			<p> When we run the transform on the example program, we get </p>
-
 <pre>
-&lt;?<b>php</b>
-   <b>if</b>($expr)
-   {
-      <i>/* TODO: Insert comment */</i>
-      <b>print</b>("Do something");
-   }
-   <b>else</b>
-   {
-      <b>print</b>("Do something else");
-   }
-?&gt;
-</pre>
-
-			<p> Obviously, one comment is missing. </p>
-
-			<h2>The Correct Transform</h2>
-
-			<p> The correct transform is slightly more complicated. The problem is
-			that we want to do reset the flag <code>comment</code> in between
-			parsing the <i>true</i> branch and the <i>false</i> branch.
-			Unfortunately, the TreeTransform API does not (directly) allow for
-			this, so we have to customize it. </p>
-			
-			<p> Every class representing AST nodes, such as <code>AST_if</code>,
-			has a method called <code>transform_children</code>. This method is
-			responsible for calling the correct methods from a
-			<code>TreeTransform</code> object on all the children of the object.
-			The default implementation for <code>AST_if</code> is </p>
-
-<pre>
-<b>void</b> transform_children(TreeTransform* transform)
-{
-   TRANSFORM(AST_expr*, expr);
-   TRANSFORM_VECTOR(AST_statement*, iftrue);
-   TRANSFORM_VECTOR(AST_statement*, iffalse);
+<b>void</b> children_if(AST_if* node)
+{  
+   TRANSFORM(AST_expr*, node-&gt;expr);
+   TRANSFORM_VECTOR(AST_statement*, node-&gt;iftrue);
+   TRANSFORM_VECTOR(AST_statement*, node-&gt;iffalse);
 }
 </pre>
-	
+
 			<p> <code>TRANSFORM</code> and <code>TRANSFORM_VECTOR</code> are
-			macros defined in <code>transform.h</code>; the first argument is the
-			type of the child (or the type of the children in the vector), and the
-			second is the name of the child. The macro will then call the
-			appropriate method in <code>transform</code>. </p>
+			defined in <code>transform.h</code>; the first argument the type of
+			the node, and the second argument is the name of the node to visit.
+			<code>TRANSFORM_VECTOR</code> calls <code>TRANSFORM</code> for every
+			element of the specified vector. So, if you want to change the order
+			in which the children of a node are visited, or not visit some
+			children at all, or simply execute some code in between two children,
+			this is the method you need to modify. </p>
 
-			<p> In the transform we require, we need to reset <code>comment</code>
-			in between the <i>true</i> and <i>false</i> branches. Thus, we need to
-			override <code>transform_children</code> in <code>AST_if</code>.
-			However, we don't want to modify <code>AST_if</code> itself; this
-			would entangle the transformation code with the <span
-			class="phc">phc</span> base code for the AST, which is Bad Idea.
-			Instead, we will create a new class <code>ProcIf</code> that inherits
-			from <code>AST_if</code>, and override <code>transform_children</code>
-			in this new class. We then modify the TreeTransform so that it
-			translates <code>AST_if</code> nodes into <code>ProcIf</code> nodes.
-			At the end of processing an if, we change the <code>ProcIf</code> node back to an <code>AST_if</code> node. </p> 
+			<p> Here is the transform that does what we need: </p>
 
 <pre>
-<b>static</b> AST_statement* comment = <b>NULL</b>;
-
-<b>class</b> ProcIf : <b>public</b> AST_if
+<b>class</b> CommentIfs : <b>public</b> TreeTransform
 {
-<b>public</b>:
-   ProcIf(AST_if* i) : AST_if(i) {}
+<b>private</b>:
+	<b>bool</b> comment;
 
 <b>public</b>:
-   <b>void</b> transform_children(TreeTransform* transform)
-   {
-      TRANSFORM(AST_expr*, expr);
-      comment = <b>this</b>;   
-      TRANSFORM_VECTOR(AST_statement*, iftrue);
-      comment = <b>this</b>;   
-      TRANSFORM_VECTOR(AST_statement*, iffalse);
-      comment = <b>NULL</b>;
-   }
-};
+	CommentIfs()
+	{
+		comment = <b>false</b>; 
+	}
 
-<b>class</b> CommentIfs : <b>public</b> TreeTransform
-{
-<b>public</b>:
-   <b>void</b> pre_if(AST_if* in, AST_statement** out)
-   {
-      *out = <b>new</b> ProcIf(in);
-   }
+	<b>void</b> children_if(AST_if* node)
+	{
+		TRANSFORM(AST_expr*, node-&gt;expr);
+		comment = <b>true</b>;
+		TRANSFORM_VECTOR(AST_statement*, node-&gt;iftrue);
+		comment = <b>true</b>;
+		TRANSFORM_VECTOR(AST_statement*, node-&gt;iffalse);
+		comment = <b>false</b>;
+	}
 
-   <b>void</b> post_if(AST_if* in, AST_statement** out)
-   {
-      *out = <b>new</b> AST_if(in);
-   }
+	<b>void</b> post_statement(AST_statement* in, AST_statement** out)
+	{
+		<b>if</b>(comment &amp;&amp; in-&gt;comments-&gt;empty())
+			in-&gt;comments-&gt;push_back(new String("/* TODO: Insert comment */"));
 
-   <b>void</b> pre_statement(AST_statement* in, AST_statement** out)
-   {
-      <b>if</b>(comment &amp;&amp; comment != in)
-      {
-         if(in-&gt;comments-&gt;empty())
-            in-&gt;comments-&gt;push_back(<b>new</b> String("/* TODO: Insert comment */"));
-            
-         comment = <b>NULL</b>;
-      }
-   }
+		comment = <b>false</b>;
+	}
 };
 </pre>
 
-			<p> Running this transform gives the desired result. By customizing
-			nodes in the tree in this way, you can implement (nearly) all the
-			transforms you can think of. </p>
-
 			<h2> What's Next? </h2>
 		
 			<p> This is the last tutorial in this series on using the

Modified: phc/src/parsing/ast.cpp
===================================================================
--- phc/src/parsing/ast.cpp	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/src/parsing/ast.cpp	2005-11-17 14:59:45 UTC (rev 396)
@@ -278,13 +278,6 @@
  * Statements
  */
 
-AST_if::AST_if(AST_if* other)
-{
-	expr					= other->expr;
-	iftrue				= other->iftrue;
-	iffalse				= other->iffalse;
-}
-
 AST_if::AST_if(AST_expr* e, AST_statement* t, AST_statement* f)
 {
 	expr					= e;

Modified: phc/src/parsing/ast.h
===================================================================
--- phc/src/parsing/ast.h	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/src/parsing/ast.h	2005-11-17 14:59:45 UTC (rev 396)
@@ -465,7 +465,6 @@
 	V(statement) iffalse;
 
 public:
-	AST_if(AST_if* other);
 	AST_if(AST_expr* e, AST_statement* t, AST_statement* f);
 	AST_if(AST_expr* e, V(statement) t, V(statement) f);
 	

Modified: phc/src/translation/transform.cpp
===================================================================
--- phc/src/translation/transform.cpp	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/src/translation/transform.cpp	2005-11-17 14:59:45 UTC (rev 396)
@@ -9,359 +9,658 @@
 #include "transform.h"
 
 /*
- * Implementation of "transform_children"
+ * Implementation of "transform_children" in TreeTransform
  */
 
 // Overall structure
 
+void TreeTransform::children_php_script(AST_php_script* node)
+{
+	TRANSFORM_VECTOR(AST_interface_def*, node->interface_defs);
+	TRANSFORM_VECTOR(AST_class_def*, node->class_defs);
+}
+
+void TreeTransform::children_interface_def(AST_interface_def* node)
+{
+	TRANSFORM(Token_interface_name*, node->interface_name);
+	TRANSFORM_VECTOR(Token_interface_name*, node->extends);
+	TRANSFORM_VECTOR(AST_member*, node->members);
+}
+
+void TreeTransform::children_class_def(AST_class_def* node)
+{
+	TRANSFORM(AST_class_mod*, node->class_mod);
+	TRANSFORM(Token_class_name*, node->class_name);
+	TRANSFORM(Token_class_name*, node->extends);
+	TRANSFORM_VECTOR(Token_interface_name*, node->implements);
+	TRANSFORM_VECTOR(AST_member*, node->members);
+}
+
+void TreeTransform::children_class_mod(AST_class_mod* node)
+{
+	// no children
+}
+
+void TreeTransform::children_method(AST_method* node)
+{
+	TRANSFORM(AST_signature*, node->signature);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_signature(AST_signature* node)
+{
+	TRANSFORM(AST_method_mod*, node->method_mod);
+	TRANSFORM(Token_function_name*, node->function_name);
+	TRANSFORM_VECTOR(AST_formal_parameter*, node->formal_parameters);
+}
+
+void TreeTransform::children_method_mod(AST_method_mod* node)
+{
+	// no children	
+}
+
+void TreeTransform::children_formal_parameter(AST_formal_parameter* node)
+{
+	TRANSFORM(AST_type*, node->type);
+	TRANSFORM(Token_variable_name*, node->variable_name);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_type(AST_type* node)
+{
+	TRANSFORM(Token_class_name*, node->class_name);
+}
+
+void TreeTransform::children_attribute(AST_attribute* node)
+{
+	TRANSFORM(AST_attr_mod*, node->attr_mod);
+	TRANSFORM(Token_variable_name*, node->variable_name);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_attr_mod(AST_attr_mod* node)
+{
+	// no children	
+}
+
+void TreeTransform::children_if(AST_if* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM_VECTOR(AST_statement*, node->iftrue);
+	TRANSFORM_VECTOR(AST_statement*, node->iffalse);
+}
+
+void TreeTransform::children_while(AST_while* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_do(AST_do* node)
+{
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_for(AST_for* node)
+{
+	TRANSFORM_VECTOR(AST_expr*, node->init);
+	TRANSFORM_VECTOR(AST_expr*, node->cond);
+	TRANSFORM_VECTOR(AST_expr*, node->incr);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_foreach(AST_foreach* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM(AST_variable*, node->key);
+	TRANSFORM(AST_variable*, node->val);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_switch(AST_switch* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM_VECTOR(AST_switch_case*, node->switch_cases);
+}
+
+void TreeTransform::children_switch_case(AST_switch_case* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_break(AST_break* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_continue(AST_continue* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_return(AST_return* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_global_declaration(AST_global_declaration* node)
+{
+	TRANSFORM_VECTOR(AST_variable_name*, node->variable_names);
+}
+
+void TreeTransform::children_static_declaration(AST_static_declaration* node)
+{
+	TRANSFORM_VECTOR(AST_static_var*, node->static_vars);
+}
+
+void TreeTransform::children_static_var(AST_static_var* node)
+{
+	TRANSFORM(Token_variable_name*, node->variable_name);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_unset(AST_unset* node)
+{
+	TRANSFORM_VECTOR(AST_variable*, node->variables);
+}
+
+void TreeTransform::children_declare(AST_declare* node)
+{
+	TRANSFORM_VECTOR(AST_directive*, node->directives);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_directive(AST_directive* node)
+{
+	TRANSFORM(Token_directive_name*, node->directive_name);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_try(AST_try* node)
+{
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+	TRANSFORM_VECTOR(AST_catch*, node->catches);
+}
+
+void TreeTransform::children_catch(AST_catch* node)
+{
+	TRANSFORM(Token_class_name*, node->class_name);
+	TRANSFORM(Token_variable_name*, node->variable_name);
+	TRANSFORM_VECTOR(AST_statement*, node->statements);
+}
+
+void TreeTransform::children_throw(AST_throw* node)
+{
+	TRANSFORM(AST_expr*, node->expr);	
+}
+
+void TreeTransform::children_eval_expr(AST_eval_expr* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+// Expressions
+
+void TreeTransform::children_assignment(AST_assignment* node)
+{
+	TRANSFORM(AST_refable_expr*, node->dst);
+	TRANSFORM(AST_expr_opt_ref*, node->src);
+}
+
+void TreeTransform::children_refed_expr(AST_refed_expr* node)
+{
+	TRANSFORM(AST_refable_expr*, node->refable_expr);
+}
+
+void TreeTransform::children_list_assignment(AST_list_assignment* node)
+{
+	TRANSFORM(AST_list_elements*, node->list_elements);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_list_elements(AST_list_elements* node)
+{
+	TRANSFORM_VECTOR(AST_list_element*, node->list_elements);
+}
+
+void TreeTransform::children_cast(AST_cast* node)
+{
+	TRANSFORM(Token_cast*, node->cast);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_unary_op(AST_unary_op* node)
+{
+	TRANSFORM(Token_op*, node->op);
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+void TreeTransform::children_bin_op(AST_bin_op* node)
+{
+	TRANSFORM(AST_expr*, node->left);
+	TRANSFORM(Token_op*, node->op);
+	TRANSFORM(AST_expr*, node->right);
+}
+
+void TreeTransform::children_conditional_expr(AST_conditional_expr* node)
+{
+	TRANSFORM(AST_expr*, node->cond);
+	TRANSFORM(AST_expr*, node->iftrue);
+	TRANSFORM(AST_expr*, node->iffalse);
+}
+
+void TreeTransform::children_ignore_errors(AST_ignore_errors* node)
+{
+	TRANSFORM(AST_expr*, node->expr);	
+}
+
+void TreeTransform::children_constant(AST_constant* node)
+{
+	TRANSFORM(Token_class_name*, node->class_name);
+	TRANSFORM(Token_constant_name*, node->constant_name);
+}
+
+void TreeTransform::children_instanceof(AST_instanceof* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+	TRANSFORM(AST_class_name*, node->class_name);
+}
+
+void TreeTransform::children_variable(AST_variable* node)
+{
+	TRANSFORM(AST_target*, node->target);
+	TRANSFORM(AST_variable_name*, node->variable_name);
+	TRANSFORM_VECTOR(AST_expr*, node->array_indices);
+	TRANSFORM(AST_expr*, node->string_index);
+}
+
+void TreeTransform::children_pre_op(AST_pre_op* node)
+{
+	TRANSFORM(Token_op*, node->op);
+	TRANSFORM(AST_variable*, node->variable);
+}
+
+void TreeTransform::children_post_op(AST_post_op* node)
+{
+	TRANSFORM(AST_variable*, node->variable);
+	TRANSFORM(Token_op*, node->op);
+}
+
+void TreeTransform::children_array(AST_array* node)
+{
+	TRANSFORM_VECTOR(AST_array_elem*, node->array_elems);
+}
+
+void TreeTransform::children_array_elem(AST_array_elem* node)
+{
+	TRANSFORM(AST_expr*, node->key);
+	TRANSFORM(AST_expr_opt_ref*, node->val);
+}
+
+void TreeTransform::children_function_call(AST_function_call* node)
+{
+	TRANSFORM(AST_target*, node->target);
+	TRANSFORM(AST_function_name*, node->function_name);
+	TRANSFORM_VECTOR(AST_expr_opt_ref*, node->params);
+}
+
+void TreeTransform::children_new(AST_new* node)
+{
+	TRANSFORM(AST_class_name*, node->class_name);
+	TRANSFORM_VECTOR(AST_expr_opt_ref*, node->params);
+}
+
+void TreeTransform::children_clone(AST_clone* node)
+{
+	TRANSFORM(AST_expr*, node->expr);
+}
+
+// Terminal symbols
+
+void TreeTransform::children_interface_name(Token_interface_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_class_name(Token_class_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_variable_name(Token_variable_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_function_name(Token_function_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_constant_name(Token_constant_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_directive_name(Token_directive_name* node)
+{
+	// no children
+}
+
+void TreeTransform::children_scalar(Token_scalar* node)
+{
+	// no children
+}
+
+void TreeTransform::children_op(Token_op* node)
+{
+	// no children
+}
+
+void TreeTransform::children_cast(Token_cast* node)
+{
+	// no children
+}
+
+/*
+ * Implementation of transform_children (in the individual AST nodes)
+ */
+
 void AST_php_script::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_interface_def*, interface_defs);
-	TRANSFORM_VECTOR(AST_class_def*, class_defs);
+	transform->children_php_script(this);
 }
 
 void AST_interface_def::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_interface_name*, interface_name);
-	TRANSFORM_VECTOR(Token_interface_name*, extends);
-	TRANSFORM_VECTOR(AST_member*, members);
+	transform->children_interface_def(this);
 }
 
 void AST_class_def::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_class_mod*, class_mod);
-	TRANSFORM(Token_class_name*, class_name);
-	TRANSFORM(Token_class_name*, extends);
-	TRANSFORM_VECTOR(Token_interface_name*, implements);
-	TRANSFORM_VECTOR(AST_member*, members);
+	transform->children_class_def(this);
 }
 
 void AST_class_mod::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_class_mod(this);
 }
 
 void AST_method::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_signature*, signature);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_method(this);
 }
 
 void AST_signature::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_method_mod*, method_mod);
-	TRANSFORM(Token_function_name*, function_name);
-	TRANSFORM_VECTOR(AST_formal_parameter*, formal_parameters);
+	transform->children_signature(this);
 }
 
 void AST_method_mod::transform_children(TreeTransform* transform)
 {
-	// no children	
+	transform->children_method_mod(this);
 }
 
 void AST_formal_parameter::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_type*, type);
-	TRANSFORM(Token_variable_name*, variable_name);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_formal_parameter(this);
 }
 
 void AST_type::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_class_name*, class_name);
+	transform->children_type(this);
 }
 
 void AST_attribute::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_attr_mod*, attr_mod);
-	TRANSFORM(Token_variable_name*, variable_name);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_attribute(this);
 }
 
 void AST_attr_mod::transform_children(TreeTransform* transform)
 {
-	// no children	
+	transform->children_attr_mod(this);
 }
 
 void AST_if::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM_VECTOR(AST_statement*, iftrue);
-	TRANSFORM_VECTOR(AST_statement*, iffalse);
+	transform->children_if(this);
 }
 
 void AST_while::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_while(this);
 }
 
 void AST_do::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_statement*, statements);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_do(this);
 }
 
 void AST_for::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_expr*, init);
-	TRANSFORM_VECTOR(AST_expr*, cond);
-	TRANSFORM_VECTOR(AST_expr*, incr);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_for(this);
 }
 
 void AST_foreach::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM(AST_variable*, key);
-	TRANSFORM(AST_variable*, val);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_foreach(this);
 }
 
 void AST_switch::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM_VECTOR(AST_switch_case*, switch_cases);
+	transform->children_switch(this);
 }
 
 void AST_switch_case::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_switch_case(this);
 }
 
 void AST_break::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
+	transform->children_break(this);
 }
 
 void AST_continue::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
+	transform->children_continue(this);
 }
 
 void AST_return::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
+	transform->children_return(this);
 }
 
 void AST_global_declaration::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_variable_name*, variable_names);
+	transform->children_global_declaration(this);
 }
 
 void AST_static_declaration::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_static_var*, static_vars);
+	transform->children_static_declaration(this);
 }
 
 void AST_static_var::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_variable_name*, variable_name);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_static_var(this);
 }
 
 void AST_unset::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_variable*, variables);
+	transform->children_unset(this);
 }
 
 void AST_declare::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_directive*, directives);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_declare(this);
 }
 
 void AST_directive::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_directive_name*, directive_name);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_directive(this);
 }
 
 void AST_try::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_statement*, statements);
-	TRANSFORM_VECTOR(AST_catch*, catches);
+	transform->children_try(this);
 }
 
 void AST_catch::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_class_name*, class_name);
-	TRANSFORM(Token_variable_name*, variable_name);
-	TRANSFORM_VECTOR(AST_statement*, statements);
+	transform->children_catch(this);
 }
 
 void AST_throw::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);	
+	transform->children_throw(this);
 }
 
 void AST_eval_expr::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
+	transform->children_eval_expr(this);
 }
 
-// Expressions
-
 void AST_assignment::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_refable_expr*, dst);
-	TRANSFORM(AST_expr_opt_ref*, src);
+	transform->children_assignment(this);
 }
 
 void AST_refed_expr::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_refable_expr*, refable_expr);
+	transform->children_refed_expr(this);
 }
 
 void AST_list_assignment::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_list_elements*, list_elements);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_list_assignment(this);
 }
 
 void AST_list_elements::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_list_element*, list_elements);
+	transform->children_list_elements(this);
 }
 
 void AST_cast::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_cast*, cast);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_cast(this);
 }
 
 void AST_unary_op::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_op*, op);
-	TRANSFORM(AST_expr*, expr);
+	transform->children_unary_op(this);
 }
 
 void AST_bin_op::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, left);
-	TRANSFORM(Token_op*, op);
-	TRANSFORM(AST_expr*, right);
+	transform->children_bin_op(this);
 }
 
 void AST_conditional_expr::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, cond);
-	TRANSFORM(AST_expr*, iftrue);
-	TRANSFORM(AST_expr*, iffalse);
+	transform->children_conditional_expr(this);
 }
 
 void AST_ignore_errors::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);	
+	transform->children_ignore_errors(this);
 }
 
 void AST_constant::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_class_name*, class_name);
-	TRANSFORM(Token_constant_name*, constant_name);
+	transform->children_constant(this);
 }
 
 void AST_instanceof::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
-	TRANSFORM(AST_class_name*, class_name);
+	transform->children_instanceof(this);
 }
 
 void AST_variable::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_target*, target);
-	TRANSFORM(AST_variable_name*, variable_name);
-	TRANSFORM_VECTOR(AST_expr*, array_indices);
-	TRANSFORM(AST_expr*, string_index);
+	transform->children_variable(this);
 }
 
 void AST_pre_op::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(Token_op*, op);
-	TRANSFORM(AST_variable*, variable);
+	transform->children_pre_op(this);
 }
 
 void AST_post_op::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_variable*, variable);
-	TRANSFORM(Token_op*, op);
+	transform->children_post_op(this);
 }
 
 void AST_array::transform_children(TreeTransform* transform)
 {
-	TRANSFORM_VECTOR(AST_array_elem*, array_elems);
+	transform->children_array(this);
 }
 
 void AST_array_elem::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, key);
-	TRANSFORM(AST_expr_opt_ref*, val);
+	transform->children_array_elem(this);
 }
 
 void AST_function_call::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_target*, target);
-	TRANSFORM(AST_function_name*, function_name);
-	TRANSFORM_VECTOR(AST_expr_opt_ref*, params);
+	transform->children_function_call(this);
 }
 
 void AST_new::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_class_name*, class_name);
-	TRANSFORM_VECTOR(AST_expr_opt_ref*, params);
+	transform->children_new(this);
 }
 
 void AST_clone::transform_children(TreeTransform* transform)
 {
-	TRANSFORM(AST_expr*, expr);
+	transform->children_clone(this);
 }
 
-// Terminal symbols
-
 void Token_interface_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_interface_name(this);
 }
 
 void Token_class_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_class_name(this);
 }
 
 void Token_variable_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_variable_name(this);
 }
 
 void Token_function_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_function_name(this);
 }
 
 void Token_constant_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_constant_name(this);
 }
 
 void Token_directive_name::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_directive_name(this);
 }
 
 void Token_scalar::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_scalar(this);
 }
 
 void Token_op::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_op(this);
 }
 
 void Token_cast::transform_children(TreeTransform* transform)
 {
-	// no children
+	transform->children_cast(this);
 }
 
 /*

Modified: phc/src/translation/transform.h
===================================================================
--- phc/src/translation/transform.h	2005-11-17 13:22:13 UTC (rev 395)
+++ phc/src/translation/transform.h	2005-11-17 14:59:45 UTC (rev 396)
@@ -20,6 +20,9 @@
 
 class TreeTransform : virtual public Object
 {
+/*
+ * Pre and post transforms
+ */
 public: // Generic methods
 	virtual void pre_member(AST_member* in, AST_member** out) {}
 	virtual void post_member(AST_member* in, AST_member** out) {}
@@ -213,31 +216,95 @@
 
 	virtual void pre_cast(Token_cast* in, Token_cast** out) {}
 	virtual void post_cast(Token_cast* in, Token_cast** out) {}
+
+/*
+ * Transform children
+ */
+public:
+	virtual void children_php_script(AST_php_script* node);
+	virtual void children_interface_def(AST_interface_def* node);
+	virtual void children_class_def(AST_class_def* node);
+	virtual void children_class_mod(AST_class_mod* node);
+	virtual void children_method(AST_method* node);
+	virtual void children_signature(AST_signature* node);
+	virtual void children_method_mod(AST_method_mod* node);
+	virtual void children_formal_parameter(AST_formal_parameter* node);
+	virtual void children_type(AST_type* node);
+	virtual void children_attribute(AST_attribute* node);
+	virtual void children_attr_mod(AST_attr_mod* node);
+	virtual void children_if(AST_if* node);
+	virtual void children_while(AST_while* node);
+	virtual void children_do(AST_do* node);
+	virtual void children_for(AST_for* node);
+	virtual void children_foreach(AST_foreach* node);
+	virtual void children_switch(AST_switch* node);
+	virtual void children_switch_case(AST_switch_case* node);
+	virtual void children_break(AST_break* node);
+	virtual void children_continue(AST_continue* node);
+	virtual void children_return(AST_return* node);
+	virtual void children_global_declaration(AST_global_declaration* node);
+	virtual void children_static_declaration(AST_static_declaration* node);
+	virtual void children_static_var(AST_static_var* node);
+	virtual void children_unset(AST_unset* node);
+	virtual void children_declare(AST_declare* node);
+	virtual void children_directive(AST_directive* node);
+	virtual void children_try(AST_try* node);
+	virtual void children_catch(AST_catch* node);
+	virtual void children_throw(AST_throw* node);
+	virtual void children_eval_expr(AST_eval_expr* node);
+	virtual void children_assignment(AST_assignment* node);
+	virtual void children_refed_expr(AST_refed_expr* node);
+	virtual void children_list_assignment(AST_list_assignment* node);
+	virtual void children_list_elements(AST_list_elements* node);
+	virtual void children_cast(AST_cast* node);
+	virtual void children_unary_op(AST_unary_op* node);
+	virtual void children_bin_op(AST_bin_op* node);
+	virtual void children_conditional_expr(AST_conditional_expr* node);
+	virtual void children_ignore_errors(AST_ignore_errors* node);
+	virtual void children_constant(AST_constant* node);
+	virtual void children_instanceof(AST_instanceof* node);
+	virtual void children_variable(AST_variable* node);
+	virtual void children_pre_op(AST_pre_op* node);
+	virtual void children_post_op(AST_post_op* node);
+	virtual void children_array(AST_array* node);
+	virtual void children_array_elem(AST_array_elem* node);
+	virtual void children_function_call(AST_function_call* node);
+	virtual void children_new(AST_new* node);
+	virtual void children_clone(AST_clone* node);
+	virtual void children_interface_name(Token_interface_name* node);
+	virtual void children_class_name(Token_class_name* node);
+	virtual void children_variable_name(Token_variable_name* node);
+	virtual void children_function_name(Token_function_name* node);
+	virtual void children_constant_name(Token_constant_name* node);
+	virtual void children_directive_name(Token_directive_name* node);
+	virtual void children_scalar(Token_scalar* node);
+	virtual void children_op(Token_op* node);
+	virtual void children_cast(Token_cast* node);
 };
 
-/**
+/*
  * Macro definitions to implement transform_children
  */
 
-#define TRANSFORM_VECTOR(type, vector) 										\
-	{ 																						\
-		if(vector) 																		\
-		{ 																					\
-			Vector<type>::iterator i; 												\
-			for(i = vector->begin(); i != vector->end(); i++) 				\
-				if(*i)																	\
-				{																			\
-					*i = dynamic_cast<type>((*i)->transform(transform));	\
-					assert(*i);															\
-				}																			\
-		} 																					\
+#define TRANSFORM_VECTOR(type, vector) 									\
+	{ 																					\
+		if(vector) 																	\
+		{ 																				\
+			Vector<type>::iterator i; 											\
+			for(i = vector->begin(); i != vector->end(); i++) 			\
+				if(*i)																\
+				{																		\
+					*i = dynamic_cast<type>((*i)->transform(this));		\
+					assert(*i);														\
+				}																		\
+		} 																				\
 	}
 
-#define TRANSFORM(type, member)													\
-	if(member) 																			\
-	{ 																						\
-		member = dynamic_cast<type>(member->transform(transform));		\
-		assert(member);																\
+#define TRANSFORM(type, member)												\
+	if(member) 																		\
+	{ 																					\
+		member = dynamic_cast<type>(member->transform(this));			\
+		assert(member);															\
 	}
 
 #endif /* TREE_TRANSFORM_H */


More information about the phc-internals mailing list