summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bytecode.c11
-rw-r--r--src/bytecode.h2
-rw-r--r--src/colm.lm3
-rw-r--r--src/compiler.cc4
-rw-r--r--src/compiler.h9
-rw-r--r--src/exports.cc6
-rw-r--r--src/loadcolm.cc51
-rw-r--r--src/parser.cc16
-rw-r--r--src/parser.h2
-rw-r--r--src/parsetree.h55
-rw-r--r--src/resolve.cc25
-rw-r--r--src/synthesis.cc30
12 files changed, 159 insertions, 55 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index a9bf9cef..518c72e4 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -2227,6 +2227,17 @@ again:
break;
}
+ case IN_PROD_NUM: {
+ debug( prg, REALM_BYTECODE, "IN_PROD_NUM\n" );
+
+ tree_t *tree = vm_pop_tree();
+ colm_tree_downref( prg, sp, tree );
+
+ value_t v = tree->prod_num;
+ vm_push_value( v );
+ break;
+ }
+
case IN_PARSE_APPEND_WC: {
debug( prg, REALM_BYTECODE, "IN_PARSE_APPEND_WC\n" );
diff --git a/src/bytecode.h b/src/bytecode.h
index 34bf991b..cb5d1a06 100644
--- a/src/bytecode.h
+++ b/src/bytecode.h
@@ -104,6 +104,7 @@ typedef unsigned char uchar;
#define IN_REJECT 0x21
#define IN_MATCH 0x22
+#define IN_PROD_NUM 0x6a
#define IN_CONSTRUCT 0x23
#define IN_CONS_OBJECT 0xf0
#define IN_CONS_GENERIC 0xf1
@@ -369,6 +370,7 @@ typedef unsigned char uchar;
#define IN_CONST_ARG 0x13
+
/*
* IN_FN instructions.
*/
diff --git a/src/colm.lm b/src/colm.lm
index a1a237fd..47188910 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -497,7 +497,8 @@ def prod_list
| [prod] :Base
def case_clause
- [CASE pattern block_or_single] commit
+ [CASE pattern block_or_single] :Pattern commit
+| [CASE id block_or_single] :Id commit
def default_clause
[DEFAULT block_or_single] commit
diff --git a/src/compiler.cc b/src/compiler.cc
index 017712a9..229b4ee8 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1200,8 +1200,10 @@ void Compiler::compile()
beginProcessing();
initKeyOps();
+ /* Declare types. */
declarePass();
+ /* Resolve type references. */
resolvePass();
makeTerminalWrappers();
@@ -1225,7 +1227,7 @@ void Compiler::compile()
/* Compile bytecode. */
compileByteCode();
- /* Make the reduced fsm. */
+ /* Make the reduced scanner. */
RedFsmBuild reduce( this, fsmGraph );
redFsm = reduce.reduceMachine();
diff --git a/src/compiler.h b/src/compiler.h
index b7b4e61a..cf23bc9c 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -152,7 +152,8 @@ struct Production
:
prodName(0), prodElList(0), prodCommit(false), redBlock(0),
prodId(0), prodNum(0), fsm(0), fsmLength(0), uniqueEmptyLeader(0),
- isLeftRec(false), localFrame(0), lhsField(0), predOf(0) {}
+ isLeftRec(false), localFrame(0), lhsField(0), predOf(0)
+ {}
static Production* cons( const InputLoc &loc, LangEl *prodName, ProdElList *prodElList,
String name, bool prodCommit, CodeBlock *redBlock, int prodId, int prodNum )
@@ -160,7 +161,7 @@ struct Production
Production *p = new Production;
p->loc = loc;
p->prodName = prodName;
- p->name = name;
+ p->_name = name;
p->prodElList = prodElList;
p->prodCommit = prodCommit;
p->redBlock = redBlock;
@@ -172,7 +173,7 @@ struct Production
InputLoc loc;
LangEl *prodName;
ProdElList *prodElList;
- String name;
+ String _name;
bool prodCommit;
CodeBlock *redBlock;
@@ -679,6 +680,8 @@ struct Compiler
void findReductionActionProds();
void resolveReducers();
+ Production *findProductionByLabel( LangEl *langEl, String label );
+
void declarePass();
void resolvePass();
diff --git a/src/exports.cc b/src/exports.cc
index fa4946a6..6b9e2858 100644
--- a/src/exports.cc
+++ b/src/exports.cc
@@ -132,15 +132,15 @@ void Compiler::generateExports()
bool prodNames = false;
for ( LelDefList::Iter prod = lel->defList; prod.lte(); prod++ ) {
- if ( prod->name.length() > 0 )
+ if ( prod->_name.length() > 0 )
prodNames = true;
}
if ( prodNames ) {
out << " enum prod_name {\n";
for ( LelDefList::Iter prod = lel->defList; prod.lte(); prod++ ) {
- if ( prod->name.length() > 0 )
- out << "\t\t" << prod->name << " = " << prod->prodNum << ",\n";
+ if ( prod->_name.length() > 0 )
+ out << "\t\t" << prod->_name << " = " << prod->prodNum << ",\n";
}
out << " };\n";
out << " enum prod_name prodName() " <<
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 63beef71..02c993a1 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -2160,40 +2160,47 @@ struct LoadColm
return stmt;
}
+ LangStmt *walkCaseClause( case_clause CaseClause, var_ref VarRef )
+ {
+ pushScope();
+
+ LangVarRef *varRef = walkVarRef( VarRef );
+
+ LangExpr *expr = 0;
+
+ if ( CaseClause.prodName() == case_clause::Pattern ) {
+ /* A match pattern. */
+ PatternItemList *list = walkPattern( CaseClause.pattern(), varRef );
+ expr = match( CaseClause.loc(), varRef, list );
+ }
+ else {
+ /* An identifier to be interpreted as a production name. */
+ String prod = CaseClause.id().text().c_str();
+ expr = prodCompare( CaseClause.loc(), varRef, prod );
+ }
+
+ StmtList *stmtList = walkBlockOrSingle( CaseClause.block_or_single() );
+
+ popScope();
+
+ return LangStmt::cons( LangStmt::IfType, expr, stmtList );
+ }
+
LangStmt *walkCaseClauseList( case_clause_list CaseClauseList, var_ref VarRef )
{
LangStmt *stmt = 0;
switch ( CaseClauseList.prodName() ) {
case case_clause_list::Recursive: {
- pushScope();
-
- LangVarRef *varRef = walkVarRef( VarRef );
- PatternItemList *list = walkPattern( CaseClauseList.case_clause().pattern(), varRef );
- LangExpr *expr = match( CaseClauseList.loc(), varRef, list );
-
- StmtList *stmtList = walkBlockOrSingle(
- CaseClauseList.case_clause().block_or_single() );
-
- popScope();
+ stmt = walkCaseClause( CaseClauseList.case_clause(), VarRef );
LangStmt *recList = walkCaseClauseList(
CaseClauseList._case_clause_list(), VarRef );
- stmt = LangStmt::cons( LangStmt::IfType, expr, stmtList, recList );
+ stmt->setElsePart( recList );
break;
}
case case_clause_list::BaseCase: {
- pushScope();
-
- LangVarRef *varRef = walkVarRef( VarRef );
- PatternItemList *list = walkPattern(
- CaseClauseList.case_clause().pattern(), varRef );
- LangExpr *expr = match( CaseClauseList.loc(), varRef, list );
-
- StmtList *stmtList = walkBlockOrSingle(
- CaseClauseList.case_clause().block_or_single() );
- popScope();
- stmt = LangStmt::cons( LangStmt::IfType, expr, stmtList, 0 );
+ stmt = walkCaseClause( CaseClauseList.case_clause(), VarRef );
break;
}
case case_clause_list::BaseDefault: {
diff --git a/src/parser.cc b/src/parser.cc
index 72a9b209..36801f5b 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -957,8 +957,16 @@ LangExpr *BaseParser::match( const InputLoc &loc, LangVarRef *varRef,
list, pd->nextPatConsId++ );
pd->patternList.append( pattern );
- LangExpr *expr = LangExpr::cons( LangTerm::cons(
- InputLoc(), LangTerm::MatchType, varRef, pattern ) );
+ LangExpr *expr = LangExpr::cons( LangTerm::consMatch(
+ InputLoc(), varRef, pattern ) );
+
+ return expr;
+}
+
+LangExpr *BaseParser::prodCompare( const InputLoc &loc, LangVarRef *varRef, const String &prod )
+{
+ LangExpr *expr = LangExpr::cons( LangTerm::consProdCompare(
+ InputLoc(), varRef, prod ) );
return expr;
}
@@ -996,8 +1004,8 @@ LangExpr *BaseParser::require( const InputLoc &loc,
list, pd->nextPatConsId++ );
pd->patternList.append( pattern );
- LangExpr *expr = LangExpr::cons( LangTerm::cons(
- InputLoc(), LangTerm::MatchType, varRef, pattern ) );
+ LangExpr *expr = LangExpr::cons( LangTerm::consMatch(
+ InputLoc(), varRef, pattern ) );
return expr;
}
diff --git a/src/parser.h b/src/parser.h
index 3f066bd8..4adbb5d8 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -156,10 +156,12 @@ struct BaseParser
ConsItemList *list, TypeRef *typeRef, FieldInitVect *fieldInitVect );
LangExpr *match( const InputLoc &loc, LangVarRef *varRef,
PatternItemList *list );
+ LangExpr *prodCompare( const InputLoc &loc, LangVarRef *varRef, const String &prod );
LangStmt *varDef( ObjectField *objField,
LangExpr *expr, LangStmt::Type assignType );
LangStmt *exportStmt( ObjectField *objField, LangStmt::Type assignType, LangExpr *expr );
+
LangExpr *require( const InputLoc &loc, LangVarRef *varRef, PatternItemList *list );
void structVarDef( const InputLoc &loc, ObjectField *objField );
void structHead( const InputLoc &loc, Namespace *inNspace,
diff --git a/src/parsetree.h b/src/parsetree.h
index d5baf64f..f5c40f14 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -970,7 +970,6 @@ struct ReduceAction
String prod;
ReduceTextItemList itemList;
-
Production *production;
ReduceAction *prev, *next;
@@ -1810,6 +1809,16 @@ struct ConsItemList
struct Pattern
{
+ Pattern()
+ :
+ nspace(0),
+ list(0),
+ patRepId(0),
+ langEl(0),
+ pdaRun(0),
+ nextBindId(1)
+ {}
+
static Pattern *cons( const InputLoc &loc, Namespace *nspace,
PatternItemList *list, int patRepId )
{
@@ -1818,12 +1827,9 @@ struct Pattern
p->nspace = nspace;
p->list = list;
p->patRepId = patRepId;
- p->langEl = 0;
- p->pdaRun = 0;
- p->nextBindId = 1;
return p;
}
-
+
InputLoc loc;
Namespace *nspace;
PatternItemList *list;
@@ -2879,6 +2885,7 @@ struct LangTerm
NumberType,
StringType,
MatchType,
+ ProdCompareType,
NewType,
ConstructType,
TypeIdType,
@@ -2975,6 +2982,28 @@ struct LangTerm
return t;
}
+ static LangTerm *consMatch( const InputLoc &loc,
+ LangVarRef *varRef, Pattern *pattern )
+ {
+ LangTerm *t = new LangTerm;
+ t->type = MatchType;
+ t->loc = loc;
+ t->varRef = varRef;
+ t->pattern = pattern;
+ return t;
+ }
+
+ static LangTerm *consProdCompare( const InputLoc &loc,
+ LangVarRef *varRef, const String &prod )
+ {
+ LangTerm *t = new LangTerm;
+ t->type = ProdCompareType;
+ t->loc = loc;
+ t->varRef = varRef;
+ t->prod = prod;
+ return t;
+ }
+
static LangTerm *cons( const InputLoc &loc, Type type, LangVarRef *varRef,
Pattern *pattern )
{
@@ -3108,6 +3137,7 @@ struct LangTerm
UniqueType *evaluateSend( Compiler *pd, CodeVect &code ) const;
UniqueType *evaluateSendTree( Compiler *pd, CodeVect &code ) const;
UniqueType *evaluateMatch( Compiler *pd, CodeVect &code ) const;
+ UniqueType *evaluateProdCompare( Compiler *pd, CodeVect &code ) const;
UniqueType *evaluate( Compiler *pd, CodeVect &code ) const;
void assignFieldArgs( Compiler *pd, CodeVect &code, UniqueType *replUT ) const;
UniqueType *evaluateMakeToken( Compiler *pd, CodeVect &code ) const;
@@ -3126,6 +3156,7 @@ struct LangTerm
ObjectField *objField;
TypeRef *typeRef;
Pattern *pattern;
+ String prod;
FieldInitVect *fieldInitArgs;
GenericType *generic;
Constructor *constructor;
@@ -3339,24 +3370,30 @@ struct LangStmt
return s;
}
- static LangStmt *cons( Type type, StmtList *stmtList )
+ static LangStmt *cons( Type type, LangExpr *expr, StmtList *stmtList, LangStmt *elsePart )
{
LangStmt *s = new LangStmt;
s->type = type;
+ s->expr = expr;
s->stmtList = stmtList;
+ s->elsePart = elsePart;
return s;
}
- static LangStmt *cons( Type type, LangExpr *expr, StmtList *stmtList, LangStmt *elsePart )
+ void setElsePart( LangStmt *elsePart )
+ {
+ this->elsePart = elsePart;
+ }
+
+ static LangStmt *cons( Type type, StmtList *stmtList )
{
LangStmt *s = new LangStmt;
s->type = type;
- s->expr = expr;
s->stmtList = stmtList;
- s->elsePart = elsePart;
return s;
}
+
static LangStmt *cons( const InputLoc &loc, Type type )
{
LangStmt *s = new LangStmt;
diff --git a/src/resolve.cc b/src/resolve.cc
index ed26871c..2577e815 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -21,12 +21,11 @@
*/
#include <stdbool.h>
-
#include <iostream>
-
#include "compiler.h"
+
/*
- * Type Resolution.
+ * Type Resolve.
*/
using std::cout;
@@ -514,6 +513,9 @@ void LangTerm::resolve( Compiler *pd )
case StringType:
break;
+ case ProdCompareType:
+ break;
+
case MatchType:
for ( PatternItemList::Iter item = *pattern->list; item.lte(); item++ ) {
switch ( item->form ) {
@@ -901,6 +903,15 @@ void Compiler::resolveReductionActions()
}
}
+Production *Compiler::findProductionByLabel( LangEl *langEl, String label )
+{
+ for ( LelDefList::Iter ldi = langEl->defList; ldi.lte(); ldi++ ) {
+ if ( strcmp( ldi->_name, label ) == 0 )
+ return ldi;
+ }
+ return 0;
+}
+
void Compiler::findReductionActionProds()
{
for ( ReductionVect::Iter r = rootNamespace->reductions; r.lte(); r++ ) {
@@ -908,13 +919,7 @@ void Compiler::findReductionActionProds()
rai->nonTerm->resolveType( this );
LangEl *langEl = rai->nonTerm->uniqueType->langEl;
- Production *prod = 0;
- for ( LelDefList::Iter ldi = langEl->defList; ldi.lte(); ldi++ ) {
- if ( strcmp( ldi->name, rai->prod ) == 0 ) {
- prod = ldi;
- break;
- }
- }
+ Production *prod = findProductionByLabel( langEl, rai->prod );
if ( prod == 0 ) {
error(rai->loc) << "could not find production \"" <<
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 629b9d4b..7ea64f09 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -22,9 +22,7 @@
#include <assert.h>
#include <stdbool.h>
-
#include <iostream>
-
#include "compiler.h"
using std::cout;
@@ -1224,6 +1222,31 @@ UniqueType *LangTerm::evaluateMatch( Compiler *pd, CodeVect &code ) const
return ut;
}
+UniqueType *LangTerm::evaluateProdCompare( Compiler *pd, CodeVect &code ) const
+{
+ UniqueType *ut = varRef->evaluate( pd, code );
+ if ( ut->typeId != TYPE_TREE && ut->typeId != TYPE_REF ) {
+ error(varRef->loc) << "expected match against a tree/ref type" << endp;
+ }
+ code.append( IN_PROD_NUM );
+
+ /* look up the production name. */
+ Production *prod = pd->findProductionByLabel( ut->langEl, this->prod );
+
+ if ( prod == 0 ) {
+ error( this->loc) << "could not find "
+ "production label: " << this->prod << endp;
+ }
+
+ unsigned int n = prod->prodNum;
+ code.append( IN_LOAD_INT );
+ code.appendWord( n );
+
+ code.append( IN_TST_EQL_VAL );
+
+ return pd->uniqueTypeInt;
+}
+
void LangTerm::evaluateCapture( Compiler *pd, CodeVect &code, UniqueType *valUt ) const
{
if ( varRef != 0 ) {
@@ -1932,6 +1955,9 @@ UniqueType *LangTerm::evaluate( Compiler *pd, CodeVect &code ) const
case MatchType:
retUt = evaluateMatch( pd, code );
break;
+ case ProdCompareType:
+ retUt = evaluateProdCompare( pd, code );
+ break;
case ParseType:
retUt = evaluateParse( pd, code, false, false );
break;