summaryrefslogtreecommitdiff
path: root/src/lookup.cc
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2013-12-31 12:26:15 -0500
committerAdrian Thurston <thurston@complang.org>2013-12-31 12:26:15 -0500
commit2c360862405ecaeb5ad99b506bddc85960fdf269 (patch)
tree4fe6dbaf0c8b4faa2570f2622889c674b532fb6e /src/lookup.cc
parent415c21f86d1d0b7ff49932b4b61251870e7400fb (diff)
downloadcolm-2c360862405ecaeb5ad99b506bddc85960fdf269.tar.gz
some code movement from synthesis to lookup
Diffstat (limited to 'src/lookup.cc')
-rw-r--r--src/lookup.cc131
1 files changed, 131 insertions, 0 deletions
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;
+}
+