summaryrefslogtreecommitdiff
path: root/src/iter.c
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2014-11-05 20:58:59 -0500
committerAdrian Thurston <thurston@complang.org>2014-11-05 20:58:59 -0500
commit8795ba68cd238f4e9a9b80e36788ede597669895 (patch)
tree75532ed1a6a338fd277d83605b4d16818491cf51 /src/iter.c
parentc20284bb779dee69799a09c6257f80c2ab868aec (diff)
downloadcolm-8795ba68cd238f4e9a9b80e36788ede597669895.tar.gz
allow breaking from for loops where args are non-references
The triter destroy will now pop temps created for iterator args that can't be referenced. They are tracked in the compile, specified in the create, and used in the destroy.
Diffstat (limited to 'src/iter.c')
-rw-r--r--src/iter.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/iter.c b/src/iter.c
index 8022d1ff..aded50ad 100644
--- a/src/iter.c
+++ b/src/iter.c
@@ -10,7 +10,8 @@
#define true 1
#define false 0
-void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long rootSize,
+void initTreeIter( TreeIter *treeIter, Tree **stackRoot,
+ long argSize, long rootSize,
const Ref *rootRef, int searchId )
{
treeIter->type = IT_Tree;
@@ -21,9 +22,11 @@ void initTreeIter( TreeIter *treeIter, Tree **stackRoot, long rootSize,
treeIter->rootSize = rootSize;
treeIter->ref.kid = 0;
treeIter->ref.next = 0;
+ treeIter->argSize = argSize;
}
-void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot, long rootSize,
+void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot,
+ long argSize, long rootSize,
const Ref *rootRef, int searchId, int children )
{
revTriter->type = IT_RevTree;
@@ -36,6 +39,7 @@ void initRevTreeIter( RevTreeIter *revTriter, Tree **stackRoot, long rootSize,
revTriter->children = children;
revTriter->ref.kid = 0;
revTriter->ref.next = 0;
+ revTriter->argSize = argSize;
}
void initUserIter( UserIter *userIter, Tree **stackRoot, long rootSize,
@@ -90,10 +94,13 @@ void uiterInit( Program *prg, Tree **sp, UserIter *uiter,
void treeIterDestroy( Program *prg, Tree ***psp, TreeIter *iter )
{
if ( (int)iter->type != 0 ) {
+ int i;
Tree **sp = *psp;
long curStackSize = vm_ssize() - iter->rootSize;
assert( iter->yieldSize == curStackSize );
vm_popn( iter->yieldSize );
+ for ( i = 0; i < iter->argSize; i++ )
+ treeDownref( prg, sp, vm_pop() );
iter->type = 0;
*psp = sp;
}
@@ -102,10 +109,13 @@ void treeIterDestroy( Program *prg, Tree ***psp, TreeIter *iter )
void revTreeIterDestroy( struct colm_program *prg, Tree ***psp, RevTreeIter *riter )
{
if ( (int)riter->type != 0 ) {
+ int i;
Tree **sp = *psp;
long curStackSize = vm_ssize() - riter->rootSize;
assert( riter->yieldSize == curStackSize );
vm_popn( riter->yieldSize );
+ for ( i = 0; i < riter->argSize; i++ )
+ treeDownref( prg, sp, vm_pop() );
riter->type = 0;
*psp = sp;
}