summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2008-11-07 21:08:38 +0000
committerAdrian Thurston <thurston@complang.org>2008-11-07 21:08:38 +0000
commit8669467abf4ccdbbdcd522467082098725af96c4 (patch)
tree01148beeddc30fed7a03de72d149287d0c50d3de
parent8e568f07ea6f54fb5e9ad61f264a4f29972fb693 (diff)
downloadcolm-8669467abf4ccdbbdcd522467082098725af96c4.tar.gz
Split the IN_PARSE instruction into _WV and _WC versions instead of using a
flag. The _WC version should not write the reverse code. After executing the root code assert reverseCode as empty. The root code should not be calling any _WC code unless it calls a parse.
-rw-r--r--colm/bytecode.cpp46
-rw-r--r--colm/bytecode.h3
-rw-r--r--colm/compile.cpp11
3 files changed, 44 insertions, 16 deletions
diff --git a/colm/bytecode.cpp b/colm/bytecode.cpp
index 092ac299..98e7713d 100644
--- a/colm/bytecode.cpp
+++ b/colm/bytecode.cpp
@@ -115,7 +115,7 @@ void send( Tree **root, Program *prg, PdaRun *parser, Tree *tree, bool ignore )
}
}
-Tree *parse( Tree **&sp, Program *prg, Stream *stream,
+Tree *call_parser( Tree **&sp, Program *prg, Stream *stream,
long parserId, long stopId, CodeVect *&cv, bool revertOn )
{
PdaTables *tables = prg->rtd->parsers[parserId];
@@ -126,8 +126,14 @@ Tree *parse( Tree **&sp, Program *prg, Stream *stream,
tree_upref( tree );
parser.clean();
- /* Return the reverse code. */
- cv = parser.allReverseCode;
+ /* Maybe return the reverse code. */
+ if ( revertOn )
+ cv = parser.allReverseCode;
+ else {
+ delete parser.allReverseCode;
+ cv = 0;
+ }
+
return tree;
}
@@ -367,7 +373,6 @@ void Program::run()
if ( rtd->rootCodeLen > 0 ) {
CodeVect reverseCode;
- CodeVect *allReverseCode = new CodeVect;
Execution execution( this, reverseCode, 0, rtd->rootCode, 0, 0 );
execution.execute( root );
@@ -376,10 +381,9 @@ void Program::run()
cerr << "freeing the root reverse code" << endl;
#endif
- bool hasrcode = make_reverse_code( allReverseCode, reverseCode );
- if ( hasrcode )
- rcode_downref( root, this, allReverseCode->data );
- delete allReverseCode;
+ /* The root code should all be commit code and reverseCode
+ * should be empty. */
+ assert( reverseCode.length() == 0 );
}
/* Clear */
@@ -1645,21 +1649,19 @@ again:
tree_downref( prg, sp, tree );
break;
}
- case IN_PARSE: {
+ case IN_PARSE_WV: {
Half parserId, stopId;
- uchar revertOn;
read_half( parserId );
read_half( stopId );
- read_byte( revertOn );
#ifdef COLM_LOG_BYTECODE
- cerr << "IN_PARSE " << parserId << " " << stopId << endl;
+ cerr << "IN_PARSE_WV " << parserId << " " << stopId << endl;
#endif
/* Comes back from parse upreffed. */
CodeVect *cv;
Tree *stream = pop();
- Tree *res = parse( sp, prg, (Stream*)stream, parserId, stopId, cv, revertOn );
+ Tree *res = call_parser( sp, prg, (Stream*)stream, parserId, stopId, cv, true );
push( res );
/* Single unit. */
@@ -1672,6 +1674,24 @@ again:
reverseCode.append( 15 );
break;
}
+ case IN_PARSE_WC: {
+ Half parserId, stopId;
+ read_half( parserId );
+ read_half( stopId );
+
+ #ifdef COLM_LOG_BYTECODE
+ cerr << "IN_PARSE_WC " << parserId << " " << stopId << endl;
+ #endif
+
+ /* Comes back from parse upreffed. */
+ CodeVect *cv;
+ Tree *stream = pop();
+ Tree *res = call_parser( sp, prg, (Stream*)stream, parserId, stopId, cv, false );
+ push( res );
+
+ tree_downref( prg, sp, (Tree*)stream );
+ break;
+ }
case IN_STREAM_PULL: {
#ifdef COLM_LOG_BYTECODE
cerr << "IN_STREAM_PULL" << endl;
diff --git a/colm/bytecode.h b/colm/bytecode.h
index aa5d185d..cef37666 100644
--- a/colm/bytecode.h
+++ b/colm/bytecode.h
@@ -200,7 +200,8 @@ typedef unsigned char uchar;
#define IN_MAKE_TOKEN 0x96
#define IN_MAKE_TREE 0xb2
#define IN_CONSTRUCT_TERM 0x9a
-#define IN_PARSE 0xb1
+#define IN_PARSE_WV 0xb1
+#define IN_PARSE_WC 0xbe
#define IN_PARSE_BKT 0xb3
#define IN_STREAM_PULL 0xb4
#define IN_STREAM_PULL_BKT 0xb5
diff --git a/colm/compile.cpp b/colm/compile.cpp
index 84f2c3e5..c5a07b2f 100644
--- a/colm/compile.cpp
+++ b/colm/compile.cpp
@@ -996,13 +996,20 @@ UniqueType *LangTerm::evaluateParse( ParseData *pd, CodeVect &code, bool stop )
* the type. */
ut->langEl->parserId = pd->nextParserId++;
- code.append( IN_PARSE );
+ /* Parse instruction, dependent on whether or not we are
+ * producing revert or commit code. */
+ if ( pd->revertOn )
+ code.append( IN_PARSE_WV );
+ else
+ code.append( IN_PARSE_WC );
+
+ /* The id of the parser, followed by the stop id. */
code.appendHalf( ut->langEl->parserId );
if ( stop )
code.appendHalf( ut->langEl->id );
else
code.appendHalf( 0 );
- code.append( pd->revertOn );
+
return ut;
}