diff options
author | Adrian Thurston <thurston@complang.org> | 2010-04-24 01:40:55 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2010-04-24 01:40:55 +0000 |
commit | 35eec09461fca18834425d46bb6738a2bf584a4d (patch) | |
tree | b7b899db4f9bd14e1dfdda2522b8b606e952c65b | |
parent | bdbeb7241a9000197f1256976fbaeb2f254477ac (diff) | |
download | colm-35eec09461fca18834425d46bb6738a2bf584a4d.tar.gz |
more C porting
-rw-r--r-- | colm/bytecode.cpp | 2 | ||||
-rw-r--r-- | colm/bytecode.h | 22 | ||||
-rw-r--r-- | colm/tree.cpp | 590 | ||||
-rw-r--r-- | colm/tree.h | 21 | ||||
-rw-r--r-- | colm/tree2.c | 577 |
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; +} + + |