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

Commit 64ce9d9

Browse files
perostOpenModelica-Hudson
authored andcommitted
Partial implementation of functions for NFInst.
- New uniontype NFFunction to represent functions. - New module NFCall with functions to handle function calls. - Added CachedData to InstNode, initially only used to cache functions.
1 parent 7cf48f8 commit 64ce9d9

File tree

13 files changed

+997
-547
lines changed

13 files changed

+997
-547
lines changed

Compiler/FrontEnd/DAEDump.mo

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,6 +3568,18 @@ algorithm
35683568
end match;
35693569
end unparseVarDirection;
35703570

3571+
function unparseVarInnerOuter
3572+
input DAE.VarInnerOuter io;
3573+
output String str;
3574+
algorithm
3575+
str := match io
3576+
case DAE.VarInnerOuter.INNER() then "inner";
3577+
case DAE.VarInnerOuter.OUTER() then "outer";
3578+
case DAE.VarInnerOuter.INNER_OUTER() then "inner outer";
3579+
else "";
3580+
end match;
3581+
end unparseVarInnerOuter;
3582+
35713583
public function getSourceInformationStr
35723584
"@author: adrpo
35733585
display the source information as string"

Compiler/NFFrontEnd/NFBuiltin.mo

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,25 @@ end Elements;
128128
constant InstNode REAL_TYPE = InstNode.CLASS_NODE("Real",
129129
Elements.REAL,
130130
listArray({Class.PARTIAL_BUILTIN(Type.REAL(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
131+
listArray({NFInstNode.CachedData.NO_CACHE()}),
131132
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());
132133

133134
constant InstNode INT_TYPE = InstNode.CLASS_NODE("Integer",
134135
Elements.INTEGER,
135136
listArray({Class.PARTIAL_BUILTIN(Type.INTEGER(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
137+
listArray({NFInstNode.CachedData.NO_CACHE()}),
136138
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());
137139

138140
constant InstNode BOOLEAN_TYPE = InstNode.CLASS_NODE("Boolean",
139141
Elements.BOOLEAN,
140142
listArray({Class.PARTIAL_BUILTIN(Type.BOOLEAN(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
143+
listArray({NFInstNode.CachedData.NO_CACHE()}),
141144
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());
142145

143146
constant InstNode STRING_TYPE = InstNode.CLASS_NODE("String",
144147
Elements.STRING,
145148
listArray({Class.PARTIAL_BUILTIN(Type.STRING(), ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
149+
listArray({NFInstNode.CachedData.NO_CACHE()}),
146150
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());
147151

148152
constant Type STATESELECT_TYPE_TYPE = Type.ENUMERATION(
@@ -151,6 +155,7 @@ constant Type STATESELECT_TYPE_TYPE = Type.ENUMERATION(
151155
constant InstNode STATESELECT_TYPE = InstNode.CLASS_NODE("StateSelect",
152156
Elements.STATESELECT,
153157
listArray({Class.PARTIAL_BUILTIN(STATESELECT_TYPE_TYPE, ClassTree.EMPTY(), listArray({}), Modifier.NOMOD())}),
158+
listArray({NFInstNode.CachedData.NO_CACHE()}),
154159
InstNode.EMPTY_NODE(), InstNodeType.NORMAL_CLASS());
155160

156161
constant Binding STATESELECT_NEVER_BINDING =

Compiler/NFFrontEnd/NFCall.mo

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*
2+
* This file is part of OpenModelica.
3+
*
4+
* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
5+
* c/o Linköpings universitet, Department of Computer and Information Science,
6+
* SE-58183 Linköping, Sweden.
7+
*
8+
* All rights reserved.
9+
*
10+
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
11+
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
12+
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
13+
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
14+
* ACCORDING TO RECIPIENTS CHOICE.
15+
*
16+
* The OpenModelica software and the Open Source Modelica
17+
* Consortium (OSMC) Public License (OSMC-PL) are obtained
18+
* from OSMC, either from the above address,
19+
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
20+
* http://www.openmodelica.org, and in the OpenModelica distribution.
21+
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
22+
*
23+
* This program is distributed WITHOUT ANY WARRANTY; without
24+
* even the implied warranty of MERCHANTABILITY or FITNESS
25+
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
26+
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
27+
*
28+
* See the full OSMC Public License conditions for more details.
29+
*
30+
*/
31+
32+
encapsulated package NFCall
33+
34+
import Absyn;
35+
import NFInstNode.InstNode;
36+
import NFExpression.Expression;
37+
import Type = NFType;
38+
39+
protected
40+
import NFInstNode.CachedData;
41+
import NFExpression.CallAttributes;
42+
import ComponentRef = NFComponentRef;
43+
import NFFunction.Function;
44+
import Inst = NFInst;
45+
import Lookup = NFLookup;
46+
import Typing = NFTyping;
47+
import Types;
48+
49+
public
50+
function instantiate
51+
input Absyn.ComponentRef functionName;
52+
input Absyn.FunctionArgs functionArgs;
53+
input InstNode scope;
54+
input SourceInfo info;
55+
output Expression callExp;
56+
protected
57+
InstNode fn_node;
58+
Function fn;
59+
list<Function> fnl;
60+
CachedData cache;
61+
ComponentRef fn_ref;
62+
Absyn.Path fn_path;
63+
algorithm
64+
// Look up the the function.
65+
(fn_node, fn_ref, fn_path) := lookupFunction(functionName, scope, info);
66+
cache := InstNode.cachedData(fn_node);
67+
68+
// Check if a cached instantiation of this function already exists.
69+
fnl := match cache
70+
case CachedData.FUNCTION() then cache.funcs;
71+
72+
else // Not yet instantiated, instantiate it and cache it in the node.
73+
algorithm
74+
fn_node := Inst.instantiate(fn_node);
75+
Inst.instExpressions(fn_node);
76+
fn := Function.new(fn_path, fn_node);
77+
fn_node := InstNode.cacheAddFunc(fn, fn_node);
78+
then
79+
{fn};
80+
end match;
81+
82+
callExp := makeCall(fn_ref, fnl, functionArgs, scope, info);
83+
end instantiate;
84+
85+
function typeCall
86+
input output Expression callExp;
87+
input InstNode scope;
88+
input SourceInfo info;
89+
output Type ty;
90+
output DAE.Const variability;
91+
protected
92+
InstNode fn_node;
93+
list<Function> fnl;
94+
Boolean fn_typed;
95+
Function fn;
96+
list<Expression> args;
97+
list<Type> arg_ty;
98+
list<DAE.Const> arg_var;
99+
CallAttributes ca;
100+
algorithm
101+
(callExp, ty, variability) := match callExp
102+
case Expression.CALL(ref = ComponentRef.CREF(node = fn_node))
103+
algorithm
104+
// Fetch the cached function(s).
105+
CachedData.FUNCTION(fnl, fn_typed) := InstNode.cachedData(fn_node);
106+
107+
// Type the function(s) if not already done.
108+
if not fn_typed then
109+
fnl := list(Function.typeFunction(f) for f in fnl);
110+
InstNode.setCachedData(CachedData.FUNCTION(fnl, true), fn_node);
111+
end if;
112+
113+
assert(not listEmpty(fnl), getInstanceName() + " couldn't find a cached function");
114+
115+
fn := match fnl
116+
case {fn} then fn; // The normal case of only one matching function.
117+
else // TODO: Handle overloaded functions.
118+
algorithm
119+
assert(false, getInstanceName() + ": IMPLEMENT ME");
120+
then
121+
fail();
122+
end match;
123+
124+
125+
// Type the arguments.
126+
(args, arg_ty, arg_var) := Typing.typeExpl(callExp.arguments, scope, info);
127+
variability := Types.constAnd(v for v in arg_var);
128+
129+
ty := fn.returnType;
130+
ca := CallAttributes.CALL_ATTR(
131+
ty,
132+
Type.isTuple(fn.returnType),
133+
Function.isBuiltin(fn),
134+
Function.isImpure(fn),
135+
Function.isFunctionPointer(fn),
136+
Function.inlineBuiltin(fn),
137+
DAE.NO_TAIL());
138+
139+
// TODO: Type check arguments against the inputs, and check variability.
140+
141+
callExp := Expression.CALL(callExp.ref, args, SOME(ca));
142+
then
143+
(callExp, ty, variability);
144+
145+
else
146+
algorithm
147+
assert(false, getInstanceName() + " got invalid function call expression");
148+
then
149+
fail();
150+
end match;
151+
end typeCall;
152+
153+
protected
154+
function lookupFunction
155+
input Absyn.ComponentRef functionName;
156+
input InstNode scope;
157+
input SourceInfo info;
158+
output InstNode node;
159+
output ComponentRef functionRef;
160+
output Absyn.Path functionPath;
161+
protected
162+
list<InstNode> nodes;
163+
InstNode found_scope;
164+
algorithm
165+
try
166+
// Make sure the name is a path.
167+
functionPath := Absyn.crefToPath(functionName);
168+
else
169+
Error.addSourceMessageAndFail(Error.SUBSCRIPTED_FUNCTION_CALL,
170+
{Dump.printComponentRefStr(functionName)}, info);
171+
end try;
172+
173+
// Look up the function and create a cref for it.
174+
(node, nodes, found_scope) := Lookup.lookupFunctionName(functionName, scope, info);
175+
176+
for s in InstNode.scopeList(found_scope) loop
177+
functionPath := Absyn.QUALIFIED(InstNode.name(s), functionPath);
178+
end for;
179+
180+
functionRef := ComponentRef.fromNodeList(InstNode.scopeList(found_scope));
181+
functionRef := Inst.makeCref(functionName, nodes, scope, info, functionRef);
182+
end lookupFunction;
183+
184+
function makeCall
185+
input ComponentRef fnRef;
186+
input list<Function> funcs;
187+
input Absyn.FunctionArgs callArgs;
188+
input InstNode scope;
189+
input SourceInfo info;
190+
output Expression call;
191+
output list<Function> matchingFuncs;
192+
protected
193+
list<Expression> args;
194+
list<tuple<String, Expression>> named_args;
195+
algorithm
196+
(args, named_args) := instArgs(callArgs, scope, info);
197+
(args, matchingFuncs) := matchArgs(args, named_args, funcs, info);
198+
call := Expression.CALL(fnRef, args, NONE());
199+
end makeCall;
200+
201+
function instArgs
202+
input Absyn.FunctionArgs args;
203+
input InstNode scope;
204+
input SourceInfo info;
205+
output list<Expression> posArgs;
206+
output list<tuple<String, Expression>> namedArgs;
207+
algorithm
208+
(posArgs, namedArgs) := match args
209+
case Absyn.FUNCTIONARGS()
210+
algorithm
211+
posArgs := list(Inst.instExp(a, scope, info) for a in args.args);
212+
namedArgs := list(instNamedArg(a, scope, info) for a in args.argNames);
213+
then
214+
(posArgs, namedArgs);
215+
216+
else
217+
algorithm
218+
assert(false, getInstanceName() + " got unknown function args");
219+
then
220+
fail();
221+
end match;
222+
end instArgs;
223+
224+
function instNamedArg
225+
input Absyn.NamedArg absynArg;
226+
input InstNode scope;
227+
input SourceInfo info;
228+
output tuple<String, Expression> arg;
229+
protected
230+
String name;
231+
Absyn.Exp exp;
232+
algorithm
233+
Absyn.NAMEDARG(argName = name, argValue = exp) := absynArg;
234+
arg := (name, Inst.instExp(exp, scope, info));
235+
end instNamedArg;
236+
237+
function matchArgs
238+
input list<Expression> posArgs;
239+
input list<tuple<String, Expression>> namedArgs;
240+
input list<Function> funcs;
241+
input SourceInfo info;
242+
output list<Expression> args;
243+
output list<Function> matchingFuncs;
244+
protected
245+
Function fn;
246+
algorithm
247+
if listLength(funcs) == 1 then
248+
(args, true) := Function.matchArgs(posArgs, namedArgs, listHead(funcs), SOME(info));
249+
matchingFuncs := funcs;
250+
else
251+
// TODO: Implement case for overloaded functions.
252+
assert(false, getInstanceName() + ": IMPLEMENT ME");
253+
end if;
254+
end matchArgs;
255+
256+
annotation(__OpenModelica_Interface="frontend");
257+
end NFCall;

Compiler/NFFrontEnd/NFComponentRef.mo

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,29 @@ public
228228
end match;
229229
end toString;
230230

231+
function toPath
232+
input ComponentRef cref;
233+
output Absyn.Path path;
234+
algorithm
235+
path := match cref
236+
case CREF()
237+
then toPath_impl(cref.restCref, Absyn.IDENT(InstNode.name(cref.node)));
238+
end match;
239+
end toPath;
240+
241+
function toPath_impl
242+
input ComponentRef cref;
243+
input Absyn.Path accumPath;
244+
output Absyn.Path path;
245+
algorithm
246+
path := match cref
247+
case CREF()
248+
then toPath_impl(cref.restCref,
249+
Absyn.QUALIFIED(InstNode.name(cref.node), accumPath));
250+
else accumPath;
251+
end match;
252+
end toPath_impl;
253+
231254
function fromNodeList
232255
input list<InstNode> nodes;
233256
output ComponentRef cref = ComponentRef.EMPTY();

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,7 @@ uniontype Expression
112112
end RECORD;
113113

114114
record CALL
115-
Absyn.Path path;
116-
ComponentRef cref;
115+
ComponentRef ref;
117116
list<Expression> arguments;
118117
Option<CallAttributes> attr;
119118
end CALL;
@@ -272,8 +271,8 @@ uniontype Expression
272271

273272
case CALL()
274273
algorithm
275-
CALL(path = p, arguments = expl) := exp2;
276-
comp := Absyn.pathCompare(exp1.path, p);
274+
CALL(ref = cr, arguments = expl) := exp2;
275+
comp := ComponentRef.compare(exp1.ref, cr);
277276
then
278277
if comp == 0 then compareList(exp1.arguments, expl) else comp;
279278

@@ -599,7 +598,7 @@ uniontype Expression
599598
then ":" + toString(Util.getOption(exp.step))
600599
else ""
601600
) + ":" + toString(exp.stop);
602-
case CALL() then Absyn.pathString(exp.path) + "(" + stringDelimitList(List.map(exp.arguments, toString), ", ") + ")";
601+
case CALL() then ComponentRef.toString(exp.ref) + "(" + stringDelimitList(List.map(exp.arguments, toString), ", ") + ")";
603602
case SIZE() then "size(" + toString(exp.exp) +
604603
(
605604
if isSome(exp.dimIndex)
@@ -659,7 +658,8 @@ uniontype Expression
659658
toDAE(exp.stop));
660659

661660
case CALL(attr = SOME(attr))
662-
then DAE.CALL(exp.path, List.map(exp.arguments, toDAE), toDAECallAtributes(attr));
661+
then DAE.CALL(ComponentRef.toPath(exp.ref),
662+
List.map(exp.arguments, toDAE), toDAECallAtributes(attr));
663663

664664
case SIZE()
665665
then DAE.SIZE(toDAE(exp.exp),

0 commit comments

Comments
 (0)