diff options
author | Adrian Thurston <thurston@complang.org> | 2010-04-24 17:32:42 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2010-04-24 17:32:42 +0000 |
commit | 47b94563aecdf163b3277929da20327fa7d3c835 (patch) | |
tree | 904a12efd0fb2d7d9229847c25b22044655fb65e /colm | |
parent | 2fa30043cac4748bf2c0eb0eac891b01dbafa54a (diff) | |
download | colm-47b94563aecdf163b3277929da20327fa7d3c835.tar.gz |
more C porting
Diffstat (limited to 'colm')
-rw-r--r-- | colm/bytecode.h | 5 | ||||
-rw-r--r-- | colm/tree.cpp | 160 | ||||
-rw-r--r-- | colm/tree.h | 19 | ||||
-rw-r--r-- | colm/tree2.c | 195 |
4 files changed, 214 insertions, 165 deletions
diff --git a/colm/bytecode.h b/colm/bytecode.h index 16ed08bc..8a79b53c 100644 --- a/colm/bytecode.h +++ b/colm/bytecode.h @@ -54,11 +54,8 @@ void rcodeDownref( Program *prg, Tree **sp, Code *instr ); #include "tree.h" -void printTree( ostream &out, Tree **&sp, Program *prg, Tree *tree ); -void printXmlTree( Tree **&sp, Program *prg, Tree *tree, bool commAttr ); -void printXmlKid( Tree **&sp, Program *prg, Kid *kid, bool commAttr, int depth ); - Tree **stackAlloc(); +void printTree( ostream &out, Tree **sp, Program *prg, Tree *tree ); /* * Runtime environment diff --git a/colm/tree.cpp b/colm/tree.cpp index 5e0ba55e..782fa1a0 100644 --- a/colm/tree.cpp +++ b/colm/tree.cpp @@ -57,7 +57,7 @@ void printIgnoreList( ostream &out, Tree **sp, Program *prg, Tree *tree ) } } -void printKid( ostream &out, Tree **&sp, Program *prg, Kid *kid, bool printIgnore ) +void printKid( ostream &out, Tree **sp, Program *prg, Kid *kid, bool printIgnore ) { Tree **root = vm_ptop(); Kid *child; @@ -115,7 +115,7 @@ rec_call: goto rec_return; } -void printTree( ostream &out, Tree **&sp, Program *prg, Tree *tree ) +void printTree( ostream &out, Tree **sp, Program *prg, Tree *tree ) { if ( tree == 0 ) out << "NIL"; @@ -128,159 +128,3 @@ void printTree( ostream &out, Tree **&sp, Program *prg, Tree *tree ) } -void xmlEscapeData( const char *data, long len ) -{ - for ( int i = 0; i < len; i++ ) { - if ( data[i] == '<' ) - cout << "<"; - else if ( data[i] == '>' ) - cout << ">"; - else if ( data[i] == '&' ) - cout << "&"; - else if ( 32 <= data[i] && data[i] <= 126 ) - cout << data[i]; - else - cout << "&#" << ((unsigned)data[i]) << ';'; - } -} - -/* Might be a good idea to include this in the printXmlKid function since - * it is recursive and can eat up stac, however it's probably not a big deal - * since the additional stack depth is only caused for nonterminals that are - * ignored. */ -void printXmlIgnoreList( Tree **sp, Program *prg, Tree *tree, long depth ) -{ - Kid *ignore = treeIgnore( prg, tree ); - while ( ignore != 0 ) { - printXmlKid( sp, prg, ignore, true, depth ); - ignore = ignore->next; - } -} - -void printXmlKid( Tree **&sp, Program *prg, Kid *kid, bool commAttr, int depth ) -{ - Kid *child; - Tree **root = vm_ptop(); - long i, objectLength; - LangElInfo *lelInfo = prg->rtd->lelInfo; - - long kidNum = 0;; - -rec_call: - - if ( kid->tree == 0 ) { - for ( i = 0; i < depth; i++ ) - cout << " "; - - cout << "NIL" << endl; - } - else { - /* First print the ignore tokens. */ - if ( commAttr ) - printXmlIgnoreList( sp, prg, kid->tree, depth ); - - for ( i = 0; i < depth; i++ ) - cout << " "; - - /* Open the tag. Afterwards we will either print data underneath it or - * we will close it off immediately. */ - cout << '<' << lelInfo[kid->tree->id].name; - - /* If this is an attribute then give the node an attribute number. */ - if ( vm_ptop() != root ) { - objectLength = lelInfo[((Kid*)vm_top())->tree->id].objectLength; - if ( kidNum < objectLength ) - cout << " an=\"" << kidNum << '"'; - } - - objectLength = lelInfo[kid->tree->id].objectLength; - child = treeChild( prg, kid->tree ); - if ( (commAttr && objectLength > 0) || child != 0 ) { - cout << '>' << endl; - vm_push( (SW) kidNum ); - vm_push( (SW) kid ); - - kidNum = 0; - kid = kid->tree->child; - - /* Skip over attributes if not printing comments and attributes. */ - if ( ! commAttr ) - kid = child; - - while ( kid != 0 ) { - /* FIXME: I don't think we need this check for ignore any more. */ - if ( kid->tree == 0 || !lelInfo[kid->tree->id].ignore ) { - depth++; - goto rec_call; - rec_return: - depth--; - } - - kid = kid->next; - kidNum += 1; - - /* If the parent kid is a repeat then skip this node and go - * right to the first child (repeated item). */ - if ( lelInfo[((Kid*)vm_top())->tree->id].repeat ) - kid = kid->tree->child; - - /* If we have a kid and the parent is a list (recursive prod of - * list) then go right to the first child. */ - if ( kid != 0 && lelInfo[((Kid*)vm_top())->tree->id].list ) - kid = kid->tree->child; - } - - kid = (Kid*) vm_pop(); - kidNum = (long) vm_pop(); - - for ( i = 0; i < depth; i++ ) - cout << " "; - cout << "</" << lelInfo[kid->tree->id].name << '>' << endl; - } - else if ( kid->tree->id == LEL_ID_PTR ) { - cout << '>' << (void*)((Pointer*)kid->tree)->value << - "</" << lelInfo[kid->tree->id].name << '>' << endl; - } - else if ( kid->tree->id == LEL_ID_BOOL ) { - if ( ((Int*)kid->tree)->value ) - cout << ">true</"; - else - cout << ">false</"; - cout << lelInfo[kid->tree->id].name << '>' << endl; - } - else if ( kid->tree->id == LEL_ID_INT ) { - cout << '>' << ((Int*)kid->tree)->value << - "</" << lelInfo[kid->tree->id].name << '>' << endl; - } - else if ( kid->tree->id == LEL_ID_STR ) { - Head *head = (Head*) ((Str*)kid->tree)->value; - - cout << '>'; - xmlEscapeData( (char*)(head->data), head->length ); - cout << "</" << lelInfo[kid->tree->id].name << '>' << endl; - } - else if ( 0 < kid->tree->id && kid->tree->id < prg->rtd->firstNonTermId && - kid->tree->tokdata != 0 && - stringLength( kid->tree->tokdata ) > 0 && - !lelInfo[kid->tree->id].literal ) - { - cout << '>'; - xmlEscapeData( stringData( kid->tree->tokdata ), - stringLength( kid->tree->tokdata ) ); - cout << "</" << lelInfo[kid->tree->id].name << '>' << endl; - } - else - cout << "/>" << endl; - } - - if ( vm_ptop() != root ) - goto rec_return; -} - -void printXmlTree( Tree **&sp, Program *prg, Tree *tree, bool commAttr ) -{ - Kid kid; - kid.tree = tree; - kid.next = 0; - printXmlKid( sp, prg, &kid, commAttr, 0 ); -} diff --git a/colm/tree.h b/colm/tree.h index c6535b68..6e61ec14 100644 --- a/colm/tree.h +++ b/colm/tree.h @@ -91,6 +91,25 @@ Tree *treeRevIterPrevChild( Program *prg, Tree ***psp, RevTreeIter *iter ); Tree *treeIterNextRepeat( Program *prg, Tree ***psp, TreeIter *iter ); Tree *treeIterPrevRepeat( Program *prg, Tree ***psp, TreeIter *iter ); +void printXmlTree( Tree **sp, Program *prg, Tree *tree, int commAttr ); + + +/* An automatically grown buffer for collecting tokens. Always reuses space; + * never down resizes. */ +typedef struct _StrCollect +{ + + char *data; + int allocated; + int length; +} StrCollect; + +void initStrCollect( StrCollect *collect ); +void strCollectDestroy( StrCollect *collect ); +void strCollectAppend( StrCollect *collect, char *data, long len ); +void strCollectClear( StrCollect *collect ); + + #if defined(__cplusplus) } #endif diff --git a/colm/tree2.c b/colm/tree2.c index ddb899d7..ed8fc3c5 100644 --- a/colm/tree2.c +++ b/colm/tree2.c @@ -32,6 +32,8 @@ #define true 1 #define false 0 +#define BUFFER_INITIAL_SIZE 4096 + void initUserIter( UserIter *userIter, Tree **stackRoot, long argSize, long searchId ) { userIter->stackRoot = stackRoot; @@ -1622,7 +1624,7 @@ Tree *treeIterNextRepeat( Program *prg, Tree ***psp, TreeIter *iter ) return (iter->ref.kid ? prg->trueVal : prg->falseVal ); } -void iter_find_rev_repeat( Program *prg, Tree ***psp, TreeIter *iter, int tryFirst ) +void iterFindRevRepeat( Program *prg, Tree ***psp, TreeIter *iter, int tryFirst ) { Tree **sp = *psp; int anyTree = iter->searchId == prg->rtd->anyId; @@ -1685,11 +1687,11 @@ Tree *treeIterPrevRepeat( Program *prg, Tree ***psp, TreeIter *iter ) if ( iter->ref.kid == 0 ) { /* Kid is zero, start from the root. */ iter->ref = iter->rootRef; - iter_find_rev_repeat( prg, psp, iter, true ); + iterFindRevRepeat( prg, psp, iter, true ); } else { /* Have a previous item, continue searching from there. */ - iter_find_rev_repeat( prg, psp, iter, false ); + iterFindRevRepeat( prg, psp, iter, false ); } iter->stackSize = iter->stackRoot - *psp; @@ -1730,4 +1732,191 @@ Tree *treeSearch2( Program *prg, Tree *tree, long id ) return res; } +void xmlEscapeData( FILE *out, const char *data, long len ) +{ + int i; + for ( i = 0; i < len; i++ ) { + if ( data[i] == '<' ) + fprintf( out, "<" ); + else if ( data[i] == '>' ) + fprintf( out, ">" ); + else if ( data[i] == '&' ) + fprintf( out, "&" ); + else if ( 32 <= data[i] && data[i] <= 126 ) + fprintf( out, "%c", data[i] ); + else + fprintf( out, "&#%u;", ((unsigned)data[i]) ); + } +} + +void printXmlKid( FILE *out, Tree **sp, Program *prg, Kid *kid, int commAttr, int depth ); + +/* Might be a good idea to include this in the printXmlKid function since + * it is recursive and can eat up stac, however it's probably not a big deal + * since the additional stack depth is only caused for nonterminals that are + * ignored. */ +void printXmlIgnoreList( FILE *out, Tree **sp, Program *prg, Tree *tree, long depth ) +{ + Kid *ignore = treeIgnore( prg, tree ); + while ( ignore != 0 ) { + printXmlKid( out, sp, prg, ignore, true, depth ); + ignore = ignore->next; + } +} + +void printXmlKid( FILE *out, Tree **sp, Program *prg, Kid *kid, int commAttr, int depth ) +{ + Kid *child; + Tree **root = vm_ptop(); + long i, objectLength; + LangElInfo *lelInfo = prg->rtd->lelInfo; + + long kidNum = 0;; + +rec_call: + + if ( kid->tree == 0 ) { + for ( i = 0; i < depth; i++ ) + fprintf( out, " " ); + + fprintf( out, "NIL\n" ); + } + else { + /* First print the ignore tokens. */ + if ( commAttr ) + printXmlIgnoreList( out, sp, prg, kid->tree, depth ); + + for ( i = 0; i < depth; i++ ) + fprintf( out, " " ); + + /* Open the tag. Afterwards we will either print data underneath it or + * we will close it off immediately. */ + fprintf( out, "<%s", lelInfo[kid->tree->id].name ); + + /* If this is an attribute then give the node an attribute number. */ + if ( vm_ptop() != root ) { + objectLength = lelInfo[((Kid*)vm_top())->tree->id].objectLength; + if ( kidNum < objectLength ) + fprintf( out, " an=\"%ld\"", kidNum ); + } + + objectLength = lelInfo[kid->tree->id].objectLength; + child = treeChild( prg, kid->tree ); + if ( (commAttr && objectLength > 0) || child != 0 ) { + fprintf( out, ">\n" ); + vm_push( (SW) kidNum ); + vm_push( (SW) kid ); + + kidNum = 0; + kid = kid->tree->child; + + /* Skip over attributes if not printing comments and attributes. */ + if ( ! commAttr ) + kid = child; + + while ( kid != 0 ) { + /* FIXME: I don't think we need this check for ignore any more. */ + if ( kid->tree == 0 || !lelInfo[kid->tree->id].ignore ) { + depth++; + goto rec_call; + rec_return: + depth--; + } + + kid = kid->next; + kidNum += 1; + + /* If the parent kid is a repeat then skip this node and go + * right to the first child (repeated item). */ + if ( lelInfo[((Kid*)vm_top())->tree->id].repeat ) + kid = kid->tree->child; + + /* If we have a kid and the parent is a list (recursive prod of + * list) then go right to the first child. */ + if ( kid != 0 && lelInfo[((Kid*)vm_top())->tree->id].list ) + kid = kid->tree->child; + } + + kid = (Kid*) vm_pop(); + kidNum = (long) vm_pop(); + + for ( i = 0; i < depth; i++ ) + fprintf( out, " " ); + fprintf( out, "</%s>\n", lelInfo[kid->tree->id].name ); + } + else if ( kid->tree->id == LEL_ID_PTR ) { + fprintf( out, ">%p</%s>\n", (void*)((Pointer*)kid->tree)->value, + lelInfo[kid->tree->id].name ); + } + else if ( kid->tree->id == LEL_ID_BOOL ) { + if ( ((Int*)kid->tree)->value ) + fprintf( out, ">true</" ); + else + fprintf( out, ">false</" ); + fprintf( out, "%s>\n", lelInfo[kid->tree->id].name ); + } + else if ( kid->tree->id == LEL_ID_INT ) { + fprintf( out, ">%ld</%s>\n", ((Int*)kid->tree)->value, + lelInfo[kid->tree->id].name ); + } + else if ( kid->tree->id == LEL_ID_STR ) { + Head *head = (Head*) ((Str*)kid->tree)->value; + + fprintf( out, ">" ); + xmlEscapeData( out, (char*)(head->data), head->length ); + fprintf( out, "</%s>\n", lelInfo[kid->tree->id].name ); + } + else if ( 0 < kid->tree->id && kid->tree->id < prg->rtd->firstNonTermId && + kid->tree->tokdata != 0 && + stringLength( kid->tree->tokdata ) > 0 && + !lelInfo[kid->tree->id].literal ) + { + fprintf( out, ">" ); + xmlEscapeData( out, stringData( kid->tree->tokdata ), + stringLength( kid->tree->tokdata ) ); + fprintf( out, "</%s>\n", lelInfo[kid->tree->id].name ); + } + else { + fprintf( out, "/>\n" ); + } + } + + if ( vm_ptop() != root ) + goto rec_return; +} + +void printXmlTree( Tree **sp, Program *prg, Tree *tree, int commAttr ) +{ + Kid kid; + kid.tree = tree; + kid.next = 0; + printXmlKid( stdout, sp, prg, &kid, commAttr, 0 ); +} + +void initStrCollect( StrCollect *collect ) +{ + collect->data = (char*) malloc( BUFFER_INITIAL_SIZE ); + collect->allocated = BUFFER_INITIAL_SIZE; + collect->length = 0; +} + +void strCollectDestroy( StrCollect *collect ) +{ + free( collect->data ); +} +void strCollectAppend( StrCollect *collect, char *data, long len ) +{ + long newLen = collect->length + len; + if ( newLen > collect->allocated ) { + collect->allocated *= newLen * 2; + collect->data = (char*) realloc( collect->data, collect->allocated ); + } + memcpy( collect->data + collect->length, data, len ); + collect->length += len; +} + +void strCollectClear( StrCollect *collect ) +{ + collect->length = 0; +} |