@@ -1017,9 +1017,11 @@ function typeExp
10171017 "Types an untyped expression, returning the typed expression itself along with
10181018 its type and variability. The default behaviour is to replace any constants
10191019 found with their bound values (giving an error if they have none), but this
1020- can be turned off with the replaceConstants parameter. Note that replaceConstants
1021- is not propagated when typing subexpressions, because this is so far only
1022- used when we need the whole expression to be kept as a cref (like connectors)."
1020+ can be turned off with the replaceConstants parameter.
1021+
1022+ NOTE: replaceConstants is not propagated when typing subexpressions, because
1023+ this is so far only used when we need the whole expression to be kept
1024+ as a cref (like connectors)."
10231025 input output Expression exp;
10241026 input ExpOrigin . Type origin;
10251027 input SourceInfo info;
@@ -1128,14 +1130,7 @@ algorithm
11281130 then
11291131 (exp, ty, variability);
11301132
1131- case Expression . IF ()
1132- algorithm
1133- next_origin := intBitOr(origin, ExpOrigin . SUBEXPRESSION );
1134- (e1, ty1, var1) := typeExp(exp. condition, next_origin, info);
1135- (e2, ty2, var2) := typeExp(exp. trueBranch, next_origin, info);
1136- (e3, ty3, var3) := typeExp(exp. falseBranch, next_origin, info);
1137- then
1138- TypeCheck . checkIfExpression(e1, ty1, var1, e2, ty2, var2, e3, ty3, var3, info);
1133+ case Expression . IF () then typeIfExpression(exp, origin, info);
11391134
11401135 case Expression . CALL ()
11411136 algorithm
@@ -1892,6 +1887,88 @@ function evaluateEnd
18921887 end match;
18931888end evaluateEnd;
18941889
1890+ function typeIfExpression
1891+ input output Expression ifExp;
1892+ input ExpOrigin . Type origin;
1893+ input SourceInfo info;
1894+ output Type ty;
1895+ output Variability var ;
1896+ protected
1897+ Expression cond, tb, fb, tb2, fb2;
1898+ ExpOrigin . Type next_origin;
1899+ Type cond_ty, tb_ty, fb_ty;
1900+ Variability cond_var, tb_var, fb_var;
1901+ MatchKind ty_match;
1902+ algorithm
1903+ Expression . IF (condition = cond, trueBranch = tb, falseBranch = fb) := ifExp;
1904+ next_origin := intBitOr(origin, ExpOrigin . SUBEXPRESSION );
1905+
1906+ (cond, cond_ty, cond_var) := typeExp(cond, next_origin, info);
1907+
1908+ // The condition must be a scalar boolean.
1909+ (cond, _, ty_match) := TypeCheck . matchTypes(cond_ty, Type . BOOLEAN (), cond);
1910+
1911+ if TypeCheck . isIncompatibleMatch(ty_match) then
1912+ Error . addSourceMessage(Error . IF_CONDITION_TYPE_ERROR ,
1913+ {Expression . toString(cond), Type . toString(cond_ty)}, info);
1914+ fail();
1915+ end if ;
1916+
1917+ if cond_var <= Variability . STRUCTURAL_PARAMETER then
1918+ // If the condition is constant, always do branch selection.
1919+ if evaluateCondition(cond, info) then
1920+ (ifExp, ty, var ) := typeExp(tb, next_origin, info);
1921+ else
1922+ (ifExp, ty, var ) := typeExp(fb, next_origin, info);
1923+ end if ;
1924+ else
1925+ // Otherwise type both of the branches.
1926+ (tb, tb_ty, tb_var) := typeExp(tb, next_origin, info);
1927+ (fb, fb_ty, fb_var) := typeExp(fb, next_origin, info);
1928+
1929+ (tb2, fb2, ty, ty_match) := TypeCheck . matchExpressions(tb, tb_ty, fb, fb_ty);
1930+
1931+ if TypeCheck . isIncompatibleMatch(ty_match) then
1932+ if cond_var <= Variability . PARAMETER then
1933+ // If the branches have different types but the condition is a parameter
1934+ // expression, do branch selection.
1935+ (ifExp, ty, var ) := if evaluateCondition(cond, info) then (tb, tb_ty, tb_var) else (fb, fb_ty, fb_var);
1936+ else
1937+ // Otherwise give an type mismatch error.
1938+ Error . addSourceMessage(Error . TYPE_MISMATCH_IF_EXP ,
1939+ {"" , Expression . toString(tb), Type . toString(tb_ty),
1940+ Expression . toString(fb), Type . toString(fb_ty)}, info);
1941+ fail();
1942+ end if ;
1943+ else
1944+ // If the types match, return a typed if-expression.
1945+ ifExp := Expression . IF (cond, tb2, fb2);
1946+ var := Prefixes . variabilityMax(cond_var, Prefixes . variabilityMax(tb_var, fb_var));
1947+ end if ;
1948+ end if ;
1949+ end typeIfExpression;
1950+
1951+ function evaluateCondition
1952+ input Expression condExp;
1953+ input SourceInfo info;
1954+ output Boolean condBool;
1955+ protected
1956+ Expression cond_exp;
1957+ algorithm
1958+ cond_exp := Ceval . evalExp(condExp, Ceval . EvalTarget . GENERIC (info));
1959+ cond_exp := SimplifyExp . simplifyExp(cond_exp);
1960+
1961+ condBool := match cond_exp
1962+ case Expression . BOOLEAN () then cond_exp. value;
1963+ else
1964+ algorithm
1965+ Error . assertion(false , getInstanceName() + " failed to evaluate condition `" +
1966+ Expression . toString(condExp) + "`" , info);
1967+ then
1968+ fail();
1969+ end match;
1970+ end evaluateCondition;
1971+
18951972function typeSections
18961973 input InstNode classNode;
18971974 input ExpOrigin . Type origin;
0 commit comments