diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/compiler.cc | 143 | ||||
-rw-r--r-- | src/compiler.h | 4 | ||||
-rw-r--r-- | src/loadcolm.cc | 9 | ||||
-rw-r--r-- | src/main.cc | 1 | ||||
-rw-r--r-- | src/reduce.cc | 219 | ||||
-rw-r--r-- | src/resolve.cc | 4 | ||||
-rw-r--r-- | src/tree.c | 9 | ||||
-rw-r--r-- | src/tree.h | 2 |
9 files changed, 245 insertions, 148 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 973e4ace..7f61d0aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,7 +61,7 @@ libprog_a_SOURCES = \ fsmgraph.cc pdagraph.cc pdabuild.cc pdacodegen.cc fsmcodegen.cc \ redfsm.cc fsmexec.cc redbuild.cc closure.cc fsmap.cc \ dotgen.cc pcheck.cc ctinput.cc declare.cc codegen.cc \ - exports.cc compiler.cc parser.cc + exports.cc compiler.cc parser.cc reduce.cc libprog_a_CXXFLAGS = $(common_CFLAGS) diff --git a/src/compiler.cc b/src/compiler.cc index ec7ca1bb..7c44e7ba 100644 --- a/src/compiler.cc +++ b/src/compiler.cc @@ -1138,149 +1138,6 @@ void Compiler::writeHostCall() } -void Compiler::writeCommitStub() -{ - *outStream << - "void commit_forward_recurse( program_t *prg, tree_t **root,\n" - " struct pda_run *pda_run, parse_tree_t *pt )\n" - "{\n" - " commit_clear_parse_tree( prg, root, pda_run, pt->child );\n" - "}\n" - "\n" - "long commit_union_sz() { return 0; }\n" - "\n"; - ; -} - -void Compiler::writeHostItemList( const ReduceTextItemList &list ) -{ - for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) { - switch ( i->type ) { - case ReduceTextItem::Txt: - *outStream << i->txt; - break; - } - } -} - -void Compiler::writeCommit() -{ - *outStream << - "#include <colm/pdarun.h>\n" - "#include <colm/debug.h>\n" - "#include <colm/bytecode.h>\n" - "#include <colm/config.h>\n" - "#include <colm/defs.h>\n" - "#include <colm/input.h>\n" - "#include <colm/tree.h>\n" - "#include <colm/program.h>\n" - "#include <colm/colm.h>\n" - "\n" - "#include <stdio.h>\n" - "#include <stdlib.h>\n" - "#include <string.h>\n" - "#include <assert.h>\n" - "\n" - "#include <iostream>\n"; - - for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { - for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) { - *outStream << - "struct lel_" << rdi->nonTerm->uniqueType->langEl->fullName << "\n" - "{"; - - writeHostItemList( rdi->itemList ); - - *outStream << - "};\n"; - } - } - - *outStream << - "union commit_reduce_union\n" - "{\n"; - - for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { - for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) { - LangEl *langEl = rdi->nonTerm->uniqueType->langEl; - *outStream << - " lel_" << langEl->fullName << " " << langEl->fullName << ";\n"; - } - } - - *outStream << - "};\n" - "\n"; - - *outStream << - "long commit_union_sz() { return sizeof( commit_reduce_union ); }\n"; - - *outStream << - "\n" - "void commit_forward_recurse( 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" - " }\n" - "\n" - " if ( !( lel->flags & PF_COMMITTED ) ) {\n" - " /* Now can execute the reduction action. */\n" - " switch ( kid->tree->id ) {\n"; - - for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { - for ( ReduceActionList::Iter rdi = (*r)->reduceActions; rdi.lte(); rdi++ ) { - int lelId = rdi->production->prodName->id; - int prodNum = rdi->production->prodNum; - - *outStream << - " case " << lelId << ": \n" - " if ( kid->tree->prod_num == " << prodNum << " ) {\n"; - - writeHostItemList( rdi->itemList ); - - *outStream << - " }\n" - " break;\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"; -} - - void Compiler::generateOutput( long activeRealm, bool includeCommit ) { FsmCodeGen *fsmGen = new FsmCodeGen( *outStream, redFsm, fsmTables ); diff --git a/src/compiler.h b/src/compiler.h index 60a7e3af..6d5d7f96 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1011,7 +1011,9 @@ struct Compiler void writeHostCall(); void writeCommit(); - void writeHostItemList( const ReduceTextItemList &list ); + void writeHostItemList( LangEl *prodName, const ReduceTextItemList &list ); + void writeHostItemList( LangEl *prodName, int prodNum, + const ReduceTextItemList &list ); void writeCommitStub(); }; diff --git a/src/loadcolm.cc b/src/loadcolm.cc index 5cc93604..7dd21141 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -2349,10 +2349,15 @@ struct LoadColm void walkRedItem( host_item item, ReduceTextItemList &list ) { if ( item.RED_LHS() != 0 ) { - + ReduceTextItem *rti = new ReduceTextItem; + rti->type = ReduceTextItem::LhsRef; + list.append( rti ); } else if ( item.RED_RHS() != 0 ) { - + ReduceTextItem *rti = new ReduceTextItem; + rti->type = ReduceTextItem::RhsRef; + rti->txt = item.RED_RHS().text().c_str(); + list.append( rti ); } else { if ( list.length() > 0 && list.tail->type == ReduceTextItem::Txt ) { diff --git a/src/main.cc b/src/main.cc index 6805f57f..6f8a28b9 100644 --- a/src/main.cc +++ b/src/main.cc @@ -734,7 +734,6 @@ int main(int argc, const char **argv) openCommit(); pd->writeCommit(); delete outStream; - } } diff --git a/src/reduce.cc b/src/reduce.cc new file mode 100644 index 00000000..c8627308 --- /dev/null +++ b/src/reduce.cc @@ -0,0 +1,219 @@ +/* + * Copyright 2015 Adrian Thurston <thurston@complang.org> + */ + +/* This file is part of Colm. + * + * Colm is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Colm is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Colm; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <iostream> +#include <iomanip> +#include <errno.h> +#include <stdlib.h> +#include <limits.h> +#include <sstream> + +#include "global.h" +#include "avltree.h" +#include "compiler.h" +#include "parser.h" +#include "parsetree.h" +#include "mergesort.h" +#include "redbuild.h" +#include "pdacodegen.h" +#include "fsmcodegen.h" +#include "pdarun.h" +#include "colm.h" +#include "pool.h" +#include "struct.h" + +void Compiler::writeCommitStub() +{ + *outStream << + "void commit_forward_recurse( program_t *prg, tree_t **root,\n" + " struct pda_run *pda_run, parse_tree_t *pt )\n" + "{\n" + " commit_clear_parse_tree( prg, root, pda_run, pt->child );\n" + "}\n" + "\n" + "long commit_union_sz() { return 0; }\n" + "\n"; + ; +} + +void Compiler::writeHostItemList( LangEl *prodName, int prodNum, + const ReduceTextItemList &list ) +{ + for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) { + switch ( i->type ) { + case ReduceTextItem::RhsRef: { + String name( i->txt.data + 1, i->txt.length() - 1 ); + + /* Find the field in the rhsVal using capture field. */ + ObjectField *field = prodName->objectDef->rootScope->findField( name ); + if ( field != 0 ) { + for ( Vector<RhsVal>::Iter r = field->rhsVal; + r.lte(); r++ ) + { + if ( r->prodEl->production->prodNum == prodNum ) { + if ( r->prodEl->langEl->type == LangEl::Term ) { + *outStream << "(get_rhs_el_kid( prg, kid->tree, " + << r->prodEl->pos << ")->tree->tokdata)"; + } + else { + *outStream << "(&((commit_reduce_union*)" + "(get_rhs_parse_tree( prg, lel, " << + r->prodEl->pos << ")+1))->" << + r->prodEl->langEl->fullName << ")"; + } + } + } + } + + break; + } + case ReduceTextItem::LhsRef: + *outStream << "(&((commit_reduce_union*)(lel+1))->" << + prodName->fullName << ")"; + break; + + case ReduceTextItem::Txt: + *outStream << i->txt; + break; + } + } +} + +void Compiler::writeCommit() +{ + *outStream << + "#include <colm/pdarun.h>\n" + "#include <colm/debug.h>\n" + "#include <colm/bytecode.h>\n" + "#include <colm/config.h>\n" + "#include <colm/defs.h>\n" + "#include <colm/input.h>\n" + "#include <colm/tree.h>\n" + "#include <colm/program.h>\n" + "#include <colm/colm.h>\n" + "\n" + "#include <stdio.h>\n" + "#include <stdlib.h>\n" + "#include <string.h>\n" + "#include <assert.h>\n" + "\n" + "#include <iostream>\n"; + + for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { + for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) { + *outStream << + "struct lel_" << rdi->nonTerm->uniqueType->langEl->fullName << "\n" + "{"; + + writeHostItemList( 0, 0, rdi->itemList ); + + *outStream << + "};\n"; + } + } + + *outStream << + "union commit_reduce_union\n" + "{\n"; + + for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { + for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) { + LangEl *langEl = rdi->nonTerm->uniqueType->langEl; + *outStream << + " lel_" << langEl->fullName << " " << langEl->fullName << ";\n"; + } + } + + *outStream << + "};\n" + "\n"; + + *outStream << + "long commit_union_sz() { return sizeof( commit_reduce_union ); }\n"; + + *outStream << + "\n" + "void commit_forward_recurse( 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" + " }\n" + "\n" + " if ( !( lel->flags & PF_COMMITTED ) ) {\n" + " /* Now can execute the reduction action. */\n" + " switch ( kid->tree->id ) {\n"; + + for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) { + for ( ReduceActionList::Iter rdi = (*r)->reduceActions; rdi.lte(); rdi++ ) { + int lelId = rdi->production->prodName->id; + int prodNum = rdi->production->prodNum; + + *outStream << + " case " << lelId << ": {\n" + " if ( kid->tree->prod_num == " << prodNum << " ) {\n"; + + writeHostItemList( rdi->production->prodName, prodNum, rdi->itemList ); + + *outStream << + " }\n" + " break;\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 9dc91abf..9bbc3c4d 100644 --- a/src/resolve.cc +++ b/src/resolve.cc @@ -24,6 +24,10 @@ #include <iostream> #include <assert.h> +/* + * Type Resolution. + */ + using std::cout; using std::cerr; using std::endl; @@ -1152,6 +1152,15 @@ kid_t *get_rhs_el_kid( program_t *prg, tree_t *lhs, long position ) return pos; } +parse_tree_t *get_rhs_parse_tree( program_t *prg, parse_tree_t *lhs, long position ) +{ + parse_tree_t *pos = lhs->child; + while ( position > 0 ) { + pos = pos->next; + position -= 1; + } + return pos; +} tree_t *colm_get_rhs_val( program_t *prg, tree_t *tree, int *a ) { @@ -256,6 +256,8 @@ tree_t *colm_tree_get_field( tree_t *tree, word_t field ); tree_t *get_field_split( struct colm_program *prg, tree_t *tree, word_t field ); tree_t *get_rhs_el( struct colm_program *prg, tree_t *lhs, long position ); kid_t *get_rhs_el_kid( struct colm_program *prg, tree_t *lhs, long position ); +parse_tree_t *get_rhs_parse_tree( struct colm_program *prg, + parse_tree_t *lhs, long position ); void colm_tree_set_field( struct colm_program *prg, tree_t *tree, long field, tree_t *value ); void set_triter_cur( struct colm_program *prg, tree_iter_t *iter, tree_t *tree ); |