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:26:24 +0000
commita5e884858837dbe06f72ef3bf0a3e3bfa3ea917f (patch)
tree8a07630df0097e569958e14f775814c25f2230e6
parent48712d213c4120a22e58ad6bba0e81ae8edba1e0 (diff)
downloadcolm-a5e884858837dbe06f72ef3bf0a3e3bfa3ea917f.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 1a14c43c..e4cb9e1e 100644
--- a/colm/pdarun.c
+++ b/colm/pdarun.c
@@ -1398,24 +1398,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;
}
}