summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-06-07 15:35:02 -0400
committerAdrian Thurston <thurston@complang.org>2015-06-07 15:35:02 -0400
commit9ed46192f42837b4c066b5e1ebf859c9f5070106 (patch)
treea6b04026c8a95a344fae7abe96058666d2a9397e
parentc158a685a7bad2c4d06b4c160704b6913f5e70bf (diff)
downloadcolm-9ed46192f42837b4c066b5e1ebf859c9f5070106.tar.gz
now creating list and map el structures in the declare pass
-rw-r--r--src/declare.cc12
-rw-r--r--src/loadcolm.cc101
-rw-r--r--src/parser.cc32
-rw-r--r--src/parsetree.cc44
-rw-r--r--src/parsetree.h39
-rw-r--r--src/resolve.cc146
-rw-r--r--src/synthesis.cc8
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 )