summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2015-08-09 15:06:04 -0400
committerAdrian Thurston <thurston@complang.org>2015-08-09 15:06:04 -0400
commit93dccf445bb3079dfa60d654ea5e56fbcc3f1c54 (patch)
treec8297427852cb8eb7bfbc9e6172a6fdbfc0405f8
parente54d88ee00461f0dc2aead950a232a721ee4644d (diff)
downloadcolm-93dccf445bb3079dfa60d654ea5e56fbcc3f1c54.tar.gz
allow globals to be declared in namespaces
-rw-r--r--src/colm.lm1
-rw-r--r--src/declare.cc36
-rw-r--r--src/loadcolm.cc20
-rw-r--r--src/lookup.cc21
-rw-r--r--src/parser.cc79
-rw-r--r--src/parsetree.h8
-rw-r--r--src/synthesis.cc35
7 files changed, 115 insertions, 85 deletions
diff --git a/src/colm.lm b/src/colm.lm
index 29c70a8c..85c86f73 100644
--- a/src/colm.lm
+++ b/src/colm.lm
@@ -351,6 +351,7 @@ def namespace_item
| [precedence_def] :Precedence commit
| [alias_def] :Alias commit
| [include] :Include commit
+| [global_def] :Global commit
def obj_var_list
[]
diff --git a/src/declare.cc b/src/declare.cc
index 9116331e..de28964f 100644
--- a/src/declare.cc
+++ b/src/declare.cc
@@ -131,12 +131,12 @@ ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *o
ObjectField *NameScope::checkRedecl( const String &name )
{
- return owner->checkRedecl( this, name );
+ return owningObj->checkRedecl( this, name );
}
void NameScope::insertField( const String &name, ObjectField *value )
{
- return owner->insertField( this, name, value );
+ return owningObj->insertField( this, name, value );
}
ObjectField *ObjectDef::checkRedecl( NameScope *inScope, const String &name )
@@ -158,7 +158,7 @@ NameScope *ObjectDef::pushScope( NameScope *curScope )
{
NameScope *newScope = new NameScope;
- newScope->owner = this;
+ newScope->owningObj = this;
newScope->parentScope = curScope;
curScope->children.append( newScope );
@@ -655,7 +655,7 @@ void Compiler::makeDefaultIterators()
/* Tree iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"triter", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::Tree );
@@ -665,7 +665,7 @@ void Compiler::makeDefaultIterators()
/* Child iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"child", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::Child );
@@ -675,7 +675,7 @@ void Compiler::makeDefaultIterators()
/* Reverse iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"rev_child", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::RevChild );
@@ -685,7 +685,7 @@ void Compiler::makeDefaultIterators()
/* Repeat iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"repeat", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::Repeat );
@@ -695,7 +695,7 @@ void Compiler::makeDefaultIterators()
/* Reverse repeat iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"rev_repeat", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::RevRepeat );
@@ -705,7 +705,7 @@ void Compiler::makeDefaultIterators()
/* List iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"list_iter", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::ListEl );
@@ -715,7 +715,7 @@ void Compiler::makeDefaultIterators()
/* Reverse Value List iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"rev_list_iter", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::RevListVal );
@@ -725,7 +725,7 @@ void Compiler::makeDefaultIterators()
/* Map iterator. */
{
UniqueType *anyRefUT = findUniqueType( TYPE_REF, anyLangEl );
- ObjectMethod *objMethod = initFunction( uniqueTypeAny, globalObjectDef,
+ ObjectMethod *objMethod = initFunction( uniqueTypeAny, rootNamespace, globalObjectDef,
"map_iter", IN_HALT, IN_HALT, anyRefUT, true );
IterDef *triter = findIterDef( IterDef::MapEl );
@@ -1028,7 +1028,7 @@ void Compiler::addStdin()
el->inGetValR = IN_GET_STDIN;
el->inGetValWC = IN_GET_STDIN;
el->inGetValWV = IN_GET_STDIN;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
}
void Compiler::addStdout()
@@ -1047,7 +1047,7 @@ void Compiler::addStdout()
el->inGetValR = IN_GET_STDOUT;
el->inGetValWC = IN_GET_STDOUT;
el->inGetValWV = IN_GET_STDOUT;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
}
void Compiler::addStderr()
@@ -1066,7 +1066,7 @@ void Compiler::addStderr()
el->inGetValR = IN_GET_STDERR;
el->inGetValWC = IN_GET_STDERR;
el->inGetValWV = IN_GET_STDERR;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
}
void Compiler::addArgv()
@@ -1075,7 +1075,7 @@ void Compiler::addArgv()
ObjectField *el = ObjectField::cons( internal,
ObjectField::StructFieldType, argvTypeRef, "argv" );
el->isConst = true;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
argv = el;
TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStr );
@@ -1083,7 +1083,7 @@ void Compiler::addArgv()
el = ObjectField::cons( internal,
ObjectField::StructFieldType, typeRef, "arg0" );
el->isConst = true;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
arg0 = el;
}
@@ -1099,7 +1099,7 @@ void Compiler::addError()
el->inGetR = IN_GET_ERROR;
el->inGetWC = IN_GET_ERROR;
el->inGetWV = IN_GET_ERROR;
- globalObjectDef->rootScope->insertField( el->name, el );
+ rootNamespace->rootScope->insertField( el->name, el );
}
void Compiler::initMapFunctions( GenericType *gen )
@@ -1397,7 +1397,7 @@ void Compiler::makeFuncVisible( Function *func, bool isUserIter )
objMethod->iterDef = uiter;
}
- NameScope *scope = !isUserIter ? func->nspace->rootScope : globalObjectDef->rootScope;
+ NameScope *scope = func->nspace->rootScope; // : globalObjectDef->rootScope;
if ( !scope->methodMap.insert( func->name, objMethod ) )
error(func->typeRef->loc) << "function " << func->name << " redeclared" << endp;
diff --git a/src/loadcolm.cc b/src/loadcolm.cc
index 9af89016..8d88b965 100644
--- a/src/loadcolm.cc
+++ b/src/loadcolm.cc
@@ -2314,11 +2314,11 @@ struct LoadColm
namespaceStack.pop();
}
- void walkNamespaceDef( namespace_def NamespaceDef )
+ void walkNamespaceDef( namespace_def NamespaceDef, StmtList *stmtList )
{
String name = NamespaceDef.id().data();
createNamespace( NamespaceDef.id().loc(), name );
- walkNamespaceItemList( NamespaceDef.ItemList() );
+ walkNamespaceItemList( NamespaceDef.ItemList(), stmtList );
namespaceStack.pop();
}
@@ -2356,7 +2356,7 @@ struct LoadColm
walkStructDef( rootItem.struct_def() );
break;
case root_item::Namespace:
- walkNamespaceDef( rootItem.namespace_def() );
+ walkNamespaceDef( rootItem.namespace_def(), stmtList );
break;
case root_item::Function:
walkFunctionDef( rootItem.function_def() );
@@ -2424,7 +2424,7 @@ struct LoadColm
walkStructDef( item.struct_def() );
break;
case namespace_item::Namespace:
- walkNamespaceDef( item.namespace_def() );
+ walkNamespaceDef( item.namespace_def(), stmtList );
break;
case namespace_item::Function:
walkFunctionDef( item.function_def() );
@@ -2448,6 +2448,12 @@ struct LoadColm
StmtList *includeList = walkInclude( item.include() );
stmtList->append( *includeList );
break;
+ }
+ case namespace_item::Global: {
+ LangStmt *stmt = walkGlobalDef( item.global_def() );
+ if ( stmt != 0 )
+ stmtList->append( stmt );
+ break;
}}
}
@@ -2488,19 +2494,15 @@ struct LoadColm
walkLiteralList( literalDef.literal_list() );
}
- StmtList *walkNamespaceItemList( _repeat_namespace_item itemList )
+ void walkNamespaceItemList( _repeat_namespace_item itemList, StmtList *stmtList )
{
- StmtList *stmtList = new StmtList;
-
/* Walk the list of items. */
while ( !itemList.end() ) {
walkNamespaceItem( itemList.value(), stmtList );
itemList = itemList.next();
}
- return stmtList;
}
-
StmtList *walkRootItemList( _repeat_root_item rootItemList )
{
StmtList *stmtList = new StmtList;
diff --git a/src/lookup.cc b/src/lookup.cc
index 5a57b66f..c5155bdb 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -59,7 +59,7 @@ ObjectField *ObjectDef::findFieldInScope( const NameScope *inScope,
ObjectField *NameScope::findField( const String &name ) const
{
- return owner->findFieldInScope( this, name );
+ return owningObj->findFieldInScope( this, name );
}
ObjectMethod *NameScope::findMethod( const String &name ) const
@@ -116,7 +116,7 @@ VarRefLookup LangVarRef::lookupQualification( Compiler *pd, NameScope *rootScope
searchScope = searchObjDef->rootScope;
}
- return VarRefLookup( lastPtrInQual, firstConstPart, searchScope->owner, searchScope );
+ return VarRefLookup( lastPtrInQual, firstConstPart, searchScope->owningObj, searchScope );
}
bool LangVarRef::isLocalRef() const
@@ -169,12 +169,17 @@ bool LangVarRef::isInbuiltObject() const
VarRefLookup LangVarRef::lookupObj( Compiler *pd ) const
{
NameScope *rootScope;
- if ( isLocalRef() )
+
+ if ( nspaceQual != 0 && nspaceQual->qualNames.length() > 0 ) {
+ Namespace *nspace = pd->rootNamespace->findNamespace( nspaceQual->qualNames[0] );
+ rootScope = nspace->rootScope;
+ }
+ else if ( isLocalRef() )
rootScope = scope;
else if ( isStructRef() )
rootScope = structDef->objectDef->rootScope;
else
- rootScope = pd->globalObjectDef->rootScope;
+ rootScope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
return lookupQualification( pd, rootScope );
}
@@ -183,7 +188,7 @@ VarRefLookup LangVarRef::lookupMethodObj( Compiler *pd ) const
{
NameScope *rootScope;
- if ( qual->length() == 0 && nspaceQual != 0 && nspaceQual->qualNames.length() > 0 ) {
+ if ( nspaceQual != 0 && nspaceQual->qualNames.length() > 0 ) {
Namespace *nspace = pd->rootNamespace->findNamespace( nspaceQual->qualNames[0] );
rootScope = nspace->rootScope;
}
@@ -191,11 +196,8 @@ VarRefLookup LangVarRef::lookupMethodObj( Compiler *pd ) const
rootScope = scope;
else if ( isStructRef() )
rootScope = structDef->objectDef->rootScope;
- else if ( qual->length() == 0 ) {
- rootScope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
- }
else
- rootScope = pd->globalObjectDef->rootScope;
+ rootScope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
return lookupQualification( pd, rootScope );
}
@@ -235,7 +237,6 @@ UniqueType *LangVarRef::lookup( Compiler *pd ) const
return elUT;
}
-
VarRefLookup LangVarRef::lookupMethod( Compiler *pd ) const
{
/* Lookup the object that the field is in. */
diff --git a/src/parser.cc b/src/parser.cc
index af00a4a5..1be88cfc 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -130,6 +130,8 @@ void BaseParser::init()
pd->globalObjectDef = ObjectDef::cons( ObjectDef::UserType,
global, pd->nextObjectId++ );
+ pd->rootNamespace->rootScope->owningObj = pd->globalObjectDef;
+
pd->global = new StructDef( internal, global, pd->globalObjectDef );
pd->globalSel = declareStruct( pd, 0, global, pd->global );
@@ -227,6 +229,8 @@ Namespace *BaseParser::createRootNamespace()
Namespace *nspace = new Namespace( internal,
String("___ROOT_NAMESPACE"), 0, 0 );
+ nspace->rootScope->owningObj = pd->globalObjectDef;
+
pd->namespaceList.append( nspace );
namespaceStack.push( nspace );
@@ -246,6 +250,7 @@ Namespace *BaseParser::createNamespace( const InputLoc &loc, const String &name
/* Link the new namespace's scope to the parent namespace's scope. */
nspace->rootScope->parentScope = parent->rootScope;
+ nspace->rootScope->owningObj = pd->globalObjectDef;
parent->childNamespaces.append( nspace );
pd->namespaceList.append( nspace );
@@ -473,7 +478,7 @@ void BaseParser::iterDef( StmtList *stmtList, ObjectDef *localFrame,
ParameterList *paramList, const String &name )
{
CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame );
- Function *newFunction = Function::cons( 0, 0, name,
+ Function *newFunction = Function::cons( curNspace(), 0, name,
paramList, codeBlock, pd->nextFuncId++, true, false );
pd->functionList.append( newFunction );
}
@@ -482,32 +487,52 @@ LangStmt *BaseParser::globalDef( ObjectField *objField, LangExpr *expr,
LangStmt::Type assignType )
{
LangStmt *stmt = 0;
+ ObjectDef *object = pd->globalObjectDef;
+ Namespace *nspace = curNspace(); //pd->rootNamespace;
- StructDef *structDef = 0;
- ObjectDef *object = 0;
- if ( curStruct() == 0 )
- object = pd->globalObjectDef;
- else {
- structDef = curStruct();
- object = structDef->objectDef;
+ if ( nspace->rootScope->checkRedecl( objField->name ) != 0 )
+ error(objField->loc) << "object field renamed" << endp;
+
+ object->insertField( nspace->rootScope, objField->name, objField );
+
+ if ( expr != 0 ) {
+ LangVarRef *varRef = LangVarRef::cons( objField->loc,
+ curNspace(), curStruct(), curScope(), objField->name );
+
+ stmt = LangStmt::cons( objField->loc, assignType, varRef, expr );
}
- if ( object->rootScope->checkRedecl( objField->name ) != 0 )
+ return stmt;
+}
+
+LangStmt *BaseParser::exportStmt( ObjectField *objField,
+ LangStmt::Type assignType, LangExpr *expr )
+{
+ LangStmt *stmt = 0;
+
+ ObjectDef *object = pd->globalObjectDef;
+ Namespace *nspace = curNspace(); //pd->rootNamespace;
+
+ if ( curStruct() != 0 )
+ error(objField->loc) << "cannot export parser context variables" << endp;
+
+ if ( nspace->rootScope->checkRedecl( objField->name ) != 0 )
error(objField->loc) << "object field renamed" << endp;
- object->rootScope->insertField( objField->name, objField );
+ object->insertField( nspace->rootScope, objField->name, objField );
+ objField->isExport = true;
if ( expr != 0 ) {
- LangVarRef *varRef = LangVarRef::cons( objField->loc,
- curNspace(), structDef, curScope(), objField->name );
+ LangVarRef *varRef = LangVarRef::cons( objField->loc,
+ curNspace(), 0, curScope(), objField->name );
- stmt = LangStmt::cons( objField->loc,
- assignType, varRef, expr );
+ stmt = LangStmt::cons( objField->loc, assignType, varRef, expr );
}
return stmt;
}
+
void BaseParser::cflDef( NtDef *ntDef, ObjectDef *objectDef, LelDefList *defList )
{
Namespace *nspace = curNspace();
@@ -945,32 +970,6 @@ LangStmt *BaseParser::varDef( ObjectField *objField,
return stmt;
}
-LangStmt *BaseParser::exportStmt( ObjectField *objField,
- LangStmt::Type assignType, LangExpr *expr )
-{
- LangStmt *stmt = 0;
-
- if ( curStruct() != 0 )
- error(objField->loc) << "cannot export parser context variables" << endp;
-
- ObjectDef *object = pd->globalObjectDef;
-
- if ( object->rootScope->checkRedecl( objField->name ) != 0 )
- error(objField->loc) << "object field renamed" << endp;
-
- object->rootScope->insertField( objField->name, objField );
- objField->isExport = true;
-
- if ( expr != 0 ) {
- LangVarRef *varRef = LangVarRef::cons( objField->loc,
- curNspace(), 0, curScope(), objField->name );
-
- stmt = LangStmt::cons( objField->loc, assignType, varRef, expr );
- }
-
- return stmt;
-}
-
LangExpr *BaseParser::require( const InputLoc &loc,
LangVarRef *varRef, PatternItemList *list )
{
diff --git a/src/parsetree.h b/src/parsetree.h
index d6cc246f..f96e83f6 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -823,12 +823,12 @@ struct NameScope
{
NameScope()
:
- owner(0),
+ owningObj(0),
parentScope(0),
childIter(0)
{}
- ObjectDef *owner;
+ ObjectDef *owningObj;
FieldMap fieldMap;
MethodMap methodMap;
@@ -2545,7 +2545,7 @@ struct ObjectDef
o->id = id;
o->rootScope = new NameScope;
- o->rootScope->owner = o;
+ o->rootScope->owningObj = o;
return o;
}
@@ -2703,6 +2703,8 @@ struct LangVarRef
void loadGlobalObj( Compiler *pd, CodeVect &code,
int lastPtrInQual, bool forWriting ) const;
void loadObj( Compiler *pd, CodeVect &code, int lastPtrInQual, bool forWriting ) const;
+ void loadScopedObj( Compiler *pd, CodeVect &code,
+ NameScope *scope, int lastPtrInQual, bool forWriting ) const;
void verifyRefPossible( Compiler *pd, VarRefLookup &lookup ) const;
bool canTakeRef( Compiler *pd, VarRefLookup &lookup ) const;
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 35877de5..d714bcb3 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -531,7 +531,7 @@ void LangVarRef::loadQualification( Compiler *pd, CodeVect &code,
}
}
- UniqueType *qualUT = loadField( pd, code, searchScope->owner,
+ UniqueType *qualUT = loadField( pd, code, searchScope->owningObj,
el, lfForWriting, lfRevert );
if ( qi->form == QualItem::Dot ) {
@@ -586,8 +586,7 @@ void LangVarRef::loadContextObj( Compiler *pd, CodeVect &code,
void LangVarRef::loadGlobalObj( Compiler *pd, CodeVect &code,
int lastPtrInQual, bool forWriting ) const
{
- /* Start the search in the global object. */
- ObjectDef *rootObj = pd->globalObjectDef;
+ NameScope *scope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
if ( forWriting && lastPtrInQual < 0 ) {
/* If we are writing an no reference was found in the qualification
@@ -603,7 +602,29 @@ void LangVarRef::loadGlobalObj( Compiler *pd, CodeVect &code,
code.append( IN_LOAD_GLOBAL_R );
}
- loadQualification( pd, code, rootObj->rootScope, lastPtrInQual, forWriting, true );
+ loadQualification( pd, code, scope, lastPtrInQual, forWriting, true );
+}
+
+void LangVarRef::loadScopedObj( Compiler *pd, CodeVect &code,
+ NameScope *scope, int lastPtrInQual, bool forWriting ) const
+{
+// NameScope *scope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope;
+
+ if ( forWriting && lastPtrInQual < 0 ) {
+ /* If we are writing an no reference was found in the qualification
+ * then load the gloabl with a revert. */
+ if ( pd->revertOn )
+ code.append( IN_LOAD_GLOBAL_WV );
+ else
+ code.append( IN_LOAD_GLOBAL_WC );
+ }
+ else {
+ /* Either we are reading or we are loading a pointer that will be
+ * dereferenced. */
+ code.append( IN_LOAD_GLOBAL_R );
+ }
+
+ loadQualification( pd, code, scope, lastPtrInQual, forWriting, true );
}
void LangVarRef::loadInbuiltObject( Compiler *pd, CodeVect &code,
@@ -623,7 +644,11 @@ void LangVarRef::loadLocalObj( Compiler *pd, CodeVect &code,
void LangVarRef::loadObj( Compiler *pd, CodeVect &code,
int lastPtrInQual, bool forWriting ) const
{
- if ( isInbuiltObject() )
+ if ( nspaceQual != 0 && nspaceQual->qualNames.length() > 0 ) {
+ Namespace *nspace = pd->rootNamespace->findNamespace( nspaceQual->qualNames[0] );
+ loadScopedObj( pd, code, nspace->rootScope, lastPtrInQual, forWriting );
+ }
+ else if ( isInbuiltObject() )
loadInbuiltObject( pd, code, lastPtrInQual, forWriting );
else if ( isLocalRef() )
loadLocalObj( pd, code, lastPtrInQual, forWriting );