diff options
author | Adrian Thurston <thurston@complang.org> | 2015-08-09 15:06:04 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-08-09 15:06:04 -0400 |
commit | 93dccf445bb3079dfa60d654ea5e56fbcc3f1c54 (patch) | |
tree | c8297427852cb8eb7bfbc9e6172a6fdbfc0405f8 | |
parent | e54d88ee00461f0dc2aead950a232a721ee4644d (diff) | |
download | colm-93dccf445bb3079dfa60d654ea5e56fbcc3f1c54.tar.gz |
allow globals to be declared in namespaces
-rw-r--r-- | src/colm.lm | 1 | ||||
-rw-r--r-- | src/declare.cc | 36 | ||||
-rw-r--r-- | src/loadcolm.cc | 20 | ||||
-rw-r--r-- | src/lookup.cc | 21 | ||||
-rw-r--r-- | src/parser.cc | 79 | ||||
-rw-r--r-- | src/parsetree.h | 8 | ||||
-rw-r--r-- | src/synthesis.cc | 35 |
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 ); |