diff --git a/Compiler/Ceval.mo b/Compiler/Ceval.mo index 6302dd930ed..e371b230eac 100644 --- a/Compiler/Ceval.mo +++ b/Compiler/Ceval.mo @@ -3313,6 +3313,7 @@ algorithm local Exp.Exp dim; equation (cache,attr,tp,bind) = Lookup.lookupVar(cache,env, cr) "If dimensions not known and impl=false, error message" ; + false = Types.dimensionsKnown(tp); cr_str = Exp.printComponentRefStr(cr); dim_str = Exp.printExpStr(dim); @@ -3347,12 +3348,15 @@ algorithm (cache,attr,tp,Types.UNBOUND()) = Lookup.lookupVar(cache,env, cr) "For crefs without value binding. If impl=true just silently fail" ; then fail(); + + /* For crefs with value binding + e.g. size(x,1) when Real x[:]=fill(0,1); */ case (cache,env,(exp as Exp.CREF(componentRef = cr,ty = crtp)),dim,impl,st,msg) local Values.Value v; Exp.Exp dim; equation - (cache,attr,tp,binding) = Lookup.lookupVar(cache,env, cr) "For crefs with value binding" ; + (cache,attr,tp,binding) = Lookup.lookupVar(cache,env, cr) ; (cache,Values.INTEGER(dimv),st_1) = ceval(cache,env, dim, impl, st, NONE, msg); (cache,v) = cevalCrefBinding(cache,env, cr, binding, impl, msg); v2 = cevalBuiltinSize2(v, dimv); @@ -3370,6 +3374,24 @@ algorithm len = listLength((e :: es)); then (cache,Values.INTEGER(len),st_1); + + /* For expressions with value binding that can not determine type + e.g. size(x,2) when Real x[:,:]=fill(0.0,0,2); empty array with second dimension == 2, no way of + knowing that from the value. Must investigate the expression itself.*/ + case (cache,env,exp,dim,impl,st,msg) + local + Values.Value v; + Exp.Exp dim; + list> adims; + Integer i; + equation + (cache,Values.ARRAY({}),st_1) = ceval(cache,env, exp, impl, st, NONE, msg) "try to ceval expression, for constant expressions" ; + (cache,Values.INTEGER(dimv),st_1) = ceval(cache,env, dim, impl, st, NONE, msg); + adims = Exp.arrayTypeDimensions(Exp.typeof(exp)); + SOME(i) = listNth(adims,dimv-1); + then + (cache,Values.INTEGER(i),st_1); + case (cache,env,exp,dim,impl,st,msg) local Values.Value v; diff --git a/Compiler/Exp.mo b/Compiler/Exp.mo index cb756a69d2a..370840d1e5a 100644 --- a/Compiler/Exp.mo +++ b/Compiler/Exp.mo @@ -3319,6 +3319,15 @@ algorithm end matchcontinue; end abs; +public function arrayTypeDimensions "Return the array dimensions of a type." + input Type tp; + output list> dims; +algorithm + dims := matchcontinue(tp) + case(T_ARRAY(_,dims)) then dims; + end matchcontinue; +end arrayTypeDimensions; + public function typeBuiltin "function: typeBuiltin Returns true if type is one of the builtin types. diff --git a/Compiler/Inst.mo b/Compiler/Inst.mo index 52a3af2a75a..228746d1a6c 100644 --- a/Compiler/Inst.mo +++ b/Compiler/Inst.mo @@ -164,26 +164,29 @@ protected import VarTransform; protected constant String forScopeName="$for loop scope$"; -protected function printDims "function: printDims +protected function printDimsStr "function: printDims - Print DimExp list + Print DimExp list to a string " input list inDimExpLst; + output String str; algorithm - _:= + str:= matchcontinue (inDimExpLst) local DimExp x; list xs; + String s1,s2; case ((x :: xs)) equation - printDim({SOME(x)}); - printDims(xs); + s1 = printDimStr({SOME(x)}); + s2 = printDimsStr(xs); + str = Util.stringDelimitListNoEmpty({s1,s2},","); then - (); - case ({}) then (); + str; + case ({}) then ""; end matchcontinue; -end printDims; +end printDimsStr; public function newIdent "function: newIdent @@ -3323,18 +3326,15 @@ algorithm crefs2 = getCrefFromDim(ad); crefs_1 = Util.listFlatten({crefs,crefs2}); crefs_2 = removeCrefFromCrefs(crefs_1, owncref); - (cache,env) = getDerivedEnv(cache,env, bc); (cache,env2,csets) = updateComponentsInEnv(cache,mods, crefs_2, env, ci_state, csets, impl); - //Update the untyped modifiers to typed ones, and extract class and //component modifiers again. (cache,mods_1) = Mod.updateMod(cache,env2, pre, mods, impl) ; - + //Refetch the component from environment, since attributes, etc. //might have changed.. comp used in redeclare_type below... (cache,_,SOME((comp,_)),_,_) = Lookup.lookupIdentLocal(cache,env2, n); - classmod_1 = Mod.lookupModificationP(mods_1, t); mm_1 = Mod.lookupCompModification(mods_1, n); (cache,m) = removeSelfModReference(cache,n,m); // Remove self-reference i.e. A a(x=a.y); @@ -3342,11 +3342,12 @@ algorithm mod = Mod.merge(classmod_1, mm_1, env2, pre); mod1 = Mod.merge(mod, m_1, env2, pre); mod1_1 = Mod.merge(cmod, mod1, env2, pre); + + /* Apply redeclaration modifier to component */ (cache,SCode.COMPONENT(n,io,final_,repl,prot,(attr as SCode.ATTR(ad,flow_,acc,param,dir)),Absyn.TPATH(t, _),m,bc,comment),mod_1,env2_1,csets) = redeclareType(cache,mod1_1, comp, env2, pre, ci_state, csets, impl); (cache,env_1) = getDerivedEnv(cache,env, bc); (cache,cl,cenv) = Lookup.lookupClass(cache,env_1, t, true); - //If the element is `protected\', and an external modification //is applied, it is an error. checkProt(prot, mm_1, vn) ; @@ -3360,10 +3361,10 @@ algorithm //The environment is extended (updated) with the new variable binding. (cache,binding) = makeBinding(cache,env2_1, attr, mod_1, ty) ; - + //true in update_frame means the variable is now instantiated. new_var = Types.VAR(n,Types.ATTR(flow_,acc,param,dir),prot,ty,binding) ; - + //type info present Now we can also put the binding into the dae. //If the type is one of the simple, predifined types a simple variable //declaration is added to the DAE. @@ -3374,6 +3375,7 @@ algorithm // If an outer element, remove this variable from the DAE. Variable references will be bound to // corresponding inner element instead. //dae2 = Util.if_(ModUtil.isOuter(io),{},dae); + then (cache,dae,env_1,csets_1,ci_state,vars); @@ -3838,6 +3840,7 @@ algorithm (cache,compenv,dae,csets_1,ty_1) = instVar2(cache,env, ci_state, mod, pre, csets, n, cl, attr, dims_1, idxs, inst_dims, impl, comment,io); ty = makeArrayType(dims_1, ty_1); + print("making array type:");print(Types.unparseType(ty));print("\n"); then (cache,compenv,dae,csets_1,ty); // Generic case: fall trough @@ -3949,7 +3952,7 @@ algorithm then (cache,env_1,dae,csets_1,ty_1); - // Array vars without binding in functions , e.g. input Real x{:} + /* Array vars without binding in functions , e.g. input Real x[:] */ case (cache,env,(ci_state as ClassInf.FUNCTION(string = _)),mod,pre,csets,n,cl,attr,(dims as (_ :: _)),idxs,inst_dims,impl,comment,io) equation //Do not flatten because it is a function @@ -3986,7 +3989,7 @@ algorithm {},idxs,inst_dims,impl,comment,io) equation idxs_1 = listReverse(idxs); - pre_1 = Prefix.prefixAdd(n, idxs_1, pre); + pre_1 = Prefix.prefixAdd(n, idxs_1, pre); (cache,dae1,env_1,csets_1,ty,st) = instClass(cache,env, mod, pre_1, csets, cl, inst_dims, impl, INNER_CALL()); dae1_1 = propagateAttributes(dae1, dir,io); subs = Exp.intSubscripts(idxs_1); @@ -4047,10 +4050,10 @@ algorithm then (cache,env_1,dae,csets_1,ty); - /* FIXME: make a similar rule: if implicit=true and we fail to flatten, we should leave it unflattened */ + /* Array variables , e.g. Real x[3]*/ case (cache,env,ci_state,mod,pre,csets,n,cl,attr,(dim :: dims),idxs,inst_dims,impl,comment,io) equation - dime = instDimExp(dim, impl) "Array variables , e.g. Real x{3} flatten" ; + dime = instDimExp(dim, impl); inst_dims_1 = listAppend(inst_dims, {dime}); (cache,compenv,dae,Connect.SETS(_,crs),ty) = instArray(cache,env, ci_state, mod, pre, csets, n, (cl,attr), 1, dim, dims, idxs, inst_dims_1, impl, comment,io); @@ -4064,6 +4067,7 @@ algorithm // parameters and protected variables) case (_,_,_,_,_,_,n,_,_,_,_,_,_,_,_) equation + print("instVar2 failed\n"); Debug.fprint("failtrace", "- inst_var2 failed: "); Debug.fprint("failtrace", n); Debug.fprint("failtrace", "\n"); @@ -4888,7 +4892,7 @@ algorithm matchcontinue (inCache,inEnv,inState,inMod,inPrefix,inSets,inIdent,inTplSCodeClassSCodeAttributes,inInteger,inDimExp,inDimExpLst,inIntegerLst,inInstDims,inBoolean,inAbsynCommentOption,io) local Exp.Exp e,e_1; - Types.Properties p; + Types.Properties p,p2; list env_1,env,compenv; Connect.Sets csets,csets_1,csets_2; tuple> ty,arrty; @@ -4929,11 +4933,19 @@ algorithm then (cache,compenv,dae,csets,ty); + /* Special case when instantiating Real[0]. We need to know the type */ + case (cache,env,ci_state,mod,pre,csets,n,(cl,attr),i,DIMINT(0),dims,idxs,inst_dims,impl,comment,io) + equation + (cache,compenv,_,csets,ty) = instVar2(cache,env, ci_state, mod, pre, csets, n, cl, attr, dims, + (0 :: idxs), inst_dims, impl, comment,io); + then + (cache,compenv,{},csets,ty); + case (cache,env,ci_state,mod,pre,csets,n,(cl,attr),i,DIMINT(integer = stop),dims,idxs,inst_dims,impl,comment,io) equation (i > stop) = true; then - (cache,{},{},csets,(Types.T_NOTYPE(),NONE)); + (cache,env,{},csets,(Types.T_NOTYPE(),NONE)); /* Modifiers of arrays that are functioncall, eg. Real x{:}=foo(...) Should only generate -one- functioncall */ @@ -5259,60 +5271,6 @@ algorithm end matchcontinue; end printDimStr; -protected function printDim "function: printDim - - Prints a dimension expression option list to the print buffer. -" - input list> dims; - String str; -algorithm - str := printDimStr(dims); - Print.printBuf(str); -end printDim; - -protected function printDim2 "function printDim2 - - Helper function to print_dim -" - input list inDimExpLst; -algorithm - _:= - matchcontinue (inDimExpLst) - local - String s; - Integer x; - list xs; - case {DIMINT(integer = x)} - equation - s = intString(x); - Print.printBuf(s); - then - (); - case {DIMEXP(subscript = x)} - local Exp.Subscript x; - equation - Exp.printSubscript(x); - then - (); - case (DIMINT(integer = x) :: xs) - equation - s = intString(x); - Print.printBuf(s); - Print.printBuf(","); - printDim2(xs); - then - (); - case (DIMEXP(subscript = x) :: xs) - local Exp.Subscript x; - equation - Exp.printSubscript(x); - Print.printBuf(","); - printDim2(xs); - then - (); - case {} then (); - end matchcontinue; -end printDim2; protected function elabArraydimDecl "function: elabArraydimDecl diff --git a/Compiler/Mod.mo b/Compiler/Mod.mo index 07694a16615..dd5a4f1dc6e 100644 --- a/Compiler/Mod.mo +++ b/Compiler/Mod.mo @@ -1111,7 +1111,7 @@ algorithm (mod,(x :: xs_1)); case (_,_,_) equation - Print.printBuf("- lookup_idx_modification2 failed\n"); + Debug.fprint("failtrace", "-lookupIdxModification2 failed\n"); then fail(); end matchcontinue; @@ -1142,6 +1142,9 @@ algorithm then Types.MOD(f,Absyn.NON_EACH(),subs,eq_1); case (Types.MOD(final_ = f,each_ = Absyn.EACH(),subModLst = subs,eqModOption = eq),idx) then Types.MOD(f,Absyn.EACH(),subs,eq); + case (_,_) equation + Debug.fprint("failtrace", "-lookupIdxModification3 failed\n"); + then fail(); end matchcontinue; end lookupIdxModification3; @@ -1169,6 +1172,10 @@ algorithm list xs; case (NONE,_) then NONE; case (e,{}) then e; + /* Subscripting empty array gives no value. This is needed in e.g. fill(1.0,0,2) */ + case (SOME(Types.TYPED(_,SOME(Values.ARRAY({})),_)),xs) then NONE; + + /* For modifiers with value, retrieve nth element*/ case (SOME(Types.TYPED(e,SOME(e_val),Types.PROP(t,c))),(x :: xs)) equation t_1 = Types.unliftArray(t); @@ -1177,13 +1184,18 @@ algorithm e = indexEqmod(SOME(Types.TYPED(exp,SOME(e_val_1),Types.PROP(t_1,c))), xs); then e; + + /* For modifiers without value, apply subscript operaor */ case (SOME(Types.TYPED(e,NONE,Types.PROP(t,c))),(x :: xs)) equation t_1 = Types.unliftArray(t); exp = Exp.simplify(Exp.ASUB(e,x)); e = indexEqmod(SOME(Types.TYPED(exp,NONE,Types.PROP(t_1,c))), xs); then - e; + e; + case (_,_) equation + Debug.fprint("failtrace", "-indexEqmod failed\n"); + then fail(); end matchcontinue; end indexEqmod; diff --git a/Compiler/Static.mo b/Compiler/Static.mo index 6103b841cea..84e02712218 100644 --- a/Compiler/Static.mo +++ b/Compiler/Static.mo @@ -440,8 +440,10 @@ algorithm (start_2,NONE,stop_2,rt) = deoverloadRange((start_1,start_t), NONE, (stop_1,stop_t)); const = Types.constAnd(c_start, c_stop); (cache,t) = elabRangeType(cache,env, start_2, NONE, stop_2, const, rt, impl); + (cache,exp_2,prop_1) = cevalIfConstant(cache,Exp.RANGE(rt,start_2,NONE,stop_2), Types.PROP(t,const), const, impl, env); then - (cache,Exp.RANGE(rt,start_1,NONE,stop_1),Types.PROP(t,const),st_2); + (cache,exp_2,prop_1,st_2); + case (cache,env,Absyn.RANGE(start = start,step = SOME(step),stop = stop),impl,st,doVect) equation (cache,start_1,Types.PROP(start_t,c_start),st_1) = elabExp(cache,env, start, impl, st,doVect) "Range expressions with step value, e.g. 1:0.5:4" ; @@ -451,8 +453,10 @@ algorithm c1 = Types.constAnd(c_start, c_step); const = Types.constAnd(c1, c_stop); (cache,t) = elabRangeType(cache,env, start_2, SOME(step_2), stop_2, const, rt, impl); + (cache,exp_2,prop_1) = cevalIfConstant(cache,Exp.RANGE(rt,start_2,SOME(step_2),stop_2), Types.PROP(t,const), const, impl, env); then - (cache,Exp.RANGE(rt,start_2,SOME(step_2),stop_2),Types.PROP(t,const),st_3); + (cache,exp_2,prop_1,st_3); + case (cache,env,Absyn.ARRAY(arrayExp = es),impl,st,doVect) equation (cache,es_1,Types.PROP(t,const)) = elabArray(cache,env, es, impl, st,doVect) "array expressions, e.g. {1,2,3}" ; @@ -2003,9 +2007,11 @@ algorithm Absyn.Exp arraycr,dim; list expl; Env.Cache cache; - case (cache,env,{arraycr,dim},impl) /* impl */ + + /*size(A,x) that returns size of x:th dimension */ + case (cache,env,{arraycr,dim},impl) equation - (cache,dimp,Types.PROP(_,c1),_) = elabExp(cache,env, dim, impl, NONE,true) "size(A,x) that returns size of x:th dimension" ; + (cache,dimp,Types.PROP(_,c1),_) = elabExp(cache,env, dim, impl, NONE,true) ; (cache,arraycrefe,Types.PROP(arrtp,_),_) = elabExp(cache,env, arraycr, impl, NONE,true); c2 = Types.dimensionsKnown(arrtp); c2_1 = Types.boolConst(c2); @@ -2013,10 +2019,12 @@ algorithm exp = Exp.SIZE(arraycrefe,SOME(dimp)); then (cache,exp,Types.PROP((Types.T_INTEGER({}),NONE),c)); + + /* size(A) */ case (cache,env,{arraycr},impl) local Boolean c; equation - (cache,arraycrefe,Types.PROP(arrtp,_),_) = elabExp(cache,env, arraycr, impl, NONE,true) "size(A)" ; + (cache,arraycrefe,Types.PROP(arrtp,_),_) = elabExp(cache,env, arraycr, impl, NONE,true) ; c = Types.dimensionsKnown(arrtp); c_1 = Types.boolConst(c); exp = Exp.SIZE(arraycrefe,NONE); @@ -2108,7 +2116,7 @@ algorithm (cache,dims_1,dimprops,_) = elabExpList(cache,env, dims, impl, NONE,true); sty = Types.getPropType(prop); (cache,dimvals) = Ceval.cevalList(cache,env, dims_1, impl, NONE, Ceval.MSG()); - (cache,exp,prop) = elabBuiltinFill2(cache,env, s_1, sty, dimvals); + (cache,exp,prop) = elabBuiltinFill2(cache,env, s_1, sty, dimvals); then (cache,exp,prop); case (cache,env,dims,impl) @@ -2147,7 +2155,7 @@ algorithm Boolean a; list env; Exp.Exp s,exp; - tuple> sty,ty; + tuple> sty,ty,sty2; Integer v; Types.Const con; list rest; @@ -2156,20 +2164,21 @@ algorithm equation arraylist = buildExpList(s, v); dimension = intString(v); - at = Types.elabType(sty); - a = Types.isArray(sty); + sty2 = (Types.T_ARRAY(Types.DIM(SOME(v)),sty),NONE); + at = Types.elabType(sty2); + a = Types.isArray(sty2); then - (cache,Exp.ARRAY(at,a,arraylist),Types.PROP((Types.T_ARRAY(Types.DIM(SOME(v)),sty),NONE), - Types.C_CONST())); + (cache,Exp.ARRAY(at,a,arraylist),Types.PROP(sty2,Types.C_CONST())); case (cache,env,s,sty,(Values.INTEGER(integer = v) :: rest)) equation (cache,exp,Types.PROP(ty,con)) = elabBuiltinFill2(cache,env, s, sty, rest); arraylist = buildExpList(exp, v); dimension = intString(v); - at = Types.elabType(ty); - a = Types.isArray(ty); + sty2 = (Types.T_ARRAY(Types.DIM(SOME(v)),ty),NONE); + at = Types.elabType(sty2); + a = Types.isArray(sty2); then - (cache,Exp.ARRAY(at,a,arraylist),Types.PROP((Types.T_ARRAY(Types.DIM(SOME(v)),ty),NONE),Types.C_CONST())); + (cache,Exp.ARRAY(at,a,arraylist),Types.PROP(sty2,Types.C_CONST())); case (_,_,_,_,_) equation Error.addMessage(Error.INTERNAL_ERROR, {"elab_builtin_fill_2 failed"}); @@ -6821,7 +6830,6 @@ algorithm b1 = (ds < 20); b2 = (ds2 < 20); true = boolAnd(b1, b2); - //elt_tp = Exp.arrayEltType(exptp); e = createCrefArray2d(cr, 1, ds, ds2, exptp, t); then e; @@ -6831,7 +6839,6 @@ algorithm equation false = Types.isArray(t); (ds < 20) = true; - //elt_tp = Exp.arrayEltType(exptp); e = createCrefArray(cr, 1, ds, exptp, t); then e; diff --git a/Compiler/Types.mo b/Compiler/Types.mo index ad93a5b19e1..82c789dba7b 100644 --- a/Compiler/Types.mo +++ b/Compiler/Types.mo @@ -714,7 +714,7 @@ algorithm case (v) local Ident vs; equation - Debug.fprint("failtrace", "-type_of_values failed: "); + Debug.fprint("failtrace", "-typeOfValue failed: "); vs = Values.valString(v); Debug.fprintln("failtrace", vs); then diff --git a/Compiler/Util.mo b/Compiler/Util.mo index 3754bfa0e5e..f2bc531d663 100644 --- a/Compiler/Util.mo +++ b/Compiler/Util.mo @@ -139,7 +139,13 @@ algorithm Type_a a; Integer n_1,n; list res; + case(a,n) equation + true = n < 0; + print("Internal Error, negative value to Util.listFill\n"); + then {}; + case (a,0) then {}; case (a,1) then {a}; + case (a,n) equation n_1 = n - 1; diff --git a/Compiler/Values.mo b/Compiler/Values.mo index 2c2cb4ba62b..4e8968a8799 100644 --- a/Compiler/Values.mo +++ b/Compiler/Values.mo @@ -570,6 +570,7 @@ algorithm case ((REAL(real = _) :: _)) then "r"; case ((STRING(string = _) :: _)) then "s"; case ((BOOL(boolean = _) :: _)) then "b"; + case ({}) then "{}"; case (_) then "error"; end matchcontinue; end unparsePrimType;