diff options
author | Adrian Thurston <thurston@complang.org> | 2015-11-05 17:40:35 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-11-05 17:40:35 -0500 |
commit | 883797b32e3a4915bf81f801946cda6798e019c9 (patch) | |
tree | 4f4ed88b5ab78ef307f3219b7c54a5660490ae69 | |
parent | 80b9fc661abe6f37853bc12889f0443a1d6c65a9 (diff) | |
download | colm-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.c | 4 | ||||
-rw-r--r-- | src/colm.lm | 2 | ||||
-rw-r--r-- | src/compiler.h | 1 | ||||
-rw-r--r-- | src/consinit.cc | 4 | ||||
-rw-r--r-- | src/loadcolm.cc | 11 | ||||
-rw-r--r-- | src/loadinit.cc | 2 | ||||
-rw-r--r-- | src/parser.cc | 11 | ||||
-rw-r--r-- | src/parser.h | 2 | ||||
-rw-r--r-- | src/parsetree.h | 12 | ||||
-rw-r--r-- | src/pdarun.c | 3 | ||||
-rw-r--r-- | src/pdarun.h | 7 | ||||
-rw-r--r-- | src/reduce.cc | 130 | ||||
-rw-r--r-- | src/resolve.cc | 18 | ||||
-rw-r--r-- | src/struct.c | 4 | ||||
-rw-r--r-- | src/struct.h | 2 | ||||
-rw-r--r-- | src/synthesis.cc | 10 |
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. |