diff options
author | Adrian Thurston <thurston@complang.org> | 2015-01-24 12:35:27 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-01-24 12:35:27 -0500 |
commit | f8444f7425cbfed78c8e49bc0ab0fd9a7d254285 (patch) | |
tree | 7127bc893cc3e38e1fea8db14b4423082160cd27 /src | |
parent | 52bcefda7ae810e7fd47d3a554282e615ce604aa (diff) | |
download | colm-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.lm | 2 | ||||
-rw-r--r-- | src/loadcolm.cc | 22 | ||||
-rw-r--r-- | src/parsetree.h | 5 | ||||
-rw-r--r-- | src/resolve.cc | 24 | ||||
-rw-r--r-- | src/synthesis.cc | 46 |
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 |