[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 — 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>
<?<b>php</b>
@@ -58,170 +62,80 @@
?>
</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 && comment != in)
- {
- <b>if</b>(in->comments->empty())
- in->comments->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>“TODO: Insert comment”</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 — 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>
-<?<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");
- }
-?>
-</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->expr);
+ TRANSFORM_VECTOR(AST_statement*, node->iftrue);
+ TRANSFORM_VECTOR(AST_statement*, node->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->expr);
+ comment = <b>true</b>;
+ TRANSFORM_VECTOR(AST_statement*, node->iftrue);
+ comment = <b>true</b>;
+ TRANSFORM_VECTOR(AST_statement*, node->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 && in->comments->empty())
+ in->comments->push_back(new String("/* TODO: Insert comment */"));
- <b>void</b> pre_statement(AST_statement* in, AST_statement** out)
- {
- <b>if</b>(comment && comment != in)
- {
- if(in->comments->empty())
- in->comments->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