summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-11-05 17:40:35 -0500
committerAdrian Thurston <thurston@complang.org>2015-11-05 17:40:35 -0500
commit883797b32e3a4915bf81f801946cda6798e019c9 (patch)
tree4f4ed88b5ab78ef307f3219b7c54a5660490ae69
parent80b9fc661abe6f37853bc12889f0443a1d6c65a9 (diff)
downloadcolm-883797b32e3a4915bf81f801946cda6798e019c9.tar.gz
split reducers into their own class
Previously selected with a runtime int. Using reduction name as the class name.
-rw-r--r--src/bytecode.c4
-rw-r--r--src/colm.lm2
-rw-r--r--src/compiler.h1
-rw-r--r--src/consinit.cc4
-rw-r--r--src/loadcolm.cc11
-rw-r--r--src/loadinit.cc2
-rw-r--r--src/parser.cc11
-rw-r--r--src/parser.h2
-rw-r--r--src/parsetree.h12
-rw-r--r--src/pdarun.c3
-rw-r--r--src/pdarun.h7
-rw-r--r--src/reduce.cc130
-rw-r--r--src/resolve.cc18
-rw-r--r--src/struct.c4
-rw-r--r--src/struct.h2
-rw-r--r--src/synthesis.cc10
16 files changed, 142 insertions, 81 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index df608cb4..6bb4d7b9 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -2735,11 +2735,13 @@ again:
}
case IN_CONS_REDUCER: {
half_t generic_id;
+ half_t reducer_id;
read_half( generic_id );
+ read_half( reducer_id );
debug( prg, REALM_BYTECODE, "IN_CONS_REDUCER %hd\n", generic_id );
- struct_t *gen = colm_construct_reducer( prg, generic_id );
+ struct_t *gen = colm_construct_reducer( prg, generic_id, reducer_id );
vm_push_struct( gen );
break;
}
diff --git a/src/colm.lm b/src/colm.lm
index 9401ad47..e50898a9 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -629,7 +629,7 @@ def code_factor
| [PARSE opt_capture type_ref opt_field_init accumulate] :Parse
| [PARSE_TREE opt_capture type_ref opt_field_init accumulate] :ParseTree
| [PARSE_STOP opt_capture type_ref opt_field_init accumulate] :ParseStop
-| [REDUCE type_ref opt_field_init accumulate] :Reduce
+| [REDUCE id type_ref opt_field_init accumulate] :Reduce
| [CONS opt_capture type_ref opt_field_init constructor] :Cons
| [MATCH var_ref pattern] :Match
| [string] :String
diff --git a/src/compiler.h b/src/compiler.h
index 288b3cf1..23195cfc 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -657,6 +657,7 @@ struct Compiler
void resolvePrecedence();
void resolveReductionActions();
void findReductionActionProds();
+ void resolveReducers();
void declarePass();
void resolvePass();
diff --git a/src/consinit.cc b/src/consinit.cc
index c0a1196a..c2e4b10b 100644
--- a/src/consinit.cc
+++ b/src/consinit.cc
@@ -42,7 +42,7 @@ extern "C" void commit_reduce_forward( program_t *prg, tree_t **root,
commit_clear_parse_tree( prg, root, pda_run, pt->child );
}
-extern "C" long commit_union_sz() { return 0; }
+extern "C" long commit_union_sz( int reducer ) { return 0; }
using std::cout;
using std::cerr;
@@ -819,7 +819,7 @@ void ConsInit::parseInput( StmtList *stmtList )
/* Parse the above list. */
LangExpr *parseExpr = parseCmd( internal, false, false, objField,
- typeRef, 0, list, true, false );
+ typeRef, 0, list, true, false, "" );
LangStmt *parseStmt = LangStmt::cons( internal, LangStmt::ExprType, parseExpr );
stmtList->append( parseStmt );
}
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 54d3d4d2..33a677c8 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -1780,7 +1780,7 @@ struct LoadColm
ConsItemList *list = walkAccumulate( codeFactor.accumulate() );
expr = parseCmd( codeFactor.PARSE().loc(), false, false, objField,
- typeRef, init, list, used, false );
+ typeRef, init, list, used, false, "" );
break;
}
case code_factor::ParseTree: {
@@ -1792,7 +1792,7 @@ struct LoadColm
ConsItemList *list = walkAccumulate( codeFactor.accumulate() );
expr = parseCmd( codeFactor.PARSE_TREE().loc(), true, false, objField,
- typeRef, init, list, used, false );
+ typeRef, init, list, used, false, "" );
break;
}
case code_factor::ParseStop: {
@@ -1804,10 +1804,13 @@ struct LoadColm
ConsItemList *list = walkAccumulate( codeFactor.accumulate() );
expr = parseCmd( codeFactor.PARSE_STOP().loc(), false, true, objField,
- typeRef, init, list, used, false );
+ typeRef, init, list, used, false, "" );
break;
}
case code_factor::Reduce: {
+ /* The reducer name. */
+ String reducer = codeFactor.id().data();
+
/* The type we are parsing. */
type_ref typeRefTree = codeFactor.type_ref();
TypeRef *typeRef = walkTypeRef( typeRefTree );
@@ -1815,7 +1818,7 @@ struct LoadColm
ConsItemList *list = walkAccumulate( codeFactor.accumulate() );
expr = parseCmd( codeFactor.REDUCE().loc(), false, false, 0,
- typeRef, init, list, used, true );
+ typeRef, init, list, used, true, reducer );
break;
}
case code_factor::Cons: {
diff --git a/src/loadinit.cc b/src/loadinit.cc
index 875d9f31..2387cd05 100644
--- a/src/loadinit.cc
+++ b/src/loadinit.cc
@@ -337,7 +337,7 @@ void LoadInit::consParseStmt( StmtList *stmtList )
/* Parse the above list. */
LangExpr *parseExpr = parseCmd( internal, false, false, objField,
- typeRef, 0, list, true, false );
+ typeRef, 0, list, true, false, "" );
LangStmt *parseStmt = LangStmt::cons( internal, LangStmt::ExprType, parseExpr );
stmtList->append( parseStmt );
}
diff --git a/src/parser.cc b/src/parser.cc
index 008e8775..90d71f59 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -692,7 +692,8 @@ LexJoin *BaseParser::lexOptJoin( LexJoin *join, LexJoin *context )
LangExpr *BaseParser::send( const InputLoc &loc, LangVarRef *varRef,
ConsItemList *list, bool eof )
{
- ParserText *parserText = ParserText::cons( loc, curNspace(), list, true, false );
+ ParserText *parserText = ParserText::cons( loc,
+ curNspace(), list, true, false, "" );
pd->parserTextList.append( parserText );
return LangExpr::cons( LangTerm::consSend( loc, varRef,
@@ -702,7 +703,8 @@ LangExpr *BaseParser::send( const InputLoc &loc, LangVarRef *varRef,
LangExpr *BaseParser::sendTree( const InputLoc &loc, LangVarRef *varRef,
ConsItemList *list, bool eof )
{
- ParserText *parserText = ParserText::cons( loc, curNspace(), list, true, false );
+ ParserText *parserText = ParserText::cons( loc,
+ curNspace(), list, true, false, "" );
pd->parserTextList.append( parserText );
return LangExpr::cons( LangTerm::consSendTree( loc, varRef,
@@ -711,7 +713,7 @@ LangExpr *BaseParser::sendTree( const InputLoc &loc, LangVarRef *varRef,
LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop,
ObjectField *objField, TypeRef *typeRef, FieldInitVect *fieldInitVect,
- ConsItemList *list, bool used, bool reduce )
+ ConsItemList *list, bool used, bool reduce, const String &reducer )
{
LangExpr *expr = 0;
@@ -732,7 +734,8 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop,
if ( objField != 0 )
used = true;
- ParserText *parserText = ParserText::cons( loc, curNspace(), list, used, reduce );
+ ParserText *parserText = ParserText::cons( loc, curNspace(),
+ list, used, reduce, reducer );
pd->parserTextList.append( parserText );
LangTerm::Type langTermType = stop ? LangTerm::ParseStopType : ( tree ?
diff --git a/src/parser.h b/src/parser.h
index 38d8b041..5a0e31cc 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -124,7 +124,7 @@ struct BaseParser
ConsItemList *list, bool eof );
LangExpr *parseCmd( const InputLoc &loc, bool tree, bool stop, ObjectField *objField,
TypeRef *typeRef, FieldInitVect *fieldInitVect, ConsItemList *list,
- bool used, bool reduce );
+ bool used, bool reduce, const String &reducer );
PatternItemList *consPatternEl( LangVarRef *varRef, PatternItemList *list );
PatternItemList *patternElNamed( const InputLoc &loc, LangVarRef *varRef,
NamespaceQual *nspaceQual, const String &data, RepeatType repeatType );
diff --git a/src/parsetree.h b/src/parsetree.h
index 8bae78f0..5f5f10a5 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -983,12 +983,15 @@ struct Reduction
Reduction( const InputLoc &loc, String name )
: loc(loc), name(name)
{
- static int nextId = 0;
+ static int nextId = 1;
id = nextId++;
+ var = name.data;
+ var.data[0] = tolower( var.data[0] );
}
InputLoc loc;
String name;
+ String var;
int id;
ReduceActionList reduceActions;
@@ -1851,7 +1854,7 @@ struct ParserText
{
static ParserText *cons( const InputLoc &loc,
Namespace *nspace, ConsItemList *list,
- bool used, bool reduce )
+ bool used, bool reduce, const String &reducer )
{
ParserText *p = new ParserText;
p->loc = loc;
@@ -1863,6 +1866,8 @@ struct ParserText
p->parse = true;
p->used = used;
p->reduce = reduce;
+ p->reducer = reducer;
+ p->reducerId = -1;
return p;
}
@@ -1875,7 +1880,8 @@ struct ParserText
bool parse;
bool used;
bool reduce;
- String reducerClass;
+ String reducer;
+ int reducerId;
ParserText *prev, *next;
};
diff --git a/src/pdarun.c b/src/pdarun.c
index a0978165..4f2befd4 100644
--- a/src/pdarun.c
+++ b/src/pdarun.c
@@ -1201,7 +1201,8 @@ void colm_pda_init( program_t *prg, struct pda_run *pda_run, struct pda_tables *
pda_run->reducer = reducer;
if ( reducer ) {
- init_pool_alloc( &pda_run->local_pool, sizeof(parse_tree_t) + commit_union_sz() );
+ init_pool_alloc( &pda_run->local_pool, sizeof(parse_tree_t) +
+ commit_union_sz(reducer) );
pda_run->parse_tree_pool = &pda_run->local_pool;
}
else {
diff --git a/src/pdarun.h b/src/pdarun.h
index 20f6e85c..21b3a2e4 100644
--- a/src/pdarun.h
+++ b/src/pdarun.h
@@ -355,7 +355,10 @@ struct pda_run
int rc_block_count;
tree_t *parse_error_text;
- char reducer;
+
+ /* Zero indicates parsing proper. Nonzero is the reducer id. */
+ int reducer;
+
parse_tree_t *last_final;
struct pool_alloc *parse_tree_pool;
@@ -456,7 +459,7 @@ void commit_reduce_forward( program_t *prg, tree_t **root,
void commit_reduce( program_t *prg, tree_t **root,
struct pda_run *pda_run );
-long commit_union_sz();
+long commit_union_sz( int reducer );
#ifdef __cplusplus
diff --git a/src/reduce.cc b/src/reduce.cc
index 84d635c1..7880c27e 100644
--- a/src/reduce.cc
+++ b/src/reduce.cc
@@ -49,7 +49,7 @@ void Compiler::writeCommitStub()
" commit_clear_parse_tree( prg, root, pda_run, pt->child );\n"
"}\n"
"\n"
- "long commit_union_sz() { return 0; }\n"
+ "long commit_union_sz( int reducer ) { return 0; }\n"
"\n";
;
}
@@ -251,10 +251,15 @@ void Compiler::writeCommit()
"using std::endl;\n"
"\n"
"#include \"reducer.h\"\n"
- "\n"
- "Reducer *reducer;\n"
- "\n"
- ;
+ "\n";
+
+ for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) {
+ Reduction *reduction = *r;
+ *outStream <<
+ reduction->name << "* " << reduction->var << ";\n";
+ }
+
+ *outStream << "\n";
for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) {
for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) {
@@ -286,51 +291,71 @@ void Compiler::writeCommit()
"\n";
*outStream <<
- "long commit_union_sz() { return sizeof( commit_reduce_union ); }\n";
+ "long commit_union_sz( int reducer )\n"
+ "{\n"
+ " return sizeof( commit_reduce_union );\n"
+ "}\n";
*outStream <<
"\n"
"void commit_reduce_forward( program_t *prg, tree_t **root,\n"
" struct pda_run *pda_run, parse_tree_t *pt )\n"
- "{ reducer->commit_reduce_forward( prg, root, pda_run, pt ); }\n"
- "\n"
- "void Reducer::commit_reduce_forward( program_t *prg, tree_t **root,\n"
- " struct pda_run *pda_run, parse_tree_t *pt )\n"
"{\n"
- " tree_t **sp = root;\n"
- "\n"
- " parse_tree_t *lel = pt;\n"
- " kid_t *kid = pt->shadow;\n"
- "\n"
- "recurse:\n"
- "\n"
- " if ( lel->child != 0 ) {\n"
- " /* There are children. Must process all children first. */\n"
- " vm_push_ptree( lel );\n"
- " vm_push_kid( kid );\n"
- "\n"
- " lel = lel->child;\n"
- " kid = kid->tree->child;\n"
- " while ( lel != 0 ) {\n"
- " goto recurse;\n"
- " resume:\n"
- " lel = lel->next;\n"
- " kid = kid->next;\n"
- " }\n"
- "\n"
- " kid = vm_pop_kid();\n"
- " lel = vm_pop_ptree();\n"
+ " switch ( pda_run->reducer ) {\n";
+
+ for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) {
+ Reduction *reduction = *r;
+ *outStream <<
+ " case " << reduction->id << ":\n"
+ " " << reduction->var << "->commit_reduce_forward( "
+ "prg, root, pda_run, pt );\n"
+ " break;\n";
+ }
+
+ *outStream <<
" }\n"
- "\n"
- " if ( !( lel->flags & PF_COMMITTED ) ) {\n"
- " /* Now can execute the reduction action. */\n"
- " switch ( reducer->current ) {\n";
+ "}\n"
+ "\n";
for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) {
Reduction *reduction = *r;
*outStream <<
- " case " << reduction->id << ": { switch ( kid->tree->id ) {\n";
+ "void " << reduction->name << "::commit_reduce_forward( program_t *prg, \n"
+ " tree_t **root, struct pda_run *pda_run, parse_tree_t *pt )\n"
+ "{\n"
+ " tree_t **sp = root;\n"
+ "\n"
+ " parse_tree_t *lel = pt;\n"
+ " kid_t *kid = pt->shadow;\n"
+ "\n"
+ "recurse:\n"
+ "\n"
+ " if ( lel->child != 0 ) {\n"
+ " /* There are children. Must process all children first. */\n"
+ " vm_push_ptree( lel );\n"
+ " vm_push_kid( kid );\n"
+ "\n"
+ " lel = lel->child;\n"
+ " kid = kid->tree->child;\n"
+ " while ( lel != 0 ) {\n"
+ " goto recurse;\n"
+ " resume:\n"
+ " lel = lel->next;\n"
+ " kid = kid->next;\n"
+ " }\n"
+ "\n"
+ " kid = vm_pop_kid();\n"
+ " lel = vm_pop_ptree();\n"
+ " }\n"
+ "\n"
+ " if ( !( lel->flags & PF_COMMITTED ) ) {\n"
+ " /* Now can execute the reduction action. */\n"
+ " {\n";
+
+
+ *outStream <<
+ " { switch ( kid->tree->id ) {\n";
/* Populate a vector with the reduce actions. */
Vector<ReduceAction*> actions;
@@ -387,22 +412,17 @@ void Compiler::writeCommit()
}
*outStream <<
- " } break; }\n";
+ " } }\n"
+ " }\n"
+ " }\n"
+ "\n"
+ " commit_clear_parse_tree( prg, sp, pda_run, lel->child );\n"
+ " lel->child = 0;\n"
+ "\n"
+ " if ( sp != root )\n"
+ " goto resume;\n"
+ " pt->flags |= PF_COMMITTED;\n"
+ "}\n"
+ "\n";
}
-
- *outStream <<
- " }\n"
- " }\n"
- "\n"
- " commit_clear_parse_tree( prg, sp, pda_run, lel->child );\n"
- " lel->child = 0;\n"
- "\n"
- " if ( sp != root )\n"
- " goto resume;\n"
- " pt->flags |= PF_COMMITTED;\n"
- "}\n"
- "\n";
}
-
-
-
diff --git a/src/resolve.cc b/src/resolve.cc
index 9bbc3c4d..79475ebe 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -921,6 +921,22 @@ void Compiler::findReductionActionProds()
}
}
}
+
+void Compiler::resolveReducers()
+{
+ for ( ParserTextList::Iter pt = parserTextList; pt.lte(); pt++ ) {
+ if ( pt->reduce ) {
+ Reduction *reduction = rootNamespace->findReduction( pt->reducer );
+ if ( reduction == 0 ) {
+ error ( pt->loc ) << "could not locate reduction \"" <<
+ pt->reducer << "\"" << endp;
+ }
+
+ pt->reducerId = reduction->id;
+ }
+ }
+}
+
void Compiler::resolvePass()
{
/*
@@ -943,4 +959,6 @@ void Compiler::resolvePass()
resolveProductionEls();
findReductionActionProds();
+
+ resolveReducers();
}
diff --git a/src/struct.c b/src/struct.c
index 6d5199c2..cd614afd 100644
--- a/src/struct.c
+++ b/src/struct.c
@@ -147,12 +147,12 @@ struct_t *colm_construct_generic( program_t *prg, long generic_id )
return new_generic;
}
-struct_t *colm_construct_reducer( program_t *prg, long generic_id )
+struct_t *colm_construct_reducer( program_t *prg, long generic_id, int reducer_id )
{
struct generic_info *generic_info = &prg->rtd->generic_info[generic_id];
struct_t *new_generic = 0;
- parser_t *parser = colm_parser_new( prg, generic_info, 1 );
+ parser_t *parser = colm_parser_new( prg, generic_info, reducer_id );
parser->input = colm_stream_new( prg );
new_generic = (struct_t*) parser;
diff --git a/src/struct.h b/src/struct.h
index fb6bd84a..0bb10cd3 100644
--- a/src/struct.h
+++ b/src/struct.h
@@ -149,7 +149,7 @@ struct colm_struct *colm_map_get( struct colm_program *prg, map_t *map,
word_t gen_id, word_t field );
struct colm_struct *colm_construct_generic( struct colm_program *prg, long generic_id );
-struct colm_struct *colm_construct_reducer( struct colm_program *prg, long generic_id );
+struct colm_struct *colm_construct_reducer( struct colm_program *prg, long generic_id, int reducer_id );
#define STRUCT_INBUILT_ID -1
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 4f262ce9..896c5496 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -1400,11 +1400,15 @@ UniqueType *LangTerm::evaluateParse( Compiler *pd, CodeVect &code,
/* Construct the parser. */
- if ( parserText->reduce )
+ if ( parserText->reduce ) {
code.append( IN_CONS_REDUCER );
- else
+ code.appendHalf( parserUT->generic->id );
+ code.appendHalf( parserText->reducerId );
+ }
+ else {
code.append( IN_CONS_GENERIC );
- code.appendHalf( parserUT->generic->id );
+ code.appendHalf( parserUT->generic->id );
+ }
/*
* First load the context into the parser.