summaryrefslogtreecommitdiff
path: root/colm
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2010-04-24 17:32:42 +0000
committerAdrian Thurston <thurston@complang.org>2010-04-24 17:32:42 +0000
commit47b94563aecdf163b3277929da20327fa7d3c835 (patch)
tree904a12efd0fb2d7d9229847c25b22044655fb65e /colm
parent2fa30043cac4748bf2c0eb0eac891b01dbafa54a (diff)
downloadcolm-47b94563aecdf163b3277929da20327fa7d3c835.tar.gz
more C porting
Diffstat (limited to 'colm')
-rw-r--r--colm/bytecode.h5
-rw-r--r--colm/tree.cpp160
-rw-r--r--colm/tree.h19
-rw-r--r--colm/tree2.c195
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 << "&lt;";
- else if ( data[i] == '>' )
- cout << "&gt;";
- else if ( data[i] == '&' )
- cout << "&amp;";
- 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, "&lt;" );
+ else if ( data[i] == '>' )
+ fprintf( out, "&gt;" );
+ else if ( data[i] == '&' )
+ fprintf( out, "&amp;" );
+ 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;
+}