diff options
-rw-r--r-- | src/bytecode.c | 11 | ||||
-rw-r--r-- | src/bytecode.h | 2 | ||||
-rw-r--r-- | src/colm.lm | 3 | ||||
-rw-r--r-- | src/compiler.cc | 4 | ||||
-rw-r--r-- | src/compiler.h | 9 | ||||
-rw-r--r-- | src/exports.cc | 6 | ||||
-rw-r--r-- | src/loadcolm.cc | 51 | ||||
-rw-r--r-- | src/parser.cc | 16 | ||||
-rw-r--r-- | src/parser.h | 2 | ||||
-rw-r--r-- | src/parsetree.h | 55 | ||||
-rw-r--r-- | src/resolve.cc | 25 | ||||
-rw-r--r-- | src/synthesis.cc | 30 |
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; |