From 2c360862405ecaeb5ad99b506bddc85960fdf269 Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Tue, 31 Dec 2013 12:26:15 -0500 Subject: some code movement from synthesis to lookup --- src/lookup.cc | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'src/lookup.cc') diff --git a/src/lookup.cc b/src/lookup.cc index 2c6dd9ea..a157ba90 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -29,6 +29,18 @@ using std::cout; using std::cerr; using std::endl; +ObjectDef *objDefFromUT( Compiler *pd, UniqueType *ut ) +{ + ObjectDef *objDef = 0; + if ( ut->typeId == TYPE_TREE || ut->typeId == TYPE_REF ) + objDef = ut->langEl->objectDef; + else { + /* This should have generated a compiler error. */ + assert(false); + } + return objDef; +} + /* Recurisve find through a single object def's scope. */ ObjectField *ObjectDef::findFieldInScope( const String &name, ObjNameScope *inScope ) { @@ -49,6 +61,95 @@ ObjectField *ObjectDef::findField( const String &name ) return 0; } +ObjMethod *ObjectDef::findMethod( const String &name ) +{ + ObjMethodMapEl *objMethodMapEl = objMethodMap->find( name ); + if ( objMethodMapEl != 0 ) + return objMethodMapEl->value; + return 0; +} + +VarRefLookup LangVarRef::lookupQualification( Compiler *pd, ObjectDef *rootDef ) const +{ + int lastPtrInQual = -1; + ObjectDef *searchObjDef = rootDef; + int firstConstPart = -1; + + for ( QualItemVect::Iter qi = *qual; qi.lte(); qi++ ) { + /* Lookup the field int the current qualification. */ + ObjectField *el = searchObjDef->findField( qi->data ); + if ( el == 0 ) + error(qi->loc) << "cannot resolve qualification " << qi->data << endp; + + /* Lookup the type of the field. */ + UniqueType *qualUT = el->typeRef->uniqueType; + + /* If we are dealing with an iterator then dereference it. */ + if ( qualUT->typeId == TYPE_ITER ) + qualUT = el->typeRef->searchUniqueType; + + /* Is it const? */ + if ( firstConstPart < 0 && el->isConst ) + firstConstPart = qi.pos(); + + /* Check for references. When loop is done we will have the last one + * present, if any. */ + if ( qualUT->typeId == TYPE_PTR ) + lastPtrInQual = qi.pos(); + + if ( qi->form == QualItem::Dot ) { + /* Cannot dot a reference. Iterator yes (access of the iterator + * not the current) */ + if ( qualUT->typeId == TYPE_PTR ) + error(loc) << "dot cannot be used to access a pointer" << endp; + } + else if ( qi->form == QualItem::Arrow ) { + if ( qualUT->typeId == TYPE_ITER ) + qualUT = el->typeRef->searchUniqueType; + else if ( qualUT->typeId == TYPE_PTR ) + qualUT = pd->findUniqueType( TYPE_TREE, qualUT->langEl ); + } + + searchObjDef = objDefFromUT( pd, qualUT ); + } + + return VarRefLookup( lastPtrInQual, firstConstPart, searchObjDef ); +} + + +VarRefLookup LangVarRef::lookupObj( Compiler *pd ) const +{ + ObjectDef *rootDef; + if ( isLocalRef( pd ) ) + rootDef = pd->curLocalFrame; + else if ( isContextRef( pd ) ) + rootDef = pd->context->contextObjDef; + else + rootDef = pd->globalObjectDef; + + return lookupQualification( pd, rootDef ); +} + +VarRefLookup LangVarRef::lookupField( Compiler *pd ) const +{ + /* Lookup the object that the field is in. */ + VarRefLookup lookup = lookupObj( pd ); + + /* Lookup the field. */ + ObjectField *field = lookup.inObject->findField( name ); + if ( field == 0 ) + error(loc) << "cannot find name " << name << " in object" << endp; + + lookup.objField = field; + lookup.uniqueType = field->typeRef->uniqueType; + + if ( field->typeRef->searchUniqueType != 0 ) + lookup.iterSearchUT = field->typeRef->searchUniqueType; + + return lookup; +} + + UniqueType *LangVarRef::lookup( Compiler *pd ) const { /* Lookup the loadObj. */ @@ -64,3 +165,33 @@ UniqueType *LangVarRef::lookup( Compiler *pd ) const return elUT; } + +VarRefLookup LangVarRef::lookupMethod( Compiler *pd ) +{ + /* Lookup the object that the field is in. */ + VarRefLookup lookup = lookupObj( pd ); + + /* Find the method. */ + assert( lookup.inObject->objMethodMap != 0 ); + ObjMethod *method = lookup.inObject->findMethod( name ); + if ( method == 0 ) { + /* Not found as a method, try it as an object on which we will call a + * default function. */ + qual->append( QualItem( QualItem::Dot, loc, name ) ); + + /* Lookup the object that the field is in. */ + VarRefLookup lookup = lookupObj( pd ); + + /* Find the method. */ + assert( lookup.inObject->objMethodMap != 0 ); + method = lookup.inObject->findMethod( "finish" ); + if ( method == 0 ) + error(loc) << "cannot find " << name << "(...) in object" << endp; + } + + lookup.objMethod = method; + lookup.uniqueType = method->returnUT; + + return lookup; +} + -- cgit v1.2.1