diff options
author | Adrian Thurston <thurston@complang.org> | 2015-08-09 10:39:31 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2015-08-09 10:39:31 -0400 |
commit | e54d88ee00461f0dc2aead950a232a721ee4644d (patch) | |
tree | e159fba2422ff414cf872cce975f19ca28ff889e /src | |
parent | 42314c5f0f87c45f6968c7c8fcfbfb8eae9f8ad6 (diff) | |
download | colm-e54d88ee00461f0dc2aead950a232a721ee4644d.tar.gz |
now scoping functions inside the namespaces they are declared in
Diffstat (limited to 'src')
-rw-r--r-- | src/colm.lm | 2 | ||||
-rw-r--r-- | src/compiler.h | 17 | ||||
-rw-r--r-- | src/consinit.cc | 15 | ||||
-rw-r--r-- | src/declare.cc | 126 | ||||
-rw-r--r-- | src/loadcolm.cc | 15 | ||||
-rw-r--r-- | src/loadinit.cc | 23 | ||||
-rw-r--r-- | src/lookup.cc | 65 | ||||
-rw-r--r-- | src/parser.cc | 55 | ||||
-rw-r--r-- | src/parser.h | 10 | ||||
-rw-r--r-- | src/parsetree.h | 134 | ||||
-rw-r--r-- | src/resolve.cc | 2 | ||||
-rw-r--r-- | src/synthesis.cc | 6 |
12 files changed, 300 insertions, 170 deletions
diff --git a/src/colm.lm b/src/colm.lm index 30a50c31..29c70a8c 100644 --- a/src/colm.lm +++ b/src/colm.lm @@ -745,7 +745,7 @@ def string # def var_ref - [qual id] + [region_qual qual id] def qual [qual id DOT] :Dot diff --git a/src/compiler.h b/src/compiler.h index e7cd3fc8..e953c473 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -1045,13 +1045,30 @@ LangEl *findType( Compiler *pd, Namespace *nspace, const String &data ); ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, const String &name, int methIdWV, int methIdWC, bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 ); + ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, const String &name, int methIdWV, int methIdWC, UniqueType *arg1, bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 ); + ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, const String &name, int methIdWV, int methIdWC, UniqueType *arg1, UniqueType *arg2, bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 ); +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, + bool isConst, bool useFnInstr = false, GenericType *useGeneric = 0 ); + +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, + UniqueType *arg1, bool isConst, bool useFnInstr = false, + GenericType *useGeneric = 0 ); + +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, + UniqueType *arg1, UniqueType *arg2, bool isConst, + bool useFnInstr = false, GenericType *useGeneric = 0 ); + + #endif /* _PARSEDATA_H */ diff --git a/src/consinit.cc b/src/consinit.cc index 0653dce2..794c07ae 100644 --- a/src/consinit.cc +++ b/src/consinit.cc @@ -755,7 +755,8 @@ void ConsInit::parseInput( StmtList *stmtList ) popQual->append( QualItem( QualItem::Arrow, internal, String( "argv" ) ) ); LangVarRef *popRef = LangVarRef::cons( internal, - 0, curLocalFrame->rootScope, popQual, String("pop") ); + curNspace(), 0, curLocalFrame()->rootScope, + NamespaceQual::cons( curNspace() ), popQual, String("pop") ); LangExpr *pop = LangExpr::cons( LangTerm::cons( InputLoc(), popRef, popArgs ) ); TypeRef *typeRef = TypeRef::cons( internal, pd->uniqueTypeStr ); @@ -774,15 +775,17 @@ void ConsInit::parseInput( StmtList *stmtList ) /* Reference A->value */ QualItemVect *qual = new QualItemVect; - LangVarRef *varRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, qual, String("A") ); + LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ), + qual, String("A") ); LangExpr *Avalue = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); /* Call open. */ QualItemVect *openQual = new QualItemVect; LangVarRef *openRef = LangVarRef::cons( internal, - 0, curLocalFrame->rootScope, openQual, String("open") ); + 0, 0, curLocalFrame()->rootScope, + NamespaceQual::cons( curNspace() ), openQual, String("open") ); CallArgVect *openArgs = new CallArgVect; openArgs->append( new CallArg(Avalue) ); openArgs->append( new CallArg(modeExpr) ); @@ -811,8 +814,8 @@ void ConsInit::exportTree( StmtList *stmtList ) { /* reference P */ QualItemVect *qual = new QualItemVect; - LangVarRef *varRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, qual, String("P") ); + LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ), qual, String("P") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); diff --git a/src/declare.cc b/src/declare.cc index 69c33a91..9116331e 100644 --- a/src/declare.cc +++ b/src/declare.cc @@ -49,38 +49,43 @@ void Compiler::initUniqueTypes( ) uniqeTypeMap.insert( uniqueTypeStream ); } -ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, - const String &name, int methIdWV, int methIdWC, bool isConst, - bool useFnInstr, GenericType *useGeneric ) +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, + int nargs, UniqueType **args, bool isConst, bool useFnInstr, + GenericType *useGeneric ) { ObjectMethod *objMethod = new ObjectMethod( retType, name, - methIdWV, methIdWC, 0, 0, 0, isConst ); + methIdWV, methIdWC, nargs, args, 0, isConst ); objMethod->useFnInstr = useFnInstr; - obj->rootScope->methodMap.insert( name, objMethod ); - + + if ( nspace != 0 ) + nspace->rootScope->methodMap.insert( name, objMethod ); + else + obj->rootScope->methodMap.insert( name, objMethod ); + if ( useGeneric ) { objMethod->useGenericId = true; objMethod->generic = useGeneric; } + return objMethod; } ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, bool isConst, + bool useFnInstr, GenericType *useGeneric ) +{ + return initFunction( retType, 0, obj, name, methIdWV, methIdWC, + 0, 0, isConst, useFnInstr, useGeneric ); +} + +ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, const String &name, int methIdWV, int methIdWC, UniqueType *arg1, bool isConst, bool useFnInstr, GenericType *useGeneric ) { UniqueType *args[] = { arg1 }; - ObjectMethod *objMethod = new ObjectMethod( retType, name, - methIdWV, methIdWC, 1, args, 0, isConst ); - objMethod->useFnInstr = useFnInstr; - obj->rootScope->methodMap.insert( name, objMethod ); - - if ( useGeneric ) { - objMethod->useGenericId = true; - objMethod->generic = useGeneric; - } - - return objMethod; + return initFunction( retType, 0, obj, name, methIdWV, methIdWC, + 1, args, isConst, useFnInstr, useGeneric ); } ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, @@ -89,19 +94,40 @@ ObjectMethod *initFunction( UniqueType *retType, ObjectDef *obj, bool isConst, bool useFnInstr, GenericType *useGeneric ) { UniqueType *args[] = { arg1, arg2 }; - ObjectMethod *objMethod = new ObjectMethod( retType, name, - methIdWV, methIdWC, 2, args, 0, isConst ); - objMethod->useFnInstr = useFnInstr; - obj->rootScope->methodMap.insert( name, objMethod ); + return initFunction( retType, 0, obj, name, methIdWV, methIdWC, + 2, args, isConst, useFnInstr, useGeneric ); +} - if ( useGeneric ) { - objMethod->useGenericId = true; - objMethod->generic = useGeneric; - } +/* + * With namespace supplied. Global functions. + */ - return objMethod; +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, bool isConst, + bool useFnInstr, GenericType *useGeneric ) +{ + return initFunction( retType, nspace, obj, name, methIdWV, methIdWC, + 0, 0, isConst, useFnInstr, useGeneric ); } +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, UniqueType *arg1, + bool isConst, bool useFnInstr, GenericType *useGeneric ) +{ + UniqueType *args[] = { arg1 }; + return initFunction( retType, nspace, obj, name, methIdWV, methIdWC, + 1, args, isConst, useFnInstr, useGeneric ); +} + +ObjectMethod *initFunction( UniqueType *retType, Namespace *nspace, ObjectDef *obj, + const String &name, int methIdWV, int methIdWC, + UniqueType *arg1, UniqueType *arg2, + bool isConst, bool useFnInstr, GenericType *useGeneric ) +{ + UniqueType *args[] = { arg1, arg2 }; + return initFunction( retType, nspace, obj, name, methIdWV, methIdWC, + 2, args, isConst, useFnInstr, useGeneric ); +} ObjectField *NameScope::checkRedecl( const String &name ) { @@ -489,7 +515,7 @@ void LangStmt::chooseDefaultIter( Compiler *pd, IterCall *iterCall ) const /* This is two-part, It gets rewritten before evaluation in synthesis. */ /* The iterator name. */ - LangVarRef *callVarRef = LangVarRef::cons( loc, context, scope, "triter" ); + LangVarRef *callVarRef = LangVarRef::cons( loc, 0, context, scope, "triter" ); /* The parameters. */ CallArgVect *callExprVect = new CallArgVect; @@ -812,7 +838,7 @@ void Compiler::declareStrFields( ) initFunction( uniqueTypeStr, strObj, "suffix", IN_STR_SUFFIX, IN_STR_SUFFIX, uniqueTypeInt, true, true ); - initFunction( uniqueTypeStr, globalObjectDef, "sprintf", + initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "sprintf", IN_SPRINTF, IN_SPRINTF, uniqueTypeStr, uniqueTypeInt, true ); addLengthField( strObj, IN_STR_LENGTH ); @@ -918,66 +944,66 @@ void Compiler::declareGlobalFields() { ObjectMethod *method; - method = initFunction( uniqueTypeStream, globalObjectDef, "open", + method = initFunction( uniqueTypeStream, rootNamespace, globalObjectDef, "open", IN_OPEN_FILE, IN_OPEN_FILE, uniqueTypeStr, uniqueTypeStr, true ); method->useCallObj = false; - method = initFunction( uniqueTypeStr, globalObjectDef, "tolower", + method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "tolower", IN_TO_LOWER, IN_TO_LOWER, uniqueTypeStr, true ); method->useCallObj = false; - method = initFunction( uniqueTypeStr, globalObjectDef, "toupper", + method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "toupper", IN_TO_UPPER, IN_TO_UPPER, uniqueTypeStr, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "atoi", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "atoi", IN_STR_ATOI, IN_STR_ATOI, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "atoo", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "atoo", IN_STR_ATOO, IN_STR_ATOO, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeStr, globalObjectDef, "prefix", + method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "prefix", IN_PREFIX, IN_PREFIX, uniqueTypeStr, uniqueTypeInt, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeStr, globalObjectDef, "suffix", + method = initFunction( uniqueTypeStr, rootNamespace, globalObjectDef, "suffix", IN_SUFFIX, IN_SUFFIX, uniqueTypeStr, uniqueTypeInt, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "uord8", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord8", IN_STR_UORD8, IN_STR_UORD8, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "sord8", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord8", IN_STR_SORD8, IN_STR_SORD8, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "uord16", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord16", IN_STR_UORD16, IN_STR_UORD16, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "sord16", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord16", IN_STR_SORD16, IN_STR_SORD16, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "uord32", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "uord32", IN_STR_UORD32, IN_STR_UORD32, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "sord32", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "sord32", IN_STR_SORD32, IN_STR_SORD32, uniqueTypeStr, true, true ); method->useCallObj = false; - method = initFunction( uniqueTypeInt, globalObjectDef, "exit", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "exit", IN_EXIT, IN_EXIT, uniqueTypeInt, true, true ); - method = initFunction( uniqueTypeInt, globalObjectDef, "exit_hard", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "exit_hard", IN_EXIT_HARD, IN_EXIT_HARD, uniqueTypeInt, true, true ); - method = initFunction( uniqueTypeInt, globalObjectDef, "system", + method = initFunction( uniqueTypeInt, rootNamespace, globalObjectDef, "system", IN_SYSTEM, IN_SYSTEM, uniqueTypeStr, true ); addStdin(); @@ -1371,7 +1397,10 @@ void Compiler::makeFuncVisible( Function *func, bool isUserIter ) objMethod->iterDef = uiter; } - globalObjectDef->rootScope->methodMap.insert( func->name, objMethod ); + NameScope *scope = !isUserIter ? func->nspace->rootScope : globalObjectDef->rootScope; + + if ( !scope->methodMap.insert( func->name, objMethod ) ) + error(func->typeRef->loc) << "function " << func->name << " redeclared" << endp; func->objMethod = objMethod; } @@ -1395,7 +1424,12 @@ void Compiler::makeInHostVisible( Function *func ) objMethod->useCallObj = false; objMethod->func = func; - globalObjectDef->rootScope->methodMap.insert( func->name, objMethod ); + NameScope *scope = func->nspace->rootScope; + + if ( !scope->methodMap.insert( func->name, objMethod ) ) { + error(func->typeRef->loc) << "in-host function " << func->name << + " redeclared" << endp; + } func->objMethod = objMethod; } diff --git a/src/loadcolm.cc b/src/loadcolm.cc index 4bb773d3..9af89016 100644 --- a/src/loadcolm.cc +++ b/src/loadcolm.cc @@ -228,7 +228,7 @@ struct LoadColm IterCall *iterCall = walkIterCall( Statement.iter_call() ); stmt = forScope( Statement.id().loc(), forDecl, - curScope, typeRef, iterCall, stmtList ); + curScope(), typeRef, iterCall, stmtList ); popScope(); break; @@ -448,7 +448,7 @@ struct LoadColm if ( optLabel.prodName() == opt_label::Id ) { String id = optLabel.id().data(); varRef = LangVarRef::cons( optLabel.id().loc(), - curStruct(), curScope, id ); + curNspace(), curStruct(), curScope(), id ); } return varRef; } @@ -1298,11 +1298,12 @@ struct LoadColm LangVarRef *walkVarRef( var_ref varRef ) { + NamespaceQual *nspaceQual = walkRegionQual( varRef.region_qual() ); qual Qual = varRef.qual(); QualItemVect *qualItemVect = walkQual( Qual ); String id = varRef.id().data(); LangVarRef *langVarRef = LangVarRef::cons( varRef.id().loc(), - curStruct(), curScope, qualItemVect, id ); + curNspace(), curStruct(), curScope(), nspaceQual, qualItemVect, id ); return langVarRef; } @@ -1891,7 +1892,7 @@ struct LoadColm LangVarRef *captureVarRef = 0; if ( captureField != 0 ) { captureVarRef = LangVarRef::cons( captureField->loc, - curStruct(), curScope, captureField->name ); + curNspace(), curStruct(), curScope(), captureField->name ); } expr = LangExpr::cons( LangTerm::consNew( @@ -1899,14 +1900,14 @@ struct LoadColm /* Check for redeclaration. */ if ( captureField != 0 ) { - if ( curScope->checkRedecl( captureField->name ) != 0 ) { + if ( curScope()->checkRedecl( captureField->name ) != 0 ) { error( captureField->loc ) << "variable " << captureField->name << " redeclared" << endp; } /* Insert it into the field map. */ captureField->typeRef = typeRef; - curScope->insertField( captureField->name, captureField ); + curScope()->insertField( captureField->name, captureField ); } break; } @@ -2040,7 +2041,7 @@ struct LoadColm case iter_call::Id: { String tree = Tree.id().data(); LangVarRef *varRef = LangVarRef::cons( Tree.id().loc(), - curStruct(), curScope, tree ); + curNspace(), curStruct(), curScope(), tree ); LangTerm *langTerm = LangTerm::cons( Tree.id().loc(), LangTerm::VarRefType, varRef ); LangExpr *langExpr = LangExpr::cons( langTerm ); diff --git a/src/loadinit.cc b/src/loadinit.cc index f8454e3a..f14ea174 100644 --- a/src/loadinit.cc +++ b/src/loadinit.cc @@ -284,8 +284,9 @@ void LoadInit::consParseStmt( StmtList *stmtList ) QualItemVect *popQual = new QualItemVect; popQual->append( QualItem( QualItem::Arrow, internal, String( "argv" ) ) ); - LangVarRef *popRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, popQual, String("pop") ); + LangVarRef *popRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, NamespaceQual::cons( curNspace() ), + popQual, String("pop") ); LangExpr *pop = LangExpr::cons( LangTerm::cons( InputLoc(), popRef, popArgs ) ); TypeRef *typeRef = TypeRef::cons( internal, pd->uniqueTypeStr ); @@ -303,16 +304,14 @@ void LoadInit::consParseStmt( StmtList *stmtList ) LangExpr *modeExpr = LangExpr::cons( LangTerm::cons( internal, modeCons ) ); /* Reference A->value */ - QualItemVect *qual = new QualItemVect; - LangVarRef *varRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, qual, String("A") ); + LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, String("A") ); LangExpr *Avalue = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); /* Call open. */ - QualItemVect *openQual = new QualItemVect; LangVarRef *openRef = LangVarRef::cons( internal, - 0, curLocalFrame->rootScope, openQual, String("open") ); + curNspace(), 0, curLocalFrame()->rootScope, String("open") ); CallArgVect *openArgs = new CallArgVect; openArgs->append( new CallArg(Avalue) ); openArgs->append( new CallArg(modeExpr) ); @@ -339,9 +338,8 @@ void LoadInit::consParseStmt( StmtList *stmtList ) void LoadInit::consExportTree( StmtList *stmtList ) { - QualItemVect *qual = new QualItemVect; - LangVarRef *varRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, qual, String("P") ); + LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, String("P") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); @@ -355,9 +353,8 @@ void LoadInit::consExportTree( StmtList *stmtList ) void LoadInit::consExportError( StmtList *stmtList ) { - QualItemVect *qual = new QualItemVect; - LangVarRef *varRef = LangVarRef::cons( internal, 0, - curLocalFrame->rootScope, qual, String("error") ); + LangVarRef *varRef = LangVarRef::cons( internal, curNspace(), 0, + curLocalFrame()->rootScope, String("error") ); LangExpr *expr = LangExpr::cons( LangTerm::cons( internal, LangTerm::VarRefType, varRef ) ); diff --git a/src/lookup.cc b/src/lookup.cc index ea4885d2..5a57b66f 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -67,6 +67,8 @@ ObjectMethod *NameScope::findMethod( const String &name ) const MethodMapEl *methodMapEl = methodMap.find( name ); if ( methodMapEl != 0 ) return methodMapEl->value; + if ( parentScope != 0 ) + return parentScope->findMethod( name ); return 0; } @@ -131,16 +133,16 @@ bool LangVarRef::isLocalRef() const return false; } -bool LangVarRef::isContextRef() const +bool LangVarRef::isStructRef() const { - if ( context != 0 ) { + if ( structDef != 0 ) { if ( qual->length() > 0 ) { - if ( context->objectDef->rootScope->findField( qual->data[0].data ) != 0 ) + if ( structDef->objectDef->rootScope->findField( qual->data[0].data ) != 0 ) return true; } - else if ( context->objectDef->rootScope->findField( name ) != 0 ) + else if ( structDef->objectDef->rootScope->findField( name ) != 0 ) return true; - else if ( context->objectDef->rootScope->findMethod( name ) != 0 ) + else if ( structDef->objectDef->rootScope->findMethod( name ) != 0 ) return true; } @@ -169,14 +171,36 @@ VarRefLookup LangVarRef::lookupObj( Compiler *pd ) const NameScope *rootScope; if ( isLocalRef() ) rootScope = scope; - else if ( isContextRef() ) - rootScope = context->objectDef->rootScope; + else if ( isStructRef() ) + rootScope = structDef->objectDef->rootScope; else rootScope = pd->globalObjectDef->rootScope; return lookupQualification( pd, rootScope ); } +VarRefLookup LangVarRef::lookupMethodObj( Compiler *pd ) const +{ + NameScope *rootScope; + + if ( qual->length() == 0 && 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 if ( qual->length() == 0 ) { + rootScope = nspace != 0 ? nspace->rootScope : pd->rootNamespace->rootScope; + } + else + rootScope = pd->globalObjectDef->rootScope; + + return lookupQualification( pd, rootScope ); +} + + VarRefLookup LangVarRef::lookupField( Compiler *pd ) const { /* Lookup the object that the field is in. */ @@ -215,6 +239,33 @@ UniqueType *LangVarRef::lookup( Compiler *pd ) const VarRefLookup LangVarRef::lookupMethod( Compiler *pd ) const { /* Lookup the object that the field is in. */ + VarRefLookup lookup = lookupMethodObj( pd ); + + /* Find the method. */ + ObjectMethod *method = lookup.inScope->findMethod( name ); + if ( method == 0 ) { + /* Not found as a method, try it as an object on which we will call a + * default function. */ + qual->append( QualItem( QualItem::Dot, loc, name ) ); + + /* Lookup the object that the field is in. */ + VarRefLookup lookup = lookupObj( pd ); + + /* Find the method. */ + method = lookup.inScope->findMethod( "finish" ); + if ( method == 0 ) + error(loc) << "cannot find " << name << "(...) in object" << endp; + } + + lookup.objMethod = method; + lookup.uniqueType = method->returnUT; + + return lookup; +} + +VarRefLookup LangVarRef::lookupIterCall( Compiler *pd ) const +{ + /* Lookup the object that the field is in. */ VarRefLookup lookup = lookupObj( pd ); /* Find the method. */ diff --git a/src/parser.cc b/src/parser.cc index 37ba9893..af00a4a5 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -150,8 +150,8 @@ void BaseParser::init() pd->rootLocalFrame = ObjectDef::cons( ObjectDef::FrameType, "local", pd->nextObjectId++ ); - curLocalFrame = pd->rootLocalFrame; - curScope = pd->rootLocalFrame->rootScope; + localFrameTop = pd->rootLocalFrame; + scopeTop = pd->rootLocalFrame->rootScope; /* Declarations of internal types. They must be declared now because we use @@ -244,6 +244,9 @@ Namespace *BaseParser::createNamespace( const InputLoc &loc, const String &name nspace = new Namespace( loc, name, pd->namespaceList.length(), parent ); + /* Link the new namespace's scope to the parent namespace's scope. */ + nspace->rootScope->parentScope = parent->rootScope; + parent->childNamespaces.append( nspace ); pd->namespaceList.append( nspace ); } @@ -433,22 +436,22 @@ ObjectDef *BaseParser::blockOpen() ObjectDef *frame = ObjectDef::cons( ObjectDef::FrameType, "local", pd->nextObjectId++ ); - curLocalFrame = frame; - curScope = frame->rootScope; + localFrameTop = frame; + scopeTop = frame->rootScope; return frame; } void BaseParser::blockClose() { - curLocalFrame = pd->rootLocalFrame; - curScope = pd->rootLocalFrame->rootScope; + localFrameTop = pd->rootLocalFrame; + scopeTop = pd->rootLocalFrame->rootScope; } void BaseParser::functionDef( StmtList *stmtList, ObjectDef *localFrame, ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt ) { CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame ); - Function *newFunction = Function::cons( typeRef, name, + Function *newFunction = Function::cons( curNspace(), typeRef, name, paramList, codeBlock, pd->nextFuncId++, false, exprt ); pd->functionList.append( newFunction ); newFunction->inContext = curStruct(); @@ -457,7 +460,7 @@ void BaseParser::functionDef( StmtList *stmtList, ObjectDef *localFrame, void BaseParser::inHostDef( const String &hostCall, ObjectDef *localFrame, ParameterList *paramList, TypeRef *typeRef, const String &name, bool exprt ) { - Function *newFunction = Function::cons( typeRef, name, + Function *newFunction = Function::cons( curNspace(), typeRef, name, paramList, 0, pd->nextHostId++, false, exprt ); newFunction->hostCall = hostCall; newFunction->localFrame = localFrame; @@ -470,7 +473,7 @@ void BaseParser::iterDef( StmtList *stmtList, ObjectDef *localFrame, ParameterList *paramList, const String &name ) { CodeBlock *codeBlock = CodeBlock::cons( stmtList, localFrame ); - Function *newFunction = Function::cons( 0, name, + Function *newFunction = Function::cons( 0, 0, name, paramList, codeBlock, pd->nextFuncId++, true, false ); pd->functionList.append( newFunction ); } @@ -496,7 +499,7 @@ LangStmt *BaseParser::globalDef( ObjectField *objField, LangExpr *expr, if ( expr != 0 ) { LangVarRef *varRef = LangVarRef::cons( objField->loc, - structDef, curScope, objField->name ); + curNspace(), structDef, curScope(), objField->name ); stmt = LangStmt::cons( objField->loc, assignType, varRef, expr ); @@ -679,7 +682,7 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop, LangVarRef *varRef = 0; if ( objField != 0 ) { varRef = LangVarRef::cons( objField->loc, - curStruct(), curScope, objField->name ); + curNspace(), curStruct(), curScope(), objField->name ); } /* The typeref for the parser. */ @@ -698,14 +701,14 @@ LangExpr *BaseParser::parseCmd( const InputLoc &loc, bool tree, bool stop, /* Check for redeclaration. */ if ( objField != 0 ) { - if ( curScope->checkRedecl( objField->name ) != 0 ) { + if ( curScope()->checkRedecl( objField->name ) != 0 ) { error( objField->loc ) << "variable " << objField->name << " redeclared" << endp; } /* Insert it into the field map. */ objField->typeRef = typeRef; - curScope->insertField( objField->name, objField ); + curScope()->insertField( objField->name, objField ); } return expr; @@ -717,7 +720,7 @@ PatternItemList *BaseParser::consPatternEl( LangVarRef *varRef, PatternItemList list->head->varRef = varRef; if ( varRef != 0 ) { - if ( curScope->checkRedecl( varRef->name ) != 0 ) { + if ( curScope()->checkRedecl( varRef->name ) != 0 ) { error( varRef->loc ) << "variable " << varRef->name << " redeclared" << endp; } @@ -727,7 +730,7 @@ PatternItemList *BaseParser::consPatternEl( LangVarRef *varRef, PatternItemList ObjectField::UserLocalType, typeRef, varRef->name ); /* Insert it into the field map. */ - curScope->insertField( varRef->name, objField ); + curScope()->insertField( varRef->name, objField ); } return list; @@ -782,7 +785,7 @@ LangStmt *BaseParser::forScope( const InputLoc &loc, const String &data, NameScope *scope, TypeRef *typeRef, IterCall *iterCall, StmtList *stmtList ) { /* Check for redeclaration. */ - if ( curScope->checkRedecl( data ) != 0 ) + if ( curScope()->checkRedecl( data ) != 0 ) error( loc ) << "variable " << data << " redeclared" << endp; /* Note that we pass in a null type reference. This type is dependent on @@ -790,7 +793,7 @@ LangStmt *BaseParser::forScope( const InputLoc &loc, const String &data, * the iterator that is called. This lookup is done at compile time. */ ObjectField *iterField = ObjectField::cons( loc, ObjectField::UserLocalType, (TypeRef*)0, data ); - curScope->insertField( data, iterField ); + curScope()->insertField( data, iterField ); LangStmt *stmt = LangStmt::cons( loc, LangStmt::ForIterType, iterField, typeRef, iterCall, stmtList, curStruct(), scope ); @@ -882,7 +885,7 @@ LangExpr *BaseParser::construct( const InputLoc &loc, ObjectField *objField, LangVarRef *varRef = 0; if ( objField != 0 ) { varRef = LangVarRef::cons( objField->loc, - curStruct(), curScope, objField->name ); + curNspace(), curStruct(), curScope(), objField->name ); } LangExpr *expr = LangExpr::cons( LangTerm::cons( loc, LangTerm::ConstructType, @@ -890,14 +893,14 @@ LangExpr *BaseParser::construct( const InputLoc &loc, ObjectField *objField, /* Check for redeclaration. */ if ( objField != 0 ) { - if ( curScope->checkRedecl( objField->name ) != 0 ) { + if ( curScope()->checkRedecl( objField->name ) != 0 ) { error( objField->loc ) << "variable " << objField->name << " redeclared" << endp; } /* Insert it into the field map. */ objField->typeRef = typeRef; - curScope->insertField( objField->name, objField ); + curScope()->insertField( objField->name, objField ); } return expr; @@ -922,19 +925,19 @@ LangStmt *BaseParser::varDef( ObjectField *objField, LangStmt *stmt = 0; /* Check for redeclaration. */ - if ( curScope->checkRedecl( objField->name ) != 0 ) { + if ( curScope()->checkRedecl( objField->name ) != 0 ) { error( objField->loc ) << "variable " << objField->name << " redeclared" << endp; } /* Insert it into the field map. */ - curScope->insertField( objField->name, objField ); + curScope()->insertField( objField->name, objField ); //cout << "var def " << $1->objField->name << endl; if ( expr != 0 ) { LangVarRef *varRef = LangVarRef::cons( objField->loc, - curStruct(), curScope, objField->name ); + curNspace(), curStruct(), curScope(), objField->name ); stmt = LangStmt::cons( objField->loc, assignType, varRef, expr ); } @@ -960,7 +963,7 @@ LangStmt *BaseParser::exportStmt( ObjectField *objField, if ( expr != 0 ) { LangVarRef *varRef = LangVarRef::cons( objField->loc, - 0, curScope, objField->name ); + curNspace(), 0, curScope(), objField->name ); stmt = LangStmt::cons( objField->loc, assignType, varRef, expr ); } @@ -1066,10 +1069,10 @@ void BaseParser::precedenceStmt( PredType predType, PredDeclList *predDeclList ) void BaseParser::pushScope() { - curScope = curLocalFrame->pushScope( curScope ); + scopeTop = curLocalFrame()->pushScope( curScope() ); } void BaseParser::popScope() { - curScope = curScope->parentScope; + scopeTop = curScope()->parentScope; } diff --git a/src/parser.h b/src/parser.h index 8843aad6..baa08f61 100644 --- a/src/parser.h +++ b/src/parser.h @@ -42,8 +42,8 @@ struct BaseParser RegionSetVect regionStack; NamespaceVect namespaceStack; StructStack structStack; - ObjectDef *curLocalFrame; - NameScope *curScope; + ObjectDef *localFrameTop; + NameScope *scopeTop; bool enterRl; @@ -55,6 +55,12 @@ struct BaseParser Namespace *curNspace() { return namespaceStack.top(); } + + NameScope *curScope() + { return scopeTop; } + + ObjectDef *curLocalFrame() + { return localFrameTop; } /* Lexical feedback. */ diff --git a/src/parsetree.h b/src/parsetree.h index d028b3f7..d6cc246f 100644 --- a/src/parsetree.h +++ b/src/parsetree.h @@ -811,13 +811,64 @@ struct TypeAlias typedef DList<TypeAlias> TypeAliasList; +typedef AvlMap<String, ObjectField*, CmpStr> FieldMap; +typedef AvlMapEl<String, ObjectField*> FieldMapEl; + +typedef AvlMap<String, ObjectMethod*, CmpStr> MethodMap; +typedef AvlMapEl<String, ObjectMethod*> MethodMapEl; + +/* tree_t of name scopes for an object def. All of the object fields inside this + * tree live in one object def. This is used for scoping names in functions. */ +struct NameScope +{ + NameScope() + : + owner(0), + parentScope(0), + childIter(0) + {} + + ObjectDef *owner; + FieldMap fieldMap; + MethodMap methodMap; + + NameScope *parentScope; + DList<NameScope> children; + + /* For iteration after declaration. */ + NameScope *childIter; + + NameScope *prev, *next; + + int depth() + { + int depth = 0; + NameScope *scope = this; + while ( scope != 0 ) { + depth += 1; + scope = scope->parentScope; + } + return depth; + } + + ObjectField *findField( const String &name ) const; + ObjectMethod *findMethod( const String &name ) const; + + ObjectField *checkRedecl( const String &name ); + void insertField( const String &name, ObjectField *value ); +}; + + struct Namespace { /* Construct with a list of joins */ Namespace( const InputLoc &loc, const String &name, int id, Namespace *parentNamespace ) : loc(loc), name(name), id(id), - parentNamespace(parentNamespace) { } + parentNamespace(parentNamespace) + { + rootScope = new NameScope; + } /* tree_t traversal. */ Namespace *findNamespace( const String &name ); @@ -850,6 +901,8 @@ struct Namespace Namespace *parentNamespace; NamespaceVect childNamespaces; + NameScope *rootScope; + Namespace *next, *prev; void declare( Compiler *pd ); @@ -2462,59 +2515,11 @@ struct ObjectField ObjectField *prev, *next; }; -typedef AvlMap<String, ObjectField*, CmpStr> FieldMap; -typedef AvlMapEl<String, ObjectField*> FieldMapEl; - typedef DListVal<ObjectField*> FieldList; typedef DList<ObjectField> ParameterList; -typedef AvlMap<String, ObjectMethod*, CmpStr> MethodMap; -typedef AvlMapEl<String, ObjectMethod*> MethodMapEl; - - -/* tree_t of name scopes for an object def. All of the object fields inside this - * tree live in one object def. This is used for scoping names in functions. */ -struct NameScope -{ - NameScope() - : - owner(0), - parentScope(0), - childIter(0) - {} - - ObjectDef *owner; - FieldMap fieldMap; - MethodMap methodMap; - - NameScope *parentScope; - DList<NameScope> children; - - /* For iteration after declaration. */ - NameScope *childIter; - - NameScope *prev, *next; - - int depth() - { - int depth = 0; - NameScope *scope = this; - while ( scope != 0 ) { - depth += 1; - scope = scope->parentScope; - } - return depth; - } - - ObjectField *findField( const String &name ) const; - ObjectMethod *findMethod( const String &name ) const; - - ObjectField *checkRedecl( const String &name ); - void insertField( const String &name, ObjectField *value ); -}; - struct ObjectDef { enum Type { @@ -2647,22 +2652,27 @@ typedef Vector<QualItem> QualItemVect; struct LangVarRef { - static LangVarRef *cons( const InputLoc &loc, StructDef *context, - NameScope *scope, QualItemVect *qual, const String &name ) + static LangVarRef *cons( const InputLoc &loc, Namespace *nspace, + StructDef *structDef, NameScope *scope, + NamespaceQual *nspaceQual, QualItemVect *qual, + const String &name ) { LangVarRef *l = new LangVarRef; l->loc = loc; - l->context = context; + l->nspace = nspace; + l->structDef = structDef; l->scope = scope; + l->nspaceQual = nspaceQual; l->qual = qual; l->name = name; return l; } - static LangVarRef *cons( const InputLoc &loc, StructDef *context, - NameScope *scope, const String &name ) + static LangVarRef *cons( const InputLoc &loc, Namespace *nspace, + StructDef *structDef, NameScope *scope, const String &name ) { - return cons( loc, context, scope, new QualItemVect, name ); + return cons( loc, nspace, structDef, scope, + NamespaceQual::cons( nspace ), new QualItemVect, name ); } void resolve( Compiler *pd ) const; @@ -2671,15 +2681,17 @@ struct LangVarRef UniqueType *loadField( Compiler *pd, CodeVect &code, ObjectDef *inObject, ObjectField *el, bool forWriting, bool revert ) const; + VarRefLookup lookupIterCall( Compiler *pd ) const; VarRefLookup lookupMethod( Compiler *pd ) const; VarRefLookup lookupField( Compiler *pd ) const; VarRefLookup lookupQualification( Compiler *pd, NameScope *rootScope ) const; VarRefLookup lookupObj( Compiler *pd ) const; + VarRefLookup lookupMethodObj( Compiler *pd ) const; bool isInbuiltObject() const; bool isLocalRef() const; - bool isContextRef() const; + bool isStructRef() const; void loadQualification( Compiler *pd, CodeVect &code, NameScope *rootScope, int lastPtrInQual, bool forWriting, bool revert ) const; void loadInbuiltObject( Compiler *pd, CodeVect &code, @@ -2721,9 +2733,12 @@ struct LangVarRef void popRefQuals( Compiler *pd, CodeVect &code, VarRefLookup &lookup, CallArgVect *args, bool temps ) const; + InputLoc loc; - StructDef *context; + Namespace *nspace; + StructDef *structDef; NameScope *scope; + NamespaceQual *nspaceQual; QualItemVect *qual; String name; long argSize; @@ -3350,6 +3365,7 @@ struct Function { Function() : + nspace(0), paramListSize(0), paramUTs(0), inContext(0), @@ -3357,12 +3373,13 @@ struct Function inHost(false) {} - static Function *cons( TypeRef *typeRef, const String &name, + static Function *cons( Namespace *nspace, TypeRef *typeRef, const String &name, ParameterList *paramList, CodeBlock *codeBlock, int funcId, bool isUserIter, bool exprt ) { Function *f = new Function; + f->nspace = nspace; f->typeRef = typeRef; f->name = name; f->paramList = paramList; @@ -3374,6 +3391,7 @@ struct Function return f; } + Namespace *nspace; TransBlock *transBlock; TypeRef *typeRef; String name; diff --git a/src/resolve.cc b/src/resolve.cc index 96742435..95221bcb 100644 --- a/src/resolve.cc +++ b/src/resolve.cc @@ -377,7 +377,7 @@ UniqueType *TypeRef::resolveIterator( Compiler *pd ) UniqueType *searchUT = searchTypeRef->resolveType( pd ); /* Lookup the iterator call. Make sure it is an iterator. */ - VarRefLookup lookup = iterCall->langTerm->varRef->lookupMethod( pd ); + VarRefLookup lookup = iterCall->langTerm->varRef->lookupIterCall( pd ); if ( lookup.objMethod->iterDef == 0 ) { error(loc) << "attempt to iterate using something " "that is not an iterator" << endp; diff --git a/src/synthesis.cc b/src/synthesis.cc index 151c941c..35877de5 100644 --- a/src/synthesis.cc +++ b/src/synthesis.cc @@ -564,7 +564,7 @@ void LangVarRef::loadContextObj( Compiler *pd, CodeVect &code, int lastPtrInQual, bool forWriting ) const { /* Start the search in the global object. */ - ObjectDef *rootObj = context->objectDef; + ObjectDef *rootObj = structDef->objectDef; if ( forWriting && lastPtrInQual < 0 ) { /* If we are writing an no reference was found in the qualification @@ -627,7 +627,7 @@ void LangVarRef::loadObj( Compiler *pd, CodeVect &code, loadInbuiltObject( pd, code, lastPtrInQual, forWriting ); else if ( isLocalRef() ) loadLocalObj( pd, code, lastPtrInQual, forWriting ); - else if ( isContextRef() ) + else if ( isStructRef() ) loadContextObj( pd, code, lastPtrInQual, forWriting ); else loadGlobalObj( pd, code, lastPtrInQual, forWriting ); @@ -2278,7 +2278,7 @@ void LangStmt::compileForIter( Compiler *pd, CodeVect &code ) const UniqueType *searchUT = typeRef->uniqueType; /* Lookup the iterator call. Make sure it is an iterator. */ - VarRefLookup lookup = iterCall->langTerm->varRef->lookupMethod( pd ); + VarRefLookup lookup = iterCall->langTerm->varRef->lookupIterCall( pd ); if ( lookup.objMethod->iterDef == 0 ) { error(loc) << "attempt to iterate using something " "that is not an iterator" << endp; |