diff options
author | Adrian Thurston <thurston@complang.org> | 2015-01-16 21:42:16 -0500 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-01-16 21:42:16 -0500 |
commit | 1a426568f512691be1c16ef06ea7f156f9002f6e (patch) | |
tree | 628b971c3e8341faf6c7d6eadef758a12258587c /src | |
parent | c5967897c8a900c10770d4b5ec77cb84cb0c5556 (diff) | |
download | colm-1a426568f512691be1c16ef06ea7f156f9002f6e.tar.gz |
some work on the object-based map generic
Diffstat (limited to 'src')
-rw-r--r-- | src/colm.lm | 4 | ||||
-rw-r--r-- | src/loadcolm.cc | 49 | ||||
-rw-r--r-- | src/parsetree.h | 1 | ||||
-rw-r--r-- | src/resolve.cc | 44 |
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 ); |