From 27385ecd7cdd6f0d9fa8dc162a1120056fa67391 Mon Sep 17 00:00:00 2001 From: Peter Aronsson Date: Thu, 6 Jul 2006 14:27:14 +0000 Subject: [PATCH] Fixed bug with lookup of constants in packages (infinite recursion, mofiles/Constant10.mo) Fixed bug which allows to write parameters or variables in packages (mofiles/Constan09.mo) Fixed bug with floor and ceil. (Should return Integer not Real, mofiles/Constant3.mo) git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@2442 f25d12d1-65f4-0310-ae8a-bbce733d8d8e --- Compiler/Ceval.mo | 9 ++-- Compiler/Error.mo | 5 +- Compiler/Lookup.mo | 118 ++++++++++++++++++++++++++++++--------------- Compiler/Static.mo | 4 +- 4 files changed, 91 insertions(+), 45 deletions(-) diff --git a/Compiler/Ceval.mo b/Compiler/Ceval.mo index 8492af02ec0..276a5422a31 100644 --- a/Compiler/Ceval.mo +++ b/Compiler/Ceval.mo @@ -3623,6 +3623,7 @@ algorithm matchcontinue (inCache,inEnv,inExpExpLst,inBoolean,inInteractiveInteractiveSymbolTableOption,inMsg) local Real rv,rv_1; + Integer iv; list env; Exp.Exp exp; Boolean impl; @@ -3633,8 +3634,9 @@ algorithm equation (cache,Values.REAL(rv),_) = ceval(cache,env, exp, impl, st, NONE, msg); rv_1 = realFloor(rv); + iv=realInt(rv_1); then - (cache,Values.REAL(rv_1),st); + (cache,Values.INTEGER(iv),st); end matchcontinue; end cevalBuiltinFloor; @@ -3672,16 +3674,15 @@ algorithm rvt = intReal(ri); (rvt ==. rv) = true; then - (cache,Values.REAL(rv_1),st); + (cache,Values.INTEGER(ri),st); case (cache,env,{exp},impl,st,msg) equation (cache,Values.REAL(rv),_) = ceval(cache,env, exp, impl, st, NONE, msg); rv_1 = realFloor(rv); ri = realInt(rv_1); ri_1 = ri + 1; - rv_2 = intReal(ri_1); then - (cache,Values.REAL(rv_2),st); + (cache,Values.INTEGER(ri_1),st); end matchcontinue; end cevalBuiltinCeil; diff --git a/Compiler/Error.mo b/Compiler/Error.mo index 82fc57b23ef..7a5b9efb025 100644 --- a/Compiler/Error.mo +++ b/Compiler/Error.mo @@ -270,6 +270,8 @@ public constant ErrorID ERROR_FLATTENING=88; public constant ErrorID DUPLICATE_ELEMENTS_NOT_IDENTICAL=89; +public constant ErrorID PACKAGE_VARIABLE_NOT_CONSTANT=90; + public constant ErrorID UNBOUND_PARAMETER_WARNING=500; public constant ErrorID BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER=501; @@ -449,7 +451,8 @@ protected constant list> errorTabl (ERROR_FLATTENING,TRANSLATION(),ERROR(), "Error occured while flattening model %s"), (DUPLICATE_ELEMENTS_NOT_IDENTICAL,TRANSLATION(),ERROR(), - "Error duplicate elements (due to inherited elements) not identical, first element is: %s, second element is: %s."), + "Error duplicate elements (due to inherited elements) not identical, first element is: %s, second element is: %s"), + (PACKAGE_VARIABLE_NOT_CONSTANT, TRANSLATION(),ERROR(),"Variable %s in package %s is not constant"), (UNBOUND_PARAMETER_WARNING,TRANSLATION(),WARNING(), "Warning, parameter %s has no value."), (BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER(),TRANSLATION(),WARNING(), diff --git a/Compiler/Lookup.mo b/Compiler/Lookup.mo index c464c63b8ad..4bf86f9768e 100644 --- a/Compiler/Lookup.mo +++ b/Compiler/Lookup.mo @@ -323,11 +323,12 @@ protected function lookupQualifiedImportedVarInFrame "function: lookupQualifiedI input Env.Env inEnv; input SCode.Ident inIdent; output Env.Cache outCache; + output Env.Env outEnv; output Types.Attributes outAttributes; output Types.Type outType; output Types.Binding outBinding; algorithm - (outCache,outAttributes,outType,outBinding):= + (outCache,outEnv,outAttributes,outType,outBinding):= matchcontinue (inCache,inEnvItemLst,inEnv,inIdent) local Env.Frame fr; @@ -336,7 +337,7 @@ algorithm Types.Binding bind; String id,ident,str; list fs; - list env; + list env,p_env; Exp.ComponentRef cref; Absyn.Path strippath,path; SCode.Class c2; @@ -348,26 +349,26 @@ algorithm fr = Env.topFrame(env); (cache,attr,ty,bind) = lookupVar(cache,{fr}, Exp.CREF_IDENT(ident,{})); then - (cache,attr,ty,bind); + (cache,{fr},attr,ty,bind); case (cache,(Env.IMPORT(import_ = Absyn.QUAL_IMPORT(path = path)) :: fs),env,ident) /* For imported qualified name, e.g. A.B.C, assert A.B is package */ equation id = Absyn.pathLastIdent(path); equality(id = ident); fr = Env.topFrame(env); cref = Exp.pathToCref(path); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); strippath = Absyn.stripLast(path); (cache,c2,_) = lookupClass(cache,{fr}, strippath, true); assertPackage(c2); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); case (cache,(Env.IMPORT(import_ = Absyn.QUAL_IMPORT(path = path)) :: fs),env,ident) /* importing qualified name, If not package, error */ equation id = Absyn.pathLastIdent(path); equality(id = ident); fr = Env.topFrame(env); cref = Exp.pathToCref(path); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); strippath = Absyn.stripLast(path); (cache,c2,_) = lookupClass(cache,{fr}, strippath, true); failure(assertPackage(c2)); @@ -380,18 +381,18 @@ algorithm equality(id = ident); fr = Env.topFrame(env); cref = Exp.pathToCref(path); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); strippath = Absyn.stripLast(path); (cache,c2,_) = lookupClass(cache,{fr}, strippath, true); assertPackage(c2); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); case (cache,(Env.IMPORT(import_ = Absyn.NAMED_IMPORT(name = id,path = path)) :: fs),env,ident) /* Assert package for Named imports */ equation equality(id = ident); fr = Env.topFrame(env); cref = Exp.pathToCref(path); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{fr}, cref); strippath = Absyn.stripLast(path); (cache,c2,_) = lookupClass(cache,{fr}, strippath, true); failure(assertPackage(c2)); @@ -401,9 +402,9 @@ algorithm fail(); case (cache,(_ :: fs),env,ident) /* Check next frame. */ equation - (cache,attr,ty,bind) = lookupQualifiedImportedVarInFrame(cache,fs, env, ident); + (cache,p_env,attr,ty,bind) = lookupQualifiedImportedVarInFrame(cache,fs, env, ident); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); end matchcontinue; end lookupQualifiedImportedVarInFrame; @@ -440,7 +441,7 @@ algorithm equation firstIdent = Absyn.pathFirstIdent(path); f::_ = Env.cacheGet(Absyn.IDENT(firstIdent),path,cache); - (cache,_,_,_) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); + (cache,_,_,_,_) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); then (cache,true); @@ -455,7 +456,7 @@ algorithm ci_state, c, false/*FIXME:prot*/, {}, false);*/ (cache,(f :: _),_) = Inst.partialInstClassIn(cache,env2, Types.NOMOD(), Prefix.NOPRE(), Connect.emptySet, ci_state, c, false, {}); - (cache,_,_,_) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); + (cache,_,_,_,_) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); then (cache,true); case (cache,(_ :: fs),env,ident) @@ -476,12 +477,13 @@ protected function lookupUnqualifiedImportedVarInFrame "function: lookupUnqualif input Env.Env inEnv; input SCode.Ident inIdent; output Env.Cache outCache; + output Env.Env outEnv; output Types.Attributes outAttributes; output Types.Type outType; output Types.Binding outBinding; output Boolean outBoolean; algorithm - (outCache,outAttributes,outType,outBinding,outBoolean):= + (outCache,outEnv,outAttributes,outType,outBinding,outBoolean):= matchcontinue (inCache,inEnvItemLst,inEnv,inIdent) local Env.Frame fr,f; @@ -490,7 +492,7 @@ algorithm String id,ident; Boolean encflag,more,unique; SCode.Restriction restr; - list env_1,env2,env; + list env_1,env2,env,p_env; ClassInf.State ci_state; Types.Attributes attr; tuple> ty; @@ -508,11 +510,11 @@ algorithm //print("look in cache\n"); firstIdent = Absyn.pathFirstIdent(path); f::_ = Env.cacheGet(Absyn.IDENT(firstIdent),path,cache); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); (cache,more) = moreLookupUnqualifiedImportedVarInFrame(cache,fs, env, ident); unique = boolNot(more); then - (cache,attr,ty,bind,unique); + (cache,p_env,attr,ty,bind,unique); // if not in cache, try to instantiate case (cache,(Env.IMPORT(import_ = Absyn.UNQUAL_IMPORT(path = path)) :: fs),env,ident) /* unique */ @@ -524,16 +526,16 @@ algorithm ci_state = ClassInf.start(restr, id); (cache,_,(f :: _),_,_,_,_) = Inst.instClassIn(cache,env2, Types.NOMOD(), Prefix.NOPRE(), Connect.emptySet, ci_state, c, false, {}, false); - (cache,attr,ty,bind) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,{f}, Exp.CREF_IDENT(ident,{})); (cache,more) = moreLookupUnqualifiedImportedVarInFrame(cache,fs, env, ident); unique = boolNot(more); then - (cache,attr,ty,bind,unique); + (cache,p_env,attr,ty,bind,unique); case (cache,(_ :: fs),env,ident) equation - (cache,attr,ty,bind,unique) = lookupUnqualifiedImportedVarInFrame(cache,fs, env, ident); + (cache,p_env,attr,ty,bind,unique) = lookupUnqualifiedImportedVarInFrame(cache,fs, env, ident); then - (cache,attr,ty,bind,unique); + (cache,p_env,attr,ty,bind,unique); end matchcontinue; end lookupUnqualifiedImportedVarInFrame; @@ -805,7 +807,7 @@ algorithm Types.Attributes attr; tuple> ty; Types.Binding binding; - list env; + list env,p_env; Exp.ComponentRef cref; Env.Cache cache; case (cache,env,cref) /* try the old lookup_var */ @@ -815,7 +817,8 @@ algorithm (cache,attr,ty,binding); case (cache,env,cref) /* then look in classes (implicitly instantiated packages) */ equation - (cache,attr,ty,binding) = lookupVarInPackages(cache,env, cref); + (cache,p_env,attr,ty,binding) = lookupVarInPackages(cache,env, cref); + checkPackageVariableConstant(p_env,attr,ty,cref); then (cache,attr,ty,binding); case (_,env,cref) equation @@ -823,6 +826,27 @@ algorithm end matchcontinue; end lookupVar; +protected function checkPackageVariableConstant " +Variables in packages must be constant. This function produces an error message and fails +if variable is not constant." + input Env.Env env; + input Types.Attributes attr; + input Types.Type tp; + input Exp.ComponentRef cref; +algorithm + _ := matchcontinue(env,attr,tp,cref) + local Absyn.Path path; + case (env, Types.ATTR(parameter_= SCode.CONST()),_,cref) + then (); + case (env,attr,tp,cref) local String s1,s2; + equation + s1=Exp.printComponentRefStr(cref); + s2 = Env.printEnvPathStr(env); + Error.addMessage(Error.PACKAGE_VARIABLE_NOT_CONSTANT,{s1,s2}); + then fail(); + end matchcontinue; +end checkPackageVariableConstant; + protected function lookupVarInternal "function: lookupVarInternal Helper function to lookup_var. Searches the frames for variables. @@ -880,18 +904,19 @@ protected function lookupVarInPackages "function: lookupVarInPackages input Env.Env inEnv; input Exp.ComponentRef inComponentRef; output Env.Cache outCache; + output Env.Env outEnv; output Types.Attributes outAttributes; output Types.Type outType; output Types.Binding outBinding; algorithm - (outCache,outAttributes,outType,outBinding):= + (outCache,outEnv,outAttributes,outType,outBinding):= matchcontinue (inCache,inEnv,inComponentRef) local SCode.Class c; String n,id1,id; Boolean encflag; SCode.Restriction r; - list env2,env3,env5,env,fs,bcframes; + list env2,env3,env5,env,fs,bcframes,p_env; ClassInf.State ci_state; list types; Types.Attributes attr; @@ -912,9 +937,9 @@ algorithm ci_state = ClassInf.start(r, n); (cache,_,env5,_,_,types,_) = Inst.instClassIn(cache,env3, Types.NOMOD(), Prefix.NOPRE(), Connect.emptySet, ci_state, c, false, {}, false); - (cache,attr,ty,bind) = lookupVarInPackages(cache,env5, id2); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,env5, id2); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); // lookup of constants on form A.B in packages. First look in cache. case (cache,env,cr as Exp.CREF_QUAL(ident = id,subscriptLst = {},componentRef = cref)) /* First part of name is a class. */ @@ -930,7 +955,21 @@ algorithm (cache,attr,ty,bind) = lookupVarLocal(cache,f::fs, Exp.CREF_IDENT(id,{})); //print("found ");print(Exp.printComponentRefStr(cr));print(" in cache\n"); then - (cache,attr,ty,bind); + (cache,f::fs,attr,ty,bind); + + /* If we search for A1.A2....An.x while in scope A1.A2...An, just search for x. + Must do like this to ensure finite recursion */ + case (cache,env,cr as Exp.CREF_QUAL(ident = id,subscriptLst = {},componentRef = cref)) + local Absyn.Path ep,p,packp; + equation + p = Exp.crefToPath(cr); + SOME(ep) = Env.getEnvPath(env); + packp = Absyn.stripLast(p); + true = ModUtil.pathEqual(ep, packp); + id = Absyn.pathLastIdent(p); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,env, Exp.CREF_IDENT(id,{})); + then + (cache,p_env,attr,ty,bind); // lookup of constants on form A.B in packages. instantiate package and look inside. case (cache,env,cr as Exp.CREF_QUAL(ident = id,subscriptLst = {},componentRef = cref)) /* First part of name is a class. */ @@ -940,14 +979,15 @@ algorithm ci_state = ClassInf.start(r, n); (cache,_,env5,_,_,types,_) = Inst.instClassIn(cache,env3, Types.NOMOD(), Prefix.NOPRE(), Connect.emptySet, ci_state, c, false, {}, /*true*/false); - (cache,attr,ty,bind) = lookupVarInPackages(cache,env5, cref); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,env5, cref); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); + case (cache,env,(cr as Exp.CREF_IDENT(ident = id,subscriptLst = sb))) local String str; equation (cache,attr,ty,bind) = lookupVarLocal(cache,env, cr); then - (cache,attr,ty,bind); + (cache,env,attr,ty,bind); /* Search base classes */ case (cache,Env.FRAME(list_5 = (bcframes as (_ :: _)))::fs,cref) @@ -956,28 +996,30 @@ algorithm (cache,attr,ty,bind) = lookupVar(cache,bcframes, cref); //print("found in baseclass\n"); then - (cache,attr,ty,bind); + (cache,bcframes,attr,ty,bind); /* Search among qualified imports, e.g. import A.B; or import D=A.B; */ case (cache,(env as (Env.FRAME(class_1 = sid,list_4 = items) :: _)),(cr as Exp.CREF_IDENT(ident = id,subscriptLst = sb))) equation - (cache,attr,ty,bind) = lookupQualifiedImportedVarInFrame(cache,items, env, id); + (cache,p_env,attr,ty,bind) = lookupQualifiedImportedVarInFrame(cache,items, env, id); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); + /* Search among unqualified imports, e.g. import A.B.* */ case (cache,(env as (Env.FRAME(class_1 = sid,list_4 = items) :: _)),(cr as Exp.CREF_IDENT(ident = id,subscriptLst = sb))) local Boolean unique; equation - (cache,attr,ty,bind,unique) = lookupUnqualifiedImportedVarInFrame(cache,items, env, id); + (cache,p_env,attr,ty,bind,unique) = lookupUnqualifiedImportedVarInFrame(cache,items, env, id); reportSeveralNamesError(unique,id); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); case (cache,(f :: fs),cr) /* Search parent scopes */ equation //print("searching parent scope of ");print(Env.printEnvPathStr(fs));print("\n"); - (cache,attr,ty,bind) = lookupVarInPackages(cache,fs, cr); + (cache,p_env,attr,ty,bind) = lookupVarInPackages(cache,fs, cr); then - (cache,attr,ty,bind); + (cache,p_env,attr,ty,bind); + case (cache,env,cr) /* Debug.fprint(\"failtrace\", \"lookup_var_in_packages failed\\n exp:\" ) & Debug.fcall(\"failtrace\", Exp.print_component_ref, cr) & Debug.fprint(\"failtrace\", \"\\n\") */ then fail(); diff --git a/Compiler/Static.mo b/Compiler/Static.mo index ca0420d15e4..2fa19a33340 100644 --- a/Compiler/Static.mo +++ b/Compiler/Static.mo @@ -2743,7 +2743,7 @@ algorithm equation (cache,s1_1,Types.PROP((Types.T_REAL({}),NONE),c),_) = elabExp(cache,env, s1, impl, NONE) "print \"# floor function not implemented yet\\n\" &" ; then - (cache,Exp.CALL(Absyn.IDENT("floor"),{s1_1},false,true),Types.PROP((Types.T_REAL({}),NONE),c)); + (cache,Exp.CALL(Absyn.IDENT("floor"),{s1_1},false,true),Types.PROP((Types.T_INTEGER({}),NONE),c)); end matchcontinue; end elabBuiltinFloor; @@ -2772,7 +2772,7 @@ algorithm equation (cache,s1_1,Types.PROP((Types.T_REAL({}),NONE),c),_) = elabExp(cache,env, s1, impl, NONE) "print \"# ceil function not implemented yet\\n\" &" ; then - (cache,Exp.CALL(Absyn.IDENT("ceil"),{s1_1},false,true),Types.PROP((Types.T_REAL({}),NONE),c)); + (cache,Exp.CALL(Absyn.IDENT("ceil"),{s1_1},false,true),Types.PROP((Types.T_INTEGER({}),NONE),c)); end matchcontinue; end elabBuiltinCeil;