summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-10-06 10:50:30 -0400
committerAdrian Thurston <thurston@complang.org>2015-10-06 10:50:30 -0400
commit0088b7912eb1bbcf7034b005ef84e133f3d89aab (patch)
tree1b03a4ac4f897bb8e00dcf0992f1053b3ec666cc /src
parentdc2a84cc6c730f991e5f7c41964f1a81a086aaae (diff)
downloadcolm-0088b7912eb1bbcf7034b005ef84e133f3d89aab.tar.gz
collect and emit reduction action items
Diffstat (limited to 'src')
-rw-r--r--src/colm.lm13
-rw-r--r--src/compiler.cc25
-rw-r--r--src/compiler.h1
-rw-r--r--src/loadcolm.cc45
-rw-r--r--src/parsetree.h30
-rw-r--r--src/struct.c2
-rw-r--r--src/struct.h4
7 files changed, 98 insertions, 22 deletions
diff --git a/src/colm.lm b/src/colm.lm
index c7c72c2a..74e83bf5 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -338,8 +338,8 @@ def reduction_def
[REDUCTION id ItemList: reduction_item* END]
lex
- token ROPEN / '{' /
- token RCLOSE / '}' /
+ token RED_OPEN / '{' /
+ token RED_CLOSE / '}' /
token red_id /
( 'a' .. 'z' | 'A' .. 'Z' | '_' ) .
@@ -360,14 +360,17 @@ lex
'\"' . ( ^( '\"' | '\\' ) | '\\' . any )* . ( '\"' | '\"i' )
/
+ token RED_LHS / '$' . '$' /
+ token RED_RHS / '$' . red_id /
+
token red_any / any /
end
def red_nonterm
- [type_ref ROPEN HostItems: host_item* RCLOSE]
+ [type_ref RED_OPEN HostItems: host_item* RED_CLOSE]
def red_action
- [type_ref COLON id ROPEN HostItems: host_item* RCLOSE]
+ [type_ref COLON id RED_OPEN HostItems: host_item* RED_CLOSE]
def host_item
[red_id]
@@ -375,6 +378,8 @@ def host_item
| [red_comment]
| [red_ws]
| [red_any]
+| [RED_LHS]
+| [RED_RHS]
def reduction_item
[red_nonterm] :NonTerm commit
diff --git a/src/compiler.cc b/src/compiler.cc
index e568de83..ec7ca1bb 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1152,6 +1152,17 @@ void Compiler::writeCommitStub()
;
}
+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 <<
@@ -1176,7 +1187,12 @@ void Compiler::writeCommit()
for ( ReduceNonTermList::Iter rdi = (*r)->reduceNonTerms; rdi.lte(); rdi++ ) {
*outStream <<
"struct lel_" << rdi->nonTerm->uniqueType->langEl->fullName << "\n"
- "{" << rdi->txt << "};\n";
+ "{";
+
+ writeHostItemList( rdi->itemList );
+
+ *outStream <<
+ "};\n";
}
}
@@ -1240,8 +1256,11 @@ void Compiler::writeCommit()
*outStream <<
" case " << lelId << ": \n"
- " if ( kid->tree->prod_num == " << prodNum << " ) {\n"
- " " << rdi->txt << "\n"
+ " if ( kid->tree->prod_num == " << prodNum << " ) {\n";
+
+ writeHostItemList( rdi->itemList );
+
+ *outStream <<
" }\n"
" break;\n";
}
diff --git a/src/compiler.h b/src/compiler.h
index 611fac6c..60a7e3af 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -1011,6 +1011,7 @@ struct Compiler
void writeHostCall();
void writeCommit();
+ void writeHostItemList( const ReduceTextItemList &list );
void writeCommitStub();
};
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 374793cc..5cc93604 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -2346,13 +2346,47 @@ struct LoadColm
namespaceStack.pop();
}
+ void walkRedItem( host_item item, ReduceTextItemList &list )
+ {
+ if ( item.RED_LHS() != 0 ) {
+
+ }
+ else if ( item.RED_RHS() != 0 ) {
+
+ }
+ else {
+ if ( list.length() > 0 && list.tail->type == ReduceTextItem::Txt ) {
+ std::string txt = item.text();
+ list.tail->txt.append( txt.c_str(), txt.size() );
+ }
+ else {
+ ReduceTextItem *rti = new ReduceTextItem;
+ rti->type = ReduceTextItem::Txt;
+ rti->txt = item.text().c_str();
+ list.append( rti );
+ }
+ }
+ }
+
+ void walkRedItemList( _repeat_host_item itemList, ReduceTextItemList &list )
+ {
+ while ( !itemList.end() ) {
+ walkRedItem( itemList.value(), list );
+ itemList = itemList.next();
+ }
+ }
+
void walkRedNonTerm( red_nonterm RN )
{
- InputLoc loc = RN.ROPEN().loc();
- String text = RN.HostItems().text().c_str();
+ InputLoc loc = RN.RED_OPEN().loc();
+
+
TypeRef *typeRef = walkTypeRef( RN.type_ref() );
- ReduceNonTerm *rnt = new ReduceNonTerm( loc, typeRef, text );
+ ReduceNonTerm *rnt = new ReduceNonTerm( loc, typeRef );
+
+ walkRedItemList( RN.HostItems(), rnt->itemList );
+
curReduction()->reduceNonTerms.append( rnt );
}
@@ -2363,7 +2397,10 @@ struct LoadColm
TypeRef *typeRef = walkTypeRef( RA.type_ref() );
- ReduceAction *ra = new ReduceAction( loc, typeRef, RA.id().data(), text );
+ ReduceAction *ra = new ReduceAction( loc, typeRef, RA.id().data() );
+
+ walkRedItemList( RA.HostItems(), ra->itemList );
+
curReduction()->reduceActions.append( ra );
}
diff --git a/src/parsetree.h b/src/parsetree.h
index 4e4fa8ac..9a7ddb4a 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -917,18 +917,33 @@ struct Namespace
typedef DList<Namespace> NamespaceList;
typedef BstSet< Namespace*, CmpOrd<Namespace*> > NamespaceSet;
+struct ReduceTextItem
+{
+ enum Type {
+ LhsRef,
+ RhsRef,
+ Txt
+ };
+
+ Type type;
+ String txt;
+
+ ReduceTextItem *prev, *next;
+};
+
+typedef DList<ReduceTextItem> ReduceTextItemList;
+
struct ReduceNonTerm
{
- ReduceNonTerm( const InputLoc &loc, TypeRef *nonTerm, const String &txt )
+ ReduceNonTerm( const InputLoc &loc, TypeRef *nonTerm )
:
loc(loc),
- nonTerm(nonTerm),
- txt(txt)
+ nonTerm(nonTerm)
{}
InputLoc loc;
TypeRef *nonTerm;
- String txt;
+ ReduceTextItemList itemList;
ReduceNonTerm *prev, *next;
};
@@ -936,17 +951,18 @@ struct ReduceNonTerm
struct ReduceAction
{
ReduceAction( const InputLoc &loc, TypeRef *nonTerm,
- const String &prod, const String &txt )
+ const String &prod )
:
loc(loc), nonTerm(nonTerm),
prod(prod),
- txt(txt), production(0)
+ production(0)
{}
InputLoc loc;
TypeRef *nonTerm;
String prod;
- String txt;
+ ReduceTextItemList itemList;
+
Production *production;
diff --git a/src/struct.c b/src/struct.c
index 51ac7315..6d5199c2 100644
--- a/src/struct.c
+++ b/src/struct.c
@@ -76,7 +76,7 @@ void colm_parser_destroy( program_t *prg, tree_t **sp, struct colm_struct *s )
colm_tree_downref( prg, sp, parser->result );
}
-parser_t *colm_parser_new( program_t *prg, struct generic_info *gi, bool reducer )
+parser_t *colm_parser_new( program_t *prg, struct generic_info *gi, int reducer )
{
struct pda_run *pda_run = malloc( sizeof(struct pda_run) );
diff --git a/src/struct.h b/src/struct.h
index 25000fbb..fb6bd84a 100644
--- a/src/struct.h
+++ b/src/struct.h
@@ -5,8 +5,6 @@
extern "C" {
#endif
-#include <stdbool.h>
-
typedef void (*colm_destructor_t)( struct colm_program *prg,
tree_t **sp, struct colm_struct *s );
@@ -131,7 +129,7 @@ struct colm_struct *colm_struct_inbuilt( struct colm_program *prg, int size,
colm_struct_get_addr( obj, map_el_t*, prg->rtd->generic_info[genId].el_offset )
parser_t *colm_parser_new( struct colm_program *prg,
- struct generic_info *gi, bool reducer );
+ struct generic_info *gi, int reducer );
stream_t *colm_stream_new( struct colm_program *prg );
stream_t *colm_stream_new_struct( struct colm_program *prg );