summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2013-04-13 10:39:14 -0400
committerAdrian Thurston <thurston@complang.org>2013-04-13 10:39:14 -0400
commite0cc080f94de6764b2eae8ef3815882316ebb922 (patch)
treec51ca85e930c4d2028eb6254fe982660c6a072a5
parent911f6dba5d5da289a1ed43ac6cc7171f7dcdc48e (diff)
downloadcolm-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.
-rw-r--r--colm/bytecode.c20
-rw-r--r--colm/bytecode.h3
-rw-r--r--colm/conscolm.cc4
-rw-r--r--colm/consinit.cc3
-rw-r--r--colm/parsedata.h1
-rw-r--r--colm/parser.cc2
-rw-r--r--colm/parsetree.h3
-rw-r--r--colm/program.c4
-rw-r--r--colm/program.h2
-rw-r--r--colm/synthesis.cc46
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()