@@ -815,41 +815,74 @@ public
815815 end match;
816816 end setType;
817817
818+ function typeCastOpt
819+ input Option < Expression > exp;
820+ input Type ty;
821+ output Option < Expression > outExp = Util . applyOption(exp, function typeCast(ty = ty));
822+ end typeCastOpt;
823+
818824 function typeCast
825+ "Converts an expression to the given type. Dimensions of array types can be
826+ omitted, and are ignored by this function, since arrays can't be cast to a
827+ different size. Only the element type of the type is used, so for example:
828+ typeCast({1, 2, 3}, Type.REAL()) => {1.0, 2.0, 3.0}
829+
830+ The function does not check that the cast is valid, and expressions that
831+ can't be converted outright will be wrapped as a CAST expression."
819832 input output Expression exp;
820833 input Type ty;
834+ protected
835+ Type t, ety;
836+ list< Expression > el;
821837 algorithm
822- exp := match (exp, ty)
823- local
824- Type t, ety;
825- list< Expression > el;
838+ ety := Type . arrayElementType(ty);
826839
840+ exp := match (exp, ety)
841+ // Integer can be cast to Real.
827842 case (INTEGER (), Type . REAL ())
828843 then REAL (intReal(exp. value));
829844
845+ // Real doesn't need to be cast to Real, since we convert e.g. array with
846+ // a mix of Integers and Reals to only Reals.
830847 case (REAL (), Type . REAL ()) then exp;
831848
849+ // For arrays we typecast each element and update the type of the array.
832850 case (ARRAY (ty = t, elements = el), _)
833851 algorithm
834- ety := Type . arrayElementType(ty);
835852 el := list(typeCast(e, ety) for e in el);
836- t := Type . setArrayElementType(t, ty );
853+ t := Type . setArrayElementType(t, ety );
837854 then
838855 ARRAY (t, el, exp. literal);
839856
857+ case (RANGE (ty = t), _)
858+ algorithm
859+ t := Type . setArrayElementType(t, ety);
860+ then
861+ RANGE (t, typeCast(exp. start, ety), typeCastOpt(exp. step, ety), typeCast(exp. stop, ety));
862+
863+ // Unary operators (i.e. -) are handled by casting the operand.
840864 case (UNARY (), _)
841- then UNARY (exp. operator, typeCast(exp. exp, ty));
865+ algorithm
866+ t := Type . setArrayElementType(Operator . typeOf(exp. operator), ety);
867+ then
868+ UNARY (Operator . setType(t, exp. operator), typeCast(exp. exp, ety));
842869
870+ // If-expressions are handled by casting each of the branches.
843871 case (IF (), _)
844- then IF (exp. condition, typeCast(exp. trueBranch, ty ), typeCast(exp. falseBranch, ty ));
872+ then IF (exp. condition, typeCast(exp. trueBranch, ety ), typeCast(exp. falseBranch, ety ));
845873
874+ // Calls are handled by Call.typeCast, which has special rules for some functions.
846875 case (CALL (), _)
847- then Call . typeCast(exp, ty);
876+ then Call . typeCast(exp, ety);
877+
878+ // Casting a cast expression overrides its current cast type.
879+ case (CAST (), _) then typeCast(exp. exp, ty);
848880
881+ // Other expressions are handled by making a CAST expression.
849882 else
850883 algorithm
851884 t := typeOf(exp);
852- t := Type . setArrayElementType(t, ty );
885+ t := Type . setArrayElementType(t, ety );
853886 then
854887 CAST (t, exp);
855888
0 commit comments