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

Commit 87286cb

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Various improvements.
- Add manual typing of cardinality and Connections.*. - Fixed typing of if equations when the condition contains one of the above mentioned connection operators. - Added evaluation of OpenModelica_uriToFilename. - Improved Expression.applyIndexSubscript for crefs. Belonging to [master]: - #2411
1 parent 89eacbb commit 87286cb

File tree

10 files changed

+552
-28
lines changed

10 files changed

+552
-28
lines changed

Compiler/NFFrontEnd/NFCall.mo

Lines changed: 314 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ uniontype Call
389389

390390
(callExp, ty, variability) := match ComponentRef.firstName(cref)
391391
case "String" then typeStringCall(call, origin, info);
392+
case "branch" then typeBranchCall(call, origin, info);
392393
case "cardinality" then typeCardinalityCall(call, origin, info);
393394
case "cat" then typeCatCall(call, origin, info);
394395
case "change" then typeChangeCall(call, origin, info);
@@ -397,14 +398,18 @@ uniontype Call
397398
case "edge" then typeEdgeCall(call, origin, info);
398399
case "fill" then typeFillCall(call, origin, info);
399400
case "initial" then typeDiscreteCall(call, origin, info);
401+
case "isRoot" then typeIsRootCall(call, origin, info);
400402
case "matrix" then typeMatrixCall(call, origin, info);
401403
case "max" then typeMinMaxCall(call, origin, info);
402404
case "min" then typeMinMaxCall(call, origin, info);
403405
case "ndims" then typeNdimsCall(call, origin, info);
404406
case "noEvent" then typeNoEventCall(call, origin, info);
405407
case "ones" then typeZerosOnesCall(call, origin, info);
408+
case "potentialRoot" then typePotentialRootCall(call, origin, info);
406409
case "pre" then typePreCall(call, origin, info);
407410
case "product" then typeSumProductCall(call, origin, info);
411+
case "root" then typeRootCall(call, origin, info);
412+
case "rooted" then typeRootedCall(call, origin, info);
408413
case "scalar" then typeScalarCall(call, origin, info);
409414
case "smooth" then typeSmoothCall(call, origin, info);
410415
case "sum" then typeSumProductCall(call, origin, info);
@@ -432,9 +437,10 @@ uniontype Call
432437
protected
433438
Call call;
434439
list<Expression> args;
440+
ComponentRef cref;
435441
algorithm
436442
outExp := match callExp
437-
case Expression.CALL(UNTYPED_CALL())
443+
case Expression.CALL(UNTYPED_CALL(ref = cref))
438444
algorithm
439445
if(builtinSpecialHandling(callExp.call)) then
440446
(outExp, ty, var) := typeSpecialBuiltinFunction(callExp.call, origin, info);
@@ -1931,7 +1937,7 @@ protected
19311937
dims := listReverseInPlace(dims);
19321938

19331939
{fn} := typeCachedFunctions(fnRef);
1934-
ty := Type.ARRAY(fillType, dims);
1940+
ty := Type.liftArrayLeftList(fillType, dims);
19351941

19361942
if variability <= Variability.STRUCTURAL_PARAMETER and intBitAnd(origin, ExpOrigin.FUNCTION) == 0 then
19371943
callExp := Ceval.evalBuiltinFill(ty_args);
@@ -2283,16 +2289,317 @@ protected
22832289
output Type ty;
22842290
output Variability var = Variability.PARAMETER;
22852291
protected
2286-
Call argtycall;
2292+
ComponentRef fn_ref;
2293+
list<Expression> args;
2294+
list<NamedArg> named_args;
2295+
Expression arg;
2296+
Function fn;
22872297
algorithm
2288-
argtycall := typeMatchNormalCall(call, origin, info);
2298+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
22892299

2290-
ty := getType(argtycall);
2291-
var := variability(argtycall);
2292-
callExp := Expression.CALL(unboxArgs(argtycall));
2300+
if not listEmpty(named_args) then
2301+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2302+
{ComponentRef.toString(fn_ref), Util.tuple21(listHead(named_args))}, info);
2303+
end if;
2304+
2305+
if listLength(args) <> 1 then
2306+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2307+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector) => Integer"}, info);
2308+
end if;
2309+
2310+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2311+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2312+
{ComponentRef.toString(fn_ref)}, info);
2313+
end if;
2314+
2315+
(arg, ty) := Typing.typeExp(listHead(args), origin, info);
2316+
2317+
if not Expression.isCref(arg) then
2318+
Error.addSourceMessageAndFail(Error.ARGUMENT_MUST_BE_VARIABLE,
2319+
{"First", ComponentRef.toString(fn_ref), "<REMOVE ME>"}, info);
2320+
end if;
2321+
2322+
if not Type.isConnector(ty) then
2323+
Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH,
2324+
{"1", ComponentRef.toString(fn_ref), "",
2325+
Expression.toString(arg), Type.toString(ty), "connector"}, info);
2326+
end if;
2327+
2328+
{fn} := typeCachedFunctions(fn_ref);
2329+
ty := Type.INTEGER();
2330+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg}, ty, var));
22932331
// TODO: Check cardinality restrictions, 3.7.2.3.
22942332
end typeCardinalityCall;
22952333

2334+
function typeBranchCall
2335+
input Call call;
2336+
input ExpOrigin.Type origin;
2337+
input SourceInfo info;
2338+
output Expression callExp;
2339+
output Type ty;
2340+
output Variability var = Variability.PARAMETER;
2341+
protected
2342+
ComponentRef fn_ref;
2343+
list<Expression> args;
2344+
list<NamedArg> named_args;
2345+
Expression arg1, arg2;
2346+
Function fn;
2347+
algorithm
2348+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
2349+
2350+
if not listEmpty(named_args) then
2351+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2352+
{ComponentRef.toString(fn_ref), Util.tuple21(listHead(named_args))}, info);
2353+
end if;
2354+
2355+
if listLength(args) <> 2 then
2356+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2357+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector, Connector)"}, info);
2358+
end if;
2359+
2360+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2361+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2362+
{ComponentRef.toString(fn_ref)}, info);
2363+
end if;
2364+
2365+
{arg1, arg2} := args;
2366+
2367+
(arg1, ty) := Typing.typeExp(arg1, origin, info);
2368+
checkConnectionsArgument(arg1, ty, fn_ref, 1, info);
2369+
(arg2, ty) := Typing.typeExp(arg2, origin, info);
2370+
checkConnectionsArgument(arg2, ty, fn_ref, 2, info);
2371+
2372+
{fn} := typeCachedFunctions(fn_ref);
2373+
ty := Type.NORETCALL();
2374+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg1, arg2}, ty, var));
2375+
end typeBranchCall;
2376+
2377+
function typeIsRootCall
2378+
input Call call;
2379+
input ExpOrigin.Type origin;
2380+
input SourceInfo info;
2381+
output Expression callExp;
2382+
output Type ty;
2383+
output Variability var = Variability.PARAMETER;
2384+
protected
2385+
ComponentRef fn_ref;
2386+
list<Expression> args;
2387+
list<NamedArg> named_args;
2388+
Expression arg;
2389+
Function fn;
2390+
algorithm
2391+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
2392+
2393+
if not listEmpty(named_args) then
2394+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2395+
{ComponentRef.toString(fn_ref), Util.tuple21(listHead(named_args))}, info);
2396+
end if;
2397+
2398+
if listLength(args) <> 1 then
2399+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2400+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
2401+
end if;
2402+
2403+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2404+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2405+
{ComponentRef.toString(fn_ref)}, info);
2406+
end if;
2407+
2408+
(arg, ty) := Typing.typeExp(listHead(args), origin, info);
2409+
checkConnectionsArgument(arg, ty, fn_ref, 1, info);
2410+
2411+
{fn} := typeCachedFunctions(fn_ref);
2412+
ty := Type.BOOLEAN();
2413+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg}, ty, var));
2414+
end typeIsRootCall;
2415+
2416+
function typePotentialRootCall
2417+
input Call call;
2418+
input ExpOrigin.Type origin;
2419+
input SourceInfo info;
2420+
output Expression callExp;
2421+
output Type ty;
2422+
output Variability var = Variability.PARAMETER;
2423+
protected
2424+
ComponentRef fn_ref;
2425+
list<Expression> args;
2426+
list<NamedArg> named_args;
2427+
Expression arg1, arg2;
2428+
Function fn;
2429+
Integer args_len;
2430+
String name;
2431+
algorithm
2432+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
2433+
2434+
for narg in named_args loop
2435+
(name, arg2) := narg;
2436+
2437+
if name == "priority" then
2438+
args := listAppend(args, {arg2});
2439+
else
2440+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2441+
{ComponentRef.toString(fn_ref), name}, info);
2442+
end if;
2443+
end for;
2444+
2445+
args_len := listLength(args);
2446+
if args_len < 1 or args_len > 2 then
2447+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2448+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector, Integer = 0)"}, info);
2449+
end if;
2450+
2451+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2452+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2453+
{ComponentRef.toString(fn_ref)}, info);
2454+
end if;
2455+
2456+
arg1 :: args := args;
2457+
2458+
(arg1, ty) := Typing.typeExp(arg1, origin, info);
2459+
checkConnectionsArgument(arg1, ty, fn_ref, 1, info);
2460+
2461+
if args_len == 2 then
2462+
arg2 := listHead(args);
2463+
(arg2, ty) := Typing.typeExp(arg2, origin, info);
2464+
2465+
if not Type.isInteger(ty) then
2466+
Error.addSourceMessageAndFail(Error.ARG_TYPE_MISMATCH,
2467+
{"2", ComponentRef.toString(fn_ref), "", Expression.toString(arg2),
2468+
Type.toString(ty), "Integer"}, info);
2469+
end if;
2470+
else
2471+
arg2 := Expression.INTEGER(0);
2472+
end if;
2473+
2474+
{fn} := typeCachedFunctions(fn_ref);
2475+
ty := Type.NORETCALL();
2476+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg1, arg2}, ty, var));
2477+
end typePotentialRootCall;
2478+
2479+
function typeRootCall
2480+
input Call call;
2481+
input ExpOrigin.Type origin;
2482+
input SourceInfo info;
2483+
output Expression callExp;
2484+
output Type ty;
2485+
output Variability var = Variability.PARAMETER;
2486+
protected
2487+
ComponentRef fn_ref;
2488+
list<Expression> args;
2489+
list<NamedArg> named_args;
2490+
Expression arg;
2491+
Function fn;
2492+
algorithm
2493+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
2494+
2495+
if not listEmpty(named_args) then
2496+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2497+
{ComponentRef.toString(fn_ref), Util.tuple21(listHead(named_args))}, info);
2498+
end if;
2499+
2500+
if listLength(args) <> 1 then
2501+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2502+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
2503+
end if;
2504+
2505+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2506+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2507+
{ComponentRef.toString(fn_ref)}, info);
2508+
end if;
2509+
2510+
(arg, ty) := Typing.typeExp(listHead(args), origin, info);
2511+
checkConnectionsArgument(arg, ty, fn_ref, 1, info);
2512+
2513+
{fn} := typeCachedFunctions(fn_ref);
2514+
ty := Type.NORETCALL();
2515+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg}, ty, var));
2516+
end typeRootCall;
2517+
2518+
function typeRootedCall
2519+
input Call call;
2520+
input ExpOrigin.Type origin;
2521+
input SourceInfo info;
2522+
output Expression callExp;
2523+
output Type ty;
2524+
output Variability var = Variability.PARAMETER;
2525+
protected
2526+
ComponentRef fn_ref;
2527+
list<Expression> args;
2528+
list<NamedArg> named_args;
2529+
Expression arg;
2530+
Function fn;
2531+
algorithm
2532+
UNTYPED_CALL(ref = fn_ref, arguments = args, named_args = named_args) := call;
2533+
2534+
if not listEmpty(named_args) then
2535+
Error.addSourceMessageAndFail(Error.NO_SUCH_PARAMETER,
2536+
{ComponentRef.toString(fn_ref), Util.tuple21(listHead(named_args))}, info);
2537+
end if;
2538+
2539+
if listLength(args) <> 1 then
2540+
Error.addSourceMessageAndFail(Error.NO_MATCHING_FUNCTION_FOUND_NFINST,
2541+
{toString(call), ComponentRef.toString(fn_ref) + "(Connector)"}, info);
2542+
end if;
2543+
2544+
if intBitAnd(origin, ExpOrigin.FUNCTION) > 0 then
2545+
Error.addSourceMessageAndFail(Error.EXP_INVALID_IN_FUNCTION,
2546+
{ComponentRef.toString(fn_ref)}, info);
2547+
end if;
2548+
2549+
(arg, ty) := Typing.typeExp(listHead(args), origin, info);
2550+
checkConnectionsArgument(arg, ty, fn_ref, 1, info);
2551+
2552+
{fn} := typeCachedFunctions(fn_ref);
2553+
ty := Type.BOOLEAN();
2554+
callExp := Expression.CALL(makeBuiltinCall2(fn, {arg}, ty, var));
2555+
end typeRootedCall;
2556+
2557+
function checkConnectionsArgument
2558+
input Expression arg;
2559+
input Type ty;
2560+
input ComponentRef fnRef;
2561+
input Integer argIndex;
2562+
input SourceInfo info;
2563+
algorithm
2564+
() := match arg
2565+
local
2566+
Type ty2;
2567+
InstNode node;
2568+
Boolean valid_cref;
2569+
ComponentRef rest_cref;
2570+
2571+
case Expression.CREF()
2572+
algorithm
2573+
valid_cref := match arg.cref
2574+
case ComponentRef.CREF(node = node, origin = NFComponentRef.Origin.CREF,
2575+
restCref = ComponentRef.CREF(ty = ty2, origin = NFComponentRef.Origin.CREF,
2576+
restCref = rest_cref))
2577+
then Class.isOverdetermined(InstNode.getClass(node)) and
2578+
Type.isConnector(ty2) and
2579+
not ComponentRef.isFromCref(rest_cref);
2580+
2581+
else false;
2582+
end match;
2583+
2584+
if not valid_cref then
2585+
Error.addSourceMessageAndFail(
2586+
if argIndex == 1 then Error.INVALID_ARGUMENT_TYPE_BRANCH_FIRST else
2587+
Error.INVALID_ARGUMENT_TYPE_BRANCH_SECOND,
2588+
{ComponentRef.toString(fnRef)}, info);
2589+
end if;
2590+
then
2591+
();
2592+
2593+
else
2594+
algorithm
2595+
Error.addSourceMessage(Error.ARG_TYPE_MISMATCH,
2596+
{String(argIndex), ComponentRef.toString(fnRef), "",
2597+
Expression.toString(arg), Type.toString(ty), "overconstrained type/record"}, info);
2598+
then
2599+
fail();
2600+
end match;
2601+
end checkConnectionsArgument;
2602+
22962603
function typeNoEventCall
22972604
input Call call;
22982605
input ExpOrigin.Type origin;

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,7 @@ algorithm
12091209
case "transpose" then evalBuiltinTranspose(listHead(args));
12101210
case "vector" then evalBuiltinVector(listHead(args));
12111211
case "zeros" then evalBuiltinZeros(args);
1212+
case "OpenModelica_uriToFilename" then evalUriToFilename(listHead(args));
12121213
else
12131214
algorithm
12141215
Error.addInternalError(getInstanceName() + ": unimplemented case for " +
@@ -2114,5 +2115,17 @@ algorithm
21142115
result := evalBuiltinFill2(Expression.INTEGER(0), args);
21152116
end evalBuiltinZeros;
21162117

2118+
function evalUriToFilename
2119+
input Expression arg;
2120+
output Expression result;
2121+
algorithm
2122+
result := match arg
2123+
case Expression.STRING()
2124+
then Expression.STRING(OpenModelica.Scripting.uriToFilename(arg.value));
2125+
2126+
else algorithm printWrongArgsError(getInstanceName(), {arg}, sourceInfo()); then fail();
2127+
end match;
2128+
end evalUriToFilename;
2129+
21172130
annotation(__OpenModelica_Interface="frontend");
21182131
end NFCeval;

0 commit comments

Comments
 (0)