summaryrefslogtreecommitdiff
path: root/src/resolve.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve.cc')
-rw-r--r--src/resolve.cc799
1 files changed, 799 insertions, 0 deletions
diff --git a/src/resolve.cc b/src/resolve.cc
new file mode 100644
index 0000000..6b5dc75
--- /dev/null
+++ b/src/resolve.cc
@@ -0,0 +1,799 @@
+/*
+ * Copyright 2009-2012 Adrian Thurston <thurston@complang.org>
+ */
+
+/* This file is part of Colm.
+ *
+ * Colm is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Colm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Colm; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "bytecode.h"
+#include "parsedata.h"
+#include <iostream>
+#include <assert.h>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+Namespace *TypeRef::resolveNspace( Compiler *pd )
+{
+ if ( parsedVarRef != 0 && !nspaceQual->thisOnly() ) {
+ UniqueType *ut = parsedVarRef->lookup( pd );
+ return ut->langEl->nspace;
+ }
+ else if ( parsedTypeRef != 0 && !nspaceQual->thisOnly() ) {
+ UniqueType *ut = parsedTypeRef->resolveType( pd );
+ return ut->langEl->nspace;
+ }
+ else {
+ /* Lookup up the qualifiction and then the name. */
+ return nspaceQual->getQual( pd );
+ }
+}
+
+UniqueType *TypeRef::resolveTypeName( Compiler *pd )
+{
+ nspace = resolveNspace( pd );
+
+ if ( nspace == 0 )
+ error(loc) << "do not have region for resolving reference" << endp;
+
+ while ( nspace != 0 ) {
+ /* Search for the token in the region by typeName. */
+ TypeMapEl *inDict = nspace->typeMap.find( typeName );
+
+ if ( inDict != 0 ) {
+ switch ( inDict->type ) {
+ /* Defer to the typeRef we are an alias of. We need to guard against loops here. */
+ case TypeMapEl::TypeAliasType:
+ return inDict->typeRef->resolveType( pd );
+
+ case TypeMapEl::LangElType:
+ return pd->findUniqueType( TYPE_TREE, inDict->value );
+ }
+ }
+
+ if ( nspaceQual->thisOnly() )
+ break;
+
+ nspace = nspace->parentNamespace;
+ }
+
+ error(loc) << "unknown type in typeof expression" << endp;
+ return 0;
+}
+
+UniqueType *TypeRef::resolveTypeLiteral( Compiler *pd )
+{
+ /* Lookup up the qualifiction and then the name. */
+ nspace = resolveNspace( pd );
+
+ if ( nspace == 0 )
+ error(loc) << "do not have region for resolving reference" << endp;
+
+ /* Interpret escape sequences and remove quotes. */
+ bool unusedCI;
+ String interp;
+ prepareLitString( interp, unusedCI, pdaLiteral->data,
+ pdaLiteral->loc );
+
+ while ( nspace != 0 ) {
+ LiteralDictEl *ldel = nspace->literalDict.find( interp );
+
+ if ( ldel != 0 )
+ return pd->findUniqueType( TYPE_TREE, ldel->value->tokenDef->tdLangEl );
+
+ if ( nspaceQual->thisOnly() )
+ break;
+
+ nspace = nspace->parentNamespace;
+ }
+
+ error(loc) << "unknown type in typeof expression" << endp;
+ return 0;
+}
+
+UniqueType *TypeRef::resolveTypeMap( Compiler *pd )
+{
+ nspace = pd->rootNamespace;
+
+ UniqueType *utKey = typeRef1->resolveType( pd );
+ UniqueType *utValue = typeRef2->resolveType( pd );
+
+ UniqueMap searchKey( utKey, utValue );
+ UniqueMap *inMap = pd->uniqueMapMap.find( &searchKey );
+ if ( inMap == 0 ) {
+ inMap = new UniqueMap( utKey, utValue );
+ pd->uniqueMapMap.insert( inMap );
+
+ /* FIXME: Need uniqe name allocator for types. */
+ static int mapId = 0;
+ String name( 36, "__map%d", mapId++ );
+
+ GenericType *generic = new GenericType( name, GEN_MAP,
+ pd->nextGenericId++, 0/*langEl*/, typeRef2 );
+ generic->keyTypeArg = typeRef1;
+
+ nspace->genericList.append( generic );
+
+ generic->declare( pd, nspace );
+
+ inMap->generic = generic;
+ }
+
+ generic = inMap->generic;
+ return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl );
+}
+
+UniqueType *TypeRef::resolveTypeList( Compiler *pd )
+{
+ nspace = pd->rootNamespace;
+
+ UniqueType *utValue = typeRef1->resolveType( pd );
+
+ UniqueList searchKey( utValue );
+ UniqueList *inMap = pd->uniqueListMap.find( &searchKey );
+ if ( inMap == 0 ) {
+ inMap = new UniqueList( utValue );
+ pd->uniqueListMap.insert( inMap );
+
+ /* FIXME: Need uniqe name allocator for types. */
+ static int listId = 0;
+ String name( 36, "__list%d", listId++ );
+
+ GenericType *generic = new GenericType( name, GEN_LIST,
+ pd->nextGenericId++, 0/*langEl*/, typeRef1 );
+
+ nspace->genericList.append( generic );
+
+ generic->declare( pd, nspace );
+
+ inMap->generic = generic;
+ }
+
+ generic = inMap->generic;
+ return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl );
+}
+
+UniqueType *TypeRef::resolveTypeVector( Compiler *pd )
+{
+ nspace = pd->rootNamespace;
+
+ UniqueType *utValue = typeRef1->resolveType( pd );
+
+ UniqueVector searchKey( utValue );
+ UniqueVector *inMap = pd->uniqueVectorMap.find( &searchKey );
+ if ( inMap == 0 ) {
+ inMap = new UniqueVector( utValue );
+ pd->uniqueVectorMap.insert( inMap );
+
+ /* FIXME: Need uniqe name allocator for types. */
+ static int vectorId = 0;
+ String name( 36, "__vector%d", vectorId++ );
+
+ GenericType *generic = new GenericType( name, GEN_VECTOR,
+ pd->nextGenericId++, 0/*langEl*/, typeRef1 );
+
+ nspace->genericList.append( generic );
+
+ generic->declare( pd, nspace );
+
+ inMap->generic = generic;
+ }
+
+ generic = inMap->generic;
+ return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl );
+}
+
+UniqueType *TypeRef::resolveTypeParser( Compiler *pd )
+{
+ nspace = pd->rootNamespace;
+
+ UniqueType *utParse = typeRef1->resolveType( pd );
+
+ UniqueParser searchKey( utParse );
+ UniqueParser *inMap = pd->uniqueParserMap.find( &searchKey );
+ if ( inMap == 0 ) {
+ inMap = new UniqueParser( utParse );
+ pd->uniqueParserMap.insert( inMap );
+
+ /* FIXME: Need uniqe name allocator for types. */
+ static int accumId = 0;
+ String name( 36, "__accum%d", accumId++ );
+
+ GenericType *generic = new GenericType( name, GEN_PARSER,
+ pd->nextGenericId++, 0/*langEl*/, typeRef1 );
+
+ nspace->genericList.append( generic );
+
+ generic->declare( pd, nspace );
+
+ inMap->generic = generic;
+ }
+
+ generic = inMap->generic;
+ return pd->findUniqueType( TYPE_TREE, inMap->generic->langEl );
+}
+
+UniqueType *TypeRef::resolveTypePtr( Compiler *pd )
+{
+ typeRef1->resolveType( pd );
+ return pd->findUniqueType( TYPE_PTR, typeRef1->uniqueType->langEl );
+}
+
+UniqueType *TypeRef::resolveTypeRef( Compiler *pd )
+{
+ typeRef1->resolveType( pd );
+ return pd->findUniqueType( TYPE_REF, typeRef1->uniqueType->langEl );
+}
+
+void TypeRef::resolveRepeat( Compiler *pd )
+{
+ if ( uniqueType->typeId != TYPE_TREE )
+ error(loc) << "cannot repeat non-tree type" << endp;
+
+ UniqueRepeat searchKey( repeatType, uniqueType->langEl );
+ UniqueRepeat *uniqueRepeat = pd->uniqeRepeatMap.find( &searchKey );
+ if ( uniqueRepeat == 0 ) {
+ uniqueRepeat = new UniqueRepeat( repeatType, uniqueType->langEl );
+ pd->uniqeRepeatMap.insert( uniqueRepeat );
+
+ LangEl *declLangEl = 0;
+
+ switch ( repeatType ) {
+ case RepeatRepeat: {
+ /* If the factor is a repeat, create the repeat element and link the
+ * factor to it. */
+ String repeatName( 128, "_repeat_%s", typeName.data );
+ declLangEl = pd->makeRepeatProd( loc, nspace, repeatName, uniqueType );
+ break;
+ }
+ case RepeatList: {
+ /* If the factor is a repeat, create the repeat element and link the
+ * factor to it. */
+ String listName( 128, "_list_%s", typeName.data );
+ declLangEl = pd->makeListProd( loc, nspace, listName, uniqueType );
+ break;
+ }
+ case RepeatOpt: {
+ /* If the factor is an opt, create the opt element and link the factor
+ * to it. */
+ String optName( 128, "_opt_%s", typeName.data );
+ declLangEl = pd->makeOptProd( loc, nspace, optName, uniqueType );
+ break;
+ }
+
+ case RepeatNone:
+ break;
+ }
+
+ uniqueRepeat->declLangEl = declLangEl;
+ declLangEl->repeatOf = uniqueRepeat->langEl;
+ }
+
+ uniqueType = pd->findUniqueType( TYPE_TREE, uniqueRepeat->declLangEl );
+}
+
+UniqueType *TypeRef::resolveIterator( Compiler *pd )
+{
+ UniqueType *searchUT = searchTypeRef->resolveType( pd );
+
+ /* Lookup the iterator call. Make sure it is an iterator. */
+ VarRefLookup lookup = iterCall->langTerm->varRef->lookupMethod( pd );
+ if ( lookup.objMethod->iterDef == 0 ) {
+ error(loc) << "attempt to iterate using something "
+ "that is not an iterator" << endp;
+ }
+
+ /* Now that we have done the iterator call lookup we can make the type
+ * reference for the object field. */
+ UniqueType *iterUniqueType = pd->findUniqueType( TYPE_ITER, lookup.objMethod->iterDef );
+
+ iterDef = lookup.objMethod->iterDef;
+ searchUniqueType = searchUT;
+
+ return iterUniqueType;
+}
+
+
+UniqueType *TypeRef::resolveType( Compiler *pd )
+{
+ if ( uniqueType != 0 )
+ return uniqueType;
+
+ /* Not an iterator. May be a reference. */
+ switch ( type ) {
+ case Name:
+ uniqueType = resolveTypeName( pd );
+ break;
+ case Literal:
+ uniqueType = resolveTypeLiteral( pd );
+ break;
+ case Map:
+ uniqueType = resolveTypeMap( pd );
+ break;
+ case List:
+ uniqueType = resolveTypeList( pd );
+ break;
+ case Vector:
+ uniqueType = resolveTypeVector( pd );
+ break;
+ case Parser:
+ uniqueType = resolveTypeParser( pd );
+ break;
+ case Ptr:
+ uniqueType = resolveTypePtr( pd );
+ break;
+ case Ref:
+ uniqueType = resolveTypeRef( pd );
+ break;
+ case Iterator:
+ uniqueType = resolveIterator( pd );
+ break;
+ case Unspecified:
+ /* No lookup needed, unique type(s) set when constructed. */
+ break;
+ }
+
+ if ( repeatType != RepeatNone )
+ resolveRepeat( pd );
+
+ return uniqueType;
+}
+
+void Compiler::resolveProdEl( ProdEl *prodEl )
+{
+ prodEl->typeRef->resolveType( this );
+ prodEl->langEl = prodEl->typeRef->uniqueType->langEl;
+}
+
+void LangTerm::resolve( Compiler *pd )
+{
+ switch ( type ) {
+ case ConstructType:
+ typeRef->resolveType( pd );
+
+ /* Initialization expressions. */
+ if ( fieldInitArgs != 0 ) {
+ for ( FieldInitVect::Iter pi = *fieldInitArgs; pi.lte(); pi++ )
+ (*pi)->expr->resolve( pd );
+ }
+
+ /* Types in constructor. */
+ for ( ConsItemList::Iter item = *constructor->list; item.lte(); item++ ) {
+ switch ( item->type ) {
+ case ConsItem::LiteralType:
+ /* Use pdaFactor reference resolving. */
+ pd->resolveProdEl( item->prodEl );
+ break;
+ case ConsItem::InputText:
+ case ConsItem::ExprType:
+ break;
+ }
+ }
+ break;
+ case VarRefType:
+ break;
+
+ case MakeTreeType:
+ case MakeTokenType:
+ case MethodCallType:
+ if ( args != 0 ) {
+ for ( CallArgVect::Iter pe = *args; pe.lte(); pe++ )
+ (*pe)->expr->resolve( pd );
+ }
+ break;
+
+ case NumberType:
+ case StringType:
+ break;
+
+ case MatchType:
+ for ( PatternItemList::Iter item = *pattern->list; item.lte(); item++ ) {
+ switch ( item->form ) {
+ case PatternItem::TypeRefForm:
+ /* Use pdaFactor reference resolving. */
+ pd->resolveProdEl( item->prodEl );
+ break;
+ case PatternItem::InputTextForm:
+ /* Nothing to do here. */
+ break;
+ }
+ }
+
+ break;
+ case NewType:
+ expr->resolve( pd );
+ break;
+ case TypeIdType:
+ typeRef->resolveType( pd );
+ break;
+ case SearchType:
+ typeRef->resolveType( pd );
+ break;
+ case NilType:
+ case TrueType:
+ case FalseType:
+ break;
+
+ case ParseStopType:
+ case ParseType:
+ typeRef->resolveType( pd );
+ /* Evaluate the initialization expressions. */
+ if ( fieldInitArgs != 0 ) {
+ for ( FieldInitVect::Iter pi = *fieldInitArgs; pi.lte(); pi++ )
+ (*pi)->expr->resolve( pd );
+ }
+
+ for ( ConsItemList::Iter item = *parserText->list; item.lte(); item++ ) {
+ switch ( item->type ) {
+ case ConsItem::LiteralType:
+ pd->resolveProdEl( item->prodEl );
+ break;
+ case ConsItem::InputText:
+ case ConsItem::ExprType:
+ break;
+ }
+ }
+ break;
+
+ case SendType:
+ break;
+ case EmbedStringType:
+ break;
+ case CastType:
+ typeRef->resolveType( pd );
+ expr->resolve( pd );
+ break;
+ }
+}
+
+void LangVarRef::resolve( Compiler *pd ) const
+{
+}
+
+void LangExpr::resolve( Compiler *pd ) const
+{
+ switch ( type ) {
+ case BinaryType: {
+ left->resolve( pd );
+ right->resolve( pd );
+ break;
+ }
+ case UnaryType: {
+ right->resolve( pd );
+ break;
+ }
+ case TermType: {
+ term->resolve( pd );
+ break;
+ }
+ }
+}
+
+void IterCall::resolve( Compiler *pd ) const
+{
+ switch ( form ) {
+ case IterCallForm:
+ langTerm->resolve( pd );
+ break;
+ case VarRefForm:
+ case ExprForm:
+ langExpr->resolve( pd );
+ break;
+ }
+}
+
+void LangStmt::resolveForIter( Compiler *pd ) const
+{
+ iterCall->resolve( pd );
+
+ /* Search type ref. */
+ typeRef->resolveType( pd );
+
+ /* Iterator type ref. */
+ objField->typeRef->resolveType( pd );
+
+ /* Resolve the statements. */
+ for ( StmtList::Iter stmt = *stmtList; stmt.lte(); stmt++ )
+ stmt->resolve( pd );
+}
+
+void LangStmt::resolve( Compiler *pd ) const
+{
+ switch ( type ) {
+ case PrintType:
+ case PrintXMLACType:
+ case PrintXMLType:
+ case PrintStreamType: {
+ /* Push the args backwards. */
+ for ( CallArgVect::Iter pex = exprPtrVect->last(); pex.gtb(); pex-- )
+ (*pex)->expr->resolve( pd );
+ break;
+ }
+ case ExprType: {
+ /* Evaluate the exrepssion, then pop it immediately. */
+ expr->resolve( pd );
+ break;
+ }
+ case IfType: {
+ /* Evaluate the test. */
+ expr->resolve( pd );
+
+ /* Analyze the if true branch. */
+ for ( StmtList::Iter stmt = *stmtList; stmt.lte(); stmt++ )
+ stmt->resolve( pd );
+
+ if ( elsePart != 0 )
+ elsePart->resolve( pd );
+
+ break;
+ }
+ case ElseType: {
+ for ( StmtList::Iter stmt = *stmtList; stmt.lte(); stmt++ )
+ stmt->resolve( pd );
+ break;
+ }
+ case RejectType:
+ break;
+ case WhileType: {
+ expr->resolve( pd );
+
+ /* Compute the while block. */
+ for ( StmtList::Iter stmt = *stmtList; stmt.lte(); stmt++ )
+ stmt->resolve( pd );
+ break;
+ }
+ case AssignType: {
+ /* Evaluate the exrepssion. */
+ expr->resolve( pd );
+ break;
+ }
+ case ForIterType: {
+ resolveForIter( pd );
+ break;
+ }
+ case ReturnType: {
+ /* Evaluate the exrepssion. */
+ expr->resolve( pd );
+ break;
+ }
+ case BreakType: {
+ break;
+ }
+ case YieldType: {
+ /* take a reference and yield it. Immediately reset the referece. */
+ varRef->resolve( pd );
+ break;
+ }
+ }
+}
+
+void ObjectDef::resolve( Compiler *pd )
+{
+ for ( ObjFieldList::Iter fli = *objFieldList; fli.lte(); fli++ ) {
+ ObjectField *field = fli->value;
+
+ if ( field->typeRef != 0 )
+ field->typeRef->resolveType( pd );
+ }
+}
+
+void CodeBlock::resolve( Compiler *pd ) const
+{
+ if ( localFrame != 0 ) {
+ localFrame->resolve( pd );
+ }
+
+ for ( StmtList::Iter stmt = *stmtList; stmt.lte(); stmt++ )
+ stmt->resolve( pd );
+}
+
+void Compiler::resolveFunction( Function *func )
+{
+ if ( func->typeRef != 0 )
+ func->typeRef->resolveType( this );
+
+ for ( ParameterList::Iter param = *func->paramList; param.lte(); param++ )
+ param->typeRef->resolveType( this );
+
+ CodeBlock *block = func->codeBlock;
+ block->resolve( this );
+}
+
+void Compiler::resolvePreEof( TokenRegion *region )
+{
+ CodeBlock *block = region->preEofBlock;
+ block->resolve( this );
+}
+
+void Compiler::resolveRootBlock()
+{
+ CodeBlock *block = rootCodeBlock;
+ block->resolve( this );
+}
+
+void Compiler::resolveTranslateBlock( LangEl *langEl )
+{
+ CodeBlock *block = langEl->transBlock;
+ block->resolve( this );
+}
+
+void Compiler::resolveReductionCode( Production *prod )
+{
+ CodeBlock *block = prod->redBlock;
+ block->resolve( this );
+}
+
+void Compiler::resolveParseTree()
+{
+ /* Compile functions. */
+ for ( FunctionList::Iter f = functionList; f.lte(); f++ )
+ resolveFunction( f );
+
+ /* Compile the reduction code. */
+ for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
+ if ( prod->redBlock != 0 )
+ resolveReductionCode( prod );
+ }
+
+ /* Compile the token translation code. */
+ for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
+ if ( lel->transBlock != 0 )
+ resolveTranslateBlock( lel );
+ }
+
+ /* Compile preeof blocks. */
+ for ( RegionList::Iter r = regionList; r.lte(); r++ ) {
+ if ( r->preEofBlock != 0 )
+ resolvePreEof( r );
+ }
+
+ /* Compile the init code */
+ resolveRootBlock( );
+
+ rootLocalFrame->resolve( this );
+
+ /* Init all user object fields (need consistent size). */
+ for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
+ ObjectDef *objDef = lel->objectDef;
+ if ( objDef != 0 ) {
+ /* Init all fields of the object. */
+ for ( ObjFieldList::Iter f = *objDef->objFieldList; f.lte(); f++ ) {
+ f->value->typeRef->resolveType( this );
+ }
+ }
+ }
+
+ /* Init all fields of the global object. */
+ for ( ObjFieldList::Iter f = *globalObjectDef->objFieldList; f.lte(); f++ ) {
+ f->value->typeRef->resolveType( this );
+ }
+
+}
+
+/* Resolves production els and computes the precedence of each prod. */
+void Compiler::resolveProductionEls()
+{
+ /* NOTE: as we process this list it may be growing! */
+ for ( DefList::Iter prod = prodList; prod.lte(); prod++ ) {
+ /* First resolve. */
+ for ( ProdElList::Iter prodEl = *prod->prodElList; prodEl.lte(); prodEl++ )
+ resolveProdEl( prodEl );
+
+ /* If there is no explicit precdence ... */
+ if ( prod->predOf == 0 ) {
+ /* Compute the precedence of the productions. */
+ for ( ProdElList::Iter prodEl = prod->prodElList->last(); prodEl.gtb(); prodEl-- ) {
+ /* Production inherits the precedence of the last terminal with
+ * precedence. */
+ if ( prodEl->langEl->predType != PredNone ) {
+ prod->predOf = prodEl->langEl;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void Compiler::resolveGenericTypes()
+{
+ for ( NamespaceList::Iter ns = namespaceList; ns.lte(); ns++ ) {
+ for ( GenericList::Iter gen = ns->genericList; gen.lte(); gen++ ) {
+ gen->utArg = gen->typeArg->resolveType( this );
+
+ if ( gen->typeId == GEN_MAP )
+ gen->keyUT = gen->keyTypeArg->resolveType( this );
+ }
+ }
+}
+
+void Compiler::makeTerminalWrappers()
+{
+ /* Make terminal language elements corresponding to each nonterminal in
+ * the grammar. */
+ for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
+ if ( lel->type == LangEl::NonTerm ) {
+ String name( lel->name.length() + 5, "_T_%s", lel->name.data );
+ LangEl *termDup = new LangEl( lel->nspace, name, LangEl::Term );
+
+ /* Give the dup the attributes of the nonterminal. This ensures
+ * that the attributes are allocated when patterns and
+ * constructors are parsed. */
+ termDup->objectDef = lel->objectDef;
+
+ langEls.append( termDup );
+ lel->termDup = termDup;
+ termDup->termDup = lel;
+ }
+ }
+}
+
+void Compiler::makeEofElements()
+{
+ /* Make eof language elements for each user terminal. This is a bit excessive and
+ * need to be reduced to the ones that we need parsers for, but we don't know that yet.
+ * Another pass before this one is needed. */
+ for ( LelList::Iter lel = langEls; lel.lte(); lel++ ) {
+ if ( lel->eofLel == 0 &&
+ lel != eofLangEl &&
+ lel != errorLangEl &&
+ lel != noTokenLangEl /* &&
+ !( lel->tokenInstance == 0 || lel->tokenInstance->dupOf == 0 ) */ )
+ {
+ String name( lel->name.length() + 5, "_eof_%s", lel->name.data );
+ LangEl *eofLel = new LangEl( lel->nspace, name, LangEl::Term );
+
+ langEls.append( eofLel );
+ lel->eofLel = eofLel;
+ eofLel->eofLel = lel;
+ eofLel->isEOF = true;
+ }
+ }
+}
+
+void Compiler::resolvePrecedence()
+{
+ for ( PredDeclList::Iter predDecl = predDeclList; predDecl != 0; predDecl++ ) {
+ predDecl->typeRef->resolveType( this );
+
+ LangEl *langEl = predDecl->typeRef->uniqueType->langEl;
+ langEl->predType = predDecl->predType;
+ langEl->predValue = predDecl->predValue;
+ }
+}
+
+
+void Compiler::resolvePass()
+{
+ /*
+ * Type Resolving.
+ */
+
+ resolvePrecedence();
+
+ resolveParseTree();
+
+ resolveGenericTypes();
+
+ argvTypeRef->resolveType( this );
+
+ /* We must do this as the last step in the type resolution process because
+ * all type resolves can cause new language elments with associated
+ * productions. They get tacked onto the end of the list of productions.
+ * Doing it at the end results processing a growing list. */
+ resolveProductionEls();
+}