diff options
author | Adrian Thurston <thurston@complang.org> | 2013-04-13 10:39:14 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2013-04-13 10:39:14 -0400 |
commit | e0cc080f94de6764b2eae8ef3815882316ebb922 (patch) | |
tree | c51ca85e930c4d2028eb6254fe982660c6a072a5 /colm | |
parent | 911f6dba5d5da289a1ed43ac6cc7171f7dcdc48e (diff) | |
download | colm-e0cc080f94de6764b2eae8ef3815882316ebb922.tar.gz |
parse expression returns the tree type, added 'error' global
Reverted back to the original semantics of the parse expression, where the
parser object is a temporary and the tree is returned. It is inconsistent form
to use:
parse Label: type [input]
and have Label be of something other than 'type'.
Added a global variable called 'error', which stores the error of the most
recently executed parse statement. This lets us have the better semantics for
the concise parse expression, and be able to get at the error.
Diffstat (limited to 'colm')
-rw-r--r-- | colm/bytecode.c | 20 | ||||
-rw-r--r-- | colm/bytecode.h | 3 | ||||
-rw-r--r-- | colm/conscolm.cc | 4 | ||||
-rw-r--r-- | colm/consinit.cc | 3 | ||||
-rw-r--r-- | colm/parsedata.h | 1 | ||||
-rw-r--r-- | colm/parser.cc | 2 | ||||
-rw-r--r-- | colm/parsetree.h | 3 | ||||
-rw-r--r-- | colm/program.c | 4 | ||||
-rw-r--r-- | colm/program.h | 2 | ||||
-rw-r--r-- | colm/synthesis.cc | 46 |
10 files changed, 67 insertions, 21 deletions
diff --git a/colm/bytecode.c b/colm/bytecode.c index b0e9779a..4cfd573e 100644 --- a/colm/bytecode.c +++ b/colm/bytecode.c @@ -2161,6 +2161,26 @@ again: break; } + case IN_SET_ERROR: { + debug( prg, REALM_BYTECODE, "IN_SET_ERROR\n" ); + + Tree *error = vm_pop(); + treeDownref( prg, sp, prg->error ); + prg->error = error; + break; + } + + case IN_GET_ERROR: { + debug( prg, REALM_BYTECODE, "IN_GET_ERROR\n" ); + + Tree *obj = vm_pop(); + treeDownref( prg, sp, obj ); + + treeUpref( (Tree*)prg->error ); + vm_push( (Tree*)prg->error ); + break; + } + case IN_PARSE_SAVE_STEPS: { debug( prg, REALM_BYTECODE, "IN_PARSE_SAVE_STEPS\n" ); diff --git a/colm/bytecode.h b/colm/bytecode.h index c84ccb6b..d7785afc 100644 --- a/colm/bytecode.h +++ b/colm/bytecode.h @@ -317,6 +317,9 @@ typedef unsigned char uchar; #define IN_SET_PARSER_MEM_WV 0x00 #define IN_SET_PARSER_MEM_BKT 0x00 +#define IN_GET_ERROR 0xcc +#define IN_SET_ERROR 0xe2 + /* Types */ #define TYPE_NIL 0x01 diff --git a/colm/conscolm.cc b/colm/conscolm.cc index 859dab76..054db4bc 100644 --- a/colm/conscolm.cc +++ b/colm/conscolm.cc @@ -305,8 +305,7 @@ void LoadColm::consParseStmt( StmtList *stmtList ) void LoadColm::consExportTree( StmtList *stmtList ) { QualItemVect *qual = new QualItemVect; - qual->append( QualItem( internal, String( "P" ), QualItem::Dot ) ); - LangVarRef *varRef = LangVarRef::cons( internal, qual, String("tree") ); + LangVarRef *varRef = LangVarRef::cons( internal, qual, String("P") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); NamespaceQual *nspaceQual = NamespaceQual::cons( namespaceStack.top() ); @@ -319,7 +318,6 @@ void LoadColm::consExportTree( StmtList *stmtList ) void LoadColm::consExportError( StmtList *stmtList ) { QualItemVect *qual = new QualItemVect; - qual->append( QualItem( internal, String( "P" ), QualItem::Dot ) ); LangVarRef *varRef = LangVarRef::cons( internal, qual, String("error") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); diff --git a/colm/consinit.cc b/colm/consinit.cc index 0893e9c4..33de078b 100644 --- a/colm/consinit.cc +++ b/colm/consinit.cc @@ -766,8 +766,7 @@ void ConsInit::parseInput( StmtList *stmtList ) void ConsInit::exportTree( StmtList *stmtList ) { QualItemVect *qual = new QualItemVect; - qual->append( QualItem( internal, String( "P" ), QualItem::Dot ) ); - LangVarRef *varRef = LangVarRef::cons( internal, qual, String("tree") ); + LangVarRef *varRef = LangVarRef::cons( internal, qual, String("P") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); NamespaceQual *nspaceQual = NamespaceQual::cons( namespaceStack.top() ); diff --git a/colm/parsedata.h b/colm/parsedata.h index 32c97a6f..7622a2da 100644 --- a/colm/parsedata.h +++ b/colm/parsedata.h @@ -768,6 +768,7 @@ struct Compiler void addStdout(); void addStderr(); void addArgv(); + void addError(); int argvOffset(); void initGlobalFunctions(); void makeDefaultIterators(); diff --git a/colm/parser.cc b/colm/parser.cc index 13e3208e..76dd00a6 100644 --- a/colm/parser.cc +++ b/colm/parser.cc @@ -575,7 +575,7 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool stop, ObjectField *obj } /* Insert it into the field map. */ - objField->typeRef = parserTypeRef; + objField->typeRef = typeRef; pd->curLocalFrame->insertField( objField->name, objField ); } diff --git a/colm/parsetree.h b/colm/parsetree.h index a8414249..6c885282 100644 --- a/colm/parsetree.h +++ b/colm/parsetree.h @@ -2601,7 +2601,7 @@ struct LangTerm UniqueType *evaluateNew( Compiler *pd, CodeVect &code ) const; UniqueType *evaluateConstruct( Compiler *pd, CodeVect &code ) const; void parseFrag( Compiler *pd, CodeVect &code, int stopId ) const; - UniqueType *evaluateParse( Compiler *pd, CodeVect &code, bool stop, bool orig ) const; + UniqueType *evaluateParse( Compiler *pd, CodeVect &code, bool stop ) const; UniqueType *evaluateSend( Compiler *pd, CodeVect &code ) const; UniqueType *evaluateMatch( Compiler *pd, CodeVect &code ) const; UniqueType *evaluate( Compiler *pd, CodeVect &code ) const; @@ -2621,7 +2621,6 @@ struct LangTerm Pattern *pattern; FieldInitVect *fieldInitArgs; GenericType *generic; - TypeRef *parserTypeRef; Constructor *constructor; ParserText *parserText; LangExpr *expr; diff --git a/colm/program.c b/colm/program.c index 5067af42..d781a57e 100644 --- a/colm/program.c +++ b/colm/program.c @@ -264,8 +264,6 @@ int colmDeleteProgram( Program *prg ) a = next; } - //assert( trueVal->refs == 1 ); - //assert( falseVal->refs == 1 ); treeDownref( prg, sp, prg->trueVal ); treeDownref( prg, sp, prg->falseVal ); @@ -273,6 +271,8 @@ int colmDeleteProgram( Program *prg ) treeDownref( prg, sp, (Tree*)prg->stdoutVal ); treeDownref( prg, sp, (Tree*)prg->stderrVal ); + treeDownref( prg, sp, prg->error ); + #if DEBUG long kidLost = kidNumLost( prg ); long treeLost = treeNumLost( prg ); diff --git a/colm/program.h b/colm/program.h index 5f1e88ed..d1b57f64 100644 --- a/colm/program.h +++ b/colm/program.h @@ -128,6 +128,8 @@ typedef struct ColmProgram Stream *stdoutVal; Stream *stderrVal; + Tree *error; + RunBuf *allocRunBuf; /* Current stack block limits. Changed when crossing block boundaries. */ diff --git a/colm/synthesis.cc b/colm/synthesis.cc index 4707e52e..ffa89993 100644 --- a/colm/synthesis.cc +++ b/colm/synthesis.cc @@ -1339,7 +1339,7 @@ void LangTerm::parseFrag( Compiler *pd, CodeVect &code, int stopId ) const } } -UniqueType *LangTerm::evaluateParse( Compiler *pd, CodeVect &code, bool stop, bool orig ) const +UniqueType *LangTerm::evaluateParse( Compiler *pd, CodeVect &code, bool stop ) const { UniqueType *ut = typeRef->uniqueType->langEl->generic->utArg; @@ -1500,26 +1500,32 @@ UniqueType *LangTerm::evaluateParse( Compiler *pd, CodeVect &code, bool stop, bo code.append( IN_POP ); + /* Parser is on the top of the stack. */ + + /* Pull out the error and save it off. */ + code.append( IN_DUP_TOP ); + code.append( IN_GET_PARSER_MEM_R ); + code.appendHalf( 1 ); + code.append( IN_SET_ERROR ); + + /* Replace the parser with the parsed tree. */ + code.append( IN_GET_PARSER_MEM_R ); + code.appendHalf( 0 ); + /* * Capture to the local var. */ if ( varRef != 0 ) { code.append( IN_DUP_TOP ); - if ( orig ) { - code.append( IN_GET_PARSER_MEM_R ); - code.appendHalf( 0 ); - } - /* Get the type of the variable being assigned to. */ VarRefLookup lookup = varRef->lookupField( pd ); varRef->loadObj( pd, code, lookup.lastPtrInQual, false ); - varRef->setField( pd, code, lookup.inObject, replUT, false ); + varRef->setField( pd, code, lookup.inObject, ut, false ); } - - return replUT; + return ut; } @@ -1672,9 +1678,9 @@ UniqueType *LangTerm::evaluate( Compiler *pd, CodeVect &code ) const case MatchType: return evaluateMatch( pd, code ); case ParseType: - return evaluateParse( pd, code, false, false ); + return evaluateParse( pd, code, false ); case ParseStopType: - return evaluateParse( pd, code, true, false ); + return evaluateParse( pd, code, true ); case ConstructType: return evaluateConstruct( pd, code ); case SendType: @@ -3296,6 +3302,23 @@ void Compiler::addArgv() globalObjectDef->insertField( el->name, el ); } +void Compiler::addError() +{ + /* Make the type ref. */ + TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStr ); + + /* Create the field and insert it into the map. */ + ObjectField *el = ObjectField::cons( internal, typeRef, "error" ); + el->beenReferenced = true; + el->beenInitialized = true; + el->isConst = true; + el->useOffset = false; + el->inGetR = IN_GET_ERROR; + el->inGetWC = IN_GET_ERROR; + el->inGetWV = IN_GET_ERROR; + globalObjectDef->insertField( el->name, el ); +} + int Compiler::argvOffset() { for ( ObjFieldList::Iter field = *globalObjectDef->objFieldList; @@ -3332,6 +3355,7 @@ void Compiler::initGlobalFunctions() addStdout(); addStderr(); addArgv(); + addError(); } void Compiler::removeNonUnparsableRepls() |