@@ -13282,7 +13282,8 @@ protected function OverloadingValidForSpec_3_2
1328213282 input Boolean isArray1;
1328313283 input Boolean isArray2;
1328413284 input list<DAE.Type> inTypeList;
13285- input list<DAE.Exp> inFuncArgs;
13285+ input Absyn.Path inPath;
13286+ input list<Absyn.Exp> inFuncArgs;
1328613287 input Boolean inImpl;
1328713288 input Option<GlobalScript.SymbolTable> inSyTabOpt;
1328813289 input Prefix.Prefix inPre;
@@ -13293,9 +13294,8 @@ protected function OverloadingValidForSpec_3_2
1329313294 output DAE.Properties outProp;
1329413295
1329513296algorithm
13296- // (outCache,outExp,outProp) :=
13297- _ :=
13298- matchcontinue (inCache,inEnv,inOper,isArray1,isArray2,inTypeList,inFuncArgs,inImpl,inSyTabOpt,inPre,inInfo, lastRound)
13297+ (outCache,outExp,outProp) :=
13298+ matchcontinue (inCache,inEnv,inOper,isArray1,isArray2,inTypeList,inPath,inFuncArgs,inImpl,inSyTabOpt,inPre,inInfo, lastRound)
1329913299 local
1330013300 list<DAE.Type> types,scalartypes, arraytypes;
1330113301 Env.Cache cache;
@@ -13311,55 +13311,50 @@ algorithm
1331113311 */
1331213312
1331313313 // If both are scalars everything should be OK.
13314- /* TODO: FIX ME
13315- case (_, _, _ ,false, false, types, _, _, _, _, _, _, _)
13314+ case (_, _, _ ,false, false, types, _, _, _, _, _, _, _)
1331613315 equation
1331713316 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,types,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
1331813317 then (cache, daeExp, prop);
13319- */
13318+
1332013319 // If the first one array and the second scalar with NON-ELEMWISE operation
1332113320 // we shouldn't expand. (remember here eventhough this
1332213321 // is normally invalid (e.g. {1,2} + 1), the user might overload
1332313322 // the operator to match this kind of operation on his records..
1332413323 //)
13325- /* TODO: FIX ME
1332613324 case (_, _, _ ,true, false, types, _, _, _, _, _, _, _)
1332713325 equation
1332813326 false = isOpElemWise(inOper);
1332913327 (arraytypes,_) = List.splitOnTrue(types,isFuncWithArrayInput);
1333013328 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,arraytypes,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
1333113329 then (cache, daeExp, prop);
13332- */
13330+
1333313331 // adrpo: v1 = n12 * v2; v1,v2 is array complex, n12 is real.
1333413332 // see Modelica.Electrical.QuasiStationary.Machines.Examples.TransformerTestbench
13335- /* TODO: FIX ME
1333613333 case (_, _, _ ,true, false, types, _, _, _, _, _, _, _)
1333713334 equation
1333813335 false = isOpElemWise(inOper);
1333913336 (_, scalartypes) = List.splitOnTrue(types,isFuncWithArrayInput);
1334013337 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,scalartypes,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
1334113338 then (cache, daeExp, prop);
13342- */
13339+
1334313340 // the first one array the second a scalar with ELEMWISE operation
1334413341 // this should be expanded.
13345- /* TODO: FIX ME
1334613342 case (_, _, _ ,true, false, types, _, _, _, _, _, _, _)
1334713343 equation
1334813344 true = isOpElemWise(inOper);
1334913345 (_, scalartypes) = List.splitOnTrue(types,isFuncWithArrayInput);
1335013346 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,scalartypes,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
1335113347 then (cache, daeExp, prop);
13352- */
13348+
1335313349 // Both are arrays with NON-ELEMWISE operator
1335413350 // Try without expanding first. (see Complex.'*'.scalarProduct)
13355- /* TODO: FIX ME
1335613351 case (_, _, _, true, true, types, _, _, _, _, _, _, _)
1335713352 equation
1335813353 false = isOpElemWise(inOper);
1335913354 (arraytypes,_) = List.splitOnTrue(types,isFuncWithArrayInput);
1336013355 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,arraytypes,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
1336113356 then (cache, daeExp, prop);
13362- */
13357+
1336313358 // Both are arrays with NON-ELEMWISE operator
1336413359 // the above case (without Expanding) failed.)
1336513360 // Try expnding.
@@ -13368,7 +13363,6 @@ algorithm
1336813363 // But this shouldn't be since, again, the user can overload for this
1336913364 // specific case. For now we print a warning and allow this
1337013365 // (allowed for all operators!!!)
13371- /* TODO: FIX ME
1337213366 case (_, _, _, true, true, types, _, _, _, _, _, _, _)
1337313367 equation
1337413368 false = isOpElemWise(inOper);
@@ -13381,30 +13375,28 @@ algorithm
1338113375 "- Automatically expanded using operator function: " +& Absyn.pathString(getCallPath(daeExp));
1338213376 Error.addSourceMessage(Error.OPERATOR_OVERLOADING_WARNING,
1338313377 {str1}, inInfo);
13384- then (cache, daeExp, prop);
13385- */
13378+ then (cache, daeExp, prop);
13379+
1338613380 // Both are arrays with ELEMWISE operator
1338713381 // this should be expanded.
13388- /* TODO: FIX ME
1338913382 case (_, _, _, true, true, types, _, _, _, _, _, _, _)
1339013383 equation
1339113384 true = isOpElemWise(inOper);
1339213385 (_, scalartypes) = List.splitOnTrue(types,isFuncWithArrayInput);
1339313386 (cache,SOME((daeExp,prop))) = elabCallArgs3(inCache,inEnv,scalartypes,inPath,inFuncArgs,{},inImpl,inSyTabOpt,inPre,inInfo);
13394- then (cache, daeExp, prop);
13395- */
13387+ then (cache, daeExp, prop);
13388+
1339613389 // If this is the last round then print the error.
13397- case (_, _, _, _, _, _, _, _, _, _, _, true)
13390+ case (_, _, _, _, _, _, _, _, _, _, _, _, true)
1339813391 equation
13399- str1 = "\n" +&
13392+ str1 = "\n" +&
1340013393 "- Failed to deoverload operator '" +& Dump.opSymbol(inOper) +& "' " +&
13401- " for record of type: ??? ";
13402- Error.addSourceMessage(Error.OPERATOR_OVERLOADING_ERROR,
13394+ " for record of type: '" +& Absyn.pathString(Absyn.pathPrefix(inPath)) +& "' ";
13395+ Error.addSourceMessage(Error.OPERATOR_OVERLOADING_ERROR,
1340313396 {str1}, inInfo);
1340413397 then fail();
1340513398
1340613399 end matchcontinue;
13407- assert(false, "");
1340813400end OverloadingValidForSpec_3_2;
1340913401
1341013402
@@ -13416,58 +13408,71 @@ resulting expression. "
1341613408 input Env.Cache inCache;
1341713409 input Env.Env inEnv;
1341813410 input Absyn.Operator inOper;
13419- input DAE .Exp inExp1;
13420- input DAE .Exp inExp2;
13411+ input Absyn .Exp inExp1;
13412+ input Absyn .Exp inExp2;
1342113413 input DAE.Type inType1;
1342213414 input DAE.Type inType2;
1342313415 input Boolean inImpl;
1342413416 input Option<GlobalScript.SymbolTable> inSyTabOpt;
1342513417 input Prefix.Prefix inPre;
1342613418 input Absyn.Info inInfo;
13419+ input Boolean lastRound;
1342713420 output Env.Cache outCache;
1342813421 output DAE.Exp outExp;
1342913422 output DAE.Properties outProp;
1343013423
1343113424algorithm
1343213425
1343313426 (outCache,outExp,outProp) :=
13434- matchcontinue (inCache, inEnv, inOper,inExp1,inExp2,inType1,inType2,inImpl,inSyTabOpt,inPre,inInfo)
13427+ matchcontinue (inCache, inEnv, inOper,inExp1,inExp2,inType1,inType2,inImpl,inSyTabOpt,inPre,inInfo,lastRound )
1343513428 local
1343613429 Boolean bool1,bool2;
13437- String opStr ;
13430+ String str1 ;
1343813431 Absyn.Path path,path2;
1343913432 list<Absyn.Path> operNames;
13440- Env.Env recordEnv,env;
13433+ Env.Env recordEnv,operatorEnv, env;
1344113434 SCode.Element operatorCl;
1344213435 Env.Cache cache;
13443- list<DAE.Type> types,types1,types2 ;
13436+ list<DAE.Type> types;
1344413437 DAE.Properties prop;
1344513438 DAE.Type type1, type2;
13446- DAE .Exp exp1,exp2;
13439+ Absyn .Exp exp1,exp2;
1344713440 Absyn.Operator op;
1344813441 Absyn.ComponentRef comRef;
1344913442 DAE.Exp daeExp;
1345013443
13451- case (cache, env, op, exp1, exp2, type1, type2, _, _, _, _)
13444+ case (cache, env, op, exp1, exp2, type1, type2, _, _, _, _,_ )
1345213445 equation
13453- opStr = "'" +& Dump.opSymbolCompact(op) +& "'";
13454- (cache,types1) = getOperatorFuncsOrEmpty(cache,env,type1,opStr,inInfo);
13455- (cache,types2) = getOperatorFuncsOrEmpty(cache,env,type2,opStr,inInfo);
13456- // Spec: [...] function f in the union of A.op and B.op [...]
13457- types = List.union(types1,types2);
13458- types = List.select1(types, isOperatorBinaryFunctionOrWarn, inInfo);
13446+
13447+ // prepare the call path for the operator.
13448+ // if * => recordPath.'*' , !!also if .* => recordPath.'*'
13449+ path = getRecordPath(type1);
13450+ path = Absyn.makeFullyQualified(path);
13451+ (cache,_,recordEnv) = Lookup.lookupClass(cache,env,path, false);
13452+
13453+ str1 = "'" +& Dump.opSymbolCompact(op) +& "'";
13454+ path = Absyn.joinPaths(path, Absyn.IDENT(str1));
13455+
13456+
13457+ // check if the operator is defined. i.e overloaded
13458+ (cache,operatorCl,operatorEnv) = Lookup.lookupClass(cache,recordEnv,path, false);
13459+ true = SCode.isOperator(operatorCl);
13460+
13461+
13462+ // get the list of functions in the operator. !! there can be multiple options
13463+ operNames = SCodeUtil.getListofQualOperatorFuncsfromOperator(operatorCl);
13464+ (cache,types) = Lookup.lookupFunctionsListInEnv(cache, operatorEnv, operNames, inInfo, {});
13465+
1345913466 // Apply operation according to the Specifications.See the function.
1346013467 bool1 = Types.arrayType(type1);
1346113468 bool2 = Types.arrayType(type2);
13462- print("TODO: Filter in types: " + Types.unparseType(DAE.T_TUPLE(types,{})) + "\n");
13463- (cache,daeExp,prop) = OverloadingValidForSpec_3_2(cache,env,op,bool1,bool2,types,{exp1,exp2},inImpl,inSyTabOpt,inPre,inInfo, false /*Never last round here. look down*/);
13469+ (cache,daeExp,prop) = OverloadingValidForSpec_3_2(cache,env,op,bool1,bool2,types,path,{exp1,exp2},inImpl,inSyTabOpt,inPre,inInfo, false /*Never last round here. look down*/);
1346413470
1346513471 then
1346613472 (cache,daeExp,prop);
1346713473
1346813474
1346913475 //Try constructing the right side(implicit) and then evaluate == L + r -> L.'+'(L,L(r))
13470- /*
1347113476 case (cache, env, op, exp1, exp2, type1, type2, _, _, _, _,_)
1347213477 equation
1347313478
@@ -13491,11 +13496,11 @@ algorithm
1349113496 comRef = Absyn.pathToCref(path2);
1349213497 exp2 = Absyn.CALL(comRef, Absyn.FUNCTIONARGS({exp2}, {}));
1349313498
13494- (cache, daeExp , prop) = userDefOperatorDeoverloadBinary(cache,env,op,exp1,exp2,type1,type2,inImpl,inSyTabOpt,inPre,inInfo, lastRound); // Now it can be last round
13499+ (cache, daeExp , prop) = userDefOperatorDeoverloadBinary(cache,env,op,exp1,exp2,type1,type2,inImpl,inSyTabOpt,inPre,inInfo, lastRound); /* Now it can be last round*/
1349513500
1349613501 then
1349713502 (cache,daeExp,prop);
13498- */
13503+
1349913504 end matchcontinue;
1350013505
1350113506end userDefOperatorDeoverloadBinary;
@@ -13665,9 +13670,21 @@ algorithm
1366513670 // if we have a record on the left side check for overloaded operators
1366613671 case(cache, env, aboper, DAE.PROP(type1, _), _, DAE.PROP(type2, _), _, _, absexp1, absexp2, _, _, _, _)
1366713672 equation
13668- true = typeIsRecord(Types.arrayElementType(type1)) or typeIsRecord(Types.arrayElementType(type2));
13673+ true = typeIsRecord(Types.arrayElementType(type1));
13674+
13675+ // If the right side is not record then (lastRound is true) which means we should print errors on this round (last one:).
13676+ lastRound = not typeIsRecord(Types.arrayElementType(type2));
1366913677
13670- (cache, exp , prop) = userDefOperatorDeoverloadBinary(cache,env,aboper,inExp1,inExp2,type1,type2,inImpl,inSymTab,inPre,inInfo);
13678+ (cache, exp , prop) = userDefOperatorDeoverloadBinary(cache,env,aboper,absexp1,absexp2,type1,type2,inImpl,inSymTab,inPre,inInfo,lastRound /**/);
13679+ (exp,_) = ExpressionSimplify.simplify(exp);
13680+ then
13681+ (cache, exp, prop);
13682+
13683+ // if we have a record on the right side check for overloaded operators
13684+ case(cache, env, aboper, DAE.PROP(type1, _), _, DAE.PROP(type2, _), _, _, absexp1, absexp2, _, _, _, _)
13685+ equation
13686+ true = typeIsRecord(Types.arrayElementType(type2));
13687+ (cache, exp , prop) = userDefOperatorDeoverloadBinary(cache,env,aboper,absexp2,absexp1,type2,type1,inImpl,inSymTab,inPre,inInfo, true); /*we have tried left side*/
1367113688 (exp,_) = ExpressionSimplify.simplify(exp);
1367213689 then
1367313690 (cache, exp, prop);
@@ -14953,80 +14970,4 @@ algorithm
1495314970 // print("replaceEnd end " +& Dump.printExpStr(Absyn.CREF(ocr)) +& "\n");
1495414971end replaceEnd2;
1495514972
14956- protected function getOperatorFuncsOrEmpty
14957- input Env.Cache inCache;
14958- input Env.Env env;
14959- input DAE.Type ty;
14960- input String opName;
14961- input Absyn.Info info;
14962- output Env.Cache cache;
14963- output list<DAE.Type> funcs;
14964- algorithm
14965- (cache,funcs) := matchcontinue (inCache,env,ty,opName,info)
14966- local
14967- Absyn.Path path,opNamePath;
14968- SCode.Element operatorCl;
14969- Env.Env recordEnv,operEnv;
14970- list<Absyn.Path> paths;
14971- case (_,_,_,_,_)
14972- equation
14973- // prepare the call path for the operator.
14974- // if * => recordPath.'*' , !!also if .* => recordPath.'*'
14975- path = getRecordPath(ty);
14976- path = Absyn.makeFullyQualified(path);
14977- (cache,_,recordEnv) = Lookup.lookupClass(inCache,env,path, false);
14978- opNamePath = Absyn.IDENT(opName);
14979- path = Absyn.joinPaths(path, opNamePath);
14980- // check if the operator is defined. i.e overloaded
14981- (cache,operatorCl,operEnv) = Lookup.lookupClass(cache,recordEnv,path,false);
14982- true = SCode.isOperator(operatorCl);
14983- // get the list of functions in the operator. !! there can be multiple options
14984- paths = SCodeUtil.getListofQualOperatorFuncsfromOperator(operatorCl);
14985- (cache,funcs) = Lookup.lookupFunctionsListInEnv(cache, operEnv, paths, info, {});
14986- funcs = List.select2(funcs,checkOperatorFunctionOutput,ty,info);
14987- then (cache,funcs);
14988- else (inCache,{});
14989- end matchcontinue;
14990- end getOperatorFuncsOrEmpty;
14991-
14992- protected function checkOperatorFunctionOutput
14993- input DAE.Type ty;
14994- input DAE.Type expected;
14995- input Absyn.Info info;
14996- output Boolean isOK;
14997- algorithm
14998- isOK := match (ty,expected,info)
14999- local
15000- DAE.Type actual;
15001- case (DAE.T_FUNCTION(funcResultType=actual),_,_)
15002- equation
15003- isOK = Types.equivtypes(actual,expected);
15004- Error.assertionOrAddSourceMessage(isOK, Error.COMPILER_WARNING, {"TODO: Better warning for: " + Types.unparseType(actual) + ", expected: " + Types.unparseType(actual)}, info);
15005- then isOK;
15006- else false;
15007- end match;
15008- end checkOperatorFunctionOutput;
15009-
15010- protected function isOperatorBinaryFunctionOrWarn
15011- input DAE.Type ty;
15012- input Absyn.Info info;
15013- output Boolean isBinaryFunc;
15014- algorithm
15015- print("isBinary? " + Types.unparseType(ty) + "\n");
15016- isBinaryFunc := match (ty,info)
15017- local
15018- list<DAE.FuncArg> rest;
15019- case (DAE.T_FUNCTION(funcArg={_}),_) then false; // Unary functions are legal even if we are not interested in them
15020- case (DAE.T_FUNCTION(funcArg=(_,_,_,_,NONE())::(_,_,_,_,NONE())::rest),_)
15021- equation
15022- isBinaryFunc = Util.boolAndList(List.mapMap(rest, Util.tuple55, Util.isSome));
15023- Error.assertionOrAddSourceMessage(isBinaryFunc, Error.COMPILER_WARNING, {"TODO: Better warning for: " + Types.unparseType(ty) + ", expected arguments 3..n to have default values"}, info);
15024- then isBinaryFunc; // Unary functions are legal even if we are not interested in them
15025- else
15026- equation
15027- Error.addSourceMessage(Error.COMPILER_WARNING, {"TODO: Better warning for: " + Types.unparseType(ty) + ", expected arguments 1&2 to not have default values"}, info);
15028- then false;
15029- end match;
15030- end isOperatorBinaryFunctionOrWarn;
15031-
1503214973end Static;
0 commit comments