summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-01-16 21:42:16 -0500
committerAdrian Thurston <thurston@complang.org>2015-01-16 21:42:16 -0500
commit1a426568f512691be1c16ef06ea7f156f9002f6e (patch)
tree628b971c3e8341faf6c7d6eadef758a12258587c /src
parentc5967897c8a900c10770d4b5ec77cb84cb0c5556 (diff)
downloadcolm-1a426568f512691be1c16ef06ea7f156f9002f6e.tar.gz
some work on the object-based map generic
Diffstat (limited to 'src')
-rw-r--r--src/colm.lm4
-rw-r--r--src/loadcolm.cc49
-rw-r--r--src/parsetree.h1
-rw-r--r--src/resolve.cc44
4 files changed, 79 insertions, 19 deletions
diff --git a/src/colm.lm b/src/colm.lm
index d1323245..f354703e 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -560,9 +560,9 @@ def code_factor
def type_ref
[region_qual id opt_repeat] :Id
-| [LIST LT type_ref GT] :List
-| [MAP LT MapKeyType: type_ref MapValueType: type_ref GT] :Map
| [PARSER LT type_ref GT] :Parser
+| [LIST LT type_ref GT] :List
+| [MAP LT KeyType: type_ref ElType: type_ref GT] :Map
def region_qual
[region_qual id DOUBLE_COLON] :Qual
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index fbb0947c..07da8e01 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -749,8 +749,7 @@ struct LoadColm
*/
NamespaceQual *nspaceQual = NamespaceQual::cons( curNspace() );
String id = curStruct()->objectDef->name;
- RepeatType repeatType = RepeatNone;
- TypeRef *objTr = TypeRef::cons( InputLoc(), nspaceQual, id, repeatType );
+ TypeRef *objTr = TypeRef::cons( InputLoc(), nspaceQual, id, RepeatNone );
TypeRef *elTr = TypeRef::cons( InputLoc(), TypeRef::ListEl, 0, objTr, 0 );
ObjectField *of = ObjectField::cons( InputLoc(),
@@ -760,6 +759,33 @@ struct LoadColm
void walkMapElDef( map_el_def Def )
{
+ /*
+ * The unique type. This is a def with a single empty form.
+ */
+ String name = Def.id().data();
+ ObjectDef *objectDef = ObjectDef::cons( ObjectDef::UserType,
+ name, pd->nextObjectId++ );
+
+ LelDefList *defList = new LelDefList;
+
+ Production *prod = BaseParser::production( InputLoc(),
+ new ProdElList, String(), false, 0, 0 );
+ prodAppend( defList, prod );
+
+ NtDef *ntDef = NtDef::cons( name, curNspace(), curStruct(), false );
+ BaseParser::cflDef( ntDef, objectDef, defList );
+
+ /*
+ * List element with the same name as containing context.
+ */
+ NamespaceQual *nspaceQual = NamespaceQual::cons( curNspace() );
+ String id = curStruct()->objectDef->name;
+ TypeRef *objTr = TypeRef::cons( InputLoc(), nspaceQual, id, RepeatNone );
+ TypeRef *elTr = TypeRef::cons( InputLoc(), TypeRef::MapEl, 0, objTr, 0 );
+
+ ObjectField *of = ObjectField::cons( InputLoc(),
+ ObjectField::UserFieldType, elTr, name );
+ structVarDef( InputLoc(), of );
}
@@ -848,23 +874,22 @@ struct LoadColm
tr = TypeRef::cons( typeRef.id().loc(), nspaceQual, id, repeatType );
break;
}
+ case type_ref::Parser: {
+ TypeRef *type = walkTypeRef( typeRef._type_ref() );
+ tr = TypeRef::cons( typeRef.loc(), TypeRef::Parser, 0, type, 0 );
+ break;
+ }
case type_ref::List: {
TypeRef *type = walkTypeRef( typeRef._type_ref() );
tr = TypeRef::cons( typeRef.loc(), TypeRef::List, 0, type, 0 );
break;
}
case type_ref::Map: {
- TypeRef *key = walkTypeRef( typeRef.MapKeyType() );
- TypeRef *value = walkTypeRef( typeRef.MapValueType() );
- tr = TypeRef::cons( typeRef.loc(), TypeRef::Map, 0, key, value );
+ TypeRef *keyType = walkTypeRef( typeRef.KeyType() );
+ TypeRef *elType = walkTypeRef( typeRef.ElType() );
+ tr = TypeRef::cons( typeRef.loc(), TypeRef::Map, 0, keyType, elType );
break;
- }
- case type_ref::Parser: {
- TypeRef *type = walkTypeRef( typeRef._type_ref() );
- tr = TypeRef::cons( typeRef.loc(), TypeRef::Parser, 0, type, 0 );
- break;
- }
- }
+ }}
return tr;
}
diff --git a/src/parsetree.h b/src/parsetree.h
index f63e453a..59c04e9d 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -728,6 +728,7 @@ struct GenericType
UniqueType *keyUT;
ObjectDef *objDef;
ObjectField *el;
+ ObjectField *keyEl;
long elOffset;
};
diff --git a/src/resolve.cc b/src/resolve.cc
index af36f6c8..3e0ca899 100644
--- a/src/resolve.cc
+++ b/src/resolve.cc
@@ -175,9 +175,42 @@ UniqueType *TypeRef::resolveTypeMap( Compiler *pd )
nspace = pd->rootNamespace;
UniqueType *utKey = typeRef1->resolveType( pd );
- UniqueType *utValue = typeRef2->resolveType( pd );
+ UniqueType *utEl = typeRef2->resolveType( pd );
- UniqueGeneric searchKey( UniqueGeneric::Map, utKey, utValue );
+ if ( utEl->typeId != TYPE_STRUCT )
+ error( loc ) << "only structs can be map elements" << endp;
+
+ /* Find the list element. */
+ ObjectField *mapEl = 0;
+ FieldList *fieldList = utEl->structEl->structDef->objectDef->fieldList;
+ for ( FieldList::Iter f = *fieldList; f.lte(); f++ ) {
+ UniqueType *fUT = f->value->typeRef->resolveType( pd );
+ if ( fUT->typeId == TYPE_GENERIC && fUT->generic != 0 &&
+ fUT->generic->typeId == GEN_MAP_EL )
+ {
+ mapEl = f->value;
+ break;
+ }
+ }
+
+ /* Find the key field (named Key). */
+ ObjectField *keyEl = 0;
+ fieldList = utEl->structEl->structDef->objectDef->fieldList;
+ for ( FieldList::Iter f = *fieldList; f.lte(); f++ ) {
+ UniqueType *fUT = f->value->typeRef->resolveType( pd );
+ if ( fUT->typeId == TYPE_TREE && strcmp( f->value->name, "Key" ) == 0 ) {
+ keyEl = f->value;
+ break;
+ }
+ }
+
+ if ( !mapEl )
+ error( loc ) << "could not find list element in type ref" << endp;
+
+ if ( !keyEl )
+ error( loc ) << "could not find Key in type ref" << endp;
+
+ UniqueGeneric searchKey( UniqueGeneric::Map, utKey, utEl );
UniqueGeneric *inMap = pd->uniqueGenericMap.find( &searchKey );
if ( inMap == 0 ) {
inMap = new UniqueGeneric( searchKey );
@@ -186,6 +219,8 @@ UniqueType *TypeRef::resolveTypeMap( Compiler *pd )
GenericType *generic = new GenericType( GEN_MAP,
pd->nextGenericId++, typeRef2 );
generic->keyTypeArg = typeRef1;
+ generic->el = mapEl;
+ generic->keyEl = mapEl;
nspace->genericList.append( generic );
@@ -202,10 +237,9 @@ UniqueType *TypeRef::resolveTypeMapEl( Compiler *pd )
{
nspace = pd->rootNamespace;
- UniqueType *utKey = typeRef1->resolveType( pd );
- UniqueType *utValue = typeRef2->resolveType( pd );
+ UniqueType *utValue = typeRef1->resolveType( pd );
- UniqueGeneric searchKey( UniqueGeneric::MapEl, utKey, utValue );
+ UniqueGeneric searchKey( UniqueGeneric::MapEl, utValue );
UniqueGeneric *inMap = pd->uniqueGenericMap.find( &searchKey );
if ( inMap == 0 ) {
inMap = new UniqueGeneric( searchKey );