Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
- Added a new expression type: DAE.RECORD (to eventually replace DAE.CALL for calling record constructor)
  - This is more tied to the record type than the constructor function (which does not take the protected components as input, and thus cannot represent records in a good way)
  - Minor changes are needed to the backend. Most is related to code generation.


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@17553 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Oct 5, 2013
1 parent 6772667 commit 98c9f2b
Show file tree
Hide file tree
Showing 15 changed files with 180 additions and 18 deletions.
13 changes: 13 additions & 0 deletions Compiler/BackEnd/Derive.mo
Expand Up @@ -198,6 +198,7 @@ algorithm
BackendDAE.VarKind kind;
Real r;
BackendDAE.Var var;
list<String> fieldNames;

case (DAE.ICONST(integer = _),_) then DAE.RCONST(0.0);
case (DAE.RCONST(real = _),_) then DAE.RCONST(0.0);
Expand Down Expand Up @@ -560,6 +561,12 @@ algorithm
then
DAE.CALL(fname,expl_1,attr);

case (e as DAE.RECORD(path=fname,exps=expl,comp=fieldNames,ty=tp),(timevars,_))
equation
expl_1 = List.map1(expl, differentiateExpTime, inVariables);
then
DAE.RECORD(fname,expl_1,fieldNames,tp);

case (e as DAE.CALL(path = a,expLst = expl),(_,BackendDAE.SHARED(functionTree=functions)))
equation
// get Derivative function
Expand Down Expand Up @@ -1171,6 +1178,7 @@ algorithm
DAE.ReductionInfo reductionInfo;
DAE.ReductionIterators riters;
DAE.CallAttributes attr;
list<String> fieldNames;

case (DAE.ICONST(integer = _),_,_,_) then DAE.RCONST(0.0);

Expand Down Expand Up @@ -1367,6 +1375,11 @@ algorithm
expl_1 = List.map3(expl, differentiateExp, inComponentRef, differentiateIfExp,inFuncs);
then DAE.CALL(a,expl_1,attr);

case (DAE.RECORD(path=a,exps=expl,comp=fieldNames,ty=tp),_,_,_)
equation
expl_1 = List.map3(expl, differentiateExp, inComponentRef, differentiateIfExp,inFuncs);
then DAE.RECORD(a,expl_1,fieldNames,tp);

/*
this is wrong. The derivative of c > d is not dc > dd. It is the derivative of
(c>d) and this is perhaps NAN for c equal d and 0 otherwise
Expand Down
6 changes: 6 additions & 0 deletions Compiler/FrontEnd/Ceval.mo
Expand Up @@ -386,6 +386,12 @@ algorithm
then
fail();

case (cache, env, DAE.RECORD(path=funcpath, exps=expl, comp = fieldNames), impl, stOpt, msg,_)
equation
(cache, vallst, stOpt) = cevalList(cache, env, expl, impl, stOpt,msg,numIter);
then
(cache,Values.RECORD(funcpath,vallst,fieldNames,-1),stOpt);

// Strings
case (cache,env,DAE.BINARY(exp1 = lh,operator = DAE.ADD(ty = DAE.T_STRING(varLst = _)),exp2 = rh),impl,stOpt,msg,_)
equation
Expand Down
7 changes: 7 additions & 0 deletions Compiler/FrontEnd/DAE.mo
Expand Up @@ -1251,6 +1251,13 @@ uniontype Exp "Expressions
CallAttributes attr;
end CALL;

record RECORD "A record value cannot be represented as a call to its constructor. This record also contains the protected components."
Absyn.Path path;
list<Exp> exps "component values";
list<String> comp "component name";
Type ty;
end RECORD;

record PARTEVALFUNCTION
Absyn.Path path;
list<Exp> expList;
Expand Down
84 changes: 70 additions & 14 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -1895,6 +1895,7 @@ algorithm
case (DAE.RELATION(operator = op)) then typeofRelation(typeofOp(op));
case (DAE.IFEXP(expCond = e1,expThen = e2,expElse = e3)) then typeof(e2);
case (DAE.CALL(attr = DAE.CALL_ATTR(ty=tp))) then tp;
case (DAE.RECORD(ty=tp)) then tp;
case (DAE.PARTEVALFUNCTION(ty=tp)) then tp;
case (DAE.ARRAY(ty = tp)) then tp;
case (DAE.MATRIX(ty = tp)) then tp;
Expand Down Expand Up @@ -2263,6 +2264,7 @@ algorithm
case (e as DAE.UNARY(operator = _)) then {e};
case (e as DAE.IFEXP(expCond = _)) then {e};
case (e as DAE.CALL(path = _)) then {e};
case (e as DAE.RECORD(path = _)) then {e};
case (e as DAE.PARTEVALFUNCTION(path = _)) then {e};
case (e as DAE.ARRAY(ty = _)) then {e};
case (e as DAE.MATRIX(ty = _)) then {e};
Expand Down Expand Up @@ -2416,6 +2418,14 @@ algorithm
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.RECORD(path = _)),acc,_,_)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.RECORD(path = _)),acc,_,_)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
then e::acc;
case ((e as DAE.PARTEVALFUNCTION(path = _)),acc,_,_)
equation
e = Debug.bcallret1(doInverseFactors, inverseFactors, e, e);
Expand Down Expand Up @@ -4040,6 +4050,14 @@ algorithm
then
((e,ext_arg_2));

case ((e as DAE.RECORD(path = fn,exps = expl,comp = fieldNames, ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpList(expl, rel, ext_arg);
e = Util.if_(referenceEq(expl,expl_1),e,DAE.RECORD(fn,expl_1,fieldNames,tp));
((e,ext_arg_2)) = rel((e,ext_arg_1));
then
((e,ext_arg_2));

case ((e as DAE.PARTEVALFUNCTION(path = fn, expList = expl, ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpList(expl, rel, ext_arg);
Expand Down Expand Up @@ -4460,6 +4478,14 @@ algorithm
then
((e,ext_arg_2));

case ((e as DAE.RECORD(path = fn,exps = expl,comp = fieldNames, ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpWithoutRelationsList(expl, rel, ext_arg);
e = Util.if_(referenceEq(expl,expl_1),e,DAE.RECORD(fn,expl_1,fieldNames,tp));
((e,ext_arg_2)) = rel((e,ext_arg_1));
then
((e,ext_arg_2));

case ((e as DAE.PARTEVALFUNCTION(path = fn, expList = expl, ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpWithoutRelationsList(expl, rel, ext_arg);
Expand Down Expand Up @@ -4850,6 +4876,12 @@ algorithm
then
((DAE.CALL(fn,expl_1,attr),ext_arg_1));

case ((e as DAE.RECORD(path = fn,exps = expl,comp = fieldNames,ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpListTopDown(expl, rel, ext_arg);
then
((DAE.RECORD(fn,expl_1,fieldNames,tp),ext_arg_1));

case ((e as DAE.PARTEVALFUNCTION(path = fn, expList = expl, ty = tp)),rel,ext_arg)
equation
((expl_1,ext_arg_1)) = traverseExpListTopDown(expl, rel, ext_arg);
Expand Down Expand Up @@ -5652,6 +5684,12 @@ algorithm
then
(DAE.CALL(path, expl, attr), tup);

case (DAE.RECORD(path = path, exps = expl, comp = strl, ty = ty), tup)
equation
(expl, tup) = traverseExpListBidir(expl, tup);
then
(DAE.RECORD(path, expl, strl, ty), tup);

case (DAE.PARTEVALFUNCTION(path = path, expList = expl, ty = ty), tup)
equation
(expl, tup) = traverseExpListBidir(expl, tup);
Expand Down Expand Up @@ -7342,6 +7380,11 @@ algorithm
res = Absyn.pathEqual(path1, path2);
then expEqualWorkList(expl1, expl2, res);

case (DAE.RECORD(path = path1,exps = expl1),DAE.RECORD(path = path2,exps = expl2),_,_)
equation
res = Absyn.pathEqual(path1, path2);
then expEqualWorkList(expl1, expl2, res);

// partially evaluated functions
case (DAE.PARTEVALFUNCTION(path = path1,expList = expl1),DAE.PARTEVALFUNCTION(path = path2,expList = expl2),_,_)
equation
Expand Down Expand Up @@ -7600,6 +7643,12 @@ algorithm
b = Debug.bcallret2(b, expStructuralEqualList, expl1, expl2, b);
then
b;
case (DAE.RECORD(path = path1,exps = expl1),DAE.RECORD(path = path2,exps = expl2))
equation
b = Absyn.pathEqual(path1, path2);
b = Debug.bcallret2(b, expStructuralEqualList, expl1, expl2, b);
then
b;
// partially evaluated functions
case (DAE.PARTEVALFUNCTION(path = path1,expList = expl1),DAE.PARTEVALFUNCTION(path = path2,expList = expl2))
equation
Expand Down Expand Up @@ -8670,6 +8719,10 @@ algorithm
c2 = listLength(exps);
/* TODO: Cost is based on type and size of inputs. Maybe even name for builtins :) */
then c1+c2+25;
case DAE.RECORD(exps=exps)
equation
c1 = List.fold(List.map(exps,complexity),intAdd,1);
then c1;
case DAE.PARTEVALFUNCTION(ty=_)
then complexityVeryBig; /* This should not be here anyway :) */
case DAE.ARRAY(array=exps,ty=tp)
Expand Down Expand Up @@ -9002,6 +9055,8 @@ algorithm
equation
true = Absyn.pathEqual(p1,p2) "is record constructor";
then exps;
case (DAE.RECORD(exps=exps),_)
then exps;
end match;
end splitRecord;

Expand Down Expand Up @@ -9247,20 +9302,21 @@ algorithm
case(DAE.RELATION(e1,op,e2,_,_)) then 5 + hashExp(e1)+hashOp(op)+hashExp(e2);
case(DAE.IFEXP(e1,e2,e3)) then 6 + hashExp(e1)+hashExp(e2)+hashExp(e3);
case(DAE.CALL(path=path,expLst=expl)) then 7 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.PARTEVALFUNCTION(path=path,expList=expl)) then 8 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.ARRAY(array=expl)) then 9 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.MATRIX(matrix=mexpl)) then 10 + List.reduce(List.map(List.flatten(mexpl),hashExp),intAdd);
case(DAE.RANGE(_,e1,SOME(e2),e3)) then 11 + hashExp(e1)+hashExp(e2)+hashExp(e3);
case(DAE.RANGE(_,e1,NONE(),e3)) then 12 + hashExp(e1)+hashExp(e3);
case(DAE.TUPLE(expl)) then 13 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.CAST(_,e1)) then 14 + hashExp(e1);
case(DAE.ASUB(e1,expl)) then 15 + hashExp(e1)+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.TSUB(e1,i,_)) then 16 + hashExp(e1)+stringHashDjb2(intString(i));
case(DAE.SIZE(e1,SOME(e2))) then 17 + hashExp(e1)+hashExp(e2);
case(DAE.SIZE(e1,NONE())) then 18 + hashExp(e1);
// case(DAE.CODE(_,_)) then 19; // TODO: implement hashing of CODE AST
// case(DAE.EMPTY(scope=_)) then 20; // TODO: implement hashing of EMTPY (needed ?)
case(DAE.REDUCTION(info,e1,iters)) then 21 + hashReductionInfo(info)+hashExp(e1)+List.reduce(List.map(iters,hashReductionIter),intAdd);
case(DAE.RECORD(path=path,exps=expl)) then 8 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.PARTEVALFUNCTION(path=path,expList=expl)) then 9 + stringHashDjb2(Absyn.pathString(path))+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.ARRAY(array=expl)) then 10 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.MATRIX(matrix=mexpl)) then 11 + List.reduce(List.map(List.flatten(mexpl),hashExp),intAdd);
case(DAE.RANGE(_,e1,SOME(e2),e3)) then 12 + hashExp(e1)+hashExp(e2)+hashExp(e3);
case(DAE.RANGE(_,e1,NONE(),e3)) then 13 + hashExp(e1)+hashExp(e3);
case(DAE.TUPLE(expl)) then 14 + List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.CAST(_,e1)) then 15 + hashExp(e1);
case(DAE.ASUB(e1,expl)) then 16 + hashExp(e1)+List.reduce(List.map(expl,hashExp),intAdd);
case(DAE.TSUB(e1,i,_)) then 17 + hashExp(e1)+stringHashDjb2(intString(i));
case(DAE.SIZE(e1,SOME(e2))) then 18 + hashExp(e1)+hashExp(e2);
case(DAE.SIZE(e1,NONE())) then 19 + hashExp(e1);
// case(DAE.CODE(_,_)) then 20; // TODO: implement hashing of CODE AST
// case(DAE.EMPTY(scope=_)) then 21; // TODO: implement hashing of EMTPY (needed ?)
case(DAE.REDUCTION(info,e1,iters)) then 22 + hashReductionInfo(info)+hashExp(e1)+List.reduce(List.map(iters,hashReductionIter),intAdd);
// TODO: hashing of all MetaModelica extensions
case(_) then stringHashDjb2(ExpressionDump.printExpStr(e));
end matchcontinue;
Expand Down
4 changes: 4 additions & 0 deletions Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -720,6 +720,7 @@ algorithm
Option<DAE.Exp> eo;
DAE.Dimensions dims;
Absyn.Path p1,p2,p3;
list<String> fieldNames;

// Real -> Real
case(DAE.RCONST(r),DAE.T_REAL(varLst = _)) then DAE.RCONST(r);
Expand Down Expand Up @@ -782,6 +783,9 @@ algorithm
true = Absyn.pathEqual(p1,p2) "It is a record constructor since it has the same path called as its output type";
then DAE.CALL(p3,exps,DAE.CALL_ATTR(tp,false,false,false,DAE.NO_INLINE(),DAE.NO_TAIL()));

case (DAE.RECORD(p1,exps,fieldNames,_),DAE.T_COMPLEX(complexClassType=ClassInf.RECORD(p3)))
then DAE.RECORD(p3,exps,fieldNames,tp);

// fill(e, ...) can be simplified
case(DAE.CALL(path=Absyn.IDENT("fill"),expLst=e::exps),_)
equation
Expand Down
10 changes: 9 additions & 1 deletion Compiler/FrontEnd/Inline.mo
Expand Up @@ -1821,6 +1821,14 @@ algorithm
(new1,ht2) = extendCrefRecords(new,ht1);
res2 = listAppend(new1,res1);
then ((c,e)::res2,ht2);
case((c,e as (DAE.RECORD(exps = expl,ty=DAE.T_COMPLEX(varLst=varLst))))::res,ht)
equation
(res1,ht1) = extendCrefRecords(res,ht);
crlst = List.map1(varLst,extendCrefRecords2,c);
new = List.threadTuple(crlst,expl);
(new1,ht2) = extendCrefRecords(new,ht1);
res2 = listAppend(new1,res1);
then ((c,e)::res2,ht2);
case((c,e)::res,ht)
equation
DAE.T_COMPLEX(varLst=varLst) = Expression.typeof(e);
Expand Down Expand Up @@ -2231,4 +2239,4 @@ algorithm
end match;
end inlineEquationExp;

end Inline;
end Inline;
6 changes: 6 additions & 0 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -14453,6 +14453,12 @@ algorithm
true = Absyn.pathEqual(path, Absyn.IDENT("Distribution"));
then
SOME(DAE.DISTRIBUTION(name, params, paramNames));
case (mod, _, index_list, bind_name, _)
equation
SOME(DAE.RECORD(path = path, exps = {name,params, paramNames})) = instBinding(mod, varLst, distributionType, index_list, bind_name, useConstValue);
true = Absyn.pathEqual(path, Absyn.IDENT("Distribution"));
then
SOME(DAE.DISTRIBUTION(name, params, paramNames));

// Cref
case (mod, _, index_list, bind_name, _)
Expand Down
7 changes: 7 additions & 0 deletions Compiler/FrontEnd/PrefixUtil.mo
Expand Up @@ -663,6 +663,7 @@ algorithm
DAE.ReductionInfo reductionInfo;
DAE.ReductionIterators riters;
DAE.CallAttributes attr;
list<String> fieldNames;

// no prefix, return the input expression
case (cache,_,_,e,Prefix.NOPRE())
Expand Down Expand Up @@ -790,6 +791,12 @@ algorithm
then
(cache,DAE.CALL(f,es_1,attr));

case (cache,env,ih,DAE.RECORD(f,es,fieldNames,t),p)
equation
(cache,es_1) = prefixExpList(cache, env, ih, es, p);
then
(cache,DAE.RECORD(f,es,fieldNames,t));

case (cache,env,ih,DAE.ARRAY(ty = t,scalar = sc,array = {}),p)
then
(cache,DAE.ARRAY(t,sc,{}));
Expand Down
15 changes: 15 additions & 0 deletions Compiler/FrontEnd/Types.mo
Expand Up @@ -4598,6 +4598,21 @@ algorithm
e_1 = DAE.METARECORDCALL(path1, elist, l, -1);
then (e_1,t2);

case (e as DAE.RECORD(path = path1, exps = elist),
t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_), varLst = v, source = {path2}),
DAE.T_METABOXED(ty = t2),
_)
equation
true = subtype(t1,t2);
true = Absyn.pathEqual(path1, path2);
t2 = DAE.T_METABOXED(t1,DAE.emptyTypeSource);
l = List.map(v, getVarName);
tys1 = List.map(v, getVarType);
tys2 = List.map(tys1, boxIfUnboxedType);
(elist,_) = matchTypeTuple(elist, tys1, tys2, printFailtrace);
e_1 = DAE.METARECORDCALL(path1, elist, l, -1);
then (e_1,t2);

case (e as DAE.CALL(path = _),
t1 as DAE.T_COMPLEX(complexClassType = ClassInf.RECORD(_), varLst = v),
DAE.T_METABOXED(ty = t2),_)
Expand Down
3 changes: 2 additions & 1 deletion Compiler/FrontEnd/ValuesUtil.mo
Expand Up @@ -946,7 +946,8 @@ algorithm
expl = List.map(vallist,valueExp);
tpl = List.map(expl,Expression.typeof);
varlst = List.threadMap(namelst,tpl,Expression.makeVar);
then DAE.CALL(path,expl,DAE.CALL_ATTR(DAE.T_COMPLEX(ClassInf.RECORD(path),varlst,NONE(),DAE.emptyTypeSource),false,false,false,DAE.NO_INLINE(),DAE.NO_TAIL()));
t = DAE.T_COMPLEX(ClassInf.RECORD(path),varlst,NONE(),DAE.emptyTypeSource);
then DAE.RECORD(path,expl,namelst,t);

case(Values.ENUM_LITERAL(name = path, index = ix))
then DAE.ENUM_LITERAL(path, ix);
Expand Down
14 changes: 13 additions & 1 deletion Compiler/Template/CodegenC.tpl
Expand Up @@ -6812,6 +6812,7 @@ template daeExp(Exp exp, Context context, Text &preExp /*BUFP*/, Text &varDecls
case e as RELATION(__) then daeExpRelation(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
case e as IFEXP(__) then daeExpIf(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
case e as CALL(__) then daeExpCall(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
case e as RECORD(__) then daeExpRecord(e, context, &preExp, &varDecls)
case e as ARRAY(__) then daeExpArray(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
case e as MATRIX(__) then daeExpMatrix(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
case e as RANGE(__) then daeExpRange(e, context, &preExp /*BUFC*/, &varDecls /*BUFD*/)
Expand Down Expand Up @@ -7662,6 +7663,16 @@ else
'<%lhs%> = <%rhs%>;'
end resultVarAssignment;

template daeExpRecord(Exp rec, Context context, Text &preExp, Text &varDecls)
::=
match rec
case RECORD(__) then
let name = tempDecl(underscorePath(path), &varDecls)
let ass = threadTuple(exps,comp) |> (exp,compn) => '<%name%>._<%compn%> = <%daeExp(exp, context, &preExp, &varDecls)%>;<%\n%>'
let &preExp += ass
name
end daeExpRecord;

template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varDecls /*BUFP*/)
"Generates code for a function call."
::=
Expand Down Expand Up @@ -9065,6 +9076,7 @@ template expTypeFromExpFlag(Exp exp, Integer flag)
case e as RELATION(__) then match flag case 1 then "boolean" else "modelica_boolean"
case IFEXP(__) then expTypeFromExpFlag(expThen, flag)
case CALL(attr=CALL_ATTR(__)) then expTypeFlag(attr.ty, flag)
case c as RECORD(__) then expTypeFlag(c.ty, flag)
case c as ARRAY(__)
case c as MATRIX(__)
case c as RANGE(__)
Expand All @@ -9086,7 +9098,7 @@ template expTypeFromExpFlag(Exp exp, Integer flag)
case BOX(__) then match flag case 1 then "metatype" else "modelica_metatype"
case c as UNBOX(__) then expTypeFlag(c.ty, flag)
case c as SHARED_LITERAL(__) then expTypeFlag(c.ty, flag)
else error(sourceInfo(), 'expTypeFromExpFlag:<%printExpStr(exp)%>')
else error(sourceInfo(), 'expTypeFromExpFlag(flag=<%flag%>):<%printExpStr(exp)%>')
end expTypeFromExpFlag;


Expand Down

0 comments on commit 98c9f2b

Please sign in to comment.