summaryrefslogtreecommitdiff
path: root/src/reduce.cc
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2018-12-17 14:10:50 +0200
committerAdrian Thurston <thurston@colm.net>2018-12-17 14:11:53 +0200
commiteccfd443ed78c614c396c542a07673c113f1ecd3 (patch)
tree297658178b1f24d53c476c9fa62f5a44b9a87d9a /src/reduce.cc
parentfc1d61f4cab2260e90fcd468078eaa0d2046f372 (diff)
downloadcolm-eccfd443ed78c614c396c542a07673c113f1ecd3.tar.gz
allow referencing a tree in reduction actions
syntax is $*N
Diffstat (limited to 'src/reduce.cc')
-rw-r--r--src/reduce.cc67
1 files changed, 59 insertions, 8 deletions
diff --git a/src/reduce.cc b/src/reduce.cc
index 6e010779..89a95015 100644
--- a/src/reduce.cc
+++ b/src/reduce.cc
@@ -47,13 +47,14 @@ void Compiler::writeCommitStub()
;
}
-void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed,
+void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed, Vector<ProdEl*> &treeUsed,
Vector<ProdEl*> &locUsed, Reduction *reduction, Production *production,
const ReduceTextItemList &list )
{
ObjectDef *objectDef = production->prodName->objectDef;
rhsUsed.setAsNew( production->prodElList->length() );
+ treeUsed.setAsNew( production->prodElList->length() );
locUsed.setAsNew( production->prodElList->length() );
for ( ReduceTextItemList::Iter i = list; i.lte(); i++ ) {
@@ -61,7 +62,10 @@ void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed,
lhsUsed = true;
}
- if ( i->type == ReduceTextItem::RhsRef || i->type == ReduceTextItem::RhsLoc ) {
+ if ( i->type == ReduceTextItem::RhsRef ||
+ i->type == ReduceTextItem::RhsLoc ||
+ i->type == ReduceTextItem::TreeRef )
+ {
if ( i->n > 0 ) {
/* Numbered. */
ProdEl *prodEl = production->prodElList->head;
@@ -73,6 +77,8 @@ void Compiler::findRhsRefs( bool &lhsUsed, Vector<ProdEl*> &rhsUsed,
if ( i->type == ReduceTextItem::RhsLoc )
locUsed[i->n-1] = prodEl;
+ else if ( i->type == ReduceTextItem::TreeRef )
+ treeUsed[i->n-1] = prodEl;
else
rhsUsed[i->n-1] = prodEl;
}
@@ -100,9 +106,10 @@ void Compiler::computeNeeded( Reduction *reduction, Production *production,
{
bool lhsUsed = false;
Vector<ProdEl*> rhsUsed;
+ Vector<ProdEl*> treeUsed;
Vector<ProdEl*> locUsed;
- findRhsRefs( lhsUsed, rhsUsed, locUsed, reduction, production, list );
+ findRhsRefs( lhsUsed, rhsUsed, treeUsed, locUsed, reduction, production, list );
/* Same length, can concurrently walk with one test. */
Vector<ProdEl*>::Iter rhs = rhsUsed;
@@ -126,9 +133,10 @@ void Compiler::loadRefs( Reduction *reduction, Production *production,
{
bool lhsUsed = false;
Vector<ProdEl*> rhsUsed;
+ Vector<ProdEl*> treeUsed;
Vector<ProdEl*> locUsed;
- findRhsRefs( lhsUsed, rhsUsed, locUsed, reduction, production, list );
+ findRhsRefs( lhsUsed, rhsUsed, treeUsed, locUsed, reduction, production, list );
if ( lhsUsed ) {
*outStream << " lel_" << production->prodName->fullName << " *_lhs = ";
@@ -200,9 +208,8 @@ void Compiler::loadRefs( Reduction *reduction, Production *production,
}
}
- /* In the second pass we load using a tree cursor. This is for token data
- * and locations.
- */
+ /* In the second pass we load using a tree cursor. This is for token/tree
+ * data and locations. */
useCursor = false;
for ( Vector<ProdEl*>::Iter rhs = rhsUsed; rhs.lte(); rhs++ ) {
@@ -213,6 +220,12 @@ void Compiler::loadRefs( Reduction *reduction, Production *production,
break;
}
}
+ for ( Vector<ProdEl*>::Iter rhs = treeUsed; rhs.lte(); rhs++ ) {
+ if ( *rhs != 0 ) {
+ useCursor = true;
+ break;
+ }
+ }
for ( Vector<ProdEl*>::Iter loc = locUsed; loc.lte(); loc++ ) {
if ( *loc != 0 ) {
useCursor = true;
@@ -234,12 +247,12 @@ void Compiler::loadRefs( Reduction *reduction, Production *production,
/* Same length, can concurrently walk with one test. */
Vector<ProdEl*>::Iter rhs = rhsUsed;
+ Vector<ProdEl*>::Iter tree = treeUsed;
Vector<ProdEl*>::Iter loc = locUsed;
for ( ; rhs.lte(); rhs++, loc++ ) {
ProdEl *prodEl = *rhs;
-
if ( prodEl != 0 ) {
if ( prodEl->production == production ) {
if ( prodEl->langEl->type == LangEl::Term ) {
@@ -262,7 +275,20 @@ void Compiler::loadRefs( Reduction *reduction, Production *production,
}
}
}
+ }
+
+ ProdEl *treeEl = *tree;
+ if ( treeEl != 0 ) {
+ if ( treeEl->production == production ) {
+ while ( cursorPos < rhs.pos() ) {
+ *outStream <<
+ " _tree_cursor = _tree_cursor->next;\n";
+ cursorPos += 1;
+ }
+ *outStream << " colm_tree *_tree" << rhs.pos() << " = ";
+ *outStream << "_tree_cursor->tree;\n";
+ }
}
ProdEl *locEl = *loc;
@@ -313,6 +339,28 @@ void Compiler::writeRhsRef( Production *production, ReduceTextItem *i )
}
}
+void Compiler::writeTreeRef( Production *production, ReduceTextItem *i )
+{
+ if ( i->n > 0 ) {
+ *outStream << "_tree" << ( 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 << "_tree" << r->prodEl->pos;
+ }
+ }
+ }
+}
+
void Compiler::writeRhsLoc( Production *production, ReduceTextItem *i )
{
if ( i->n > 0 ) {
@@ -351,6 +399,9 @@ void Compiler::writeHostItemList( Production *production,
case ReduceTextItem::RhsRef:
writeRhsRef( production, i );
break;
+ case ReduceTextItem::TreeRef:
+ writeTreeRef( production, i );
+ break;
case ReduceTextItem::RhsLoc:
writeRhsLoc( production, i );
break;