diff options
-rw-r--r-- | colm.vim | 4 | ||||
-rw-r--r-- | colm/bytecode.cpp | 54 | ||||
-rw-r--r-- | colm/bytecode.h | 6 | ||||
-rw-r--r-- | colm/compile.cpp | 84 | ||||
-rw-r--r-- | colm/fsmrun.cpp | 2 | ||||
-rw-r--r-- | colm/lmparse.kl | 27 | ||||
-rw-r--r-- | colm/lmscan.rl | 2 | ||||
-rw-r--r-- | colm/parsedata.cpp | 4 | ||||
-rw-r--r-- | colm/parsedata.h | 5 | ||||
-rw-r--r-- | colm/pdabuild.cpp | 19 | ||||
-rw-r--r-- | colm/pdacodegen.cpp | 4 | ||||
-rw-r--r-- | colm/pdarun.cpp | 34 | ||||
-rw-r--r-- | colm/pdarun.h | 7 | ||||
-rw-r--r-- | colm/tree.cpp | 3 |
14 files changed, 175 insertions, 80 deletions
@@ -55,8 +55,8 @@ syntax match tlNumber "false" syntax keyword Type \ commit include literal iter \ namespace lex reducefirst global include - \ construct parse parse_stop match require - \ preeof left right nonassoc prec accum context + \ construct cons parse parse_stop match require + \ preeof left right nonassoc prec accum context parser alias syntax keyword typeKeywords \ int str bool any ref vector map list ptr diff --git a/colm/bytecode.cpp b/colm/bytecode.cpp index c34e47e0..9edbebbf 100644 --- a/colm/bytecode.cpp +++ b/colm/bytecode.cpp @@ -163,7 +163,7 @@ struct ParserRet FsmRun *fsmRun; }; -void call_parser( ParserRet &ret, Tree **&sp, Program *prg, InputStream *inputStream, Stream *stream, +void call_parser( ParserRet &ret, Tree **&sp, Program *prg, Tree *context, InputStream *inputStream, Stream *stream, long parserId, long stopId, CodeVect *&cv, bool revertOn ) { PdaTables *tables = prg->rtd->pdaTables; @@ -171,7 +171,7 @@ void call_parser( ParserRet &ret, Tree **&sp, Program *prg, InputStream *inputSt fsmRun->curStream = (Tree*)stream; PdaRun pdaRun( prg, tables, fsmRun, parserId, stopId, revertOn ); - init_pda_run( &pdaRun ); + init_pda_run( &pdaRun, context ); init_fsm_run( fsmRun, inputStream ); new_token( &pdaRun, fsmRun ); parse_loop( sp, &pdaRun, fsmRun, inputStream ); @@ -196,6 +196,12 @@ void call_parser( ParserRet &ret, Tree **&sp, Program *prg, InputStream *inputSt ret.fsmRun = fsmRun; } + +void parser_accum_set_ctx( Tree **&sp, Program *prg, Accum *accum, Tree *val ) +{ + accum->pdaRun->context = split_tree( prg, val ); +} + void call_tree_parser( ParserRet &ret, Tree **&sp, Program *prg, Tree *input, long parserId, long stopId, CodeVect *&cv, bool revertOn ) { @@ -208,7 +214,7 @@ void call_tree_parser( ParserRet &ret, Tree **&sp, Program *prg, Tree *input, InputStreamString inputStream( s.c_str(), s.size() ); init_input_stream( &inputStream ); - call_parser( ret, sp, prg, &inputStream, 0, parserId, stopId, cv, revertOn ); + call_parser( ret, sp, prg, 0, &inputStream, 0, parserId, stopId, cv, revertOn ); } Head *tree_to_str( Tree **sp, Program *prg, Tree *tree ) @@ -2330,8 +2336,9 @@ again: /* Comes back from parse upreffed. */ CodeVect *cv; Tree *stream = pop(); + Tree *context = pop(); ParserRet ret; - call_parser( ret, sp, prg, ((Stream*)stream)->in, (Stream*)stream, parserId, stopId, cv, true ); + call_parser( ret, sp, prg, context, ((Stream*)stream)->in, (Stream*)stream, parserId, stopId, cv, true ); push( ret.tree ); /* Single unit. */ @@ -2359,8 +2366,9 @@ again: /* Comes back from parse upreffed. */ CodeVect *cv; Tree *stream = pop(); + Tree *context = pop(); ParserRet ret; - call_parser( ret, sp, prg, ((Stream*)stream)->in, (Stream*)stream, parserId, stopId, cv, false ); + call_parser( ret, sp, prg, context, ((Stream*)stream)->in, (Stream*)stream, parserId, stopId, cv, false ); push( ret.tree ); tree_downref( prg, sp, (Tree*)stream ); @@ -2401,6 +2409,42 @@ again: tree_downref( prg, sp, accum ); break; } + + case IN_GET_ACCUM_CTX_R: { + #ifdef COLM_LOG_BYTECODE + if ( colm_log_bytecode ) { + cerr << "IN_GET_ACCUM_CTX_R" << endl; + } + #endif + + Tree *obj = pop(); + Tree *ctx = ((Accum*)obj)->pdaRun->context; + tree_upref( ctx ); + push( ctx ); + tree_downref( prg, sp, obj ); + break; + } + + case IN_SET_ACCUM_CTX_WC: { + #ifdef COLM_LOG_BYTECODE + if ( colm_log_bytecode ) { + cerr << "IN_SET_ACCUM_CTX_WC" << endl; + } + #endif + + Tree *obj = pop(); + Tree *val = pop(); + parser_accum_set_ctx( sp, prg, (Accum*)obj, val ); + tree_downref( prg, sp, obj ); + break; + } + +// case IN_GET_ACCUM_CTX_WC: +// case IN_GET_ACCUM_CTX_WV: +// case IN_SET_ACCUM_CTX_WC: +// case IN_SET_ACCUM_CTX_WV: +// break; + case IN_ACCUM_FINISH_WC: { #ifdef COLM_LOG_BYTECODE if ( colm_log_bytecode ) { diff --git a/colm/bytecode.h b/colm/bytecode.h index 0a88c585..5c7d788c 100644 --- a/colm/bytecode.h +++ b/colm/bytecode.h @@ -244,6 +244,12 @@ typedef unsigned char uchar; #define IN_LOAD_CONTEXT_WC 0xae #define IN_LOAD_CONTEXT_BKT 0xaf +#define IN_GET_ACCUM_CTX_R 0xb0 +#define IN_GET_ACCUM_CTX_WC 0xb1 +#define IN_GET_ACCUM_CTX_WV 0xb2 +#define IN_SET_ACCUM_CTX_WC 0xb3 +#define IN_SET_ACCUM_CTX_WV 0xb4 + /* Types */ #define TYPE_NIL 0x01 diff --git a/colm/compile.cpp b/colm/compile.cpp index 68717c10..fe306b52 100644 --- a/colm/compile.cpp +++ b/colm/compile.cpp @@ -1198,12 +1198,36 @@ UniqueType *LangTerm::evaluateParse( ParseData *pd, CodeVect &code, bool stop ) error(loc) << "can only parse trees" << endl; /* Should be one arg, a stream. */ - if ( args == 0 || args->length() != 1 ) - error(loc) << "expecting one argument" << endp; + if ( args == 0 || ( args->length() != 1 && args->length() != 2 ) ) + error(loc) << "expecting one or two args" << endp; + + int context, input; + if ( ut->langEl->contextIn == 0 ) { + if ( args->length() != 1 ) + error(loc) << "parse command requires just input" << endp; + context = -1; + input = 0; + } + else { + if ( args->length() != 2 ) + error(loc) << "parse command requires context and input" << endp; + context = 0; + input = 1; + } + + if ( context < 0 ) { + code.append( IN_LOAD_NIL ); + } + else { + UniqueType *argUT = args->data[context]->evaluate( pd, code ); + if ( argUT != pd->uniqueTypeStream && argUT->typeId != TYPE_TREE ) + error(loc) << "context argument must be a stream or a tree" << endp; + } + - UniqueType *argUT = args->data[0]->evaluate( pd, code ); + UniqueType *argUT = args->data[input]->evaluate( pd, code ); if ( argUT != pd->uniqueTypeStream && argUT->typeId != TYPE_TREE ) - error(loc) << "single argument must be a stream or a tree" << endp; + error(loc) << "input argument must be a stream or a tree" << endp; /* Allocate a parser id. This will cause a parser to be built for * the type. */ @@ -2505,27 +2529,17 @@ void ParseData::initAllLanguageObjects() { /* Init all user object fields (need consistent size). */ for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) { - ObjectDef *obj = lel->objectDef; - if ( obj != 0 ) { + ObjectDef *objDef = lel->objectDef; + if ( objDef != 0 ) { /* Init all fields of the object. */ - for ( ObjFieldList::Iter f = *obj->objFieldList; f.lte(); f++ ) - obj->initField( this, f->value ); + for ( ObjFieldList::Iter f = *objDef->objFieldList; f.lte(); f++ ) + objDef->initField( this, f->value ); } } /* Init all fields of the global object. */ for ( ObjFieldList::Iter f = *globalObjectDef->objFieldList; f.lte(); f++ ) globalObjectDef->initField( this, f->value ); - - /* Init all fields of all context objects. */ - for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) { - if ( lel->context != 0 ) { - cout << "initializing fields for context " << lel->name << endl; - - for ( ObjFieldList::Iter f = *globalObjectDef->objFieldList; f.lte(); f++ ) - globalObjectDef->initField( this, f->value ); - } - } } void ParseData::initMapFunctions( GenericType *gen ) @@ -2596,8 +2610,37 @@ void ParseData::initVectorFunctions( GenericType *gen ) void ParseData::initAccumFunctions( GenericType *gen ) { - initFunction( gen->utArg, gen->objDef, "finish", - IN_ACCUM_FINISH_WC, IN_ACCUM_FINISH_WC, false ); + initFunction( gen->utArg, gen->objDef, "finish", IN_ACCUM_FINISH_WC, IN_ACCUM_FINISH_WC, false ); +} + +void ParseData::initCtxField( GenericType *gen ) +{ + KlangEl *langEl = gen->utArg->langEl; + Context *context = langEl->contextIn; + + /* Make the type ref and create the field. */ + UniqueType *ctxUT = findUniqueType( TYPE_TREE, context->lel ); + TypeRef *typeRef = new TypeRef( InputLoc(), ctxUT ); + ObjField *el = new ObjField( InputLoc(), typeRef, "ctx" ); + + el->inGetR = IN_GET_ACCUM_CTX_R; + el->inGetWC = IN_GET_ACCUM_CTX_WC; + el->inGetWV = IN_GET_ACCUM_CTX_WV; + el->inSetWC = IN_SET_ACCUM_CTX_WC; + el->inSetWV = IN_SET_ACCUM_CTX_WV; + + gen->objDef->insertField( el->name, el ); + + el->useOffset = false; + el->beenReferenced = true; + el->beenInitialized = true; +} + +void ParseData::initAccumFields( GenericType *gen ) +{ + KlangEl *langEl = gen->utArg->langEl; + if ( langEl->contextIn != 0 ) + initCtxField( gen ); } void ParseData::resolveGenericTypes() @@ -2630,6 +2673,7 @@ void ParseData::resolveGenericTypes() /* Need to generate a parser for the type. */ gen->utArg->langEl->parserId = nextParserId++; initAccumFunctions( gen ); + initAccumFields( gen ); break; } diff --git a/colm/fsmrun.cpp b/colm/fsmrun.cpp index 7076f4b2..5efb362d 100644 --- a/colm/fsmrun.cpp +++ b/colm/fsmrun.cpp @@ -854,7 +854,7 @@ long undo_parse( Tree **sp, InputStream *inputStream, FsmRun *fsmRun, PdaRun *pd Tree *tree, CodeVect *rev ) { /* PDA must be init first to set next region. */ - init_pda_run( pdaRun ); + init_pda_run( pdaRun, 0 ); Kid *top = pdaRun->prg->kidPool.allocate(); top->next = pdaRun->stackTop; diff --git a/colm/lmparse.kl b/colm/lmparse.kl index f2711d13..ec293184 100644 --- a/colm/lmparse.kl +++ b/colm/lmparse.kl @@ -339,6 +339,15 @@ pred_token: pd->resolveLiteralFactor( $$->factor ); }; +context_cfl_def: cfl_def_head obj_var_list properties_list cfl_prod_list + final { + /* Get the language element. */ + KlangEl *langEl = getKlangEl( pd, namespaceStack.top(), curDefineId ); + langEl->objectDef = pd->objectDef; + langEl->contextIn = contextStack.top(); + }; + + cfl_def: cfl_def_head obj_var_list properties_list cfl_prod_list final { /* Get the language element. */ @@ -512,7 +521,7 @@ context_item: context_var_def commit; context_item: literal_def commit; context_item: rl_def commit; context_item: token_def commit; -context_item: cfl_def commit; +context_item: context_cfl_def commit; context_item: region_def commit; context_item: context_def commit; context_item: function_def commit; @@ -537,14 +546,24 @@ context_head: final { Namespace *nspace = namespaceStack.top(); KlangEl *lel = getKlangEl( pd, nspace, $2->data ); + Context *context = new Context( $1->loc, lel ); contextStack.push( context ); - context->contextObjDef = new ObjectDef( ObjectDef::UserType, "context", + context->contextObjDef = new ObjectDef( ObjectDef::UserType, $2->data, new ObjFieldMap, new ObjFieldList, new ObjMethodMap(), pd->nextObjectId++ ); - lel->context = context; - cout << lel->context << endl; + /* Check that the element wasn't previously defined as something else. */ + if ( lel->type != KlangEl::Unknown ) { + error($2->loc) << "'" << curDefineId << + "' has already been defined, maybe you want to use redef?" << endp; + } + lel->type = KlangEl::NonTerm; + ProdElList *prodElList = new ProdElList; + addProduction( $1->loc, $2->data, prodElList, false, 0, 0 ); + + lel->contextDef = context; + lel->objectDef = context->contextObjDef; }; pattern_list: pattern_list pattern; diff --git a/colm/lmscan.rl b/colm/lmscan.rl index 5269460d..b123ebc7 100644 --- a/colm/lmscan.rl +++ b/colm/lmscan.rl @@ -425,6 +425,7 @@ void Scanner::endSection( ) 'def' => { token( KW_Def ); }; 'ignore' => { token( KW_Ignore ); }; 'construct' => { token( KW_Construct ); }; + 'cons' => { token( KW_Construct ); }; 'new' => { token( KW_New ); }; 'if' => { token( KW_If ); }; 'reject' => { token( KW_Reject ); }; @@ -444,6 +445,7 @@ void Scanner::endSection( ) 'list' => { token( KW_List ); }; 'vector' => { token( KW_Vector ); }; 'accum' => { token( KW_Accum ); }; + 'parser' => { token( KW_Accum ); }; 'return' => { token( KW_Return ); }; 'break' => { token( KW_Break ); }; 'yield' => { token( KW_Yield ); }; diff --git a/colm/parsedata.cpp b/colm/parsedata.cpp index b754ce06..095f9854 100644 --- a/colm/parsedata.cpp +++ b/colm/parsedata.cpp @@ -1488,7 +1488,7 @@ void ParseData::parsePatterns() repl->pdaRun = new PdaRun( &program, pdaTables, fsmRun, repl->langEl->parserId, 0, false ); - init_pda_run( repl->pdaRun ); + init_pda_run( repl->pdaRun, 0 ); init_fsm_run( fsmRun, &in ); new_token( repl->pdaRun, fsmRun ); parse_loop( root, repl->pdaRun, fsmRun, &in ); @@ -1507,7 +1507,7 @@ void ParseData::parsePatterns() pat->pdaRun = new PdaRun( &program, pdaTables, fsmRun, pat->langEl->parserId, 0, false ); - init_pda_run( pat->pdaRun ); + init_pda_run( pat->pdaRun, 0 ); init_fsm_run( fsmRun, &in ); new_token( pat->pdaRun, fsmRun ); parse_loop( root, pat->pdaRun, fsmRun, &in ); diff --git a/colm/parsedata.h b/colm/parsedata.h index 3a0228a3..9521efd9 100644 --- a/colm/parsedata.h +++ b/colm/parsedata.h @@ -215,7 +215,8 @@ struct KlangEl : public DListEl<KlangEl> PredType predType; long predValue; - Context *context; + Context *contextDef; + Context *contextIn; }; struct PdaFactor @@ -745,6 +746,8 @@ struct ParseData void initListFunctions( GenericType *gen ); void initVectorFunctions( GenericType *gen ); void initAccumFunctions( GenericType *gen ); + void initAccumFields( GenericType *gen ); + void initCtxField( GenericType *gen ); void addStdin(); void addStdout(); diff --git a/colm/pdabuild.cpp b/colm/pdabuild.cpp index 6a39b11b..afdf5016 100644 --- a/colm/pdabuild.cpp +++ b/colm/pdabuild.cpp @@ -89,7 +89,8 @@ KlangEl::KlangEl( Namespace *nspace, const String &name, Type type ) parserId(-1), predType(PredNone), predValue(0), - context(0) + contextDef(0), + contextIn(0) { } @@ -1411,14 +1412,14 @@ void ParseData::makeRuntimeData() ( lel->objectDef == 0 || lel->objectDef == tokenObj ) ? 0 : lel->objectDef->size(); - runtimeData->lelInfo[i].contextTypeId = - lel->context == 0 ? 0 : lel->context->contextObjDef->id; - runtimeData->lelInfo[i].contextLength = lel->context == 0 ? 0 : - lel->context->contextObjDef->size(); - if ( lel->context != 0 ) { - cout << "type: " << runtimeData->lelInfo[i].contextTypeId << " length: " << - runtimeData->lelInfo[i].contextLength << endl; - } +// runtimeData->lelInfo[i].contextTypeId = 0; +// lel->context == 0 ? 0 : lel->context->contextObjDef->id; +// runtimeData->lelInfo[i].contextLength = 0; //lel->context == 0 ? 0 : +// lel->context->contextObjDef->size(); +// if ( lel->context != 0 ) { +// cout << "type: " << runtimeData->lelInfo[i].contextTypeId << " length: " << +// runtimeData->lelInfo[i].contextLength << endl; +// } runtimeData->lelInfo[i].termDupId = lel->termDup == 0 ? 0 : lel->termDup->id; runtimeData->lelInfo[i].genericId = lel->generic == 0 ? 0 : lel->generic->id; diff --git a/colm/pdacodegen.cpp b/colm/pdacodegen.cpp index aa572b4b..4195cd1e 100644 --- a/colm/pdacodegen.cpp +++ b/colm/pdacodegen.cpp @@ -189,8 +189,8 @@ void PdaCodeGen::writeRuntimeData( RuntimeData *runtimeData, PdaTables *pdaTable out << runtimeData->lelInfo[i].objectLength << ", "; - out << runtimeData->lelInfo[i].contextTypeId << ", "; - out << runtimeData->lelInfo[i].contextLength << ", "; +// out << runtimeData->lelInfo[i].contextTypeId << ", "; +// out << runtimeData->lelInfo[i].contextLength << ", "; out << runtimeData->lelInfo[i].termDupId << ", "; diff --git a/colm/pdarun.cpp b/colm/pdarun.cpp index 46843da4..1f944c02 100644 --- a/colm/pdarun.cpp +++ b/colm/pdarun.cpp @@ -74,7 +74,7 @@ void clean_parser( Tree **sp, PdaRun *pdaRun ) kid = next; } - pdaRun->clearContext( sp ); +// pdaRun->clearContext( sp ); } bool PdaRun::isParserStopFinished() @@ -86,7 +86,7 @@ bool PdaRun::isParserStopFinished() return done; } -void init_pda_run( PdaRun *pdaRun ) +void init_pda_run( PdaRun *pdaRun, Tree *context ) { /* FIXME: need the right one here. */ pdaRun->cs = pdaRun->prg->rtd->startStates[pdaRun->parserId]; @@ -109,37 +109,13 @@ void init_pda_run( PdaRun *pdaRun ) pdaRun->allReverseCode = new CodeVect; - pdaRun->allocContext(); -} - -void PdaRun::allocContext() -{ - long id = prg->rtd->parserLelIds[parserId]; - if ( prg->rtd->lelInfo[id].contextTypeId != 0 ) { - cout << "runtime allocating context for parser of LEL " << prg->rtd->lelInfo[id].name << endl; - - Tree *tree = prg->treePool.allocate(); - tree->child = alloc_attrs( prg, prg->rtd->lelInfo[id].contextLength ); - tree->refs = 1; - context = tree; - } + pdaRun->context = split_tree( pdaRun->prg, context ); } void PdaRun::clearContext( Tree **sp ) { - long id = prg->rtd->parserLelIds[parserId]; - if ( prg->rtd->lelInfo[id].contextTypeId != 0 ) { - /* Downref all the fields first. */ - for ( int c = 0; c < prg->rtd->lelInfo[id].contextLength; c++ ) { - //assert( get_attr( global, g )->refs == 1 ); - tree_downref( prg, sp, get_attr( context, c ) ); - } - - /* Free the global object. */ - if ( prg->rtd->lelInfo[id].contextLength > 0 ) - free_attrs( prg, context->child ); - prg->treePool.free( context ); - } + if ( context != 0 ) + tree_downref( prg, sp, context ); } diff --git a/colm/pdarun.h b/colm/pdarun.h index 257d6d70..199849e5 100644 --- a/colm/pdarun.h +++ b/colm/pdarun.h @@ -388,8 +388,8 @@ struct LangElInfo long ofiOffset; long objectLength; - long contextTypeId; - long contextLength; +// long contextTypeId; +// long contextLength; long termDupId; long genericId; @@ -580,7 +580,6 @@ struct PdaRun Tree *context; void clearContext( Tree **sp ); - void allocContext(); }; void clean_parser( Tree **root, PdaRun *pdaRun ); @@ -592,6 +591,6 @@ long undo_parse( Tree **sp, InputStream *inputStream, FsmRun *fsmRun, PdaRun *pdaRun, Tree *tree, CodeVect *rev ); void xml_print_list( RuntimeData *runtimeData, Kid *lel, int depth ); ostream &parse_error( InputStream *inputStream, FsmRun *fsmRun, PdaRun *pdaRun, int tokId, Tree *tree ); -void init_pda_run( PdaRun *pdaRun ); +void init_pda_run( PdaRun *pdaRun, Tree *tree ); #endif /* _PDARUN_H */ diff --git a/colm/tree.cpp b/colm/tree.cpp index 6f1bb78b..21e00a51 100644 --- a/colm/tree.cpp +++ b/colm/tree.cpp @@ -1013,7 +1013,7 @@ Tree *create_generic( Program *prg, long genericId ) accum->inputStream = new InputStreamAccum(); /* Start off the parsing process. */ - init_pda_run( accum->pdaRun ); + init_pda_run( accum->pdaRun, 0 ); init_fsm_run( accum->fsmRun, accum->inputStream ); new_token( accum->pdaRun, accum->fsmRun ); @@ -1067,6 +1067,7 @@ free_tree: Accum *accum = (Accum*)tree; /* FIXME: Need to clean up here. */ delete accum->fsmRun; + accum->pdaRun->clearContext( sp ); delete accum->pdaRun; prg->mapElPool.free( (MapEl*)accum ); } |