diff options
author | Adrian Thurston <thurston@complang.org> | 2013-06-01 15:43:23 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2013-06-01 15:43:23 +0000 |
commit | 8fcb8e61fb6d89c98cee8ff57bd629cf61587f9b (patch) | |
tree | f4356138e2d87d7b8e2895a9e458588dd8517284 | |
parent | 3f5699f5048ec6d9b42b1dc833b2ab42e23705dd (diff) | |
download | colm-8fcb8e61fb6d89c98cee8ff57bd629cf61587f9b.tar.gz |
downref exiting tree when setting a reference val
Downref a tree before replacing it in a reference. Also, don't need to walk the
list of references to set all kids to handle refs of refs. Normally these will
be split and the chain will be zero length. But even if they weren't, the kid
is the same and the tree in it needs to be replaced only once.
-rw-r--r-- | colm/bytecode.c | 2 | ||||
-rw-r--r-- | colm/tree.c | 9 | ||||
-rw-r--r-- | colm/tree.h | 2 |
3 files changed, 5 insertions, 8 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c index 955aac1d..a58f395f 100644 --- a/colm/bytecode.c +++ b/colm/bytecode.c @@ -1341,7 +1341,7 @@ again: Tree *val = vm_pop(); Ref *ref = (Ref*) vm_plocal(field); splitRef( prg, &sp, ref ); - refSetValue( ref, val ); + refSetValue( prg, sp, ref, val ); break; } case IN_GET_FIELD_R: { diff --git a/colm/tree.c b/colm/tree.c index c5dc548c..515aadef 100644 --- a/colm/tree.c +++ b/colm/tree.c @@ -1216,13 +1216,10 @@ Tree *treeIterDerefCur( TreeIter *iter ) return iter->ref.kid == 0 ? 0 : iter->ref.kid->tree; } -void refSetValue( Ref *ref, Tree *v ) +void refSetValue( Program *prg, Tree **sp, Ref *ref, Tree *v ) { - Kid *firstKid = ref->kid; - while ( ref != 0 && ref->kid == firstKid ) { - ref->kid->tree = v; - ref = ref->next; - } + treeDownref( prg, sp, ref->kid->tree ); + ref->kid->tree = v; } Tree *getRhsEl( Program *prg, Tree *lhs, long position ) diff --git a/colm/tree.h b/colm/tree.h index 80b980de..91051022 100644 --- a/colm/tree.h +++ b/colm/tree.h @@ -273,7 +273,7 @@ void setField( struct colm_program *prg, Tree *tree, long field, Tree *value ); void setTriterCur( struct colm_program *prg, TreeIter *iter, Tree *tree ); void setUiterCur( struct colm_program *prg, UserIter *uiter, Tree *tree ); -void refSetValue( Ref *ref, Tree *v ); +void refSetValue( struct colm_program *prg, Tree **sp, Ref *ref, Tree *v ); Tree *treeSearch( struct colm_program *prg, Tree *tree, long id ); Location *locSearch( struct colm_program *prg, Tree *tree ); |