From a08ef7bf2427366a3f4d4818e7ba81560de53e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Wed, 24 Oct 2018 13:24:39 +0200 Subject: [PATCH] [NF] Fix typing of Clock constructors. - Fix the Clock() definitions in NFBuiltinFuncs, and use them in NFBuiltinCall.typeClockCall instead of doing argument matching manually. This fixes the typing such that e.g. Clock(1, 2) works. Belonging to [master]: - OpenModelica/OMCompiler#2737 - OpenModelica/OpenModelica-testsuite#1059 --- Compiler/NFFrontEnd/NFBuiltinCall.mo | 106 +++++++++----------------- Compiler/NFFrontEnd/NFBuiltinFuncs.mo | 34 +++------ 2 files changed, 43 insertions(+), 97 deletions(-) diff --git a/Compiler/NFFrontEnd/NFBuiltinCall.mo b/Compiler/NFFrontEnd/NFBuiltinCall.mo index 0e9ffc12170..10a665959f6 100644 --- a/Compiler/NFFrontEnd/NFBuiltinCall.mo +++ b/Compiler/NFFrontEnd/NFBuiltinCall.mo @@ -1619,84 +1619,46 @@ protected input ExpOrigin.Type origin; input SourceInfo info; output Expression callExp; - output Type outType; - output Variability var; + output Type outType = Type.CLOCK(); + output Variability var = Variability.PARAMETER; protected - Type arg_ty; - list args; - list named_args; Call ty_call; - Expression e, e1, e2; - Type t, t1, t2; - Variability v, v1, v2; + list args; + Integer args_count; + Expression e1, e2; algorithm - ty_call as Call.ARG_TYPED_CALL(_, args, named_args) := Call.typeNormalCall(call, origin, info); - (callExp, outType, var) := match(args, named_args) - // Clock() - inferred clock - case ({}, {}) - then (Expression.CLKCONST(Expression.ClockKind.INFERRED_CLOCK()), Type.CLOCK(), Variability.PARAMETER); - // Clock(intervalCounter) - integer clock - case ({(e, Type.INTEGER(), v)}, {}) - then (Expression.CLKCONST(Expression.INTEGER_CLOCK(e, Expression.INTEGER(1))), Type.CLOCK(), Variability.PARAMETER); - // Clock(intervalCounter, resolution) - integer clock - case ({(e, Type.INTEGER(), v), (e1, Type.REAL(), v1)}, {}) - algorithm - e2 := Ceval.evalExp(e1); - Error.assertionOrAddSourceMessage(Expression.integerValue(e2) >= 1, - Error.WRONG_VALUE_OF_ARG, {"Clock", "resolution", Expression.toString(e2), ">= 1"}, info); - then - (Expression.CLKCONST(Expression.INTEGER_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); - // Clock(intervalCounter, resolution=expression) - integer clock - case ({(e, Type.INTEGER(), v)}, {("resolution", e1, Type.REAL(), v1)}) - algorithm - e2 := Ceval.evalExp(e1); - Error.assertionOrAddSourceMessage(Expression.integerValue(e2) >= 1, - Error.WRONG_VALUE_OF_ARG, {"Clock", "resolution", Expression.toString(e2), ">= 1"}, info); - then - (Expression.CLKCONST(Expression.INTEGER_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); - // Clock(interval) - real clock - case ({(e, Type.REAL(), v)}, {}) - then - (Expression.CLKCONST(Expression.REAL_CLOCK(e)), Type.CLOCK(), Variability.PARAMETER); - // Clock(condition) - boolean clock - case ({(e, Type.BOOLEAN(), v)}, {}) - then - (Expression.CLKCONST(Expression.BOOLEAN_CLOCK(e, Expression.REAL(0.0))), Type.CLOCK(), Variability.PARAMETER); - // Clock(condition, startInterval) - boolean clock - case ({(e, Type.BOOLEAN(), v), (e1, Type.REAL(), v1)}, {}) - algorithm - e2 := Ceval.evalExp(e1); - Error.assertionOrAddSourceMessage(Expression.realValue(e2) > 0.0, - Error.WRONG_VALUE_OF_ARG, {"Clock", "startInterval", Expression.toString(e2), "> 0.0"}, info); - then - (Expression.CLKCONST(Expression.BOOLEAN_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); - // Clock(condition, startInterval=expression) - boolean clock - case ({(e, Type.BOOLEAN(), v)}, {("startInterval", e1, Type.REAL(), v1)}) + Call.TYPED_CALL(arguments = args) := Call.typeMatchNormalCall(call, origin, info); + args_count := listLength(args); + + callExp := match args + // Clock() - inferred clock. + case {} then Expression.CLKCONST(Expression.ClockKind.INFERRED_CLOCK()); + // Clock(interval) - real clock. + case {e1} then Expression.CLKCONST(Expression.ClockKind.REAL_CLOCK(e1)); + case {e1, e2} algorithm - e2 := Ceval.evalExp(e1); - Error.assertionOrAddSourceMessage(Expression.realValue(e2) > 0.0, - Error.WRONG_VALUE_OF_ARG, {"Clock", "startInterval", Expression.toString(e2), "> 0.0"}, info); - then - (Expression.CLKCONST(Expression.BOOLEAN_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); - // Clock(c, solverMethod) - solver clock - case ({(e, Type.CLOCK(), v), (e1, Type.STRING(), v1)}, {}) - algorithm - e2 := Ceval.evalExp(e1); - then - (Expression.CLKCONST(Expression.SOLVER_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); - - // Clock(c, solverMethod=string) - solver clock - case ({(e, Type.CLOCK(), v)}, {("solverMethod", e1, Type.STRING(), v1)}) - algorithm - e2 := Ceval.evalExp(e1); + e2 := Ceval.evalExp(e2); + + callExp := match Expression.typeOf(e2) + // Clock(intervalCounter, resolution) - integer clock. + case Type.INTEGER() + algorithm + Error.assertionOrAddSourceMessage(Expression.integerValue(e2) >= 1, + Error.WRONG_VALUE_OF_ARG, {"Clock", "resolution", Expression.toString(e2), "=> 1"}, info); + then + Expression.CLKCONST(Expression.INTEGER_CLOCK(e1, e2)); + + // Clock(condition, startInterval) - boolean clock. + case Type.REAL() + then Expression.CLKCONST(Expression.BOOLEAN_CLOCK(e1, e2)); + + // Clock(c, solverMethod) - solver clock. + case Type.STRING() + then Expression.CLKCONST(Expression.SOLVER_CLOCK(e1, e2)); + end match; then - (Expression.CLKCONST(Expression.SOLVER_CLOCK(e, e2)), Type.CLOCK(), Variability.PARAMETER); + callExp; - else - algorithm - Error.addSourceMessage(Error.WRONG_TYPE_OR_NO_OF_ARGS, {Call.toString(call), ""}, info); - then - fail(); end match; end typeClockCall; diff --git a/Compiler/NFFrontEnd/NFBuiltinFuncs.mo b/Compiler/NFFrontEnd/NFBuiltinFuncs.mo index 3bdefdbfa77..ef1bfb8db2c 100644 --- a/Compiler/NFFrontEnd/NFBuiltinFuncs.mo +++ b/Compiler/NFFrontEnd/NFBuiltinFuncs.mo @@ -300,48 +300,34 @@ constant Function CLOCK_INFERED = Function.FUNCTION(Path.IDENT("Clock"), CLOCK_DUMMY_NODE, {}, {CLOCK_PARAM}, {}, {}, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); -// Clock(intervalCounter) - clock with Integer interval +// Clock(intervalCounter, resolution = 1) - clock with Integer interval constant Function CLOCK_INT = Function.FUNCTION(Path.IDENT("Clock"), - CLOCK_DUMMY_NODE, {INT_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("intervalCounter", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED) - }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, - Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); - -// Clock(intervalCounter, resolution) - clock with Integer interval -constant Function CLOCK_INT_RESOLUTION = Function.FUNCTION(Path.IDENT("Clock"), CLOCK_DUMMY_NODE, {INT_PARAM, INT_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("intervalCounter", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), - Slot.SLOT("resolution", SlotType.NAMED, SOME(Expression.INTEGER(1)), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) + Slot.SLOT("intervalCounter", SlotType.GENERIC, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), + Slot.SLOT("resolution", SlotType.GENERIC, SOME(Expression.INTEGER(1)), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); // Clock(interval) - clock with Real interval constant Function CLOCK_REAL = Function.FUNCTION(Path.IDENT("Clock"), CLOCK_DUMMY_NODE, {REAL_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("interval", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED) + Slot.SLOT("interval", SlotType.GENERIC, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED) }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); -// Clock(condition) - Boolean clock, triggered by zero-crossing events +// Clock(condition, startInterval = 0.0) - Boolean clock, triggered by zero-crossing events constant Function CLOCK_BOOL = Function.FUNCTION(Path.IDENT("Clock"), - CLOCK_DUMMY_NODE, {BOOL_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("condition", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED) - }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, - Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); - -// Clock(condition, startInterval) - Boolean clock, triggered by zero-crossing events -constant Function CLOCK_BOOL_INTERVAL = Function.FUNCTION(Path.IDENT("Clock"), CLOCK_DUMMY_NODE, {BOOL_PARAM, REAL_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("condition", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), - Slot.SLOT("startInterval", SlotType.NAMED, SOME(Expression.REAL(0.0)), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) + Slot.SLOT("condition", SlotType.GENERIC, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), + Slot.SLOT("startInterval", SlotType.GENERIC, SOME(Expression.REAL(0.0)), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); // Clock(c, solverMethod) - Solver clock constant Function CLOCK_SOLVER = Function.FUNCTION(Path.IDENT("Clock"), CLOCK_DUMMY_NODE, {CLOCK_PARAM, STRING_PARAM}, {CLOCK_PARAM}, {}, { - Slot.SLOT("condition", SlotType.POSITIONAL, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), - Slot.SLOT("solverMethod", SlotType.NAMED, NONE(), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) + Slot.SLOT("c", SlotType.GENERIC, NONE(), NONE(), 1, SlotEvalStatus.NOT_EVALUATED), + Slot.SLOT("solverMethod", SlotType.GENERIC, NONE(), NONE(), 2, SlotEvalStatus.NOT_EVALUATED) }, Type.CLOCK(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(FunctionStatus.BUILTIN), Pointer.createImmutable(0)); @@ -354,10 +340,8 @@ constant InstNode CLOCK_NODE = InstNode.CLASS_NODE("Clock", NFInstNode.CachedData.FUNCTION({ CLOCK_INFERED, CLOCK_INT, - CLOCK_INT_RESOLUTION, CLOCK_REAL, CLOCK_BOOL, - CLOCK_BOOL_INTERVAL, CLOCK_SOLVER }, true, true),