Skip to content

Commit

Permalink
Implement pure() operator (#8300)
Browse files Browse the repository at this point in the history
Fixes #8296
  • Loading branch information
perost committed Dec 10, 2021
1 parent 8290037 commit 3d91fc8
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 2 deletions.
33 changes: 33 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFBuiltinCall.mo
Expand Up @@ -139,6 +139,7 @@ public
case "pre" then typePreCall(call, next_context, info);
case "product" then typeProductCall(call, next_context, info);
case "promote" then typePromoteCall(call, next_context, info);
case "pure" then typePureCall(call, next_context, info);
case "rooted" then typeRootedCall(call, next_context, info);
case "root" then typeRootCall(call, next_context, info);
case "sample" then typeSampleCall(call, next_context, info);
Expand Down Expand Up @@ -2300,5 +2301,37 @@ protected
callExp := Expression.CALL(Call.unboxArgs(ty_call));
end typeSuperSampleCall;

function typePureCall
input Call call;
input InstContext.Type context;
input SourceInfo info;
output Expression callExp;
output Type ty;
output Variability var;
output Purity purity = Purity.PURE;
protected
Expression arg;
Call c;
algorithm
Call.TYPED_CALL(arguments = {arg}, ty = ty, var = var) :=
Call.typeMatchNormalCall(call, context, info, vectorize = false);
callExp := Expression.unbox(arg);

callExp := match callExp
case Expression.CALL(call = c as Call.TYPED_CALL())
algorithm
c.purity := Expression.purityList(c.arguments);
then
Expression.CALL(c);

else
algorithm
Error.addSourceMessage(Error.FUNCTION_ARGUMENT_MUST_BE,
{"pure", Gettext.translateContent(Error.FUNCTION_CALL_EXPRESSION)}, info);
then
fail();
end match;
end typePureCall;

annotation(__OpenModelica_Interface="frontend");
end NFBuiltinCall;
6 changes: 4 additions & 2 deletions OMCompiler/Compiler/NFFrontEnd/NFCall.mo
Expand Up @@ -351,7 +351,7 @@ public

args := {};
var := Variability.CONSTANT;
pur := Purity.PURE;
pur := if Function.isImpure(func) or Function.isOMImpure(func) then Purity.IMPURE else Purity.PURE;

for a in typed_args loop
TypedArg.TYPED_ARG(value = arg_exp, var = arg_var, purity = arg_pur) := a;
Expand Down Expand Up @@ -510,7 +510,7 @@ public
algorithm
isImpure := match call
case UNTYPED_CALL() then Function.isImpure(listHead(Function.getRefCache(call.ref)));
case TYPED_CALL() then Function.isImpure(call.fn) or Function.isOMImpure(call.fn);
case TYPED_CALL(purity = Purity.IMPURE) then Function.isImpure(call.fn) or Function.isOMImpure(call.fn);
else false;
end match;
end isImpure;
Expand Down Expand Up @@ -2680,6 +2680,8 @@ protected
then Expression.typeOf(Expression.unbox(listHead(args)));
case Absyn.IDENT("DynamicSelect")
then Expression.typeOf(Expression.unbox(listHead(args)));
case Absyn.IDENT("pure")
then Expression.typeOf(Expression.unbox(listHead(args)));
else
algorithm
Error.assertion(false, getInstanceName() + ": unhandled case for " +
Expand Down
1 change: 1 addition & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -1652,6 +1652,7 @@ uniontype Function
// needs unboxing and return type fix.
case "product" then true;
case "promote" then true;
case "pure" then true;
case "root" then true;
case "rooted" then true;
case "uniqueRoot" then true;
Expand Down
6 changes: 6 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFModelicaBuiltin.mo
Expand Up @@ -672,6 +672,12 @@ function inStream
</html>"));
end inStream;

function pure<T>
input T x;
output T y;
external "builtin";
annotation(__OpenModelica_builtin=true, __OpenModelica_UnboxArguments=true, version="Modelica 3.4");
end pure;

/* Extension for uncertainty computations */
record Distribution
Expand Down
4 changes: 4 additions & 0 deletions OMCompiler/Compiler/Util/Error.mo
Expand Up @@ -859,6 +859,10 @@ public constant ErrorTypes.Message CONVERSION_MISSING_USES = ErrorTypes.MESSAGE(
public constant ErrorTypes.Message CONVERSION_NO_COMPATIBLE_SCRIPT_FOUND = ErrorTypes.MESSAGE(393, ErrorTypes.SCRIPTING(), ErrorTypes.ERROR(),
Gettext.gettext("No compatible conversion script for converting from %s %s to %s could be found."));

public constant Gettext.TranslatableContent FUNCTION_CALL_EXPRESSION = Gettext.gettext("a function call expression");
public constant ErrorTypes.Message FUNCTION_ARGUMENT_MUST_BE = ErrorTypes.MESSAGE(394, ErrorTypes.SCRIPTING(), ErrorTypes.ERROR(),
Gettext.gettext("The argument to ‘%s‘ must be %s."));

public constant ErrorTypes.Message INITIALIZATION_NOT_FULLY_SPECIFIED = ErrorTypes.MESSAGE(496, ErrorTypes.TRANSLATION(), ErrorTypes.WARNING(),
Gettext.gettext("The initial conditions are not fully specified. %s."));
public constant ErrorTypes.Message INITIALIZATION_OVER_SPECIFIED = ErrorTypes.MESSAGE(497, ErrorTypes.TRANSLATION(), ErrorTypes.WARNING(),
Expand Down
42 changes: 42 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FuncBuiltinPure1.mo
@@ -0,0 +1,42 @@
// name: FuncBuiltinPure1
// keywords:
// status: correct
// cflags: -d=newInst
//
//

impure function f
input Real x;
output Real y = x;
end f;

function f2
input Real x;
output Real y;
algorithm
y := pure(f(x));
end f2;

model FuncBuiltinPure1
Real x = f2(time);
Real y = pure(f(time));
end FuncBuiltinPure1;

// Result:
// impure function f
// input Real x;
// output Real y = x;
// end f;
//
// function f2
// input Real x;
// output Real y;
// algorithm
// y := f(x);
// end f2;
//
// class FuncBuiltinPure1
// Real x = f2(time);
// Real y = f(time);
// end FuncBuiltinPure1;
// endResult
20 changes: 20 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FuncBuiltinPure2.mo
@@ -0,0 +1,20 @@
// name: FuncBuiltinPure2
// keywords:
// status: incorrect
// cflags: -d=newInst
//
//

model FuncBuiltinPure2
Real x = pure(1.0);
end FuncBuiltinPure2;

// Result:
// Error processing file: FuncBuiltinPure2.mo
// [flattening/modelica/scodeinst/FuncBuiltinPure2.mo:9:3-9:21:writable] Error: The argument to ‘pure‘ must be a function call expression.
//
// # Error encountered! Exiting...
// # Please check the error message and the flags.
//
// Execution failed!
// endResult
2 changes: 2 additions & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -522,6 +522,8 @@ FuncBuiltinPre.mo \
FuncBuiltinProduct.mo \
FuncBuiltinPromote.mo \
FuncBuiltinPromoteInvalid1.mo \
FuncBuiltinPure1.mo \
FuncBuiltinPure2.mo \
FuncBuiltinReduction.mo \
FuncBuiltinRem.mo \
FuncBuiltinSample.mo \
Expand Down

0 comments on commit 3d91fc8

Please sign in to comment.