summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2013-02-06 16:24:40 +0000
committerAdrian Thurston <thurston@complang.org>2013-02-06 16:24:40 +0000
commit839de5ccf33ea0180681ef2e13c16d4409778560 (patch)
tree9124d7794df72078de84b1a4c9fbacf3bb5b7ee4
parent331e2cedecc2f31b9bedaa0fb31106ee0021b5ae (diff)
downloadcolm-839de5ccf33ea0180681ef2e13c16d4409778560.tar.gz
proper, non-recursive implementation of clear parse tree
-rw-r--r--colm/pdarun.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/colm/pdarun.c b/colm/pdarun.c
index 62ab107e..83dffde4 100644
--- a/colm/pdarun.c
+++ b/colm/pdarun.c
@@ -1428,24 +1428,41 @@ Tree *getParsedRoot( PdaRun *pdaRun, int stop )
return 0;
}
-void clearParseTree( Program *prg, Tree **sp, ParseTree *parseTree )
+void clearParseTree( Program *prg, Tree **sp, ParseTree *pt )
{
- /* Traverse the stack downreffing. */
- ParseTree *pt = parseTree;
- while ( pt != 0 ) {
- ParseTree *next = pt->next;
- if ( pt->shadow != 0 ) {
- treeDownref( prg, sp, pt->shadow->tree );
- kidFree( prg, pt->shadow );
- }
- if ( pt->child != 0 )
- clearParseTree( prg, sp, pt->child );
- if ( pt->leftIgnore != 0 )
- clearParseTree( prg, sp, pt->leftIgnore );
- if ( pt->rightIgnore != 0 )
- clearParseTree( prg, sp, pt->rightIgnore );
- parseTreeFree( prg, pt );
- pt = next;
+ Tree **top = vm_ptop();
+
+ if ( pt == 0 )
+ return;
+
+free_tree:
+ if ( pt->next != 0 ) {
+ vm_push( (Tree*)pt->next );
+ }
+
+ if ( pt->leftIgnore != 0 ) {
+ vm_push( (Tree*)pt->leftIgnore );
+ }
+
+ if ( pt->child != 0 ) {
+ vm_push( (Tree*)pt->child );
+ }
+
+ if ( pt->rightIgnore != 0 ) {
+ vm_push( (Tree*)pt->rightIgnore );
+ }
+
+ if ( pt->shadow != 0 ) {
+ treeDownref( prg, sp, pt->shadow->tree );
+ kidFree( prg, pt->shadow );
+ }
+
+ parseTreeFree( prg, pt );
+
+ /* Any trees to downref? */
+ if ( sp != top ) {
+ pt = (ParseTree*)vm_pop();
+ goto free_tree;
}
}