diff options
author | Adrian Thurston <thurston@complang.org> | 2015-06-07 15:35:02 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-06-07 15:35:02 -0400 |
commit | 9ed46192f42837b4c066b5e1ebf859c9f5070106 (patch) | |
tree | a6b04026c8a95a344fae7abe96058666d2a9397e | |
parent | c158a685a7bad2c4d06b4c160704b6913f5e70bf (diff) | |
download | colm-9ed46192f42837b4c066b5e1ebf859c9f5070106.tar.gz |
now creating list and map el structures in the declare pass
-rw-r--r-- | src/declare.cc | 12 | ||||
-rw-r--r-- | src/loadcolm.cc | 101 | ||||
-rw-r--r-- | src/parser.cc | 32 | ||||
-rw-r--r-- | src/parsetree.cc | 44 | ||||
-rw-r--r-- | src/parsetree.h | 39 | ||||
-rw-r--r-- | src/resolve.cc | 146 | ||||
-rw-r--r-- | src/synthesis.cc | 8 |
7 files changed, 190 insertions, 192 deletions
diff --git a/src/declare.cc b/src/declare.cc index 8a85a4c3..725930f1 100644 --- a/src/declare.cc +++ b/src/declare.cc @@ -252,6 +252,8 @@ StructEl *declareStruct( Compiler *pd, Namespace *inNspace, if ( structDef->listEl ) structEl->listEl = true; + if ( structDef->mapEl ) + structEl->mapEl = true; if ( inNspace ) { TypeMapEl *typeMapEl = new TypeMapEl( TypeMapEl::StructType, data, structEl ); @@ -430,12 +432,8 @@ void Namespace::declare( Compiler *pd ) } } - for ( StructDefList::Iter s = structDefList; s.lte(); s++ ) { - StructEl *sel = declareStruct( pd, this, s->name, s ); - if ( s == pd->argvEl ) - pd->argvElSel = sel; - - } + for ( StructDefList::Iter s = structDefList; s.lte(); s++ ) + declareStruct( pd, this, s->name, s ); for ( TokenDefListNs::Iter tokenDef = tokenDefList; tokenDef.lte(); tokenDef++ ) { /* Literals already taken care of. */ @@ -731,8 +729,6 @@ void Compiler::makeDefaultIterators() objMethod->iterDef = triter; } - - /* Map iterator. */ { UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl ); diff --git a/src/loadcolm.cc b/src/loadcolm.cc index 6071beea..027ffedb 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -826,91 +826,25 @@ struct LoadColm TypeRef *walkValueList( type_ref typeRef ) { TypeRef *valType = walkTypeRef( typeRef._type_ref() ); - - /* Create the value list element. */ - String name( 32, "vlist_el_%s", valType->stringify().c_str() ); - - if ( !genericElDefined.find( name ) ) { - genericElDefined.insert( name ); - - structHead( internal, pd->rootNamespace, name, ObjectDef::StructType ); - - /* Var def. */ - String id = "value"; - ObjectField *elValObjField = ObjectField::cons( internal, - ObjectField::StructFieldType, valType, id ); - structVarDef( internal, elValObjField ); - elValObjField->context->listEl = true; - - /* List El. */ - listElDef( "el" ); - - structStack.pop(); - namespaceStack.pop(); - } - - TypeRef *elType = TypeRef::cons( typeRef.loc(), emptyNspaceQual(), name ); + TypeRef *elType = TypeRef::cons( typeRef.loc(), TypeRef::ListEl, valType ); return TypeRef::cons( typeRef.loc(), TypeRef::List, 0, elType, valType ); } TypeRef *walkListEl( type_ref typeRef ) { TypeRef *valType = walkTypeRef( typeRef._type_ref() ); - - /* Create the value list element. */ - String name( 32, "vlist_el_%s", valType->stringify().c_str() ); - - if ( !genericElDefined.find( name ) ) { - genericElDefined.insert( name ); - - structHead( internal, pd->rootNamespace, name, ObjectDef::StructType ); - - /* Var def. */ - String id = "value"; - ObjectField *elValObjField = ObjectField::cons( internal, - ObjectField::StructFieldType, valType, id ); - structVarDef( internal, elValObjField ); - elValObjField->context->listEl = true; - - /* List El. */ - listElDef( "el" ); - - structStack.pop(); - namespaceStack.pop(); - } - - return TypeRef::cons( typeRef.loc(), emptyNspaceQual(), name ); + return TypeRef::cons( typeRef.loc(), TypeRef::ListEl, valType ); } TypeRef *walkValueMap( type_ref typeRef ) { TypeRef *keyType = walkTypeRef( typeRef.KeyType() ); TypeRef *valType = walkTypeRef( typeRef.ValType() ); + TypeRef *elType = TypeRef::cons( typeRef.loc(), + TypeRef::MapEl, 0, keyType, valType ); - String name( 32, "vmap_el_%s_%s", keyType->stringify().c_str(), - valType->stringify().c_str() ); - - if ( !genericElDefined.find( name ) ) { - genericElDefined.insert( name ); - - structHead( internal, pd->rootNamespace, name, ObjectDef::StructType ); - - /* Var def. */ - String id = "value"; - ObjectField *elValObjField = ObjectField::cons( internal, - ObjectField::StructFieldType, valType, id ); - structVarDef( internal, elValObjField ); - - /* Map El. */ - mapElDef( "el", keyType ); - - structStack.pop(); - namespaceStack.pop(); - } - - TypeRef *elType = TypeRef::cons( typeRef.loc(), emptyNspaceQual(), name ); - - return TypeRef::cons( typeRef.loc(), TypeRef::Map, 0, keyType, elType, valType ); + return TypeRef::cons( typeRef.loc(), TypeRef::Map, 0, + keyType, elType, valType ); } TypeRef *walkMapEl( type_ref typeRef ) @@ -918,28 +852,7 @@ struct LoadColm TypeRef *keyType = walkTypeRef( typeRef.KeyType() ); TypeRef *valType = walkTypeRef( typeRef.ValType() ); - String name( 32, "vmap_el_%s_%s", keyType->stringify().c_str(), - valType->stringify().c_str() ); - - if ( !genericElDefined.find( name ) ) { - genericElDefined.insert( name ); - - structHead( internal, pd->rootNamespace, name, ObjectDef::StructType ); - - /* Var def. */ - String id = "value"; - ObjectField *elValObjField = ObjectField::cons( internal, - ObjectField::StructFieldType, valType, id ); - structVarDef( internal, elValObjField ); - - /* Map El. */ - mapElDef( "el", keyType ); - - structStack.pop(); - namespaceStack.pop(); - } - - return TypeRef::cons( typeRef.loc(), emptyNspaceQual(), name ); + return TypeRef::cons( typeRef.loc(), TypeRef::MapEl, 0, keyType, valType ); } TypeRef *walkTypeRef( type_ref typeRef ) diff --git a/src/parser.cc b/src/parser.cc index 5d4775aa..dc4d4576 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -423,36 +423,8 @@ void BaseParser::literalDef( const InputLoc &loc, const String &data, void BaseParser::addArgvList() { TypeRef *valType = TypeRef::cons( internal, pd->uniqueTypeStr ); - - /* Create the value list element. */ - String name( 32, "vlist_el_%s", valType->stringify().c_str() ); - - if ( !genericElDefined.find( name ) ) { - genericElDefined.insert( name ); - - structHead( internal, pd->rootNamespace, name, ObjectDef::StructType ); - - /* Var def. */ - String id = "value"; - ObjectField *elValObjField = ObjectField::cons( internal, - ObjectField::StructFieldType, valType, id ); - structVarDef( internal, elValObjField ); - - pd->argvEl = elValObjField->context; - elValObjField->context->listEl = true; - - /* List El. */ - listElDef( "el" ); - - structStack.pop(); - namespaceStack.pop(); - } - - TypeRef *elType = TypeRef::cons( internal, - emptyNspaceQual(), name ); - - pd->argvTypeRef = TypeRef::cons( internal, - TypeRef::List, 0, elType, valType ); + TypeRef *elType = TypeRef::cons( internal, TypeRef::ListEl, valType ); + pd->argvTypeRef = TypeRef::cons( internal, TypeRef::List, 0, elType, valType ); } ObjectDef *BaseParser::blockOpen() diff --git a/src/parsetree.cc b/src/parsetree.cc index 6f6758de..7a6f131d 100644 --- a/src/parsetree.cc +++ b/src/parsetree.cc @@ -37,48 +37,6 @@ ostream &operator<<( ostream &out, const NameRef &nameRef ); ostream &operator<<( ostream &out, const NameInst &nameInst ); ostream &operator<<( ostream &out, const Token &token ); -string TypeRef::stringify() -{ - string s; - switch ( type ) { - case Unspecified: { - if ( uniqueType->typeId == TYPE_INT ) - s = "int"; - else - s = "unspecified"; - break; - } - case Name: - s = typeName; - break; - case Literal: - s = "literal"; - break; - case Iterator: - s = "iterator"; - break; - case List: - s = "list"; - break; - case ListPtrs: - s = "list_ptrs"; - break; - case Map: - s = "map"; - break; - case MapPtrs: - s = "map_ptrs"; - break; - case Parser: - s = "parser"; - break; - case Ref: - s = "ref"; - break; - } - return s; -} - /* Convert the literal string which comes in from the scanner into an array of * characters with escapes and options interpreted. Also null terminates the * string. Though this null termination should not be relied on for @@ -214,11 +172,13 @@ int CmpUniqueGeneric::compare( const UniqueGeneric &ut1, const UniqueGeneric &ut switch ( ut1.type ) { case UniqueGeneric::List: case UniqueGeneric::ListPtrs: + case UniqueGeneric::ListEl: case UniqueGeneric::Parser: break; case UniqueGeneric::Map: case UniqueGeneric::MapPtrs: + case UniqueGeneric::MapEl: if ( ut1.key < ut2.key ) return -1; else if ( ut1.key > ut2.key ) diff --git a/src/parsetree.h b/src/parsetree.h index dece2439..a7751ca0 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -555,7 +555,8 @@ struct StructDef name(name), objectDef(objectDef), structEl(0), - listEl(false) + listEl(false), + mapEl(false) {} InputLoc loc; @@ -563,6 +564,7 @@ struct StructDef ObjectDef *objectDef; StructEl *structEl; bool listEl; + bool mapEl; StructDef *prev, *next; }; @@ -574,13 +576,15 @@ struct StructEl name(name), structDef(structDef), id(-1), - listEl(false) + listEl(false), + mapEl(false) {} String name; StructDef *structDef; int id; bool listEl; + bool mapEl; StructEl *prev, *next; }; @@ -1955,21 +1959,37 @@ struct UniqueGeneric { List, ListPtrs, + ListEl, Map, MapPtrs, + MapEl, Parser }; - UniqueGeneric( Type type, UniqueType *value ) : - type(type), key(0), value(value), generic(0) {} + UniqueGeneric( Type type, UniqueType *value ) + : + type(type), + key(0), + value(value), + generic(0), + structEl(0) + {} - UniqueGeneric( Type type, UniqueType *key, UniqueType *value ) : - type(type), key(key), value(value), generic(0) {} + UniqueGeneric( Type type, UniqueType *key, UniqueType *value ) + : + type(type), + key(key), + value(value), + generic(0), + structEl(0) + {} Type type; UniqueType *key; UniqueType *value; + GenericType *generic; + StructEl *structEl; }; struct CmpUniqueGeneric @@ -1980,7 +2000,6 @@ struct CmpUniqueGeneric typedef AvlBasic< UniqueGeneric, CmpUniqueGeneric > UniqueGenericMap; - /* * */ @@ -2000,7 +2019,9 @@ struct TypeRef Iterator, List, ListPtrs, + ListEl, Map, + MapEl, MapPtrs, Parser, Ref @@ -2187,8 +2208,10 @@ struct TypeRef UniqueType *resolveTypeLiteral( Compiler *pd ); UniqueType *resolveTypeList( Compiler *pd ); UniqueType *resolveTypeListPtrs( Compiler *pd ); + UniqueType *resolveTypeListEl( Compiler *pd ); UniqueType *resolveTypeMap( Compiler *pd ); UniqueType *resolveTypeMapPtrs( Compiler *pd ); + UniqueType *resolveTypeMapEl( Compiler *pd ); UniqueType *resolveTypeParser( Compiler *pd ); UniqueType *resolveType( Compiler *pd ); UniqueType *resolveTypeRef( Compiler *pd ); @@ -2215,8 +2238,6 @@ struct TypeRef UniqueType *searchUniqueType; GenericType *generic; TypeRef *searchTypeRef; - - std::string stringify(); }; typedef DList<ObjectField> ParameterList; diff --git a/src/resolve.cc b/src/resolve.cc index 947231e2..94bc76c3 100644 --- a/src/resolve.cc +++ b/src/resolve.cc @@ -189,6 +189,65 @@ UniqueType *TypeRef::resolveTypeListPtrs( Compiler *pd ) return pd->findUniqueType( TYPE_GENERIC, inMap->generic ); } +UniqueType *TypeRef::resolveTypeListEl( Compiler *pd ) +{ + UniqueType *utValue = typeRef1->resolveType( pd ); + + UniqueGeneric searchKey( UniqueGeneric::ListEl, utValue ); + UniqueGeneric *inMap = pd->uniqueGenericMap.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueGeneric( searchKey ); + pd->uniqueGenericMap.insert( inMap ); + + static long vlistElId = 1; + String name( 32, "vlist_el_%d", vlistElId++ ); + ObjectDef *objectDef = ObjectDef::cons( ObjectDef::StructType, + name, pd->nextObjectId++ ); + + StructDef *structDef = new StructDef( loc, name, objectDef ); + + pd->rootNamespace->structDefList.append( structDef ); + + /* Make the new namespace. */ + Namespace *nspace = new Namespace( loc, name, + pd->namespaceList.length(), pd->rootNamespace ); + + pd->rootNamespace->childNamespaces.append( nspace ); + + pd->namespaceList.append( nspace ); + + + /* Value Element. */ + String id = "value"; + ObjectField *elValObjField = ObjectField::cons( internal, + ObjectField::StructFieldType, typeRef1, id ); + + elValObjField->context = structDef; + objectDef->rootScope->insertField( elValObjField->name, elValObjField ); + + elValObjField->context->listEl = true; + + /* List element with the same name as containing context. */ + NamespaceQual *nspaceQual = NamespaceQual::cons( nspace ); + TypeRef *objTr = TypeRef::cons( InputLoc(), nspaceQual, name, RepeatNone ); + TypeRef *elTr = TypeRef::cons( InputLoc(), TypeRef::ListPtrs, 0, objTr, 0 ); + + ObjectField *of = ObjectField::cons( InputLoc(), + ObjectField::GenericElementType, elTr, name ); + + of->context = structDef; + objectDef->rootScope->insertField( of->name, of ); + + /* Note this is recurse, all of above must complete. */ + //structDef->declare( pd, nspace ); + + StructEl *sel = declareStruct( pd, pd->rootNamespace, name, structDef ); + inMap->structEl = sel; + } + + return pd->findUniqueType( TYPE_STRUCT, inMap->structEl ); +} + UniqueType *TypeRef::resolveTypeMapPtrs( Compiler *pd ) { nspace = pd->rootNamespace; @@ -215,6 +274,70 @@ UniqueType *TypeRef::resolveTypeMapPtrs( Compiler *pd ) return pd->findUniqueType( TYPE_GENERIC, inMap->generic ); } +UniqueType *TypeRef::resolveTypeMapEl( Compiler *pd ) +{ + TypeRef *keyType = typeRef1; + TypeRef *valType = typeRef2; + + UniqueType *utKey = keyType->resolveType( pd ); + UniqueType *utValue = valType->resolveType( pd ); + + UniqueGeneric searchKey( UniqueGeneric::MapEl, utKey, utValue ); + UniqueGeneric *inMap = pd->uniqueGenericMap.find( &searchKey ); + if ( inMap == 0 ) { + inMap = new UniqueGeneric( searchKey ); + pd->uniqueGenericMap.insert( inMap ); + + static long vlistElId = 1; + String name( 32, "map_el_%d", vlistElId++ ); + ObjectDef *objectDef = ObjectDef::cons( ObjectDef::StructType, + name, pd->nextObjectId++ ); + + StructDef *structDef = new StructDef( loc, name, objectDef ); + + pd->rootNamespace->structDefList.append( structDef ); + + /* Make the new namespace. */ + Namespace *nspace = new Namespace( loc, name, + pd->namespaceList.length(), pd->rootNamespace ); + + pd->rootNamespace->childNamespaces.append( nspace ); + + pd->namespaceList.append( nspace ); + + + /* Value Element. */ + String id = "value"; + ObjectField *elValObjField = ObjectField::cons( internal, + ObjectField::StructFieldType, valType, id ); + + elValObjField->context = structDef; + objectDef->rootScope->insertField( elValObjField->name, elValObjField ); + + elValObjField->context->mapEl = true; + + /* List element with the same name as containing context. */ + NamespaceQual *nspaceQual = NamespaceQual::cons( nspace ); + TypeRef *objTr = TypeRef::cons( InputLoc(), nspaceQual, name, RepeatNone ); + TypeRef *elTr = TypeRef::cons( InputLoc(), TypeRef::MapPtrs, 0, objTr, keyType ); + + ObjectField *of = ObjectField::cons( InputLoc(), + ObjectField::GenericElementType, elTr, name ); + + of->context = structDef; + objectDef->rootScope->insertField( of->name, of ); + + /* Note this is recurse, all of above must complete. */ + //structDef->declare( pd, nspace ); + + StructEl *sel = declareStruct( pd, pd->rootNamespace, name, structDef ); + inMap->structEl = sel; + } + + return pd->findUniqueType( TYPE_STRUCT, inMap->structEl ); +} + + UniqueType *TypeRef::resolveTypeMap( Compiler *pd ) { nspace = pd->rootNamespace; @@ -381,12 +504,6 @@ UniqueType *TypeRef::resolveType( Compiler *pd ) case Literal: uniqueType = resolveTypeLiteral( pd ); break; - case ListPtrs: - uniqueType = resolveTypeListPtrs( pd ); - break; - case MapPtrs: - uniqueType = resolveTypeMapPtrs( pd ); - break; case Parser: uniqueType = resolveTypeParser( pd ); break; @@ -396,12 +513,26 @@ UniqueType *TypeRef::resolveType( Compiler *pd ) case Iterator: uniqueType = resolveIterator( pd ); break; + case List: uniqueType = resolveTypeList( pd ); break; + case ListPtrs: + uniqueType = resolveTypeListPtrs( pd ); + break; + case ListEl: + uniqueType = resolveTypeListEl( pd ); + break; + case Map: uniqueType = resolveTypeMap( pd ); break; + case MapPtrs: + uniqueType = resolveTypeMapPtrs( pd ); + break; + case MapEl: + uniqueType = resolveTypeMapEl( pd ); + break; case Unspecified: /* No lookup needed, unique type(s) set when constructed. */ @@ -859,7 +990,8 @@ void Compiler::resolvePass() resolveParseTree(); - argvTypeRef->resolveType( this ); + UniqueType *argvUT = argvTypeRef->resolveType( this ); + argvElSel = argvUT->generic->elUt->structEl; /* We must do this as the last step in the type resolution process because * all type resolves can cause new language elments with associated diff --git a/src/synthesis.cc b/src/synthesis.cc index dccfe333..6bdd3ec4 100644 --- a/src/synthesis.cc +++ b/src/synthesis.cc @@ -851,8 +851,12 @@ IterImpl *LangVarRef::chooseTriterCall( Compiler *pd, if ( exprUT->typeId == TYPE_GENERIC && exprUT->generic->typeId == GEN_MAP ) iterImpl = new IterImpl( IterImpl::Map ); - if ( exprUT->typeId == TYPE_GENERIC && exprUT->generic->typeId == GEN_VMAP ) - iterImpl = new IterImpl( IterImpl::ValueMap ); + if ( exprUT->typeId == TYPE_GENERIC && exprUT->generic->typeId == GEN_VMAP ) { + if ( searchUT->structEl != 0 && searchUT->structEl->mapEl ) + iterImpl = new IterImpl( IterImpl::Map ); + else + iterImpl = new IterImpl( IterImpl::ValueMap ); + } } if ( iterImpl == 0 ) |