summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-01-24 12:35:27 -0500
committerAdrian Thurston <thurston@complang.org>2015-01-24 12:35:27 -0500
commitf8444f7425cbfed78c8e49bc0ab0fd9a7d254285 (patch)
tree7127bc893cc3e38e1fea8db14b4423082160cd27 /src
parent52bcefda7ae810e7fd47d3a554282e615ce604aa (diff)
downloadcolm-f8444f7425cbfed78c8e49bc0ab0fd9a7d254285.tar.gz
require that a new parser of a context-type receive the context at new time
Diffstat (limited to 'src')
-rw-r--r--src/colm.lm2
-rw-r--r--src/loadcolm.cc22
-rw-r--r--src/parsetree.h5
-rw-r--r--src/resolve.cc24
-rw-r--r--src/synthesis.cc46
5 files changed, 71 insertions, 28 deletions
diff --git a/src/colm.lm b/src/colm.lm
index 399ecc5b..cd449372 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -556,7 +556,7 @@ def code_factor
| [MAKE_TREE POPEN call_arg_list PCLOSE] :MakeTree
| [MAKE_TOKEN POPEN call_arg_list PCLOSE] :MakeToken
| [TYPEID LT type_ref GT] :TypeId
-| [NEW opt_capture type_ref POPEN call_arg_list PCLOSE] :New
+| [NEW opt_capture type_ref POPEN FieldInitList: field_init* PCLOSE] :New
| [CAST LT type_ref GT code_factor] :Cast
def type_ref
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 64f7e0b7..4405e334 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -1732,17 +1732,20 @@ struct LoadColm
list->append( init );
}
+ FieldInitVect *walkFieldInit( _repeat_field_init fieldInitList )
+ {
+ FieldInitVect *list = new FieldInitVect;
+ while ( !fieldInitList.end() ) {
+ walkFieldInit( list, fieldInitList.value() );
+ fieldInitList = fieldInitList.next();
+ }
+ return list;
+ }
FieldInitVect *walkOptFieldInit( opt_field_init optFieldInit )
{
FieldInitVect *list = 0;
- if ( optFieldInit.prodName() == opt_field_init::Init ) {
- list = new FieldInitVect;
- _repeat_field_init fieldInitList = optFieldInit.FieldInitList();
- while ( !fieldInitList.end() ) {
- walkFieldInit( list, fieldInitList.value() );
- fieldInitList = fieldInitList.next();
- }
- }
+ if ( optFieldInit.prodName() == opt_field_init::Init )
+ list = walkFieldInit( optFieldInit.FieldInitList() );
return list;
}
@@ -1891,6 +1894,7 @@ struct LoadColm
TypeRef *typeRef = walkTypeRef( codeFactor.type_ref() );
ObjectField *captureField = walkOptCapture( codeFactor.opt_capture() );
+ FieldInitVect *init = walkFieldInit( codeFactor.FieldInitList() );
LangVarRef *captureVarRef = 0;
if ( captureField != 0 ) {
@@ -1899,7 +1903,7 @@ struct LoadColm
}
expr = LangExpr::cons( LangTerm::consNew(
- codeFactor.loc(), typeRef, captureVarRef ) );
+ codeFactor.loc(), typeRef, captureVarRef, init ) );
/* Check for redeclaration. */
if ( captureField != 0 ) {
diff --git a/src/parsetree.h b/src/parsetree.h
index f5c96ce4..0e60dc4e 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -2869,16 +2869,18 @@ struct LangTerm
}
static LangTerm *consNew( const InputLoc &loc, TypeRef *typeRef,
- LangVarRef *captureVarRef )
+ LangVarRef *captureVarRef, FieldInitVect *fieldInitArgs )
{
LangTerm *s = new LangTerm;
s->type = NewType;
s->loc = loc;
s->typeRef = typeRef;
s->varRef = captureVarRef;
+ s->fieldInitArgs = fieldInitArgs;
return s;
}
+ void resolveFieldArgs( Compiler *pd );
void resolve( Compiler *pd );
void evaluateCapture( Compiler *pd, CodeVect &code, UniqueType *valUt ) const;
@@ -2899,6 +2901,7 @@ struct LangTerm
UniqueType *evaluateEmbedString( Compiler *pd, CodeVect &code ) const;
UniqueType *evaluateSearch( Compiler *pd, CodeVect &code ) const;
UniqueType *evaluateCast( Compiler *pd, CodeVect &code ) const;
+ void resolveFieldArgs( Compiler *pd ) const;
InputLoc loc;
Type type;
diff --git a/src/resolve.cc b/src/resolve.cc
index e2820bce..32ebfda9 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -421,17 +421,22 @@ void Compiler::resolveProdEl( ProdEl *prodEl )
prodEl->langEl = prodEl->typeRef->uniqueType->langEl;
}
+void LangTerm::resolveFieldArgs( Compiler *pd )
+{
+ /* Initialization expressions. */
+ if ( fieldInitArgs != 0 ) {
+ for ( FieldInitVect::Iter pi = *fieldInitArgs; pi.lte(); pi++ )
+ (*pi)->expr->resolve( pd );
+ }
+}
+
void LangTerm::resolve( Compiler *pd )
{
switch ( type ) {
case ConstructType:
typeRef->resolveType( pd );
- /* Initialization expressions. */
- if ( fieldInitArgs != 0 ) {
- for ( FieldInitVect::Iter pi = *fieldInitArgs; pi.lte(); pi++ )
- (*pi)->expr->resolve( pd );
- }
+ resolveFieldArgs( pd );
/* Types in constructor. */
for ( ConsItemList::Iter item = *constructor->list; item.lte(); item++ ) {
@@ -477,6 +482,8 @@ void LangTerm::resolve( Compiler *pd )
break;
case NewType:
+ /* Init args, then the new type. */
+ resolveFieldArgs( pd );
typeRef->resolveType( pd );
break;
case TypeIdType:
@@ -494,11 +501,8 @@ void LangTerm::resolve( Compiler *pd )
case ParseTreeType:
case ParseStopType:
typeRef->resolveType( pd );
- /* Evaluate the initialization expressions. */
- if ( fieldInitArgs != 0 ) {
- for ( FieldInitVect::Iter pi = *fieldInitArgs; pi.lte(); pi++ )
- (*pi)->expr->resolve( pd );
- }
+
+ resolveFieldArgs( pd );
for ( ConsItemList::Iter item = *parserText->list; item.lte(); item++ ) {
switch ( item->type ) {
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 9b440ee4..199224af 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -1068,23 +1068,55 @@ void LangTerm::evaluateCapture( Compiler *pd, CodeVect &code, UniqueType *valUt
UniqueType *LangTerm::evaluateNew( Compiler *pd, CodeVect &code ) const
{
/* What is being newstructed. */
- UniqueType *replUT = typeRef->uniqueType;
+ UniqueType *newUT = typeRef->uniqueType;
- if ( replUT->typeId != TYPE_STRUCT && replUT->typeId != TYPE_GENERIC )
+ if ( newUT->typeId != TYPE_STRUCT && newUT->typeId != TYPE_GENERIC )
error(loc) << "can only new a struct or generic" << endp;
- if ( replUT->typeId == TYPE_GENERIC ) {
+ bool context = false;
+ if ( newUT->typeId == TYPE_GENERIC &&
+ newUT->generic->typeId == GEN_PARSER &&
+ newUT->generic->utArg->langEl->contextIn != 0 )
+ {
+ if ( fieldInitArgs == 0 || fieldInitArgs->length() != 1 )
+ error(loc) << "parse command requires just input" << endp;
+ context = true;
+ }
+
+ if ( newUT->typeId == TYPE_GENERIC ) {
code.append( IN_CONS_GENERIC );
- code.appendHalf( replUT->generic->id );
+ code.appendHalf( newUT->generic->id );
+
+ if ( newUT->generic->typeId == GEN_PARSER ) {
+
+ }
}
else {
code.append( IN_NEW_STRUCT );
- code.appendHalf( replUT->structEl->id );
+ code.appendHalf( newUT->structEl->id );
}
- evaluateCapture( pd, code, replUT );
+ /*
+ * First load the context into the parser.
+ */
+ if ( context ) {
+ /* Dup the parser. */
+ code.append( IN_DUP_VAL );
- return replUT;
+ /* Eval the context. */
+ UniqueType *argUT = fieldInitArgs->data[0]->expr->evaluate( pd, code );
+
+ if ( argUT != pd->uniqueTypeStream && argUT->typeId != TYPE_STRUCT )
+ error(loc) << "context argument must be a stream or a tree" << endp;
+
+ /* Store the context. */
+ code.append( IN_TOP_SWAP );
+ code.append( IN_SET_PARSER_CTX_WC );
+ }
+
+ evaluateCapture( pd, code, newUT );
+
+ return newUT;
}
UniqueType *LangTerm::evaluateCast( Compiler *pd, CodeVect &code ) const