diff options
author | Adrian Thurston <thurston@complang.org> | 2011-11-13 00:44:57 +0000 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2011-11-13 00:44:57 +0000 |
commit | 562a05797e143a1f7294230766bd87225fd9821f (patch) | |
tree | 9d0b6712b61d7b6c5ea14769bb5f71ab7717d1df | |
parent | 1c848101d8fa37b3bf3a04fc5602a8c34f21949d (diff) | |
download | colm-562a05797e143a1f7294230766bd87225fd9821f.tar.gz |
Eliminated recursive call to bytecode loop in parse finish WC 3.
refs #332.
-rw-r--r-- | colm/bytecode.c | 88 | ||||
-rw-r--r-- | colm/bytecode.h | 13 | ||||
-rw-r--r-- | colm/compile.cc | 23 |
3 files changed, 109 insertions, 15 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c index 3ba41326..fb97bd81 100644 --- a/colm/bytecode.c +++ b/colm/bytecode.c @@ -2365,7 +2365,6 @@ again: break; } - case IN_PARSE_FRAG_BKT: { Tree *accum; Tree *input; @@ -2495,32 +2494,97 @@ again: FsmRun *fsmRun = ((Accum*)accum)->fsmRun; long pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrStart ); - while ( pcr == PcrReduction ) { - Execution exec2; - Execution *exec = &exec2; + + vm_push( (SW)pdaRun ); + vm_push( (SW)fsmRun ); + vm_push( (SW)pcr ); + vm_push( result ); + + vm_push( (Tree*)stream ); + vm_push( accum ); + break; + } + + case IN_PARSE_FINISH_WC2: { + debug( REALM_BYTECODE, "IN_PARSE_FINISH_WC2\n" ); + + Tree *accum = vm_pop(); + Tree *stream = vm_pop(); + + Tree *result = vm_pop(); + long pcr = (long)vm_pop(); + FsmRun *fsmRun = (FsmRun*)vm_pop(); + PdaRun *pdaRun = (PdaRun*)vm_pop(); + + if ( pcr == PcrReduction ) { + /* Push the execution. */ + vm_pushn( SIZEOF_WORD * 20 ); + Execution *pushedExec = (Execution*)vm_ptop(); + memcpy( pushedExec, exec, sizeof(Execution) ); pdaRun->exec = exec; - debug( REALM_BYTECODE, "reduction in finish\n" ); /* Execution environment for the reduction code. */ initReductionExecution( pdaRun->exec, prg, &pdaRun->rcodeCollect, pdaRun, fsmRun, prg->rtd->prodInfo[pdaRun->reduction].frameId, pdaRun->fi->codeWV, pdaRun->redLel->tree, 0, 0, fsmRun->mark ); + vm_push( (SW)pdaRun ); + vm_push( (SW)fsmRun ); + vm_push( (SW)pcr ); + vm_push( result ); + + vm_push( stream ); + vm_push( accum ); + /* Push the instruction. */ - vm_push( 0 ) ;//(SW)instr ); + vm_push( (SW)instr ); /* Push the LHS onto the stack. */ vm_push( exec->lhs ); - /* Execution loop. */ - sp = executeCode( exec, sp, exec->code ); + /* Call execution. */ + instr = exec->code; + } + else { + instr += SIZEOF_CODE; - pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrReduction ); + vm_push( result ); + treeDownref( prg, sp, accum ); + if ( prg->induceExit ) + goto out; } + break; + } + + case IN_PARSE_FINISH_WC3: { + debug( REALM_BYTECODE, "IN_PARSE_FINISH_WC3\n" ); + + Tree *accum = vm_pop(); + Tree *stream = vm_pop(); + + Tree *result = vm_pop(); + long pcr = (long)vm_pop(); + FsmRun *fsmRun = (FsmRun*)vm_pop(); + PdaRun *pdaRun = (PdaRun*)vm_pop(); + + pcr = parseFinish( &result, prg, sp, (Accum*)accum, stream, false, PcrReduction ); + + /* Pop the saved execution. */ + Execution *pushedExec = (Execution*)vm_ptop(); + memcpy( exec, pushedExec, sizeof(Execution) ); + vm_popn( SIZEOF_WORD * 20 ); + + vm_push( (SW)pdaRun ); + vm_push( (SW)fsmRun ); + vm_push( (SW)pcr ); vm_push( result ); - treeDownref( prg, sp, accum ); - if ( prg->induceExit ) - goto out; + + vm_push( stream ); + vm_push( accum ); + + instr -= SIZEOF_CODE; + instr -= SIZEOF_CODE; + break; } case IN_PARSE_FINISH_WV: { diff --git a/colm/bytecode.h b/colm/bytecode.h index 7d3c5936..011e4380 100644 --- a/colm/bytecode.h +++ b/colm/bytecode.h @@ -230,10 +230,11 @@ typedef unsigned char uchar; #define IN_PARSE_FRAG_WC 0xc0 #define IN_PARSE_FRAG_WC2 0xe0 #define IN_PARSE_FRAG_WC3 0xe1 -#define IN_RED_RET 0xe3 + #define IN_PARSE_FRAG_WV 0xc1 #define IN_PARSE_FRAG_WV2 0xe2 #define IN_PARSE_FRAG_WV3 0xe4 + #define IN_PARSE_FRAG_BKT 0xc2 #define IN_PARSE_FRAG_BKT2 0xe5 #define IN_PARSE_FRAG_BKT3 0xe6 @@ -249,8 +250,18 @@ typedef unsigned char uchar; #define IN_STREAM_APPEND_BKT 0xc8 #define IN_PARSE_FINISH_WC 0x9d +#define IN_PARSE_FINISH_WC2 0xe7 +#define IN_PARSE_FINISH_WC3 0xea + #define IN_PARSE_FINISH_WV 0xbd +#define IN_PARSE_FINISH_WV2 0xe8 +#define IN_PARSE_FINISH_WV3 0xeb + #define IN_PARSE_FINISH_BKT 0xbf +#define IN_PARSE_FINISH_BKT2 0xe9 +#define IN_PARSE_FINISH_BKT3 0xec + +#define IN_RED_RET 0xe3 #define IN_PARSE_EXTRACT_INPUT diff --git a/colm/compile.cc b/colm/compile.cc index 209fa5d9..ec4028a8 100644 --- a/colm/compile.cc +++ b/colm/compile.cc @@ -1059,10 +1059,16 @@ void LangVarRef::callOperation( ParseData *pd, CodeVect &code, VarRefLookup &loo bool revert = lookup.lastPtrInQual >= 0 || !isLocalRef(pd); /* The call instruction. */ - if ( pd->revertOn && revert ) + if ( pd->revertOn && revert ) { code.append( lookup.objMethod->opcodeWV ); - else + } + else { code.append( lookup.objMethod->opcodeWC ); + if ( lookup.objMethod->opcodeWC == IN_PARSE_FINISH_WC ) { + code.append( IN_PARSE_FINISH_WC2 ); + code.append( IN_PARSE_FINISH_WC3 ); + } + } if ( lookup.objMethod->useFuncId ) code.appendHalf( lookup.objMethod->funcId ); @@ -1467,6 +1473,19 @@ UniqueType *LangTerm::evaluateParse( ParseData *pd, CodeVect &code, bool stop ) else code.append( IN_PARSE_FINISH_WC ); + if ( pd->revertOn ) + {//code.append( IN_PARSE_FINISH_WV2 ); + } + else + code.append( IN_PARSE_FINISH_WC2 ); + + if ( pd->revertOn ) + {//code.append( IN_PARSE_FINISH_WV3 ); + } + else + code.append( IN_PARSE_FINISH_WC3 ); + + /* Lookup the type of the replacement and store it in the replacement * object so that replacement parsing has a target. */ replacement->langEl = generic->langEl; |