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;