summaryrefslogtreecommitdiff
path: root/src/reduce.cc
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-11-01 10:35:19 -0500
committerAdrian Thurston <thurston@complang.org>2015-11-01 10:35:19 -0500
commit80b9fc661abe6f37853bc12889f0443a1d6c65a9 (patch)
tree156be0111d93e2b5f3ae56c41d2bc4bb5ef47e8c /src/reduce.cc
parent0b175a8ed019785233618b3bb8e3c064e567f2ec (diff)
downloadcolm-80b9fc661abe6f37853bc12889f0443a1d6c65a9.tar.gz
allow access to rhs elements by number
Diffstat (limited to 'src/reduce.cc')
-rw-r--r--src/reduce.cc88
1 files changed, 57 insertions, 31 deletions
diff --git a/src/reduce.cc b/src/reduce.cc
index 989329ee..84d635c1 100644
--- a/src/reduce.cc
+++ b/src/reduce.cc
@@ -69,15 +69,30 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list
}
if ( i->type == ReduceTextItem::RhsRef || i->type == ReduceTextItem::RhsLoc ) {
- String name( i->txt.data + 1, i->txt.length() - 1 );
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal; r.lte(); r++ ) {
- if ( r->prodEl->production == production ) {
- if ( i->type == ReduceTextItem::RhsLoc )
- locUsed[r->prodEl->pos] = r->prodEl;
- else
- rhsUsed[r->prodEl->pos] = r->prodEl;
+ if ( i->n > 0 ) {
+ ProdEl *prodEl = production->prodElList->head;
+ int adv = i->n - 1;
+ while ( adv > 0 ) {
+ prodEl = prodEl->next;
+ adv -= 1;
+ }
+
+ if ( i->type == ReduceTextItem::RhsLoc )
+ locUsed[i->n-1] = prodEl;
+ else
+ rhsUsed[i->n-1] = prodEl;
+ }
+ else {
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal; r.lte(); r++ ) {
+ if ( r->prodEl->production == production ) {
+ if ( i->type == ReduceTextItem::RhsLoc )
+ locUsed[r->prodEl->pos] = r->prodEl;
+ else
+ rhsUsed[r->prodEl->pos] = r->prodEl;
+ }
}
}
}
@@ -128,34 +143,44 @@ void Compiler::loadRefs( Production *production, const ReduceTextItemList &list
void Compiler::writeRhsRef( Production *production, ReduceTextItem *i )
{
- ObjectDef *objectDef = production->prodName->objectDef;
- String name( i->txt.data + 1, i->txt.length() - 1 );
-
- /* Find the field in the rhsVal using capture field. */
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal;
- r.lte(); r++ )
- {
- if ( r->prodEl->production == production )
- *outStream << "_rhs" << r->prodEl->pos;
+ if ( i->n > 0 ) {
+ *outStream << "_rhs" << ( i->n - 1 );
+ }
+ else {
+ ObjectDef *objectDef = production->prodName->objectDef;
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+
+ /* Find the field in the rhsVal using capture field. */
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal;
+ r.lte(); r++ )
+ {
+ if ( r->prodEl->production == production )
+ *outStream << "_rhs" << r->prodEl->pos;
+ }
}
}
}
void Compiler::writeRhsLoc( Production *production, ReduceTextItem *i )
{
- ObjectDef *objectDef = production->prodName->objectDef;
- String name( i->txt.data + 1, i->txt.length() - 1 );
-
- /* Find the field in the rhsVal using capture field. */
- ObjectField *field = objectDef->rootScope->findField( name );
- if ( field != 0 ) {
- for ( Vector<RhsVal>::Iter r = field->rhsVal;
- r.lte(); r++ )
- {
- if ( r->prodEl->production == production )
- *outStream << "_loc" << r->prodEl->pos;
+ if ( i->n > 0 ) {
+ *outStream << "_loc" << ( i->n - 1 );
+ }
+ else {
+ ObjectDef *objectDef = production->prodName->objectDef;
+ String name( i->txt.data + 1, i->txt.length() - 1 );
+
+ /* Find the field in the rhsVal using capture field. */
+ ObjectField *field = objectDef->rootScope->findField( name );
+ if ( field != 0 ) {
+ for ( Vector<RhsVal>::Iter r = field->rhsVal;
+ r.lte(); r++ )
+ {
+ if ( r->prodEl->production == production )
+ *outStream << "_loc" << r->prodEl->pos;
+ }
}
}
}
@@ -220,6 +245,7 @@ void Compiler::writeCommit()
"#include <stdlib.h>\n"
"#include <string.h>\n"
"#include <assert.h>\n"
+ "#include <errno.h>\n"
"\n"
"#include <iostream>\n"
"using std::endl;\n"