@@ -140,13 +140,11 @@ algorithm
140140 SCode . COMMENT (NONE (), NONE ()),
141141 NONE (),
142142 info), scope);
143-
144143 fakeComponent := Inst . instComponent(fakeComponent, scope, InstNode . parent(classNode));
145144
146145 // we need something better than this as this will type the function twice
147146 fakeComponent := Typing . typeComponent(fakeComponent);
148147 (classNode, classType) := Typing . typeClass(classNode);
149-
150148 // see if the class is a builtin function (including definitions in the ModelicaBuiltin.mo), record or normal function
151149
152150 // is builtin function defined in ModelicaBuiltin.mo
@@ -163,7 +161,6 @@ algorithm
163161
164162 // is normal function call
165163 (typedExp, ty, variability) := typeNormalFunction(functionName, functionArgs, prefix, classNode, classType, cls, scope, info);
166-
167164end typeFunctionCall;
168165
169166function getFunctionInputs
@@ -519,7 +516,19 @@ algorithm
519516 "cat" ,
520517 "rem" ,
521518 "actualStream" ,
522- "inStream" });
519+ "inStream" ,
520+ // TODO Clock
521+ "previous" ,
522+ "hold" ,
523+ "subSample" ,
524+ "superSample" ,
525+ // TODO sample, shiftSample, backSample, noClock
526+ "initialState" ,
527+ "transition" ,
528+ "activeState" ,
529+ "ticksInState" ,
530+ "timeInState"
531+ });
523532 then
524533 b;
525534
@@ -745,6 +754,118 @@ algorithm
745754 then
746755 (typedExp, ty, vr);
747756
757+ case (Absyn . CREF_IDENT (name = "previous" ), Absyn . FUNCTIONARGS (args = {aexp1}))
758+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
759+ algorithm
760+ // TODO? Check that aexp1 is a Component Expression (MLS 3.3, Section 16.2.3) or parameter expression
761+ (dexp1, ty, vr) := Typing . typeExp(aexp1, scope, info);
762+ // create the typed call
763+ typedExp := Expression . makeBuiltinCall("previous" , {dexp1}, ty, true );
764+ then
765+ (typedExp, ty, vr);
766+
767+ case (Absyn . CREF_IDENT (name = "hold" ), Absyn . FUNCTIONARGS (args = {aexp1}))
768+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
769+ algorithm
770+ // TODO? Check that aexp1 is a Component Expression (MLS 3.3, Section 16.2.3) or parameter expression
771+ (dexp1, ty, vr) := Typing . typeExp(aexp1, scope, info);
772+ // create the typed call
773+ typedExp := Expression . makeBuiltinCall("hold" , {dexp1}, ty, true );
774+ then
775+ (typedExp, ty, vr);
776+
777+ // subSample(u)/superSample(u), subSample(u, factor)/superSample(u, factor)
778+ case (Absyn . CREF_IDENT (name = fnName), Absyn . FUNCTIONARGS (args = afargs))
779+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 ) and
780+ listMember(fnName, {"subSample" , "superSample" }) and
781+ (listLength(afargs) == 1 or listLength(afargs) == 2 )
782+ algorithm
783+ if listLength(afargs) == 1 then
784+ aexp1 := listHead(afargs);
785+ // Create default argument factor=0
786+ dexp2 := Expression . INTEGER (0 );
787+ else
788+ {aexp1, aexp2} := afargs;
789+ (dexp2, ty2, vr2) := Typing . typeExp(aexp2, scope, info);
790+ Type . INTEGER () := ty2;
791+ // TODO FIXME check if vr2 is a parameter expressions
792+ // TODO FIXME (evaluate) and check if factor >= 0
793+ end if ;
794+ (dexp1, ty, vr) := Typing . typeExp(aexp1, scope, info);
795+
796+ // create the typed call
797+ typedExp := Expression . makeBuiltinCall(fnName, {dexp1, dexp2}, ty, true );
798+ then
799+ (typedExp, ty, vr);
800+
801+ // initialState(state)
802+ case (Absyn . CREF_IDENT (name = "initialState" ), Absyn . FUNCTIONARGS (args = {aexp1}))
803+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
804+ algorithm
805+ (dexp1, ty1, vr) := Typing . typeExp(aexp1, scope, info);
806+
807+ // MLS 3.3 requires a 'block' instance as argument aexp1.
808+ // Checking here for 'complex' types is too broad, but convenient
809+ Error . assertionOrAddSourceMessage(Type . isComplex(ty1),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
810+ {"initialState(" + Expression . toString(dexp1) + "), Argument needs to be a block instance." ,
811+ Absyn . pathString(InstNode . path(scope))}, info);
812+
813+ ty := Type . NORETCALL ();
814+
815+ // create the typed call
816+ typedExp := Expression . makeBuiltinCall("initialState" , {dexp1}, ty, true );
817+ then
818+ (typedExp, ty, vr);
819+
820+ // transition(from, to, condition, immediate=true, reset=true, synchronize=false, priority=1)
821+ case (Absyn . CREF_IDENT (name = "transition" ), _)
822+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
823+ then
824+ elabBuiltinTransition(functionName, functionArgs, prefix, classNode, classType, cls, scope, info);
825+
826+ // activeState(state)
827+ case (Absyn . CREF_IDENT (name = "activeState" ), Absyn . FUNCTIONARGS (args = {aexp1}))
828+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
829+ algorithm
830+ (dexp1, ty1, vr) := Typing . typeExp(aexp1, scope, info);
831+
832+ // MLS 3.3 requires a 'block' instance as argument aexp1.
833+ // Checking here for 'complex' types is too broad, but convenient
834+ Error . assertionOrAddSourceMessage(Type . isComplex(ty1),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
835+ {"activeState(" + Expression . toString(dexp1) + "), Argument needs to be a block instance." ,
836+ Absyn . pathString(InstNode . path(scope))}, info);
837+
838+ ty := Type . BOOLEAN ();
839+
840+ // create the typed call
841+ typedExp := Expression . makeBuiltinCall("activeState" , {dexp1}, ty, true );
842+ then
843+ (typedExp, ty, vr);
844+
845+ // ticksInState()
846+ case (Absyn . CREF_IDENT (name = "ticksInState" ), Absyn . FUNCTIONARGS (args = {}))
847+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
848+ algorithm
849+ ty := Type . INTEGER ();
850+ vr := DAE . C_VAR ();
851+ // create the typed call
852+ typedExp := Expression . makeBuiltinCall("ticksInState" , {}, ty, true );
853+ then
854+ (typedExp, ty, vr);
855+
856+ // timeInState()
857+ case (Absyn . CREF_IDENT (name = "timeInState" ), Absyn . FUNCTIONARGS (args = {}))
858+ guard intGe(Flags . getConfigEnum(Flags . LANGUAGE_STANDARD ), 33 )
859+ algorithm
860+ ty := Type . REAL ();
861+ vr := DAE . C_VAR ();
862+ // create the typed call
863+ typedExp := Expression . makeBuiltinCall("timeInState" , {}, ty, true );
864+ then
865+ (typedExp, ty, vr);
866+
867+
868+
748869 /* adrpo: adapt these to the new structures, see above
749870 case (Absyn.CREF_IDENT(name = "product"), Absyn.FUNCTIONARGS(args = afargs))
750871 equation
@@ -910,6 +1031,122 @@ algorithm
9101031 end matchcontinue;
9111032end typeBuiltinFunctionCall;
9121033
1034+
1035+ protected function elabBuiltinTransition
1036+ "elaborate the builtin operator
1037+ transition(from, to, condition, immediate=true, reset=true, synchronize=false, priority=1)"
1038+ input Absyn . ComponentRef functionName;
1039+ input Absyn . FunctionArgs functionArgs;
1040+ input Prefix prefix;
1041+ input InstNode classNode;
1042+ input Type classType;
1043+ input SCode . Element cls;
1044+ input InstNode scope;
1045+ input SourceInfo info;
1046+ output Expression typedExp;
1047+ output Type ty;
1048+ output DAE . Const variability;
1049+ protected
1050+ list< Absyn . Exp > afargs;
1051+ list< Absyn . NamedArg > anamed_args;
1052+ Absyn . Ident argName;
1053+ Absyn . Exp argValue;
1054+ array< Absyn . Exp > argExps = listArray({Absyn . STRING ("from_NoDefault" ), Absyn . STRING ("to_NoDefault" ), Absyn . STRING ("condition_NoDefault" ), Absyn . BOOL (true ), Absyn . BOOL (true ), Absyn . BOOL (false ), Absyn . INTEGER (1 )});
1055+ array< Absyn . Exp > afargsArray;
1056+ Expression dexp1, dexp2, dexp3, dexp4, dexp5, dexp6, dexp7;
1057+ Type ty1, ty2, ty3, ty4, ty5, ty6, ty7;
1058+ DAE . Const vr1, vr2, vr3, vr4, vr5, vr6, vr7;
1059+ String str;
1060+ Integer afargsLen;
1061+ algorithm
1062+ Absyn . FUNCTIONARGS (args= afargs, argNames= anamed_args) := functionArgs;
1063+ afargsArray := listArray(afargs);
1064+ afargsLen := listLength(afargs);
1065+
1066+ for i in 1 :afargsLen loop
1067+ argExps := arrayUpdate(argExps, i, arrayGet(afargsArray,i));
1068+ end for ;
1069+
1070+ for anamed in anamed_args loop
1071+ Absyn . NAMEDARG (argName, argValue) := anamed;
1072+ if argName == "from" and afargsLen < 1 then arrayUpdate(argExps, 1 , argValue);
1073+ elseif argName == "to" and afargsLen < 2 then arrayUpdate(argExps, 2 , argValue);
1074+ elseif argName == "condition" and afargsLen < 3 then arrayUpdate(argExps, 3 , argValue);
1075+ elseif argName == "immediate" and afargsLen < 4 then arrayUpdate(argExps, 4 , argValue);
1076+ elseif argName == "reset" and afargsLen < 5 then arrayUpdate(argExps, 5 , argValue);
1077+ elseif argName == "synchronize" and afargsLen < 6 then arrayUpdate(argExps, 6 , argValue);
1078+ elseif argName == "priority" and afargsLen < 7 then arrayUpdate(argExps, 7 , argValue);
1079+ else
1080+ Error . addSourceMessageAndFail(Error . NO_SUCH_ARGUMENT ,
1081+ {"transition(" + argName + "=" + Dump . dumpExpStr(argValue) + "), no such argument or conflict with unnamed arguments" ,
1082+ Absyn . pathString(InstNode . path(scope))}, info);
1083+ end if ;
1084+ end for ;
1085+
1086+ // check if first 3 mandatory arguments have been provided
1087+ for i in 1 :3 loop
1088+ () := match arrayGet(argExps, i)
1089+ case Absyn . STRING (str)
1090+ algorithm
1091+ Error . addSourceMessageAndFail(Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1092+ {"transition(from, to, condition, immediate=true, reset=true, synchronize=false, priority=1), missing " + intString(i) + ". argument" ,
1093+ Absyn . pathString(InstNode . path(scope))}, info);
1094+ then fail();
1095+ else then ();
1096+ end match;
1097+ end for ;
1098+
1099+ (dexp1, ty1, vr1) := Typing . typeExp(arrayGet(argExps,1 ), scope, info);
1100+ (dexp2, ty2, vr2) := Typing . typeExp(arrayGet(argExps,2 ), scope, info);
1101+ // MLS 3.3 requires a 'block' instances as argument 1 and 2.
1102+ // Checking here for 'complex' types is too broad, but convenient
1103+ Error . assertionOrAddSourceMessage(Type . isComplex(ty1),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1104+ {"transition(" + Expression . toString(dexp1) + ", ...), Argument needs to be a block instance." ,
1105+ Absyn . pathString(InstNode . path(scope))}, info);
1106+ Error . assertionOrAddSourceMessage(Type . isComplex(ty2),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1107+ {"transition(..., " + Expression . toString(dexp2) + ", ...), Argument needs to be a block instance." ,
1108+ Absyn . pathString(InstNode . path(scope))}, info);
1109+
1110+ // TODO check that variability of arguments below are parameter or constant
1111+
1112+ (dexp3, ty3, vr3) := Typing . typeExp(arrayGet(argExps,3 ), scope, info);
1113+ Error . assertionOrAddSourceMessage(Type . isBoolean(ty3),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1114+ {"transition(..., " + Expression . toString(dexp3) + ", ...), Argument needs to be of type Boolean." ,
1115+ Absyn . pathString(InstNode . path(scope))}, info);
1116+
1117+ (dexp4, ty4, vr4) := Typing . typeExp(arrayGet(argExps,4 ), scope, info);
1118+ Error . assertionOrAddSourceMessage(Type . isBoolean(ty4),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1119+ {"transition(..., " + Expression . toString(dexp4) + ", ...), Argument needs to be of type Boolean." ,
1120+ Absyn . pathString(InstNode . path(scope))}, info);
1121+
1122+ // Error.assertionOrAddSourceMessage(Types.isParameterOrConstant(vr4),Error.WRONG_TYPE_OR_NO_OF_ARGS,
1123+ // {"transition(..., " + Expression.toString(dexp4) + ", ...), Argument needs to be of type Boolean.",
1124+ // Absyn.pathString(InstNode.path(scope))}, info);
1125+
1126+ (dexp5, ty5, vr5) := Typing . typeExp(arrayGet(argExps,5 ), scope, info);
1127+ Error . assertionOrAddSourceMessage(Type . isBoolean(ty5),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1128+ {"transition(..., " + Expression . toString(dexp5) + ", ...), Argument needs to be of type Boolean." ,
1129+ Absyn . pathString(InstNode . path(scope))}, info);
1130+
1131+ (dexp6, ty6, vr6) := Typing . typeExp(arrayGet(argExps,6 ), scope, info);
1132+ Error . assertionOrAddSourceMessage(Type . isBoolean(ty6),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1133+ {"transition(..., " + Expression . toString(dexp6) + ", ...), Argument needs to be of type Boolean." ,
1134+ Absyn . pathString(InstNode . path(scope))}, info);
1135+
1136+ (dexp7, ty7, vr7) := Typing . typeExp(arrayGet(argExps,7 ), scope, info);
1137+ // TODO check that "priority" argument is >= 1
1138+ Error . assertionOrAddSourceMessage(Type . isInteger(ty7),Error . WRONG_TYPE_OR_NO_OF_ARGS ,
1139+ {"transition(..., " + Expression . toString(dexp7) + ", ...), Argument needs to be of type Integer." ,
1140+ Absyn . pathString(InstNode . path(scope))}, info);
1141+
1142+
1143+ ty := Type . NORETCALL ();
1144+ // create the typed call
1145+ typedExp := Expression . makeBuiltinCall("transition" , {dexp1, dexp2, dexp3, dexp4, dexp5, dexp6, dexp7}, ty, true );
1146+ variability := DAE . C_UNKNOWN ();
1147+ end elabBuiltinTransition;
1148+
1149+
9131150function getFunctionAttributes
9141151 input InstNode funcNode;
9151152 output DAE . FunctionAttributes attr;
0 commit comments