summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2010-04-24 01:40:55 +0000
committerAdrian Thurston <thurston@complang.org>2010-04-24 01:40:55 +0000
commit35eec09461fca18834425d46bb6738a2bf584a4d (patch)
treeb7b899db4f9bd14e1dfdda2522b8b606e952c65b
parentbdbeb7241a9000197f1256976fbaeb2f254477ac (diff)
downloadcolm-35eec09461fca18834425d46bb6738a2bf584a4d.tar.gz
more C porting
-rw-r--r--colm/bytecode.cpp2
-rw-r--r--colm/bytecode.h22
-rw-r--r--colm/tree.cpp590
-rw-r--r--colm/tree.h21
-rw-r--r--colm/tree2.c577
5 files changed, 611 insertions, 601 deletions
diff --git a/colm/bytecode.cpp b/colm/bytecode.cpp
index 43c5ba7b..94111707 100644
--- a/colm/bytecode.cpp
+++ b/colm/bytecode.cpp
@@ -2367,7 +2367,7 @@ again:
#endif
Tree *tree = pop();
- Tree *res = treeSearch( prg, tree, id );
+ Tree *res = treeSearch2( prg, tree, id );
treeUpref( res );
push( res );
treeDownref( prg, sp, tree );
diff --git a/colm/bytecode.h b/colm/bytecode.h
index df4869d1..4458ba0c 100644
--- a/colm/bytecode.h
+++ b/colm/bytecode.h
@@ -61,12 +61,10 @@ struct TreePair
void rcodeDownref( Program *prg, Tree **sp, Code *instr );
-bool matchPattern( Tree **bindings, Program *prg, long pat, Kid *kid, bool checkNext );
#include "tree.h"
-Tree *copyRealTree( Program *prg, Tree *tree, Kid *oldNextDown, Kid *&newNextDown, bool parsed );
void printTree( ostream &out, Tree **&sp, Program *prg, Tree *tree );
void printXmlTree( Tree **&sp, Program *prg, Tree *tree, bool commAttr );
@@ -80,36 +78,21 @@ Tree *setListMem( List *list, Half field, Tree *value );
Tree *mapFind( Program *prg, Map *map, Tree *key );
long mapLength( Map *map );
-bool mapInsert( Program *prg, Map *map, Tree *key, Tree *element );
+int mapInsert( Program *prg, Map *map, Tree *key, Tree *element );
void mapUnremove( Program *prg, Map *map, Tree *key, Tree *element );
Tree *mapUninsert( Program *prg, Map *map, Tree *key );
Tree *mapStore( Program *prg, Map *map, Tree *key, Tree *element );
Tree *mapUnstore( Program *prg, Map *map, Tree *key, Tree *existing );
TreePair mapRemove( Program *prg, Map *map, Tree *key );
-Tree *getPtrVal( Pointer *ptr );
-Tree *getPtrValSplit( Program *prg, Pointer *ptr );
-Tree *getField( Tree *tree, Word field );
-Tree *getFieldSplit( Program *prg, Tree *tree, Word field );
-Tree *getRhsEl( Program *prg, Tree *lhs, long position );
-void setField( Program *prg, Tree *tree, long field, Tree *value );
-
-/* For making references of attributes. */
-Kid *getFieldKid( Tree *tree, Word field );
Tree *treeIterAdvance( Program *prg, Tree **&sp, TreeIter *iter );
Tree *treeIterNextChild( Program *prg, Tree **&sp, TreeIter *iter );
Tree *treeRevIterPrevChild( Program *prg, Tree **&sp, RevTreeIter *iter );
Tree *treeIterNextRepeat( Program *prg, Tree **&sp, TreeIter *iter );
Tree *treeIterPrevRepeat( Program *prg, Tree **&sp, TreeIter *iter );
-Tree *treeIterDerefCur( TreeIter *iter );
-void setTriterCur( TreeIter *iter, Tree *tree );
-void splitIterCur( Tree **&sp, Program *prg, TreeIter *iter );
-void refSetValue( Ref *ref, Tree *v );
-Tree *treeSearch( Program *prg, Kid *kid, long id );
-Tree *treeSearch( Program *prg, Tree *tree, long id );
-void splitRef( Tree **&sp, Program *prg, Ref *fromRef );
+void splitIterCur( Tree **&sp, Program *prg, TreeIter *iter );
Tree **stackAlloc();
/*
@@ -123,5 +106,6 @@ void runProgram( Program *prg );
void allocGlobal( Program *prg );
void executeCode( Execution *exec, Tree **sp, Code *instr );
+void splitRef( Tree **&sp, Program *prg, Ref *fromRef );
#endif
diff --git a/colm/tree.cpp b/colm/tree.cpp
index de40c23a..aa6c41bc 100644
--- a/colm/tree.cpp
+++ b/colm/tree.cpp
@@ -287,512 +287,9 @@ void printXmlTree( Tree **&sp, Program *prg, Tree *tree, bool commAttr )
printXmlKid( sp, prg, &kid, commAttr, 0 );
}
-
-/* New tree has zero ref. */
-Tree *copyRealTree( Program *prg, Tree *tree, Kid *oldNextDown,
- Kid *&newNextDown, bool parseTree )
-{
- /* Need to keep a lookout for next down. If
- * copying it, return the copy. */
- Tree *newTree;
- if ( parseTree ) {
- newTree = (Tree*) parseTreeAllocate( prg );
- newTree->flags |= AF_PARSE_TREE;
- }
- else {
- newTree = treeAllocate( prg );
- }
-
- newTree->id = tree->id;
- newTree->tokdata = stringCopy( prg, tree->tokdata );
-
- /* Copy the child list. Start with ignores, then the list. */
- Kid *child = tree->child, *last = 0;
-
- /* Left ignores. */
- if ( tree->flags & AF_LEFT_IGNORE ) {
- newTree->flags |= AF_LEFT_IGNORE;
- Kid *newHeader = copyIgnoreList( prg, child );
-
- /* Always the head. */
- newTree->child = newHeader;
-
- child = child->next;
- last = newHeader;
- }
-
- /* Right ignores. */
- if ( tree->flags & AF_RIGHT_IGNORE ) {
- newTree->flags |= AF_RIGHT_IGNORE;
- Kid *newHeader = copyIgnoreList( prg, child );
- if ( last == 0 )
- newTree->child = newHeader;
- else
- last->next = newHeader;
- child = child->next;
- last = newHeader;
- }
-
- /* Attributes and children. */
- while ( child != 0 ) {
- Kid *newKid = kidAllocate( prg );
-
- /* Watch out for next down. */
- if ( child == oldNextDown )
- newNextDown = newKid;
-
- newKid->tree = child->tree;
- newKid->next = 0;
-
- /* May be an attribute. */
- if ( newKid->tree != 0 )
- newKid->tree->refs += 1;
-
- /* Store the first child. */
- if ( last == 0 )
- newTree->child = newKid;
- else
- last->next = newKid;
-
- child = child->next;
- last = newKid;
- }
-
- return newTree;
-}
-
-List *copyList( Program *prg, List *list, Kid *oldNextDown, Kid *&newNextDown )
+void iterFind( Program *prg, Tree **&sp, TreeIter *iter, int tryFirst )
{
- #ifdef COLM_LOG_BYTECODE
- if ( colm_log_bytecode ) {
- cerr << "splitting list: " << list << " refs: " <<
- list->refs << endl;
- }
- #endif
-
- /* Not a need copy. */
- List *newList = (List*)mapElAllocate( prg );
- newList->id = list->genericInfo->langElId;
- newList->genericInfo = list->genericInfo;
-
- ListEl *src = list->head;
- while( src != 0 ) {
- ListEl *newEl = listElAllocate( prg );
- newEl->value = src->value;
- treeUpref( newEl->value );
-
- listAppend( newList, newEl );
-
- /* Watch out for next down. */
- if ( (Kid*)src == oldNextDown )
- newNextDown = (Kid*)newEl;
-
- src = src->next;
- }
-
- return newList;
-}
-
-Map *copyMap( Program *prg, Map *map, Kid *oldNextDown, Kid *&newNextDown )
-{
- #ifdef COLM_LOG_BYTECODE
- if ( colm_log_bytecode ) {
- cerr << "splitting map: " << map << " refs: " <<
- map->refs << endl;
- }
- #endif
-
- Map *newMap = (Map*)mapElAllocate( prg );
- newMap->id = map->genericInfo->langElId;
- newMap->genericInfo = map->genericInfo;
- newMap->treeSize = map->treeSize;
- newMap->root = 0;
-
- /* If there is a root, copy the tree. */
- if ( map->root != 0 ) {
- newMap->root = mapCopyBranch( prg, newMap, map->root,
- oldNextDown, &newNextDown );
- }
-
- for ( MapEl *el = newMap->head; el != 0; el = el->next ) {
- assert( map->genericInfo->typeArg == TYPE_TREE );
- treeUpref( el->tree );
- }
-
- return newMap;
-}
-
-Tree *copyTree( Program *prg, Tree *tree, Kid *oldNextDown, Kid *&newNextDown )
-{
- LangElInfo *lelInfo = prg->rtd->lelInfo;
- long genericId = lelInfo[tree->id].genericId;
- if ( genericId > 0 ) {
- GenericInfo *generic = &prg->rtd->genericInfo[genericId];
- if ( generic->type == GEN_LIST )
- tree = (Tree*) copyList( prg, (List*) tree, oldNextDown, newNextDown );
- else if ( generic->type == GEN_MAP )
- tree = (Tree*) copyMap( prg, (Map*) tree, oldNextDown, newNextDown );
- else if ( generic->type == GEN_PARSER ) {
- /* Need to figure out the semantics here. */
- cerr << "ATTEMPT TO COPY PARSER" << endl;
- assert(false);
- }
- }
- else if ( tree->id == LEL_ID_PTR )
- assert(false);
- else if ( tree->id == LEL_ID_BOOL )
- assert(false);
- else if ( tree->id == LEL_ID_INT )
- assert(false);
- else if ( tree->id == LEL_ID_STR )
- assert(false);
- else if ( tree->id == LEL_ID_STREAM )
- assert(false);
- else {
- tree = copyRealTree( prg, tree, oldNextDown, newNextDown, false );
- }
-
- assert( tree->refs == 0 );
- return tree;
-}
-
-Tree *splitTree( Program *prg, Tree *tree )
-{
- if ( tree != 0 ) {
- assert( tree->refs >= 1 );
-
- if ( tree->refs > 1 ) {
- #ifdef COLM_LOG_BYTECODE
- if ( colm_log_bytecode ) {
- cerr << "splitting tree: " << tree << " refs: " <<
- tree->refs << endl;
- }
- #endif
-
- Kid *oldNextDown = 0, *newNextDown = 0;
- Tree *newTree = copyTree( prg, tree, oldNextDown, newNextDown );
- treeUpref( newTree );
-
- /* Downref the original. Don't need to consider freeing because
- * refs were > 1. */
- tree->refs -= 1;
-
- tree = newTree;
- }
-
- assert( tree->refs == 1 );
- }
- return tree;
-}
-
-Tree *createGeneric( Program *prg, long genericId )
-{
- GenericInfo *genericInfo = &prg->rtd->genericInfo[genericId];
- Tree *newGeneric = 0;
- switch ( genericInfo->type ) {
- case GEN_MAP: {
- Map *map = (Map*)mapElAllocate( prg );
- map->id = genericInfo->langElId;
- map->genericInfo = genericInfo;
- newGeneric = (Tree*) map;
- break;
- }
- case GEN_LIST: {
- List *list = (List*)mapElAllocate( prg );
- list->id = genericInfo->langElId;
- list->genericInfo = genericInfo;
- newGeneric = (Tree*) list;
- break;
- }
- case GEN_PARSER: {
- Accum *accum = (Accum*)mapElAllocate( prg );
- accum->id = genericInfo->langElId;
- accum->genericInfo = genericInfo;
- accum->fsmRun = new FsmRun;
- accum->pdaRun = new PdaRun;
-
- /* Start off the parsing process. */
- initPdaRun( accum->pdaRun, prg, prg->rtd->pdaTables,
- accum->fsmRun, genericInfo->parserId, false, false, 0 );
- initFsmRun( accum->fsmRun, prg );
- newToken( accum->pdaRun, accum->fsmRun );
-
- newGeneric = (Tree*) accum;
- break;
- }
- default:
- assert(false);
- return 0;
- }
-
- return newGeneric;
-}
-
-
-/* We can't make recursive calls here since the tree we are freeing may be
- * very large. Need the VM stack. */
-void treeFree( Program *prg, Tree **sp, Tree *tree )
-{
- Tree **top = sp;
-
-free_tree:
- LangElInfo *lelInfo = prg->rtd->lelInfo;
- long genericId = lelInfo[tree->id].genericId;
- if ( genericId > 0 ) {
- GenericInfo *generic = &prg->rtd->genericInfo[genericId];
- if ( generic->type == GEN_LIST ) {
- List *list = (List*) tree;
- ListEl *el = list->head;
- while ( el != 0 ) {
- ListEl *next = el->next;
- vm_push( el->value );
- listElFree( prg, el );
- el = next;
- }
- mapElFree( prg, (MapEl*)list );
- }
- else if ( generic->type == GEN_MAP ) {
- Map *map = (Map*)tree;
- MapEl *el = map->head;
- while ( el != 0 ) {
- MapEl *next = el->next;
- vm_push( el->key );
- vm_push( el->tree );
- mapElFree( prg, el );
- el = next;
- }
- mapElFree( prg, (MapEl*)map );
- }
- else if ( generic->type == GEN_PARSER ) {
- Accum *accum = (Accum*)tree;
- delete accum->fsmRun;
- cleanParser( sp, accum->pdaRun );
- clearContext( accum->pdaRun, sp );
- rcodeDownrefAll( prg, sp, accum->pdaRun->allReverseCode );
- delete accum->pdaRun;
- treeDownref( prg, sp, (Tree*)accum->stream );
- mapElFree( prg, (MapEl*)accum );
- }
- else
- assert(false);
- }
- else {
- if ( tree->id == LEL_ID_STR ) {
- Str *str = (Str*) tree;
- stringFree( prg, str->value );
- treeFree( prg, tree );
- }
- else if ( tree->id == LEL_ID_BOOL || tree->id == LEL_ID_INT )
- treeFree( prg, tree );
- else if ( tree->id == LEL_ID_PTR ) {
- //Pointer *ptr = (Pointer*)tree;
- //vm_push( ptr->value->tree );
- //kidFree( prg, ptr->value );
- treeFree( prg, tree );
- }
- else if ( tree->id == LEL_ID_STREAM )
- streamFree( prg, (Stream*) tree );
- else {
- stringFree( prg, tree->tokdata );
- Kid *child = tree->child;
-
- /* Left ignore trees. */
- if ( tree->flags & AF_LEFT_IGNORE ) {
- Kid *ic = (Kid*)child->tree;
- while ( ic != 0 ) {
- Kid *next = ic->next;
- vm_push( ic->tree );
- kidFree( prg, ic );
- ic = next;
- }
-
- Kid *next = child->next;
- kidFree( prg, child );
- child = next;
- }
-
- /* Right ignore trees. */
- if ( tree->flags & AF_RIGHT_IGNORE ) {
- Kid *ic = (Kid*)child->tree;
- while ( ic != 0 ) {
- Kid *next = ic->next;
- vm_push( ic->tree );
- kidFree( prg, ic );
- ic = next;
- }
-
- Kid *next = child->next;
- kidFree( prg, child );
- child = next;
- }
-
- /* Attributes and grammar-based children. */
- while ( child != 0 ) {
- Kid *next = child->next;
- vm_push( child->tree );
- kidFree( prg, child );
- child = next;
- }
-
- if ( tree->flags & AF_PARSE_TREE )
- parseTreeFree( prg, (ParseTree*)tree );
- else
- treeFree( prg, tree );
- }
- }
-
- /* Any trees to downref? */
- while ( sp != top ) {
- tree = vm_pop();
- if ( tree != 0 ) {
- assert( tree->refs > 0 );
- tree->refs -= 1;
- if ( tree->refs == 0 )
- goto free_tree;
- }
- }
-}
-
-void treeUpref( Tree *tree )
-{
- if ( tree != 0 )
- tree->refs += 1;
-}
-
-void treeDownref( Program *prg, Tree **sp, Tree *tree )
-{
- if ( tree != 0 ) {
- assert( tree->refs > 0 );
- tree->refs -= 1;
- if ( tree->refs == 0 )
- treeFree( prg, sp, tree );
- }
-}
-
-/* Find the first child of a tree. */
-Kid *treeChild( Program *prg, const Tree *tree )
-{
- LangElInfo *lelInfo = prg->rtd->lelInfo;
- Kid *kid = tree->child;
-
- if ( tree->flags & AF_LEFT_IGNORE )
- kid = kid->next;
- if ( tree->flags & AF_RIGHT_IGNORE )
- kid = kid->next;
-
- /* Skip over attributes. */
- long objectLength = lelInfo[tree->id].objectLength;
- for ( long a = 0; a < objectLength; a++ )
- kid = kid->next;
-
- return kid;
-}
-
-/* Find the first child of a tree. */
-Kid *treeExtractChild( Program *prg, Tree *tree )
-{
- LangElInfo *lelInfo = prg->rtd->lelInfo;
- Kid *kid = tree->child, *last = 0;
-
- if ( tree->flags & AF_LEFT_IGNORE )
- kid = kid->next;
- if ( tree->flags & AF_RIGHT_IGNORE )
- kid = kid->next;
-
- /* Skip over attributes. */
- long objectLength = lelInfo[tree->id].objectLength;
- for ( long a = 0; a < objectLength; a++ ) {
- last = kid;
- kid = kid->next;
- }
-
- if ( last == 0 )
- tree->child = 0;
- else
- last->next = 0;
-
- return kid;
-}
-
-
-Kid *treeIgnore( Program *prg, Tree *tree )
-{
- if ( tree->flags & AF_LEFT_IGNORE )
- return (Kid*)tree->child->tree;
- return 0;
-}
-
-Tree *treeIterDerefCur( TreeIter *iter )
-{
- return iter->ref.kid == 0 ? 0 : iter->ref.kid->tree;
-}
-
-void refSetValue( Ref *ref, Tree *v )
-{
- Kid *firstKid = ref->kid;
- while ( ref != 0 && ref->kid == firstKid ) {
- ref->kid->tree = v;
- ref = ref->next;
- }
-}
-
-Tree *getRhsEl( Program *prg, Tree *lhs, long position )
-{
- Kid *pos = treeChild( prg, lhs );
- while ( position > 0 ) {
- pos = pos->next;
- position -= 1;
- }
- return pos->tree;
-}
-
-void setField( Program *prg, Tree *tree, long field, Tree *value )
-{
- assert( tree->refs == 1 );
- if ( value != 0 )
- assert( value->refs >= 1 );
- setAttr( tree, field, value );
-}
-
-Tree *getField( Tree *tree, Word field )
-{
- return getAttr( tree, field );
-}
-
-Kid *getFieldKid( Tree *tree, Word field )
-{
- return getAttrKid( tree, field );
-}
-
-Tree *getFieldSplit( Program *prg, Tree *tree, Word field )
-{
- Tree *val = getAttr( tree, field );
- Tree *split = splitTree( prg, val );
- setAttr( tree, field, split );
- return split;
-}
-
-void setTriterCur( TreeIter *iter, Tree *tree )
-{
- iter->ref.kid->tree = tree;
-}
-
-Tree *getPtrVal( Pointer *ptr )
-{
- return ptr->value->tree;
-}
-
-Tree *getPtrValSplit( Program *prg, Pointer *ptr )
-{
- Tree *val = ptr->value->tree;
- Tree *split = splitTree( prg, val );
- ptr->value->tree = split;
- return split;
-}
-
-void iterFind( Program *prg, Tree **&sp, TreeIter *iter, bool tryFirst )
-{
- bool anyTree = iter->searchId == prg->rtd->anyId;
+ int anyTree = iter->searchId == prg->rtd->anyId;
Tree **top = iter->stackRoot;
Kid *child;
@@ -921,9 +418,9 @@ Tree *treeRevIterPrevChild( Program *prg, Tree **&sp, RevTreeIter *iter )
return (iter->ref.kid ? prg->trueVal : prg->falseVal );
}
-void iterFindRepeat( Program *prg, Tree **&sp, TreeIter *iter, bool tryFirst )
+void iterFindRepeat( Program *prg, Tree **&sp, TreeIter *iter, int tryFirst )
{
- bool anyTree = iter->searchId == prg->rtd->anyId;
+ int anyTree = iter->searchId == prg->rtd->anyId;
Tree **top = iter->stackRoot;
Kid *child;
@@ -979,9 +476,9 @@ Tree *treeIterNextRepeat( Program *prg, Tree **&sp, TreeIter *iter )
return (iter->ref.kid ? prg->trueVal : prg->falseVal );
}
-void iter_find_rev_repeat( Program *prg, Tree **&sp, TreeIter *iter, bool tryFirst )
+void iter_find_rev_repeat( Program *prg, Tree **&sp, TreeIter *iter, int tryFirst )
{
- bool anyTree = iter->searchId == prg->rtd->anyId;
+ int anyTree = iter->searchId == prg->rtd->anyId;
Tree **top = iter->stackRoot;
Kid *child;
@@ -1070,7 +567,7 @@ Tree *treeSearch( Program *prg, Kid *kid, long id )
return res;
}
-Tree *treeSearch( Program *prg, Tree *tree, long id )
+Tree *treeSearch2( Program *prg, Tree *tree, long id )
{
Tree *res = 0;
if ( tree->id == id )
@@ -1083,7 +580,7 @@ Tree *treeSearch( Program *prg, Tree *tree, long id )
return res;
}
-bool mapInsert( Program *prg, Map *map, Tree *key, Tree *element )
+int mapInsert( Program *prg, Map *map, Tree *key, Tree *element )
{
MapEl *mapEl = mapInsertKey( prg, map, key, 0 );
@@ -1274,7 +771,7 @@ void splitRef( Tree **&sp, Program *prg, Ref *fromRef )
Kid *newNextKidDown = 0;
Tree *newTree = copyTree( prg, ref->kid->tree,
- oldNextKidDown, newNextKidDown );
+ oldNextKidDown, &newNextKidDown );
treeUpref( newTree );
/* Downref the original. Don't need to consider freeing because
@@ -1376,72 +873,3 @@ extern "C" long cmpTree( Program *prg, const Tree *tree1, const Tree *tree2 )
}
}
-/* This must traverse in the same order that the bindId assignments are done
- * in. */
-bool matchPattern( Tree **bindings, Program *prg, long pat, Kid *kid, bool checkNext )
-{
- PatReplNode *nodes = prg->rtd->patReplNodes;
-
- #ifdef COLM_LOG_MATCH
- if ( colm_log_match ) {
- LangElInfo *lelInfo = prg->rtd->lelInfo;
- cerr << "match pattern " << ( pat == -1 ? "NULL" : lelInfo[nodes[pat].id].name ) <<
- " vs " << ( kid == 0 ? "NULL" : lelInfo[kid->tree->id].name ) << endl;
- }
- #endif
-
- /* match node, recurse on children. */
- if ( pat != -1 && kid != 0 ) {
- if ( nodes[pat].id == kid->tree->id ) {
- /* If the pattern node has data, then this means we need to match
- * the data against the token data. */
- if ( nodes[pat].data != 0 ) {
- /* Check the length of token text. */
- if ( nodes[pat].length != stringLength( kid->tree->tokdata ) )
- return false;
-
- /* Check the token text data. */
- if ( nodes[pat].length > 0 && memcmp( nodes[pat].data,
- stringData( kid->tree->tokdata ), nodes[pat].length ) != 0 )
- return false;
- }
-
- /* No failure, all okay. */
- if ( nodes[pat].bindId > 0 ) {
- #ifdef COLM_LOG_MATCH
- if ( colm_log_match ) {
- cerr << "bindId: " << nodes[pat].bindId << endl;
- }
- #endif
- bindings[nodes[pat].bindId] = kid->tree;
- }
-
- /* If we didn't match a terminal duplicate of a nonterm then check
- * down the children. */
- if ( !nodes[pat].stop ) {
- /* Check for failure down child branch. */
- bool childCheck = matchPattern( bindings, prg,
- nodes[pat].child, treeChild( prg, kid->tree ), true );
- if ( ! childCheck )
- return false;
- }
-
- /* If checking next, then look for failure there. */
- if ( checkNext ) {
- bool nextCheck = matchPattern( bindings, prg,
- nodes[pat].next, kid->next, true );
- if ( ! nextCheck )
- return false;
- }
-
- return true;
- }
- }
- else if ( pat == -1 && kid == 0 ) {
- /* Both null is a match. */
- return 1;
- }
-
- return false;
-}
-
diff --git a/colm/tree.h b/colm/tree.h
index 05d3ab4d..6ba4f4e2 100644
--- a/colm/tree.h
+++ b/colm/tree.h
@@ -47,6 +47,27 @@ Stream *openFile( Program *prg, Tree *name, Tree *mode );
Stream *openStreamFd( Program *prg, long fd );
Kid *copyIgnoreList( Program *prg, Kid *ignoreHeader );
void streamFree( Program *prg, Stream *s );
+Tree *copyTree( Program *prg, Tree *tree, Kid *oldNextDown, Kid **newNextDown );
+
+Tree *getPtrVal( Pointer *ptr );
+Tree *getPtrValSplit( Program *prg, Pointer *ptr );
+Tree *getField( Tree *tree, Word field );
+Tree *getFieldSplit( Program *prg, Tree *tree, Word field );
+Tree *getRhsEl( Program *prg, Tree *lhs, long position );
+void setField( Program *prg, Tree *tree, long field, Tree *value );
+
+void setTriterCur( TreeIter *iter, Tree *tree );
+void refSetValue( Ref *ref, Tree *v );
+Tree *treeSearch( Program *prg, Kid *kid, long id );
+Tree *treeSearch2( Program *prg, Tree *tree, long id );
+
+int matchPattern( Tree **bindings, Program *prg, long pat, Kid *kid, int checkNext );
+Tree *treeIterDerefCur( TreeIter *iter );
+
+/* For making references of attributes. */
+Kid *getFieldKid( Tree *tree, Word field );
+
+Tree *copyRealTree( Program *prg, Tree *tree, Kid *oldNextDown, Kid *&newNextDown, int parsed );
#if defined(__cplusplus)
}
diff --git a/colm/tree2.c b/colm/tree2.c
index 45657614..e7c09c55 100644
--- a/colm/tree2.c
+++ b/colm/tree2.c
@@ -547,3 +547,580 @@ Kid *copyIgnoreList( Program *prg, Kid *ignoreHeader )
}
return newHeader;
}
+
+/* New tree has zero ref. */
+Tree *copyRealTree( Program *prg, Tree *tree, Kid *oldNextDown,
+ Kid **newNextDown, int parseTree )
+{
+ /* Need to keep a lookout for next down. If
+ * copying it, return the copy. */
+ Tree *newTree;
+ if ( parseTree ) {
+ newTree = (Tree*) parseTreeAllocate( prg );
+ newTree->flags |= AF_PARSE_TREE;
+ }
+ else {
+ newTree = treeAllocate( prg );
+ }
+
+ newTree->id = tree->id;
+ newTree->tokdata = stringCopy( prg, tree->tokdata );
+
+ /* Copy the child list. Start with ignores, then the list. */
+ Kid *child = tree->child, *last = 0;
+
+ /* Left ignores. */
+ if ( tree->flags & AF_LEFT_IGNORE ) {
+ newTree->flags |= AF_LEFT_IGNORE;
+ Kid *newHeader = copyIgnoreList( prg, child );
+
+ /* Always the head. */
+ newTree->child = newHeader;
+
+ child = child->next;
+ last = newHeader;
+ }
+
+ /* Right ignores. */
+ if ( tree->flags & AF_RIGHT_IGNORE ) {
+ newTree->flags |= AF_RIGHT_IGNORE;
+ Kid *newHeader = copyIgnoreList( prg, child );
+ if ( last == 0 )
+ newTree->child = newHeader;
+ else
+ last->next = newHeader;
+ child = child->next;
+ last = newHeader;
+ }
+
+ /* Attributes and children. */
+ while ( child != 0 ) {
+ Kid *newKid = kidAllocate( prg );
+
+ /* Watch out for next down. */
+ if ( child == oldNextDown )
+ *newNextDown = newKid;
+
+ newKid->tree = child->tree;
+ newKid->next = 0;
+
+ /* May be an attribute. */
+ if ( newKid->tree != 0 )
+ newKid->tree->refs += 1;
+
+ /* Store the first child. */
+ if ( last == 0 )
+ newTree->child = newKid;
+ else
+ last->next = newKid;
+
+ child = child->next;
+ last = newKid;
+ }
+
+ return newTree;
+}
+
+List *copyList( Program *prg, List *list, Kid *oldNextDown, Kid **newNextDown )
+{
+ #ifdef COLM_LOG_BYTECODE
+ if ( colm_log_bytecode ) {
+ cerr << "splitting list: " << list << " refs: " <<
+ list->refs << endl;
+ }
+ #endif
+
+ /* Not a need copy. */
+ List *newList = (List*)mapElAllocate( prg );
+ newList->id = list->genericInfo->langElId;
+ newList->genericInfo = list->genericInfo;
+
+ ListEl *src = list->head;
+ while( src != 0 ) {
+ ListEl *newEl = listElAllocate( prg );
+ newEl->value = src->value;
+ treeUpref( newEl->value );
+
+ listAppend( newList, newEl );
+
+ /* Watch out for next down. */
+ if ( (Kid*)src == oldNextDown )
+ *newNextDown = (Kid*)newEl;
+
+ src = src->next;
+ }
+
+ return newList;
+}
+
+Map *copyMap( Program *prg, Map *map, Kid *oldNextDown, Kid **newNextDown )
+{
+ #ifdef COLM_LOG_BYTECODE
+ if ( colm_log_bytecode ) {
+ cerr << "splitting map: " << map << " refs: " <<
+ map->refs << endl;
+ }
+ #endif
+
+ Map *newMap = (Map*)mapElAllocate( prg );
+ newMap->id = map->genericInfo->langElId;
+ newMap->genericInfo = map->genericInfo;
+ newMap->treeSize = map->treeSize;
+ newMap->root = 0;
+
+ /* If there is a root, copy the tree. */
+ if ( map->root != 0 ) {
+ newMap->root = mapCopyBranch( prg, newMap, map->root,
+ oldNextDown, newNextDown );
+ }
+ MapEl *el;
+ for ( el = newMap->head; el != 0; el = el->next ) {
+ assert( map->genericInfo->typeArg == TYPE_TREE );
+ treeUpref( el->tree );
+ }
+
+ return newMap;
+}
+
+Tree *copyTree( Program *prg, Tree *tree, Kid *oldNextDown, Kid **newNextDown )
+{
+ LangElInfo *lelInfo = prg->rtd->lelInfo;
+ long genericId = lelInfo[tree->id].genericId;
+ if ( genericId > 0 ) {
+ GenericInfo *generic = &prg->rtd->genericInfo[genericId];
+ if ( generic->type == GEN_LIST )
+ tree = (Tree*) copyList( prg, (List*) tree, oldNextDown, newNextDown );
+ else if ( generic->type == GEN_MAP )
+ tree = (Tree*) copyMap( prg, (Map*) tree, oldNextDown, newNextDown );
+ else if ( generic->type == GEN_PARSER ) {
+ /* Need to figure out the semantics here. */
+ fatal( "ATTEMPT TO COPY PARSER\n" );
+ assert(false);
+ }
+ }
+ else if ( tree->id == LEL_ID_PTR )
+ assert(false);
+ else if ( tree->id == LEL_ID_BOOL )
+ assert(false);
+ else if ( tree->id == LEL_ID_INT )
+ assert(false);
+ else if ( tree->id == LEL_ID_STR )
+ assert(false);
+ else if ( tree->id == LEL_ID_STREAM )
+ assert(false);
+ else {
+ tree = copyRealTree( prg, tree, oldNextDown, newNextDown, false );
+ }
+
+ assert( tree->refs == 0 );
+ return tree;
+}
+
+Tree *splitTree( Program *prg, Tree *tree )
+{
+ if ( tree != 0 ) {
+ assert( tree->refs >= 1 );
+
+ if ( tree->refs > 1 ) {
+ #ifdef COLM_LOG_BYTECODE
+ if ( colm_log_bytecode ) {
+ cerr << "splitting tree: " << tree << " refs: " <<
+ tree->refs << endl;
+ }
+ #endif
+
+ Kid *oldNextDown = 0, *newNextDown = 0;
+ Tree *newTree = copyTree( prg, tree, oldNextDown, &newNextDown );
+ treeUpref( newTree );
+
+ /* Downref the original. Don't need to consider freeing because
+ * refs were > 1. */
+ tree->refs -= 1;
+
+ tree = newTree;
+ }
+
+ assert( tree->refs == 1 );
+ }
+ return tree;
+}
+
+Tree *createGeneric( Program *prg, long genericId )
+{
+ GenericInfo *genericInfo = &prg->rtd->genericInfo[genericId];
+ Tree *newGeneric = 0;
+ switch ( genericInfo->type ) {
+ case GEN_MAP: {
+ Map *map = (Map*)mapElAllocate( prg );
+ map->id = genericInfo->langElId;
+ map->genericInfo = genericInfo;
+ newGeneric = (Tree*) map;
+ break;
+ }
+ case GEN_LIST: {
+ List *list = (List*)mapElAllocate( prg );
+ list->id = genericInfo->langElId;
+ list->genericInfo = genericInfo;
+ newGeneric = (Tree*) list;
+ break;
+ }
+ case GEN_PARSER: {
+ Accum *accum = (Accum*)mapElAllocate( prg );
+ accum->id = genericInfo->langElId;
+ accum->genericInfo = genericInfo;
+ accum->fsmRun = malloc( sizeof(FsmRun) );
+ accum->pdaRun = malloc( sizeof(PdaRun) );
+
+ /* Start off the parsing process. */
+ initPdaRun( accum->pdaRun, prg, prg->rtd->pdaTables,
+ accum->fsmRun, genericInfo->parserId, false, false, 0 );
+ initFsmRun( accum->fsmRun, prg );
+ newToken( accum->pdaRun, accum->fsmRun );
+
+ newGeneric = (Tree*) accum;
+ break;
+ }
+ default:
+ assert(false);
+ return 0;
+ }
+
+ return newGeneric;
+}
+
+
+/* We can't make recursive calls here since the tree we are freeing may be
+ * very large. Need the VM stack. */
+void treeFreeRec( Program *prg, Tree **sp, Tree *tree )
+{
+ Tree **top = sp;
+ LangElInfo *lelInfo;
+ long genericId;
+
+free_tree:
+ lelInfo = prg->rtd->lelInfo;
+ genericId = lelInfo[tree->id].genericId;
+ if ( genericId > 0 ) {
+ GenericInfo *generic = &prg->rtd->genericInfo[genericId];
+ if ( generic->type == GEN_LIST ) {
+ List *list = (List*) tree;
+ ListEl *el = list->head;
+ while ( el != 0 ) {
+ ListEl *next = el->next;
+ vm_push( el->value );
+ listElFree( prg, el );
+ el = next;
+ }
+ mapElFree( prg, (MapEl*)list );
+ }
+ else if ( generic->type == GEN_MAP ) {
+ Map *map = (Map*)tree;
+ MapEl *el = map->head;
+ while ( el != 0 ) {
+ MapEl *next = el->next;
+ vm_push( el->key );
+ vm_push( el->tree );
+ mapElFree( prg, el );
+ el = next;
+ }
+ mapElFree( prg, (MapEl*)map );
+ }
+ else if ( generic->type == GEN_PARSER ) {
+ Accum *accum = (Accum*)tree;
+ free( accum->fsmRun );
+ cleanParser( sp, accum->pdaRun );
+ clearContext( accum->pdaRun, sp );
+ rcodeDownrefAll( prg, sp, accum->pdaRun->allReverseCode );
+ free( accum->pdaRun );
+ treeDownref( prg, sp, (Tree*)accum->stream );
+ mapElFree( prg, (MapEl*)accum );
+ }
+ else
+ assert(false);
+ }
+ else {
+ if ( tree->id == LEL_ID_STR ) {
+ Str *str = (Str*) tree;
+ stringFree( prg, str->value );
+ treeFree( prg, tree );
+ }
+ else if ( tree->id == LEL_ID_BOOL || tree->id == LEL_ID_INT )
+ treeFree( prg, tree );
+ else if ( tree->id == LEL_ID_PTR ) {
+ //Pointer *ptr = (Pointer*)tree;
+ //vm_push( ptr->value->tree );
+ //kidFree( prg, ptr->value );
+ treeFree( prg, tree );
+ }
+ else if ( tree->id == LEL_ID_STREAM )
+ streamFree( prg, (Stream*) tree );
+ else {
+ stringFree( prg, tree->tokdata );
+ Kid *child = tree->child;
+
+ /* Left ignore trees. */
+ if ( tree->flags & AF_LEFT_IGNORE ) {
+ Kid *ic = (Kid*)child->tree;
+ while ( ic != 0 ) {
+ Kid *next = ic->next;
+ vm_push( ic->tree );
+ kidFree( prg, ic );
+ ic = next;
+ }
+
+ Kid *next = child->next;
+ kidFree( prg, child );
+ child = next;
+ }
+
+ /* Right ignore trees. */
+ if ( tree->flags & AF_RIGHT_IGNORE ) {
+ Kid *ic = (Kid*)child->tree;
+ while ( ic != 0 ) {
+ Kid *next = ic->next;
+ vm_push( ic->tree );
+ kidFree( prg, ic );
+ ic = next;
+ }
+
+ Kid *next = child->next;
+ kidFree( prg, child );
+ child = next;
+ }
+
+ /* Attributes and grammar-based children. */
+ while ( child != 0 ) {
+ Kid *next = child->next;
+ vm_push( child->tree );
+ kidFree( prg, child );
+ child = next;
+ }
+
+ if ( tree->flags & AF_PARSE_TREE )
+ parseTreeFree( prg, (ParseTree*)tree );
+ else
+ treeFree( prg, tree );
+ }
+ }
+
+ /* Any trees to downref? */
+ while ( sp != top ) {
+ tree = vm_pop();
+ if ( tree != 0 ) {
+ assert( tree->refs > 0 );
+ tree->refs -= 1;
+ if ( tree->refs == 0 )
+ goto free_tree;
+ }
+ }
+}
+
+void treeUpref( Tree *tree )
+{
+ if ( tree != 0 )
+ tree->refs += 1;
+}
+
+void treeDownref( Program *prg, Tree **sp, Tree *tree )
+{
+ if ( tree != 0 ) {
+ assert( tree->refs > 0 );
+ tree->refs -= 1;
+ if ( tree->refs == 0 )
+ treeFreeRec( prg, sp, tree );
+ }
+}
+
+/* Find the first child of a tree. */
+Kid *treeChild( Program *prg, const Tree *tree )
+{
+ LangElInfo *lelInfo = prg->rtd->lelInfo;
+ Kid *kid = tree->child;
+
+ if ( tree->flags & AF_LEFT_IGNORE )
+ kid = kid->next;
+ if ( tree->flags & AF_RIGHT_IGNORE )
+ kid = kid->next;
+
+ /* Skip over attributes. */
+ long objectLength = lelInfo[tree->id].objectLength;
+ long a;
+ for ( a = 0; a < objectLength; a++ )
+ kid = kid->next;
+
+ return kid;
+}
+
+/* Find the first child of a tree. */
+Kid *treeExtractChild( Program *prg, Tree *tree )
+{
+ LangElInfo *lelInfo = prg->rtd->lelInfo;
+ Kid *kid = tree->child, *last = 0;
+
+ if ( tree->flags & AF_LEFT_IGNORE )
+ kid = kid->next;
+ if ( tree->flags & AF_RIGHT_IGNORE )
+ kid = kid->next;
+
+ /* Skip over attributes. */
+ long objectLength = lelInfo[tree->id].objectLength;
+ long a;
+ for ( a = 0; a < objectLength; a++ ) {
+ last = kid;
+ kid = kid->next;
+ }
+
+ if ( last == 0 )
+ tree->child = 0;
+ else
+ last->next = 0;
+
+ return kid;
+}
+
+
+Kid *treeIgnore( Program *prg, Tree *tree )
+{
+ if ( tree->flags & AF_LEFT_IGNORE )
+ return (Kid*)tree->child->tree;
+ return 0;
+}
+
+Tree *treeIterDerefCur( TreeIter *iter )
+{
+ return iter->ref.kid == 0 ? 0 : iter->ref.kid->tree;
+}
+
+void refSetValue( Ref *ref, Tree *v )
+{
+ Kid *firstKid = ref->kid;
+ while ( ref != 0 && ref->kid == firstKid ) {
+ ref->kid->tree = v;
+ ref = ref->next;
+ }
+}
+
+Tree *getRhsEl( Program *prg, Tree *lhs, long position )
+{
+ Kid *pos = treeChild( prg, lhs );
+ while ( position > 0 ) {
+ pos = pos->next;
+ position -= 1;
+ }
+ return pos->tree;
+}
+
+void setField( Program *prg, Tree *tree, long field, Tree *value )
+{
+ assert( tree->refs == 1 );
+ if ( value != 0 )
+ assert( value->refs >= 1 );
+ setAttr( tree, field, value );
+}
+
+Tree *getField( Tree *tree, Word field )
+{
+ return getAttr( tree, field );
+}
+
+Kid *getFieldKid( Tree *tree, Word field )
+{
+ return getAttrKid( tree, field );
+}
+
+Tree *getFieldSplit( Program *prg, Tree *tree, Word field )
+{
+ Tree *val = getAttr( tree, field );
+ Tree *split = splitTree( prg, val );
+ setAttr( tree, field, split );
+ return split;
+}
+
+void setTriterCur( TreeIter *iter, Tree *tree )
+{
+ iter->ref.kid->tree = tree;
+}
+
+Tree *getPtrVal( Pointer *ptr )
+{
+ return ptr->value->tree;
+}
+
+Tree *getPtrValSplit( Program *prg, Pointer *ptr )
+{
+ Tree *val = ptr->value->tree;
+ Tree *split = splitTree( prg, val );
+ ptr->value->tree = split;
+ return split;
+}
+
+/* This must traverse in the same order that the bindId assignments are done
+ * in. */
+int matchPattern( Tree **bindings, Program *prg, long pat, Kid *kid, int checkNext )
+{
+ PatReplNode *nodes = prg->rtd->patReplNodes;
+
+ #ifdef COLM_LOG_MATCH
+ if ( colm_log_match ) {
+ LangElInfo *lelInfo = prg->rtd->lelInfo;
+ cerr << "match pattern " << ( pat == -1 ? "NULL" : lelInfo[nodes[pat].id].name ) <<
+ " vs " << ( kid == 0 ? "NULL" : lelInfo[kid->tree->id].name ) << endl;
+ }
+ #endif
+
+ /* match node, recurse on children. */
+ if ( pat != -1 && kid != 0 ) {
+ if ( nodes[pat].id == kid->tree->id ) {
+ /* If the pattern node has data, then this means we need to match
+ * the data against the token data. */
+ if ( nodes[pat].data != 0 ) {
+ /* Check the length of token text. */
+ if ( nodes[pat].length != stringLength( kid->tree->tokdata ) )
+ return false;
+
+ /* Check the token text data. */
+ if ( nodes[pat].length > 0 && memcmp( nodes[pat].data,
+ stringData( kid->tree->tokdata ), nodes[pat].length ) != 0 )
+ return false;
+ }
+
+ /* No failure, all okay. */
+ if ( nodes[pat].bindId > 0 ) {
+ #ifdef COLM_LOG_MATCH
+ if ( colm_log_match ) {
+ cerr << "bindId: " << nodes[pat].bindId << endl;
+ }
+ #endif
+ bindings[nodes[pat].bindId] = kid->tree;
+ }
+
+ /* If we didn't match a terminal duplicate of a nonterm then check
+ * down the children. */
+ if ( !nodes[pat].stop ) {
+ /* Check for failure down child branch. */
+ int childCheck = matchPattern( bindings, prg,
+ nodes[pat].child, treeChild( prg, kid->tree ), true );
+ if ( ! childCheck )
+ return false;
+ }
+
+ /* If checking next, then look for failure there. */
+ if ( checkNext ) {
+ int nextCheck = matchPattern( bindings, prg,
+ nodes[pat].next, kid->next, true );
+ if ( ! nextCheck )
+ return false;
+ }
+
+ return true;
+ }
+ }
+ else if ( pat == -1 && kid == 0 ) {
+ /* Both null is a match. */
+ return 1;
+ }
+
+ return false;
+}
+
+