summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--colm.vim4
-rw-r--r--colm/bytecode.cpp54
-rw-r--r--colm/bytecode.h6
-rw-r--r--colm/compile.cpp84
-rw-r--r--colm/fsmrun.cpp2
-rw-r--r--colm/lmparse.kl27
-rw-r--r--colm/lmscan.rl2
-rw-r--r--colm/parsedata.cpp4
-rw-r--r--colm/parsedata.h5
-rw-r--r--colm/pdabuild.cpp19
-rw-r--r--colm/pdacodegen.cpp4
-rw-r--r--colm/pdarun.cpp34
-rw-r--r--colm/pdarun.h7
-rw-r--r--colm/tree.cpp3
14 files changed, 175 insertions, 80 deletions
diff --git a/colm.vim b/colm.vim
index d0e8cd5c..2a1938fd 100644
--- a/colm.vim
+++ b/colm.vim
@@ -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 );
}