Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 6533bcd

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Handle function derivative annotations.
Belonging to [master]: - #2501 - OpenModelica/OpenModelica-testsuite#973
1 parent 82c686d commit 6533bcd

File tree

10 files changed

+422
-52
lines changed

10 files changed

+422
-52
lines changed

Compiler/FrontEnd/SCode.mo

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,6 +3921,60 @@ algorithm
39213921
end match;
39223922
end hasNamedAnnotation;
39233923

3924+
public function lookupNamedAnnotation
3925+
"Returns the modifier with the given name if it can be found in the
3926+
annotation, otherwise an empty modifier."
3927+
input Annotation ann;
3928+
input String name;
3929+
output Mod mod;
3930+
protected
3931+
list<SubMod> submods;
3932+
String id;
3933+
algorithm
3934+
mod := match ann
3935+
case Annotation.ANNOTATION(modification = Mod.MOD(subModLst = submods))
3936+
algorithm
3937+
for sm in submods loop
3938+
SubMod.NAMEMOD(id, mod) := sm;
3939+
3940+
if id == name then
3941+
return;
3942+
end if;
3943+
end for;
3944+
then
3945+
Mod.NOMOD();
3946+
3947+
else Mod.NOMOD();
3948+
end match;
3949+
end lookupNamedAnnotation;
3950+
3951+
public function lookupNamedAnnotations
3952+
"Returns a list of modifiers with the given name found in the annotation."
3953+
input Annotation ann;
3954+
input String name;
3955+
output list<Mod> mods = {};
3956+
protected
3957+
list<SubMod> submods;
3958+
String id;
3959+
Mod mod;
3960+
algorithm
3961+
mods := match ann
3962+
case Annotation.ANNOTATION(modification = Mod.MOD(subModLst = submods))
3963+
algorithm
3964+
for sm in submods loop
3965+
SubMod.NAMEMOD(id, mod) := sm;
3966+
3967+
if id == name then
3968+
mods := mod :: mods;
3969+
end if;
3970+
end for;
3971+
then
3972+
mods;
3973+
3974+
else {};
3975+
end match;
3976+
end lookupNamedAnnotations;
3977+
39243978
public function hasBooleanNamedAnnotationInClass
39253979
input Element inClass;
39263980
input String namedAnnotation;

Compiler/NFFrontEnd/NFBuiltinFuncs.mo

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ constant InstNode INTEGER_DUMMY_NODE = NFInstNode.CLASS_NODE("Integer",
128128
constant Function INTEGER_FUNCTION = Function.FUNCTION(Path.IDENT("Integer"),
129129
INTEGER_DUMMY_NODE, {ENUM_PARAM}, {}, {}, {
130130
Slot.SLOT("e", SlotType.POSITIONAL, NONE(), NONE())
131-
}, Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, Pointer.createImmutable(true), Pointer.createImmutable(0));
131+
}, Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {}, Pointer.createImmutable(true), Pointer.createImmutable(0));
132132

133133
constant InstNode INTEGER_NODE = InstNode.CLASS_NODE("IntegerFunc",
134134
DUMMY_ELEMENT, Visibility.PUBLIC,
@@ -153,15 +153,15 @@ constant Function STRING_REAL = Function.FUNCTION(Path.IDENT("String"),
153153
Slot.SLOT("significantDigits", SlotType.NAMED, SOME(Expression.INTEGER(6)), NONE()),
154154
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
155155
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
156-
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
156+
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
157157
Pointer.createImmutable(true), Pointer.createImmutable(0));
158158

159159
// String(r, format="-0.6g")
160160
constant Function STRING_REAL_FORMAT = Function.FUNCTION(Path.IDENT("String"),
161161
STRING_DUMMY_NODE, {REAL_PARAM, STRING_PARAM}, {STRING_PARAM}, {}, {
162162
Slot.SLOT("r", SlotType.POSITIONAL, NONE(), NONE()),
163163
Slot.SLOT("format", SlotType.NAMED, NONE(), NONE())
164-
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
164+
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
165165
Pointer.createImmutable(true), Pointer.createImmutable(0));
166166

167167
// String(i, minimumLength=0, leftJustified=true)
@@ -170,7 +170,7 @@ constant Function STRING_INT = Function.FUNCTION(Path.IDENT("String"),
170170
Slot.SLOT("i", SlotType.POSITIONAL, NONE(), NONE()),
171171
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
172172
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
173-
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
173+
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
174174
Pointer.createImmutable(true), Pointer.createImmutable(0));
175175

176176
// String(b, minimumLength=0, leftJustified=true)
@@ -179,7 +179,7 @@ constant Function STRING_BOOL = Function.FUNCTION(Path.IDENT("String"),
179179
Slot.SLOT("b", SlotType.POSITIONAL, NONE(), NONE()),
180180
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
181181
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
182-
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
182+
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
183183
Pointer.createImmutable(true), Pointer.createImmutable(0));
184184

185185
// String(e, minimumLength=0, leftJustified=true)
@@ -188,7 +188,7 @@ constant Function STRING_ENUM = Function.FUNCTION(Path.IDENT("String"),
188188
Slot.SLOT("e", SlotType.POSITIONAL, NONE(), NONE()),
189189
Slot.SLOT("minimumLength", SlotType.NAMED, SOME(Expression.INTEGER(0)), NONE()),
190190
Slot.SLOT("leftJustified", SlotType.NAMED, SOME(Expression.BOOLEAN(true)), NONE())
191-
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
191+
}, Type.STRING(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
192192
Pointer.createImmutable(true), Pointer.createImmutable(0));
193193

194194
constant InstNode STRING_NODE = InstNode.CLASS_NODE("String",
@@ -213,67 +213,67 @@ constant ComponentRef STRING_CREF =
213213

214214
constant Function ABS_REAL = Function.FUNCTION(Path.IDENT("abs"),
215215
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
216-
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
216+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
217217
Pointer.createImmutable(true), Pointer.createImmutable(0));
218218

219219
constant Function MAX_INT = Function.FUNCTION(Path.IDENT("max"),
220220
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
221-
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
221+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
222222
Pointer.createImmutable(true), Pointer.createImmutable(0));
223223

224224
constant Function MAX_REAL = Function.FUNCTION(Path.IDENT("max"),
225225
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
226-
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
226+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
227227
Pointer.createImmutable(true), Pointer.createImmutable(0));
228228

229229
constant Function DIV_INT = Function.FUNCTION(Path.IDENT("div"),
230230
InstNode.EMPTY_NODE(), {INT_PARAM, INT_PARAM}, {INT_PARAM}, {}, {},
231-
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
231+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
232232
Pointer.createImmutable(true), Pointer.createImmutable(0));
233233

234234
constant Function FLOOR = Function.FUNCTION(Path.IDENT("floor"),
235235
InstNode.EMPTY_NODE(), {REAL_PARAM}, {REAL_PARAM}, {}, {},
236-
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
236+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
237237
Pointer.createImmutable(true), Pointer.createImmutable(0));
238238

239239
constant Function INTEGER_REAL = Function.FUNCTION(Path.IDENT("integer"),
240240
InstNode.EMPTY_NODE(), {REAL_PARAM}, {INT_PARAM}, {}, {},
241-
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
241+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
242242
Pointer.createImmutable(true), Pointer.createImmutable(0));
243243

244244
constant Function INTEGER_ENUM = Function.FUNCTION(Path.IDENT("Integer"),
245245
InstNode.EMPTY_NODE(), {ENUM_PARAM}, {INT_PARAM}, {}, {},
246-
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
246+
Type.INTEGER(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
247247
Pointer.createImmutable(true), Pointer.createImmutable(0));
248248

249249
constant Function POSITIVE_MAX_REAL = Function.FUNCTION(Path.IDENT("$OMC$PositiveMax"),
250250
InstNode.EMPTY_NODE(), {REAL_PARAM, REAL_PARAM}, {REAL_PARAM}, {}, {},
251-
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
251+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
252252
Pointer.createImmutable(true), Pointer.createImmutable(0));
253253

254254
constant Function IN_STREAM = Function.FUNCTION(Path.IDENT("inStream"),
255255
InstNode.EMPTY_NODE(), {REAL_PARAM}, {REAL_PARAM}, {}, {},
256-
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
256+
Type.REAL(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
257257
Pointer.createImmutable(true), Pointer.createImmutable(0));
258258

259259
constant Function PROMOTE = Function.FUNCTION(Path.IDENT("promote"),
260260
InstNode.EMPTY_NODE(), {}, {}, {}, {},
261-
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
261+
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
262262
Pointer.createImmutable(true), Pointer.createImmutable(0));
263263

264264
constant Function CAT = Function.FUNCTION(Path.IDENT("cat"),
265265
InstNode.EMPTY_NODE(), {}, {}, {}, {},
266-
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
266+
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
267267
Pointer.createImmutable(true), Pointer.createImmutable(0));
268268

269269
constant Function ARRAY_FUNC = Function.FUNCTION(Path.IDENT("array"),
270270
InstNode.EMPTY_NODE(), {}, {}, {}, {},
271-
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
271+
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
272272
Pointer.createImmutable(true), Pointer.createImmutable(0));
273273

274274
constant Function FILL_FUNC = Function.FUNCTION(Path.IDENT("fill"),
275275
InstNode.EMPTY_NODE(), {}, {}, {}, {},
276-
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN,
276+
Type.UNKNOWN(), DAE.FUNCTION_ATTRIBUTES_BUILTIN, {},
277277
Pointer.createImmutable(true), Pointer.createImmutable(0));
278278

279279
annotation(__OpenModelica_Interface="frontend");

Compiler/NFFrontEnd/NFConvertDAE.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ algorithm
925925
else DAE.FunctionDefinition.FUNCTION_DEF(listReverse(elems));
926926
end match;
927927
then
928-
Function.toDAE(func, {def});
928+
Function.toDAE(func, def);
929929

930930
case Class.INSTANCED_CLASS(restriction = Restriction.RECORD_CONSTRUCTOR())
931931
then DAE.Function.RECORD_CONSTRUCTOR(Function.name(func),

Compiler/NFFrontEnd/NFEvalFunction.mo

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import ElementSource;
5252
import ModelicaExternalC;
5353
import System;
5454
import NFTyping.ExpOrigin;
55+
import SCode;
5556

5657
encapsulated package ReplTree
5758
import BaseAvlTree;
@@ -759,21 +760,18 @@ end isKnownExternalFunc;
759760

760761
function isKnownLibrary
761762
input Option<SCode.Annotation> extAnnotation;
762-
output Boolean isKnown;
763+
output Boolean isKnown = false;
763764
protected
764765
SCode.Annotation ann;
765-
Absyn.Exp exp;
766+
Option<Absyn.Exp> oexp;
766767
algorithm
767768
if isSome(extAnnotation) then
768769
SOME(ann) := extAnnotation;
770+
oexp := SCode.getModifierBinding(SCode.lookupNamedAnnotation(ann, "Library"));
769771

770-
try
771-
isKnown := isKnownLibraryExp(SCode.getNamedAnnotation(ann, "Library"));
772-
else
773-
isKnown := false;
774-
end try;
775-
else
776-
isKnown := false;
772+
if isSome(oexp) then
773+
isKnown := isKnownLibraryExp(Util.getOption(oexp));
774+
end if;
777775
end if;
778776
end isKnownLibrary;
779777

Compiler/NFFrontEnd/NFFlatten.mo

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,12 @@ algorithm
10901090
Function.collect(fn);
10911091
funcs := FunctionTree.add(funcs, Function.name(fn), fn);
10921092
funcs := collectClassFunctions(fn.node, funcs);
1093+
1094+
for fn_der in fn.derivatives loop
1095+
for der_fn in Function.getCachedFuncs(fn_der.derivativeFn) loop
1096+
funcs := flattenFunction(der_fn, funcs);
1097+
end for;
1098+
end for;
10931099
end if;
10941100
end flattenFunction;
10951101

Compiler/NFFrontEnd/NFFunction.mo

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import NFInstNode.InstNode;
3838
import Type = NFType;
3939
import NFPrefixes.*;
4040
import List;
41+
import FunctionDerivative = NFFunctionDerivative;
4142

4243
protected
4344
import ErrorExt;
@@ -208,6 +209,7 @@ uniontype Function
208209
list<Slot> slots;
209210
Type returnType;
210211
DAE.FunctionAttributes attributes;
212+
list<FunctionDerivative> derivatives;
211213
Pointer<Boolean> collected "Whether this function has already been added to the function tree or not.";
212214
Pointer<Integer> callCounter "Used during function evaluation to limit recursion.";
213215
end FUNCTION;
@@ -228,7 +230,7 @@ uniontype Function
228230
// Make sure builtin functions aren't added to the function tree.
229231
collected := Pointer.create(isBuiltinAttr(attr));
230232
fn := FUNCTION(path, node, inputs, outputs, locals, {}, Type.UNKNOWN(),
231-
attr, collected, Pointer.create(0));
233+
attr, {}, collected, Pointer.create(0));
232234
end new;
233235

234236
function lookupFunctionSimple
@@ -336,6 +338,7 @@ uniontype Function
336338
Absyn.ComponentRef cr;
337339
InstNode sub_fnNode;
338340
list<Function> funcs;
341+
list<FunctionDerivative> fn_ders;
339342

340343
case SCode.CLASS() guard SCode.isRecord(def)
341344
algorithm
@@ -367,8 +370,9 @@ uniontype Function
367370
algorithm
368371
fnNode := InstNode.setNodeType(NFInstNode.InstNodeType.ROOT_CLASS(), fnNode);
369372
fnNode := instFunction3(fnNode);
370-
fn := Function.new(fnPath, fnNode);
373+
fn := new(fnPath, fnNode);
371374
specialBuiltin := isSpecialBuiltin(fn);
375+
fn.derivatives := FunctionDerivative.instDerivatives(fnNode, fn);
372376
fnNode := InstNode.cacheAddFunc(fnNode, fn, specialBuiltin);
373377
then
374378
(fnNode, specialBuiltin);
@@ -936,27 +940,9 @@ uniontype Function
936940
they are not already typed."
937941
input ComponentRef functionRef;
938942
output list<Function> functions;
939-
protected
940-
InstNode fn_node;
941-
Boolean typed, special;
942-
String name;
943943
algorithm
944944
functions := match functionRef
945-
case ComponentRef.CREF(node = fn_node)
946-
algorithm
947-
fn_node := InstNode.classScope(fn_node);
948-
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);
949-
950-
// Type the function(s) if not already done.
951-
if not typed then
952-
functions := list(typeFunctionSignature(f) for f in functions);
953-
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
954-
functions := list(typeFunctionBody(f) for f in functions);
955-
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
956-
end if;
957-
then
958-
functions;
959-
945+
case ComponentRef.CREF() then typeNodeCache(functionRef.node);
960946
else
961947
algorithm
962948
Error.assertion(false, getInstanceName() + " got invalid function call reference", sourceInfo());
@@ -965,6 +951,28 @@ uniontype Function
965951
end match;
966952
end typeRefCache;
967953

954+
function typeNodeCache
955+
"Returns the function(s) in the cache of the given node, and types them if
956+
they are not already typed."
957+
input InstNode functionNode;
958+
output list<Function> functions;
959+
protected
960+
InstNode fn_node;
961+
Boolean typed, special;
962+
String name;
963+
algorithm
964+
fn_node := InstNode.classScope(functionNode);
965+
CachedData.FUNCTION(functions, typed, special) := InstNode.getFuncCache(fn_node);
966+
967+
// Type the function(s) if not already done.
968+
if not typed then
969+
functions := list(typeFunctionSignature(f) for f in functions);
970+
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
971+
functions := list(typeFunctionBody(f) for f in functions);
972+
InstNode.setFuncCache(fn_node, CachedData.FUNCTION(functions, true, special));
973+
end if;
974+
end typeNodeCache;
975+
968976
function typeFunction
969977
input output Function fn;
970978
algorithm
@@ -1015,6 +1023,11 @@ uniontype Function
10151023

10161024
// Type the algorithm section of the function, if it has one.
10171025
Typing.typeFunctionSections(fn.node, ExpOrigin.FUNCTION);
1026+
1027+
// Type any derivatives of the function.
1028+
for fn_der in fn.derivatives loop
1029+
FunctionDerivative.typeDerivative(fn_der);
1030+
end for;
10181031
end typeFunctionBody;
10191032

10201033
function isBuiltin
@@ -1154,19 +1167,21 @@ uniontype Function
11541167

11551168
function toDAE
11561169
input Function fn;
1157-
input list<DAE.FunctionDefinition> defs;
1170+
input DAE.FunctionDefinition def;
11581171
output DAE.Function daeFn;
11591172
protected
11601173
SCode.Visibility vis;
11611174
Boolean par, impr;
11621175
DAE.InlineType ity;
11631176
DAE.Type ty;
1177+
list<DAE.FunctionDefinition> defs;
11641178
algorithm
11651179
vis := SCode.PUBLIC(); // TODO: Use the actual visibility.
11661180
par := false; // TODO: Use the actual partial prefix.
11671181
impr := fn.attributes.isImpure;
11681182
ity := fn.attributes.inline;
11691183
ty := makeDAEType(fn);
1184+
defs := def :: list(FunctionDerivative.toDAE(fn_der) for fn_der in fn.derivatives);
11701185
daeFn := DAE.FUNCTION(fn.path, defs, ty, vis, par, impr, ity,
11711186
DAE.emptyElementSource, SCode.getElementComment(InstNode.definition(fn.node)));
11721187
end toDAE;

0 commit comments

Comments
 (0)