diff options
author | Adrian Thurston <thurston@complang.org> | 2008-11-07 21:08:38 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2008-11-07 21:08:38 +0000 |
commit | 8669467abf4ccdbbdcd522467082098725af96c4 (patch) | |
tree | 01148beeddc30fed7a03de72d149287d0c50d3de | |
parent | 8e568f07ea6f54fb5e9ad61f264a4f29972fb693 (diff) | |
download | colm-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.cpp | 46 | ||||
-rw-r--r-- | colm/bytecode.h | 3 | ||||
-rw-r--r-- | colm/compile.cpp | 11 |
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; } |