diff --git a/OMCompiler/Compiler/.cmake/meta_modelica_source_list.cmake b/OMCompiler/Compiler/.cmake/meta_modelica_source_list.cmake index e2e6f726d74..dbb9d8f0ef1 100644 --- a/OMCompiler/Compiler/.cmake/meta_modelica_source_list.cmake +++ b/OMCompiler/Compiler/.cmake/meta_modelica_source_list.cmake @@ -399,7 +399,6 @@ set(OMC_MM_BACKEND_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCppHpcom.mo ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCppHpcomOld.mo ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCppInit.mo - ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCSharp.mo ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenFMU.mo ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenFMU1.mo ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenFMU2.mo diff --git a/OMCompiler/Compiler/.cmake/template_compilation.cmake b/OMCompiler/Compiler/.cmake/template_compilation.cmake index 38cfd44322c..ef67f2e1626 100644 --- a/OMCompiler/Compiler/.cmake/template_compilation.cmake +++ b/OMCompiler/Compiler/.cmake/template_compilation.cmake @@ -141,9 +141,6 @@ omc_add_template_target(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenFMU2. DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenC.tpl DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenUtil.tpl) -omc_add_template_target(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCSharp.tpl - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Template/SimCodeTV.mo) - omc_add_template_target(SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/Template/CodegenCppCommon.tpl DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/Template/SimCodeTV.mo) diff --git a/OMCompiler/Compiler/SimCode/SimCodeMain.mo b/OMCompiler/Compiler/SimCode/SimCodeMain.mo index d6819ae9208..69bd43e12d9 100644 --- a/OMCompiler/Compiler/SimCode/SimCodeMain.mo +++ b/OMCompiler/Compiler/SimCode/SimCodeMain.mo @@ -69,7 +69,6 @@ import CodegenOMSICpp; import CodegenFMUCppHpcomOld; import CodegenAdevs; import CodegenSparseFMI; -import CodegenCSharp; import CodegenCppOld; import CodegenCppHpcomOld; import CodegenOMSIC; @@ -509,10 +508,6 @@ algorithm list>> res; list strs, tmp, matches; - case "CSharp" equation - Tpl.tplNoret(CodegenCSharp.translateModel, simCode); - then (); - case "Cpp" algorithm callTargetTemplatesCPP(simCode); diff --git a/OMCompiler/Compiler/SimCode/SimCodeUtil.mo b/OMCompiler/Compiler/SimCode/SimCodeUtil.mo index 547484dbeac..2ebd9c237a7 100644 --- a/OMCompiler/Compiler/SimCode/SimCodeUtil.mo +++ b/OMCompiler/Compiler/SimCode/SimCodeUtil.mo @@ -14489,25 +14489,6 @@ algorithm end match; end codegenExpSanityCheck; -public function isModelTooBigForCSharpInOneFile -"Used by C# template to determine if the generated code should be split into several files - to make Visual Studio responsive when the file is opened (C# compiler is OK, - but VS does not scale well for big C# files)." - input SimCode.SimCode simCode; - output Boolean outIsTooBig; -algorithm - outIsTooBig := match(simCode) - local - Integer numAlgVars; - - case (SimCode.SIMCODE(modelInfo = SimCode.MODELINFO(varInfo = SimCode.VARINFO(numAlgVars = numAlgVars)))) - equation - outIsTooBig = numAlgVars > 1000; - then outIsTooBig; - - end match; -end isModelTooBigForCSharpInOneFile; - public function absoluteClockIdxForBaseClock input Integer baseClockIdx; // one-based input list allBaseClockPartitions; diff --git a/OMCompiler/Compiler/Template/CodegenCSharp.tpl b/OMCompiler/Compiler/Template/CodegenCSharp.tpl deleted file mode 100644 index 52c543fd589..00000000000 --- a/OMCompiler/Compiler/Template/CodegenCSharp.tpl +++ /dev/null @@ -1,3094 +0,0 @@ -// This file defines templates for transforming Modelica code to C# code. - -package CodegenCSharp - -import interface SimCodeTV; -import ExpressionDumpTpl; - -// SECTION: SIMULATION TARGET, ROOT TEMPLATE - -template translateModel(SimCode simCode) ::= - match simCode - case SIMCODE(modelInfo = MODELINFO(__)) then - let()= textFile(simulationFile(simCode), '<%dotPath(modelInfo.name)%>.cs') - //let()= textFile(simulationFunctionsFile(simCode), '<%modelInfo.name%>_functions.cs') - "" // empty result of the top-level template .., only side effects -end translateModel; - -template wrapIntoExtraFileIfModelTooBig(Text txtCode, String fileNamePostfix, SimCode simCode) ::= - match simCode - case SIMCODE(modelInfo = MODELINFO(__)) then - if isModelTooBigForCSharpInOneFile(simCode) then - let wrappedCode = - << - // Simulation code for <%dotPath(modelInfo.name)%> generated by the OpenModelica Compiler. - - using System; - using System.Collections.Generic; - using Bodylight.Solvers; - namespace Bodylight.Models<%modelNameSpace(modelInfo.name)%> - { - public partial class <%lastIdentOfPath(modelInfo.name)%> : DAESystem - { - <% txtCode %> - } - } - >> - let fileName = '<%dotPath(modelInfo.name)%>_<%fileNamePostfix%>.cs' - let()= textFile(wrappedCode, fileName) - << - - //----------------------------------- - //#include <%fileName%> - //----------------------------------- - - >> - else - txtCode -end wrapIntoExtraFileIfModelTooBig; - -// SECTION: SIMULATION TARGET, C# FILE SPECIFIC TEMPLATES - - -template simulationFile(SimCode simCode) ::= -match simCode -case SIMCODE(modelInfo = MODELINFO(__)) then -<< -// Simulation code for <%dotPath(modelInfo.name)%> generated by the OpenModelica Compiler. - -using System; -using System.Collections.Generic; -using Bodylight.Solvers; - -namespace Bodylight.Models<%modelNameSpace(modelInfo.name)%> -{ - - public partial class <%lastIdentOfPath(modelInfo.name)%> : DAESystem - { - <%modelDescription(modelInfo, simCode)%> - - <%wrapIntoExtraFileIfModelTooBig( - << - <%modelMetadata(modelInfo, simCode)%> - - <%sharedLiteralDefinitions(literals, simCode)%> - >> - , "MetaData", simCode) - %> - - <%let fbody = simulationFunctionsBody(simCode) - if fbody then - << - #region Functions - <%fbody%> - #endregion - >> - else "//** No functions **" - %> - - <%functionCallExternalObjectConstructors(extObjInfo, simCode)%> - - <%functionCallExternalObjectDestructors(extObjInfo, simCode)%> - - <% wrapIntoExtraFileIfModelTooBig( - << - <%functionNonlinearResiduals(initialEquations, contextAlgloopInitialisation, simCode)%> - - <%functionNonlinearResiduals(parameterEquations, contextAlgloop, simCode)%> - - <%functionNonlinearResiduals(allEquations, contextAlgloop, simCode)%> - - <%functionInitialNonLinearSystems(initialEquations, parameterEquations, allEquations, simCode)%> - >> - , "Residuals", simCode) - %> - - <%functionInput(modelInfo, simCode)%> - - <%functionOutput(modelInfo, simCode)%> - - <%functionInitSample(timeEvents, simCode)%> - - <%functionStoreDelayed(simCode)%> - - <%functionUpdateBoundStartValues(startValueEquations, simCode)%> - - <% wrapIntoExtraFileIfModelTooBig( - functionInitialEquations(initialEquations, simCode), - "InitialEquations", simCode) %> - - <%functionUpdateBoundParameters(parameterEquations, simCode)%> - - <% wrapIntoExtraFileIfModelTooBig( - functionODE(odeEquations, simCode), - "FunctionODE", simCode) %> - - <%functionAlgebraic(algebraicEquations, simCode)%> - - <% wrapIntoExtraFileIfModelTooBig( - functionDAE(allEquations, simCode), - "FunctionDAE", simCode) %> - - <%functionZeroCrossing(zeroCrossings, simCode)%> - - <%functionRelations(relations, simCode)%> - - <%functionCheckForDiscreteChanges(simCode)%> - - <%/*functionAssertsforCheck(algorithmAndEquationAsserts)*/%> - - } -} ->> -end simulationFile; - -template modelNameSpace(Path modelName) ::= - match modelName - case QUALIFIED(__) then '.<%name%><%modelNameSpace(path)%>' - case FULLYQUALIFIED(__) then modelNameSpace(path) -end modelNameSpace; - -template lastIdentOfPath(Path modelName) ::= - match modelName - case QUALIFIED(__) then lastIdentOfPath(path) - case IDENT(__) then name - case FULLYQUALIFIED(__) then lastIdentOfPath(path) -end lastIdentOfPath; - -template sharedLiteralDefinitions(list literals, SimCode simCode) -::= - << - <%literals |> literal hasindex i0 fromindex 0 => literalExpConst(literal, i0, simCode) ; separator="\n";empty%> - >> -end sharedLiteralDefinitions; - -template literalExpConst(Exp lit, Integer index, SimCode simCode) -::= - let name = '_OMC_LIT<%index%>' - - match lit - case SCONST(__) then - let escstr = Util.escapeModelicaStringToCString(string) - << - const string <%name%> = "<%Util.escapeModelicaStringToCString(string)%>"; - >> - case lit as MATRIX(ty=ty as T_ARRAY(__)) - case lit as ARRAY(ty=ty as T_ARRAY(__)) then - let arrType = expTypeArray(ty, listLength(getDimensionSizes(ty))) - let sty = expTypeShort(ty) - let dims = (getDimensionSizes(ty) |> dim => dim ;separator=", ") - let data = flattenArrayExpToList(lit) |> exp => literalExpConstArrayVal(exp) ; separator=", " - << - static <%arrType%> <%name%> = new <%arrType%>(<%dims%>,-1, new <%sty%>[] { <%data%> }); - >> - else error(sourceInfo(), 'literalExpConst failed: <%ExpressionDumpTpl.dumpExp(lit,"\"")%>') -end literalExpConst; - -//should be identical to call daeExp() -//but it is more specific, maybe can catch an illegal exp which is expected to be a constant -template literalExpConstArrayVal(Exp lit) -::= - match lit - case ICONST(__) then integer - case BCONST(__) then if bool then "true" else "false" - case RCONST(__) then real - case ENUM_LITERAL(__) then '<%index%>/*ENUM:<%dotPath(name)%>*/' - case SHARED_LITERAL(__) then '_OMC_LIT<%index%>' - else error(sourceInfo(), 'literalExpConstArrayVal failed: <%ExpressionDumpTpl.dumpExp(lit,"\"")%>') -end literalExpConstArrayVal; - -template simulationFunctionsBody(SimCode simCode) ::= -match simCode -case SIMCODE(modelInfo = modelInfo as MODELINFO(__)) then - (modelInfo.functions |> fn => match fn - case FUNCTION(__) then functionBodyRegularFunction(fn, simCode) - case EXTERNAL_FUNCTION(__) then functionBodyExternalFunction(fn, simCode) //'EXTERNAL_FUN_NOT_IMPLEMETED(name=<%dotPath(name)%>)' - case RECORD_CONSTRUCTOR(__) then 'RECORD_CONSTRUCTOR_NOT_IMPLEMENTED(name=<%dotPath(name)%>)' - else "UNKNOWN_FUNCTION" - ;separator="\n") -end simulationFunctionsBody; - -/* -//not used now -template simulationFunctionsFile(SimCode simCode) ::= -match simCode -case SIMCODE(modelInfo = MODELINFO(__)) then -<< -// Simulation functions code for <%modelInfo.name%> generated by the OpenModelica Compiler. - -using System; -using Bodylight.Solvers; -namespace Bodylight.Models -{ - public partial class <%dotPath(modelInfo.name)%> : DAESystem - { - - <%simulationFunctionsBody(simCode)%> - - } -} ->> -end simulationFunctionsFile; -*/ - -template recordDeclaration(RecordDeclaration recDecl, SimCode simCode) - "Generates structs for a record declaration." -::= - match recDecl - case RECORD_DECL_FULL(__) then - << - struct <%name%> { - <%variables |> var as VARIABLE(__) => '<%varType(var)%> <%crefStr(var.name,simCode)%>;' ;separator="\n"%> - }; - >> - case RECORD_DECL_DEF(__) then "RECORD_DECL_DEF_NOT_SUPPORTED" - else "UNKNOWN_RECORD_DECL_" -end recordDeclaration; - - - -template functionBodyRegularFunction(Function fn, SimCode simCode) - "Generates the body for a Modelica/MetaModelica function." -::= -match fn -case FUNCTION(__) then - let()= System.tmpTickReset(1) - let fname = underscorePath(name) - let retType = match outVars //a hack, only one output var for now - case fv :: _ then varType(fv) - else "void" - let retVar = match outVars - case (fv as VARIABLE(__)) :: _ then crefStr(fv.name,simCode) - let varInits = variableDeclarations |> var => varInit(var, simCode) - ;separator="\n" //TODO:special end of line,see varInit - let bodyPart = funStatement(body, simCode) - << - <%retType%> _<%fname%>(<%functionArguments |> var => funArgDefinition(var,simCode) ;separator=", "%>) - { - <%varInits%> - - <%bodyPart%> - - _return: - <%if outVars then 'return <%retVar%>;'%> - } - - >> -end functionBodyRegularFunction; - - -template functionBodyExternalFunction(Function fn, SimCode simCode) - "Generates the body for an external function (just a wrapper)." -::= -match fn -case efn as EXTERNAL_FUNCTION(__) then - let()= System.tmpTickReset(1) - let fname = underscorePath(name) - let retType = match outVars - case fv :: _ then varType(fv) - else "void" - let &preExp = buffer "" /*BUFD*/ - let callPart = //extFunCall(fn, &preExp /*BUFC*/, &varDecls /*BUFD*/) - let args = (extArgs |> arg => extArg(arg, &preExp, simCode) ;separator=", ") - let lib = hackGetFirstExternalFunctionLib(libs) // match libs case fnLib::_ then fnLib else "NO_EXT_LIB" - 'Bodylight.Solvers.ExternalLibraries.<%lib%>.<%extName%>(<%args%>);' - << - static <%retType%> _<%fname%>(<%funArgs |> var => funArgDefinition(var,simCode) ;separator=", "%>) - { - <%preExp%> - <%if outVars then "return " - %><%callPart%> - } - - >> -end functionBodyExternalFunction; - - -template extArg(SimExtArg extArg, Text &preExp, SimCode simCode) - "Helper to extFunCall." -::= - match extArg - case SIMEXTARG(cref=c, outputIndex=oi, isArray=true, type_=t) then - let name = if oi then 'NOT_SUPPORTED_out.targ<%oi%>' else crefStr(c,simCode) - name - //let shortTypeStr = expTypeShort(t) - //'(<%extType(t,isInput,true)%>) data_of_<%shortTypeStr%>_array(&(<%name%>))' - case SIMEXTARG(cref=c, isInput=ii, outputIndex=0, type_=t) then - let cr = crefStr(c,simCode) - cr - case SIMEXTARG(cref=c, isInput=ii, outputIndex=oi, type_=t) then - 'NOT_SUPPORTED_ext<%oi%>' - case SIMEXTARGEXP(__) then - daeExp(exp, contextFunction, &preExp, simCode) - case SIMEXTARGSIZE(cref=c) then - let name = if outputIndex then 'NOT_SUPPORTED_SIZE_out.targ<%outputIndex%>' else crefStr(c,simCode) - match exp - case ICONST(__) then - '<%name%>.size<%integer%>' - else - '<%name%>.size(<%daeExp(exp, contextFunction, &preExp, simCode)%>)' -end extArg; - - -template varInit(Variable var, SimCode simCode) - "Generates code to initialize variables." -::= -match var -case var as VARIABLE(__) then - if instDims then - let varName = crefStr(var.name,simCode) - let &preDimsExp = buffer "" - let instDimsInit = (var.instDims |> dim => dimension(dim, contextFunction, &preDimsExp, simCode) ;separator=", ") - << - <%preDimsExp%> - var <%varName%> = new <%expTypeArray(var.ty,listLength(instDims))%>(<%instDimsInit%>);<% - //special \n solution ... the new line is dependent on this line, but the varInit as a whole does not put \n - match var.value case SOME(CREF(componentRef = cr)) then - '<%\n%><%varName%>.CopyFrom(<%crefStr(cr,simCode)%>);' - %> - >> - else - << - <%varType(var)%> <%crefStr(var.name,simCode)%>; - >> -else "UNSUPPORTED_VARIABLE_varInit" - -end varInit; - -template funArgDefinition(Variable var, SimCode simCode) -::= - match var - case VARIABLE(__) then '<%varType(var)%> <%crefStr(name,simCode)%>' - case FUNCTION_PTR(__) then 'funArgDefinition_UNSUPPORTED_fnptr <%name%>' - else "UNSUPPORTED_VARIABLE_funArgDefinition" -end funArgDefinition; - -template funStatement(list statementLst, SimCode simCode) - "Generates function statements." -::= - statementLst |> stmt => algStatement(stmt, contextFunction, simCode) -end funStatement; - -constant String localRepresentationArrayDefines = -"var X = States; var Xd = StatesDerivatives; var Y = Algebraics; var YI = AlgebraicsInt; var YB = AlgebraicsBool; -var P = Parameters; var PI = ParametersInt; var PB = ParametersBool; var PS = ParametersString; var EO = ExternalObjects; -var preX = PreStates; var preXd = PreStatesDerivatives; var preY = PreAlgebraics; var preYI = PreAlgebraicsInt; var preYB = PreAlgebraicsBool; -var mathEVPre = MathEventsValuePre; -/*TODO: HACK FOR non-time varying params*/ var preP = P; var prePI = PI; var prePB = PB;"; - -template modelDescription(ModelInfo modelInfo, SimCode simCode) ::= -match modelInfo -case MODELINFO(varInfo = VARINFO(__), vars = SIMVARS(__)) then -<< -#region Model description - -const int - NG = <%varInfo.numZeroCrossings%>, - NREL = <%varInfo.numRelations%>, - NM = <%varInfo.numMathEventFunctions%>, - NG_SAM = <%varInfo.numTimeEvents%>, - NX = <%varInfo.numStateVars%>, - NY = <%varInfo.numAlgVars%> + <%varInfo.numDiscreteReal%>, - NA = <%varInfo.numAlgAliasVars%>, // number of alias variables - NP = <%varInfo.numParams%>, - NO = <%varInfo.numOutVars%>, - NI = <%varInfo.numInVars%>, - NEXT = <%varInfo.numExternalObjects%>, - //NFUNC = <%listLength(functions)%>, // number of functions used by the simulation - NYSTR = <%varInfo.numStringAlgVars%>, - NASTR = <%varInfo.numStringAliasVars%>, // number of alias string variables - NYI = <%varInfo.numIntAlgVars%>, - NAI = <%varInfo.numIntAliasVars%>, // number of alias int variables - NYB = <%varInfo.numBoolAlgVars%>, - NAB = <%varInfo.numBoolAliasVars%>, // number of alias bool variables - NPI = <%varInfo.numIntParams%>, - NPB = <%varInfo.numBoolParams%>, - NPSTR = <%varInfo.numStringParamVars%>, - NAAll = NA+NAI+NAB+NASTR, // number of all aliases - NLS = <%varInfo.numLinearSystems%>, - NNLS = <%varInfo.numNonLinearSystems%>, - NMIXS = <%varInfo.numMixedSystems%>; - - private class <%lastIdentOfPath(name)%>Metadata : DAESystemMetadata - { - public override int ZeroCrossingsCount { get { return NG; } } - public override int RelationsCount { get { return NREL; } } - public override int MathEventsCount { get { return NM; } } - public override int SampleTypesCount { get { return NG_SAM; } } - - public override int OutputsCount { get { return NO; } } - public override int InputsCount { get { return NI; } } - public override int ExternalObjectsCount { get { return NEXT; } } - - public override int LinearSystemsCount { get { return NLS; } } - public override int NonLinearSystemsCount { get { return NNLS; } } - public override int MixedSystemsCount { get { return NMIXS; } } - - public <%lastIdentOfPath(name)%>Metadata(VarData[][] varData, AliasVarData[] aliasVarData, Dictionary fullVarDictionary, - Dictionary startValues, Dictionary startValuesInt, Dictionary startValuesBool, - string[] startParameterString) - : base("<%dotPath(name)%>", varData, aliasVarData, fullVarDictionary, startValues, startValuesInt, startValuesBool, startParameterString) - {} - - public override DAESystem NewSystem() - { - return new <%lastIdentOfPath(name)%>(); - } - } - - public static readonly DAESystemMetadata SystemMetadata; - - public <%lastIdentOfPath(name)%>() : base(<%lastIdentOfPath(name)%>.SystemMetadata) - {} -#endregion ->> -end modelDescription; - -template modelMetadata(ModelInfo modelInfo, SimCode simCode) ::= -match modelInfo -case MODELINFO(varInfo = VARINFO(__), vars = SIMVARS(__)) then -<< -static <%lastIdentOfPath(name)%>() { - var varData = new VarData[(int)SimVarType.NonAliasTypesCnt][]; - VarData[] vd; - - <%{ - varInfos("State", vars.stateVars, varInfo.numStateVars, simCode), - varInfos("StateDer", vars.derivativeVars, varInfo.numStateVars, simCode), - varInfosAlgebraic("Algebraic", vars.algVars, vars.discreteAlgVars, varInfo.numAlgVars, varInfo.numDiscreteReal, simCode), - //may be later: - //varInfos("Algebraic", vars.algVars, varInfo.numAlgVars, simCode), - //varInfos("AlgebraicDiscrete", vars.discreteAlgVars, varInfo.numDiscreteReal, simCode), - varInfos("AlgebraicInt", vars.intAlgVars, varInfo.numIntAlgVars, simCode), - varInfos("AlgebraicBool", vars.boolAlgVars, varInfo.numBoolAlgVars, simCode), - varInfos("AlgebraicString", vars.stringAlgVars, varInfo.numStringAlgVars, simCode), - varInfos("Parameter", vars.paramVars, varInfo.numParams, simCode), - varInfos("ParameterInt", vars.intParamVars, varInfo.numIntParams, simCode), - varInfos("ParameterBool", vars.boolParamVars, varInfo.numBoolParams, simCode), - varInfos("ParameterString", vars.stringParamVars, varInfo.numStringParamVars, simCode) - } ;separator="\n\n"%> - - #region *** all aliases *** - var fvd = Bodylight.Solvers.SystemMetadata.SetupVariableNamesLookup(varData, NAAll); - var ad = new AliasVarData[NAAll]; - <%{ - aliasVarInfos("alias Algebraic", vars.aliasVars, /*varInfo.numAlgAliasVars,*/ "", simCode), - aliasVarInfos("alias AlgebraicInt", vars.intAliasVars, /*varInfo.numIntAliasVars,*/ "NA+", simCode), - aliasVarInfos("alias AlgebraicBool", vars.boolAliasVars, /*varInfo.numBoolAliasVars,*/ "NA+NAI+", simCode), - aliasVarInfos("alias AlgebraicString", vars.stringAliasVars, /*varInfo.numStringAliasVars,*/ "NA+NAI+NAB+", simCode) - } ;separator="\n\n"%> - #endregion - - #region *** start values *** - var svs = new Dictionary(); - var svsI = new Dictionary(); - var svsB = new Dictionary(); - var svsS = new string[NPSTR]; - - <%initVals("svs", "State", vars.stateVars, simCode)%> - <%initVals("svs", "StateDer", vars.derivativeVars, simCode)%> - <%initVals("svs", "Algebraic", vars.algVars, simCode)%> - <%initVals("svs", "Algebraic", vars.discreteAlgVars, simCode)%> - <%initVals("svs", "Parameter", vars.paramVars, simCode)%> - <%initVals("svsI", "AlgebraicInt", vars.intAlgVars, simCode)%> - <%initVals("svsI", "ParameterInt", vars.intParamVars, simCode)%> - <%initVals("svsB", "AlgebraicBool", vars.boolAlgVars, simCode)%> - <%initVals("svsB", "ParameterBool", vars.boolParamVars, simCode)%> - - // *** AlgebraicStrings not fully supported *** - <%/*initVals("AlgebraicString", vars.stringAlgVars, simCode)*/%> - <%initValsString("svsS", "ParameterString", vars.stringParamVars, simCode)%> - - #endregion - - SystemMetadata = new <%lastIdentOfPath(name)%>Metadata(varData, ad, fvd, svs, svsI, svsB, svsS); -} ->> -end modelMetadata; - - -template simVarTypeName(VarKind varKind, Type type_) ::= - match varKind - case VARIABLE(__) then "Algebraic" + simVarTypeNamePostfix(type_) - case STATE(__) then "State" - case STATE_DER(__) then "StateDer" - case DUMMY_DER(__) //then "Algebraic" - case DUMMY_STATE(__) then "Algebraic" - case DISCRETE(__) then 'Algebraic<%simVarTypeNamePostfix(type_)%>/*d*/' - case PARAM(__) then "Parameter" + simVarTypeNamePostfix(type_) - else error(sourceInfo(), "Unexpected simVarTypeName varKind") - //case EXTOBJ(__) then "EO" - //case CONST(__) then "CONST_VAR_KIND" -end simVarTypeName; - -template simVarTypeNamePostfix(Type type_) ::= - match type_ - case T_INTEGER(__) then "Int" - case T_REAL(__) then "" - case T_BOOL(__) then "Bool" - case T_STRING(__) then "String" - case T_ENUMERATION(__) then "/*Enum*/" - //case T_COMPLEX(__) then "Complex" - //case T_ARRAY(__) then "Array" - //case T_OTHER(__) then "Other" - else error(sourceInfo(), "Unknown simVarTypeNamePostfix") -end simVarTypeNamePostfix; - -template varInfos(String regionName, list varsLst, Integer varsCnt, SimCode simCode) ::= - //if varsLst then - //we need all of them to initialize also empty arrays - << - #region *** (<%varsCnt%>) <%regionName%> variable data *** - vd = new VarData[<%varsCnt%>]; - <% varsLst |> sv as SIMVAR(__) => - << - vd[<%index%>] = new VarData("<%crefStrWithDerOnLast(name, simCode)%>", "<%Util.escapeModelicaStringToCString(comment)%>"<%noaliasSimVarInfoRest(sv)%>); - >> - ;separator="\n" - %> - varData[(int)SimVarType.<%regionName%>] = vd; - #endregion<%\n%> - >> -end varInfos; - -template varInfosAlgebraic(String regionName, list varsLstAlg, list varsLstDisc, Integer varsCntAlg, Integer varsCntDisc, SimCode simCode) ::= -//A hack to temorarily handle discrete algebraics -//TODO: fix it - //if varsLst then - //we need all of them to initialize also empty arrays - << - #region *** (<%varsCntAlg%> + <%varsCntDisc%>) algebraic and discrete algebraic variable data *** - vd = new VarData[<%varsCntAlg%> + <%varsCntDisc%>]; - <% varsLstAlg |> sv as SIMVAR(__) => - << - vd[<%index%>] = new VarData("<%crefStrWithDerOnLast(name, simCode)%>", "<%Util.escapeModelicaStringToCString(comment)%>"<%noaliasSimVarInfoRest(sv)%>); - >> - ;separator="\n" - %> - <% varsLstDisc |> sv as SIMVAR(__) => - << - vd[<%varsCntAlg%> + <%index%>] = new VarData("<%crefStrWithDerOnLast(name, simCode)%>", "<%Util.escapeModelicaStringToCString(comment)%>"<%noaliasSimVarInfoRest(sv)%>); - >> - ;separator="\n" - %> - - varData[(int)SimVarType.<%regionName%>] = vd; - #endregion<%\n%> - >> -end varInfosAlgebraic; - - -//rather hacky ... when more attributes, use named members initalization -template noaliasSimVarInfoRest(SimVar simVar) ::= - match simVar - case sv as SIMVAR(__) then - if initialValue then - match nominalValue - case SOME(exp as RCONST(__)) then ', new SimVarAttributes(<%exp.real%>, true, <%sv.isFixed%>)' - case SOME(__) then error(sourceInfo(), "Unexpected expression for nominal value.") - else ', SimVarAttributes.DefaultUseStart<%if sv.isFixed then "Fixed"%>' - else - match nominalValue - case SOME(exp as RCONST(__)) then ', new SimVarAttributes(<%exp.real%>, false, <%sv.isFixed%>)' - case SOME(__) then "Error-other-nominal-value-than-real-constant-not-supported" - else if sv.isFixed then ", SimVarAttributes.DefaultFixed" - //else nothing ... -end noaliasSimVarInfoRest; - -template aliasVarInfos(String regionName, list varsLst, /*Integer varsCnt,*/ String offset, SimCode simCode) ::= - if varsLst then - << - #region *** (<%listLength(varsLst)%>) <%regionName%> variable infos *** - <% varsLst |> sv as SIMVAR(__) hasindex i0 => - let strNameCmt = '"<%crefStrWithDerOnLast(name, simCode)%>", "<%Util.escapeModelicaStringToCString(comment)%>"' - let aliasLookup = - match aliasvar - case NOALIAS(__) then - error(sourceInfo(), "Unexpected non-alias variable amongst aliases.") - case ALIAS(__) then - 'fvd["<%crefStrWithDerOnLast(varName, simCode)%>"]' - case NEGATEDALIAS(__) then - '-fvd["<%crefStrWithDerOnLast(varName, simCode)%>"]' - << - ad[<%offset%><%i0%>] = new AliasVarData("<%crefStrWithDerOnLast(name, simCode)%>", "<%Util.escapeModelicaStringToCString(comment)%>", <%aliasLookup%>); - >> - ;separator="\n" - %> - #endregion<%\n%> - >> -end aliasVarInfos; - - - - -//template nominalVal(DAE.Exp nomExp) ::= -// match nomExp -// case RCONST(__) then real -// else 'other nominal value than real const not supported' -//end nominalVal; - -template initVals(String arrName, String typName, list varsLst, SimCode simCode) ::= -if varsLst then -<< - -#region **** <%typName%> start values ***** -<% - varsLst |> sv as SIMVAR(__) => - match initialValue - case SOME(v) then - match v - case ICONST(__) - case RCONST(__) - case SCONST(__) - case BCONST(__) - case ENUM_LITERAL(__) then - let &preExp = buffer "" //dummy ... the value should be always a constant - match daeExp(v, contextOther, &preExp, simCode) - case vStr as "0" - case vStr as "0.0" - case vStr as "false" - case vStr as "(0)" then - '//<%arrName%>[<%sv.index%>] = <%vStr%>; //<%crefStr(sv.name, simCode)%> --> zero val' - //case "true" then //a hack for now - // '<%arrName%>[<%sv.index%>] = 1.0; //true //<%crefStr(sv.name, simCode)%>' - case vStr then - '<%arrName%>[(int)SimVarType.<%typName%>+(<%sv.index%><<4)] = <%vStr%>; //<%crefStr(sv.name, simCode)%>' - end match - else '//<%arrName%>[<%sv.index%>] = 0.0; //<%crefStr(sv.name, simCode)%> --> default val' - ;separator="\n" -%> -#endregion ->> -end initVals; - -template initValsString(String arrName, String typName, list varsLst, SimCode simCode) ::= -if varsLst then -<< - -#region **** (<%listLength(varsLst)%>) <%typName%> start values ***** -<% - varsLst |> sv as SIMVAR(__) => - match initialValue - case SOME(v) then - let &preExp = buffer "" //dummy ... the value should be always a constant - let val = daeExp(v, contextOther, &preExp, simCode) - '<%arrName%>[<%sv.index%>] = <%val%>; //<%crefStr(sv.name, simCode)%>' - else '<%arrName%>[<%sv.index%>] = ""; //<%crefStr(sv.name, simCode)%> --> default val' - ;separator="\n" -%> -#endregion ->> -end initValsString; - -/* -template initFixed(list simVarLst, String varType, Boolean defaultIsTrue, SimCode simCode) ::= - simVarLst |> SIMVAR(__) => - << - <%if defaultIsTrue then (if isFixed then "//") - else (if not isFixed then "//") - %><%varType%>InitialFixed[<%index%>] = <%isFixed%>; /* <%crefStr(name, simCode)%> */ - >> - ;separator="\n" -end initFixed; -*/ - -template functionCallExternalObjectConstructors(ExtObjInfo extObjInfo, SimCode simCode) - "Generates external objects construction calls." -::= -match extObjInfo -case EXTOBJINFO(__) then - << - public override void FunCallExternalObjectConstructors() { - <% localRepresentationArrayDefines %> - <% vars |> var as SIMVAR(initialValue=SOME(exp)) => - let &preExp = buffer "" /*BUFD*/ - let arg = daeExp(exp, contextOther, &preExp, simCode) - << - <%preExp%> - <%cref(var.name, simCode)%> = <%arg%>; - >> - %> - <%aliases |> (var1, var2) => '<%cref(var1,simCode)%> = <%cref(var2,simCode)%>;' ;separator="\n"%> - } - - >> -end functionCallExternalObjectConstructors; - -template functionCallExternalObjectDestructors(ExtObjInfo extObjInfo, SimCode simCode) - "Generates external objects construction calls." -::= -match extObjInfo -case EXTOBJINFO(__) then - << - public override void FunCallExternalObjectDestructors() { - <% localRepresentationArrayDefines %> - <% vars |> var as SIMVAR(varKind=ext as EXTOBJ(__)) => - << - _<%underscorePath(ext.fullClassName)%>_destructor(<%cref(var.name, simCode)%>); - >> - ;separator="\n" - %> - } - - >> -end functionCallExternalObjectDestructors; - -template functionAlgebraic(list> algebraicEquations, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void FunAlgebraics() -{ - <% localRepresentationArrayDefines %> - var preRels = PreRelations; - <% List.flatten(algebraicEquations) |> it => equation_(it,contextSimulationNonDiscrete, simCode) ;separator="\n"%> -} ->> -end functionAlgebraic; - - -template functionInput(ModelInfo modelInfo, SimCode simCode) ::= -match modelInfo -case MODELINFO(varInfo = VARINFO(__), vars = SIMVARS(__)) then -<< -public override void InputFun() -{ - <% localRepresentationArrayDefines %> - <%vars.inputVars |> SIMVAR(__) hasindex i0 => - << - <%cref(name, simCode)%> = inputVars[<%i0%>]; - >> ;separator="\n"%> -} ->> -end functionInput; - -template functionOutput(ModelInfo modelInfo, SimCode simCode) ::= -match modelInfo -case MODELINFO(varInfo = VARINFO(__), vars = SIMVARS(__)) then -<< -public override void OutputFun() -{ - <% localRepresentationArrayDefines %> - // * not yet - <%vars.outputVars |> SIMVAR(__) hasindex i0 => - << - //outputVars[<%i0%>] = <%cref(name, simCode)%>; - >> ;separator="\n"%> -} ->> -end functionOutput; - - -template functionInitSample(list timeEvents, SimCode simCode) - "Generates function initSample() in simulation file." -::= - /* Initializes the raw time events of the simulation using the now - calcualted parameters. */ - << - public override void FunSampleInit() - { - <% localRepresentationArrayDefines %> - var SA = SampleHeap.Samples; - - <%(timeEvents |> timeEvent => - match timeEvent - case SAMPLE_TIME_EVENT(__) then - let &preExp = buffer "" /*BUFD*/ - let startE = daeExp(startExp, contextOther, &preExp, simCode) - let intervalE = daeExp(intervalExp, contextOther, &preExp, simCode) - << - <%preExp%> - /* $P$sample<%index%> */ - SA[i++] = new OneSample(<%intervalE%>, <%startE%>, <%intSub(index, 1)%>, false); - >> - else '' - )%> - } - >> -end functionInitSample; - - -template functionDAE(list allEquationsPlusWhen, SimCode simCode) -::= -let()= System.tmpTickReset(1) -<< -public override bool FunDAE() -{ - <% localRepresentationArrayDefines %> - var rels = Relations; var preRels = PreRelations; var relsHE = RelationsHysteresisEnabled; var relsZC = RelationsZeroCrossing; - var needToIterate = false; - - <%allEquationsPlusWhen |> eq => equation_(eq, contextSimulationDiscrete, simCode) ;separator="\n"%> - - return needToIterate; -} ->> -end functionDAE; - -template whenConditions(list conditions, SimCode simCode) -" Generates reinit statemeant" -::= - //if conditions then - (conditions |> cr => '<%cref(cr, simCode)%> && !<%preCref(cr, simCode)%> /* edge */';separator=" || ") - //else "false" -end whenConditions; - -template infoArgs(builtin.SourceInfo info) -::= - match info - case SOURCEINFO(__) then '"<%fileName%>",<%lineNumberStart%>,<%columnNumberStart%>,<%lineNumberEnd%>,<%columnNumberEnd%>,<%if isReadOnly then 1 else 0%>' -end infoArgs; - -template assertCommon(Exp condition, Exp message, builtin.SourceInfo info, Context context, SimCode simCode) - "Generates an assert statement." -::= - let &preExpCond = buffer "" - let &preExpMsg = buffer "" - let condVar = daeExp(condition, context, &preExpCond, simCode) - let msgVar = daeExp(message, context, &preExpMsg, simCode) - << - <%preExpCond%> - if (!<%condVar%>) { - <%preExpMsg%> - //<%infoArgs(info)%> - throw new Exception(<%msgVar%>); - } - >> -end assertCommon; - - - -template functionZeroCrossing(list zeroCrossingLst, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void FunZeroCrossings(double time, double[] gout) //TODO:??time in original is *t only ... how is it called? -{ - <% localRepresentationArrayDefines %> - var rels = Relations; var relsHE = RelationsHysteresisEnabled; var relsZC = RelationsZeroCrossing; - <%zeroCrossingLst |> ZERO_CROSSING(__) hasindex i0 => - let &preExp = buffer "" - let zc = zeroCrossing(relation_, &preExp, simCode) - << - //ZC for: <%ExpressionDumpTpl.dumpExp(relation_,"\"")%> - <%preExp%> - gout[<%i0%>] = <%zc%>; - >> - ;separator="\n"%> -} ->> -end functionZeroCrossing; - -template zeroCrossing(Exp zcExp, Text &preExp, SimCode simCode) ::= - match zcExp - case RELATION(index=-1) then - //probably a discrete only relation (e.g., with parameter against a constant) - //should be used only in a logical expression (not a proper zero crossing) - //going like logical unary only - //no need for hysteresis there as it should be constant during continuous intervals - let e1 = daeExp(zcExp, contextZeroCross, &preExp, simCode) - '(<%e1%>)?1:-1' - case RELATION(__) then - let e1 = daeExp(exp1, contextZeroCross, &preExp, simCode) - let e2 = daeExp(exp2, contextZeroCross, &preExp, simCode) - zeroCrossingValue(zcExp, e1, e2) - case (LBINARY(exp1=CALL(path=IDENT(name="initial"), expLst={}), operator=OR(__) )) - case (LBINARY(exp1=LUNARY( operator=NOT(__),exp=CALL(path=IDENT(name="initial"), expLst={}) ), operator=AND(__) )) - then - '/*opt out initial()*/<%zeroCrossing(exp2, &preExp, simCode)%>' - case (LBINARY(__)) - case (LUNARY(__)) - then - let e1 = daeExp(zcExp, contextZeroCross, &preExp, simCode) - '(<%e1%>) ? 1:-1' - - case CALL(path=IDENT(name="integer"), expLst={exp1, idx}) - case CALL(path=IDENT(name="floor"), expLst={exp1, idx}) - then - let e1 = daeExp(exp1, contextZeroCross, &preExp, simCode) - let indx = daeExp(idx, contextZeroCross, &preExp, simCode) - '(Math.Floor(<%e1%>) != mathEVPre[<%indx%>]) ? 1:-1' - case CALL(path=IDENT(name="ceil"), expLst={exp1, idx}) then - let e1 = daeExp(exp1, contextZeroCross, &preExp, simCode) - let indx = daeExp(idx, contextZeroCross, &preExp, simCode) - '(Math.Ceil(<%e1%>) != mathEVPre[<%indx%>]) ? 1:-1' - case CALL(path=IDENT(name="div"), expLst={exp1, exp2, idx}) then - let e1 = daeExp(exp1, contextZeroCross, &preExp, simCode) - let e2 = daeExp(exp2, contextZeroCross, &preExp, simCode) - let indx = daeExp(idx, contextZeroCross, &preExp, simCode) - '( (int)(<%e1%>/<%e2%>) != (int)mathEVPre[<%indx%>] ) ? 1:-1' - -/** these were attemt to use Min/Max as "logical" zero crossing operators, - ** but failed to work due to non-equivalence of g > 0 and -g <= 0 - ** when used in Min and Max ... it would work with both-sided epsilon on hysteresis (as C runtime uses), - ** but not with epsilon only on the > side (to allow equality to be found precisely) - ** so, sadly, this won't work ... - ** instead, we should find every relation change and then decide if it is an event (a condition changed) - case (LBINARY(operator=AND(__))) then - <), - (<%zeroCrossing(exp2, &preExp, simCode)%>) - )>> - case (LBINARY(operator=OR(__))) then - <), - (<%zeroCrossing(exp2, &preExp, simCode)%>) - )>> - case (LUNARY(__)) then - let e1 = daeExp(zcExp, contextOther, &preExp, simCode) - //the very high number is to assure a good chance for root finding to take advantage of interpolation - //in cases this is combined via Min or Max with something else - '(<%e1%>)?1e12:-1e12' -**/ - - else - error(sourceInfo(), 'Unexpected zero crossing expression: <%ExpressionDumpTpl.dumpExp(zcExp,"\"")%>') - -end zeroCrossing; - -template zeroCrossingOpFunc(Operator it) ::= - match it - case LESS(__) then "Less" - case GREATER(__) then "Greater" - case LESSEQ(__) then "LessEq" - case GREATEREQ(__) then "GreaterEq" - case EQUAL(__) then "!!!Equal" - case NEQUAL(__) then "!!!NEqual" - else "!!!unsupported ZC operator!!!" - -end zeroCrossingOpFunc; - -template functionRelations(list relations, SimCode simCode) "template functionRelations - Generates function in simulation file. - This is a helper of template simulationFile." -::= - let &varDecls = buffer "" /*BUFD*/ - //using only contextOther, here, only relation operands are genereted - let relationsCode = relationsTpl(relations, contextOther, simCode) - //let relationsCodeElse = relationsTpl(relations, contextOther, simCode) - - << - public override void FunUpdateRelations() - { - <% localRepresentationArrayDefines %> - var rels = Relations; var relsHE = RelationsHysteresisEnabled; var relsZC = RelationsZeroCrossing; - - <%relationsCode%> - } - >> -end functionRelations; - -template relationsTpl(list relations, Context context, SimCode simCode) - "Generates code for zero crossings." -::= - (relations |> ZERO_CROSSING(__) hasindex i0 => - relationTpl(i0, relation_, context, simCode) - ;separator="\n";empty) -end relationsTpl; - - -template relationTpl(Integer index1, Exp relationExp, Context context, SimCode simCode) - "Generates code for a zero crossing." -::= - match relationExp - case RELATION(__) then - let &preExp = buffer "" - let e1 = daeExp(exp1, context, &preExp, simCode) - let e2 = daeExp(exp2, context, &preExp, simCode) - << - //relation[<%index%>]: <%ExpressionDumpTpl.dumpExp(relationExp,"\"")%> - <%preExp%> - <%relationWithZeroCrossing(relationExp, e1, e2)%> - >> - else - << - // UNKNOWN Relation[<%index1%>]: <%ExpressionDumpTpl.dumpExp(relationExp,"\"")%> - >> -end relationTpl; - -// New runtime function. What should it do? -template functionStoreDelayed(SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void FunStoreDelayed() -{ - <% localRepresentationArrayDefines %> -} ->> -end functionStoreDelayed; - -template functionODE(list> stateContEquations, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void FunODE() -{ - <% localRepresentationArrayDefines %> - var preRels = PreRelations; - <%stateContEquations |> eqs => - (eqs |> it => equation_(it, contextSimulationNonDiscrete, simCode) ;separator="\n") - ;separator="\n"%> -} ->> -end functionODE; - -//TODO:??there is st more in the trunk -template functionUpdateBoundStartValues(list startValueEquations, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void UpdateBoundStartValues() -{ - <% localRepresentationArrayDefines %> - <%startValueEquations |> saeq as SES_SIMPLE_ASSIGN(__) => equation_(saeq, contextOther, simCode) ;separator="\n"%> - - //if (sim_verbose) { - <%startValueEquations |> SES_SIMPLE_ASSIGN(__) => - << - //Debug.WriteLine("Setting variable start value: {0}(start={1})", "<%cref(cref, simCode)%>", <%cref(cref, simCode)%>); - >> ;separator="\n"%> - //} -} ->> -end functionUpdateBoundStartValues; - -template functionNonlinearResiduals(list allEquations, Context context, SimCode simCode) ::= - let()= System.tmpTickReset(1) - (allEquations |> eq => match eq - case SES_MIXED(__) then functionNonlinearResidual(cont, context, simCode) - case SES_NONLINEAR(__) then functionNonlinearResidual(eq, context, simCode) - ;separator="\n") -end functionNonlinearResiduals; - -template functionNonlinearResidual(SimEqSystem equ, Context context, SimCode simCode) ::= - match equ - case SES_NONLINEAR(nlSystem=nls as NONLINEARSYSTEM(__)) then - << - int ResidualFun<%nls.index%>(int n, double[] xloc, double[] res, int iflag) - { - <% localRepresentationArrayDefines %> - var rels = Relations; var preRels = PreRelations; var relsHE = RelationsHysteresisEnabled; var relsZC = RelationsZeroCrossing; - <%nls.crefs |> cr hasindex i0 => '<%cref(cr,simCode)%> = xloc[<%i0%>];' ;separator="\n"%> - <%nls.eqs |> saeq => //as SES_SIMPLE_ASSIGN(__) => - (match saeq - case SES_RESIDUAL(__) then "" - else - equation_(saeq, context, simCode) - ) ;separator="\n" - %> - <%nls.eqs |> SES_RESIDUAL(__) hasindex i0 => - let &preExp = buffer "" - let expPart = daeExp(exp, context, &preExp, simCode) - << - <%preExp%> - res[<%i0%>] = <%expPart%>; - >> ;separator="\n" - %> - return 0; - } - >> -end functionNonlinearResidual; - -template functionInitialNonLinearSystems(list initialEquations, - list parameterEquations, list allEquations, SimCode simCode) -::= - << - public override void FunInitialNonLinearSystem() - { - var nlss = NonLinearSystems; - NLSystem nls; - <%bodyNonLinearSystems(initialEquations, simCode)%> - <%bodyNonLinearSystems(parameterEquations, simCode)%> - <%bodyNonLinearSystems(allEquations, simCode)%> - } - >> -end functionInitialNonLinearSystems; - -template bodyNonLinearSystems(list equations, SimCode simCode) -::= - equations |> eqn => bodyInitialNonLinearSystem(eqn, simCode) - ;separator="\n" -end bodyNonLinearSystems; - -template bodyInitialNonLinearSystem(SimEqSystem eqn, SimCode simCode) -::= - match eqn - case SES_MIXED(__) then bodyInitialNonLinearSystem(cont, simCode) - case SES_NONLINEAR(nlSystem=nls as NONLINEARSYSTEM(__)) then - let size = listLength(nls.crefs) - //let newtonStep = if linearTearing then '1' else '0' - //let generatedJac = match jacobianMatrix case SOME(__) then 'functionJacNLSJac<%eq.index%>_column' case NONE() then 'NULL' - //let initialJac = match jacobianMatrix case SOME(__) then 'initialAnalyticJacobianNLSJac<%eq.index%>' case NONE() then 'NULL' - // et jacIndex = match jacobianMatrix case SOME(__) then 'INDEX_JAC_NLSJac<%eq.index%>' case NONE() then '-1' - let attribs = - nls.crefs |> cr hasindex i0 => - (cref2simvar(cr, simCode) |> SIMVAR(__) => - let nominalAssign = - match nominalValue - case SOME(exp as RCONST(__)) then 'nls.Nominals[<%i0%>] = <%exp.real%>; // ' - case SOME(__) then error(sourceInfo(), "Unexpected expression for nominal value.") - else '//[<%i0%>] default nominal = 1.0 for ' - '<%nominalAssign%><%crefStr(cr, simCode)%>' - ); separator="\n" - << - nls = nlss[<%nls.indexNonLinearSystem%>] = new NLSystem(this, ResidualFun<%nls.index%>, <%size%>, <%nls.index%>); - <%attribs%> - >> -end bodyInitialNonLinearSystem; - - -template functionInitialEquations(list initalEquations, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override bool UseSymbolicInitialization { get { return true; } } -public override void FunInitialEquations() -{ - <% localRepresentationArrayDefines %> - var rels = Relations; var relsHE = RelationsHysteresisEnabled; var relsZC = RelationsZeroCrossing; - <%initalEquations |> eq => equation_(eq, contextSimulationDiscrete, simCode) ;separator="\n"%> -} ->> -end functionInitialEquations; - -template functionUpdateBoundParameters(list parameterEquations, SimCode simCode) ::= -let()= System.tmpTickReset(1) -<< -public override void UpdateBoundParameters() -{ - <% localRepresentationArrayDefines %> - <% parameterEquations - |> saeq as SES_SIMPLE_ASSIGN(__) => equation_(saeq, contextOther, simCode) ;separator="\n"%> - <% parameterEquations - |> eq as SES_ALGORITHM(__) => equation_(eq, contextOther, simCode) ;separator="\n"%> -} ->> -end functionUpdateBoundParameters; - -// TODO: Is the -1 thing really correct? It seems to work. -template functionCheckForDiscreteChanges(SimCode simCode) ::= -match simCode case SIMCODE(__) then -<< -public override bool CheckForDiscreteChanges() -{ - <% localRepresentationArrayDefines %> - //var needToIterate = false; -<%/* old stuff - //edge(H[i]) - <% helpVarInfo |> (id1, exp, id2) => match id2 case -1 then "" - else - 'if (<%edgeHelpVar(id1)%>) EventQueue.Add(<%id2%> + NG);' - ;separator="\n" %> -*/%> - //if change() - <%discreteModelVars |> var => - match var - case CREF_QUAL(__) - case CREF_IDENT(__) then - << - if (<%preCref(var, simCode)%> != <%cref(var, simCode)%>) return true; - >> ;separator="\n" - %> -<%/* old stuff - for (int i = 0; i < H.Length; i++) { - //change(H[i]) ?? TODO: not sure if it can be only 1.0 or 0.0 - if (H[i] != preH[i]) - return true; //needToIterate=true; - } -*/%> - return false; //needToIterate; -} ->> -end functionCheckForDiscreteChanges; - -template edgeHelpVar(String idx) ::= - '(/*edge(h[<%idx%>])*/H[<%idx%>]!=0.0 && preH[<%idx%>]==0.0)' -end edgeHelpVar; - -//TODO: eliminate this entirely ?? -template daeExpToReal(Exp exp, Context context, Text &preExp, SimCode simCode) ::= - daeExp(exp, context, &preExp, simCode) - + (match expTypeFromExp(exp) case "bool" then " ?1.0:0.0") //TODO: a HACK ? - -end daeExpToReal; - -// Residual equations are not handled here -template equation_(SimEqSystem eq, Context context, SimCode simCode) ::= -match eq -case SES_SIMPLE_ASSIGN(__) then - let &preExp = buffer "" - let expPart = daeExp(exp, context, &preExp, simCode) //was daeExpToReal - << - <%preExp%> - <%cref(cref, simCode)%> = <%expPart%>; - >> -case SES_ARRAY_CALL_ASSIGN(__) then "SES_ARRAY_CALL_ASSIGN" -case SES_ALGORITHM(__) then - (statements |> stmt => - algStatement(stmt, context, simCode) - ;separator="\n") - -case SES_LINEAR(lSystem=ls as LINEARSYSTEM(__)) then - let uid = System.tmpTick() - let size = listLength(ls.vars) - let aname = 'A<%uid%>' - let bname = 'b<%uid%>' - << - var <%aname%> = new double[<%size%>*<%size%>]; //declare_matrix(<%aname%>, <%size%>, <%size%>); - var <%bname%> = new double[<%size%>]; //declare_vector(<%bname%>, <%size%>); - <%ls.simJac |> (row, col, eq as SES_RESIDUAL(__)) => - let &preExp = buffer "" - let expPart = daeExpToReal(eq.exp, context, &preExp, simCode) - '<%preExp%><%aname%>[<%row%>+<%col%>*<%size%>] = <%expPart%>; //set_matrix_elt(<%aname%>, <%row%>, <%col%>, <%size%>, <%expPart%>);' - ;separator="\n"%> - <%ls.beqs|> it hasindex i0 => - let &preExp = buffer "" - let expPart = daeExpToReal(it, context, &preExp, simCode) - '<%preExp%><%bname%>[<%i0%>] = <%expPart%>; //set_vector_elt(<%bname%>, <%i0%>, <%expPart%>);' - ;separator="\n"%> - <%if ls.partOfMixed then - 'if(SolveLinearSystemMixed(<%aname%>, <%bname%>, <%size%>, <%uid%>) != 0) found_solution = -1;' - else - 'SolveLinearSystem(<%aname%>, <%bname%>, <%size%>, <%uid%>);' - %> - <%ls.vars |> SIMVAR(__) hasindex i0 => '<%cref(name, simCode)%> = <%bname%>[<%i0%>]; //get_vector_elt(<%bname%>, <%i0%>);' ;separator="\n"%> - >> -case SES_MIXED(__) then - let uid = System.tmpTick() - let contEqs = equation_(cont, context, simCode) - let numDiscVarsStr = listLength(discVars) -// let valuesLenStr = listLength(values) - let &preDisc = buffer "" /*BUFD*/ - let discLoc2 = - discEqs |> discEq as SES_SIMPLE_ASSIGN(__) hasindex i0 => - << - <%cref(discEq.cref, simCode)%> = <%daeExp(discEq.exp, context, &preDisc, simCode)%>; - double discrete_loc2_<%i0%> = <%crefToReal(discEq.cref, simCode)%>; - >> - //double discrete_loc2_<%i0%> = <%daeExpToReal(discEq.exp, context, &preDisc, simCode)%>; - //<%cref(discEq.cref, simCode)%> = discrete_loc2_<%i0%>; - - ;separator="\n" - /* - match discEqs - case { discEq as SES_SIMPLE_ASSIGN(__) } then - << - <%cref(discEq.cref, simCode)%> = <%daeExpToReal(discEq.exp, context, &preDisc, simCode)%>; - double discrete_loc2_0 = <%crefToReal(discEq.cref, simCode)%>; - >> - case discEqs then - << - var discrete_loc2 = new double[<%numDiscVarsStr%>]; - <%discEqs |> discEq as SES_SIMPLE_ASSIGN(__) hasindex i0 => - << - <%cref(discEq.cref, simCode)%> = <%daeExpToReal(exp, context, &preDisc, simCode)%>; - discrete_loc2[<%i0%>] = <%crefToReal(discEq.cref, simCode)%>; - >> - ;separator="\n"%> - >> - */ - << - // *** mixed_equation_system(<%numDiscVarsStr%>) *** - { int found_solution = 0; - <%/* - int cur_value_indx = -1; - var values = new double[]{<%values ;separator=", "%>}; - */%> - var boolVar = new bool[<%numDiscVarsStr%>]; - do { - <% - discVars |> SIMVAR(__) hasindex i0 => - 'double discrete_loc_<%i0%> = <%crefToReal(name, simCode)%>;' - ;separator="\n" - - /*match discVars - case { var as SIMVAR(__) } then - << - double discrete_loc_0 = <%crefToReal(var.name, simCode)%>; - >> - case discVars then - << - var discrete_loc = new double[<%numDiscVarsStr%>] { - <%discVars |> SIMVAR(__) => cref(name, simCode) ;separator=",\n"%> - }; - >> */ - %> - { - <%contEqs%> - } - <%preDisc%> - <%discLoc2%> - { - // check_discrete_values(...); - if (found_solution == -1) { /*system of equations failed*/ - found_solution = 0; - } else { - found_solution = 1; - <% - discVars |> SIMVAR(__) hasindex i0 => - << - if ( Math.Abs(discrete_loc_<%i0%> - discrete_loc2_<%i0%>) > 1e-12) found_solution = 0; - >> ;separator="\nelse " - /*match discVars - case { SIMVAR(__) } then - << - if ( Math.Abs(discrete_loc_0 - discrete_loc2_0) > 1e-12) { - found_solution = 0; - } - >> - case discVars then - << - for (int i=0; i < <%numDiscVarsStr%>; i++) { - if ( Math.Abs(discrete_loc[i] - discrete_loc2[i]) > 1e-12) { - found_solution = 0; - } - } - >>*/ - %> - } - if (found_solution == 0) { //!found_solution - if (NextMixedBoolCombination(boolVar)){ - <% discVars |> SIMVAR(__) hasindex i0 => - '<%cref(name, simCode)%> = <%preCref(name, simCode)%> != boolVar[<%i0%>];' - ;separator="\n" - %> - } - else - throw new Exception("Mixed system could not be solved."); - } - } - } while (found_solution == 0); - } // *** mixed_equation_system_end(<%numDiscVarsStr%>) *** - >> - -case SES_NONLINEAR(nlSystem=nls as NONLINEARSYSTEM(__)) then - let size = listLength(nls.crefs) - << - //start NLS ResidualFun<%nls.index%>, size=<%size%>); - { var nls = NonLinearSystems[<%nls.indexNonLinearSystem%>]; var nls_X = nls.X; - <%nls.crefs |> name hasindex i0 => - << - nls_X[<%i0%>] = <%cref(name, simCode)%>; - >> ;separator="\n" - %> - nls.Solve(); - <% //*** maybe this is useless as the last call to the ResidualFun has already set the crefs **** - nls.crefs |> name hasindex i0 => - '<%cref(name, simCode)%> = <%convertRealExpForCref('nls_X[<%i0%>]', name, simCode)%>;' - ;separator="\n" - %> - } //end_nonlinear_system(); - >> - - /******* old impl - << - //start NLS ResidualFun<%index%>, size=<%size%>); - { var oldX = StatesOld; var oldXd = StatesDerivativesOld; var old2X = StatesOld2; var old2Xd = StatesDerivativesOld2; - var oldY = AlgebraicsOld; var old2Y = AlgebraicsOld2; var extrapolateTimeFactor = (TimeOld - TimeOld2) != 0.0 ? (Time - TimeOld2)/(TimeOld - TimeOld2) : 0.0; - var nls = NonLinearSystems[<%indexNonLinearSystem%>]; var nls_x = nls.X; var nls_xold = nls.XOld; - <%crefs |> name hasindex i0 => - << - nls_x[<%i0%>] = /*extraPolate(<%crefStr(name, simCode)%>)*/ extrapolateTimeFactor == 0.0 ? <%cref(name, simCode)%> : (<%old2Cref(name, simCode)%> + extrapolateTimeFactor * (<%oldCref(name, simCode)%> - <%old2Cref(name, simCode)%>)); - nls_xold[<%i0%>] = <%oldCref(name, simCode)%>; - >> ;separator="\n" - %> - nls.Solve(); - <%nls.crefs |> name hasindex i0 => - '<%cref(name, simCode)%> = <%convertRealExpForCref('nls_x[<%i0%>]', name, simCode)%>;' - ;separator="\n" - %> - } //end_nonlinear_system(); - >> - old impl *********/ - -case SES_WHEN(__) then - let body = whenOperators(whenStmtLst, context, simCode) - let elseWhenConds = match elseWhen case SOME(ew) then equationElseWhen(ew, context, simCode) - if initialCall then - << - if(Initial<%if conditions then " || " + whenConditions(conditions, simCode)%>) { - <%body%> - } - <%elseWhenConds%> - >> - else - << - if( ! Initial) { - if(<%whenConditions(conditions, simCode)%>) { - <%body%> - } - <%elseWhenConds%> - } - >> -else - error(sourceInfo(), "UNKNOWN_equation") - -end equation_; - -template equationElseWhen(SimEqSystem eq, Context context, SimCode simCode) ::= -match eq -case SES_WHEN(__) then - let body = whenOperators(whenStmtLst, context, simCode) - let elseWhenConds = match elseWhen case SOME(ew) then equationElseWhen(ew, context, simCode) - << - else if(<%whenConditions(conditions, simCode)%>) { - <%body%> - } - <%elseWhenConds%> - >> -end equationElseWhen; - -template whenOperators(list whenOps, Context context, SimCode simCode) - "Generates re-init statement for when equation." -::= - whenOps |> whenOp => - match whenOp - case ASSIGN(left = lhs as DAE.CREF(componentRef = left)) then - let preExp = "" - let rightExp = daeExp(right, context, &preExp, simCode) - << - <%preExp%> - <%cref(left, simCode)%> = <%rightExp%>; - >> - case ASSIGN(__) then - let preExp = "" - let rightExp = daeExp(right, context, &preExp, simCode) - let leftExp = daeExp(left, context, &preExp, simCode) - << - <%preExp%> - <%leftExp%> = <%rightExp%>; - >> - case REINIT(__) then - let &preExp = buffer "" - let val = daeExp(value, contextSimulationDiscrete, &preExp, simCode) - << - <%preExp%> - <%cref(stateVar, simCode)%> = <%val%>; - needToIterate = true; - >> - case TERMINATE(__) then - let &preExp = buffer "" - let msgVar = daeExp(message, contextSimulationDiscrete, &preExp, simCode) - << - <%preExp%> - MODELICA_TERMINATE(<%msgVar%>); - >> - case ASSERT(source=SOURCE(info=info)) then - assertCommon(condition, message, info, contextSimulationDiscrete, simCode) - ;separator="\n" -end whenOperators; - -// SECTION: SIMULATION TARGET, FUNCTIONS FILE SPECIFIC TEMPLATES -// not yet implemented - -// SECTION: GENERAL TEMPLATES, COMPONENT REFERENCES - -template crefRepresentationArrayAndIndex(ComponentRef cr, Text &indexTxt, SimCode simCode) ::= - match cr - //deprecated: case CREF_IDENT(ident = "xloc") then crefStr(cr, simCode) //TODO: ??xloc - case CREF_IDENT(ident = "time") then "Time" //no index - case CREF_IDENT(ident = "$_lambda") then "_lambda" //no index - //??is this a HACK (on the SimCode level) ?? - case CREF_QUAL(ident = "$PRE") then - 'pre<%crefRepresentationArrayAndIndex(componentRef, &indexTxt, simCode)%>' - else -// (cref2simvar(cr, simCode) |> SIMVAR(__) => -// let &indexTxt += index -// representationArrayName(varKind, type_)) - - match cref2simvar(cr, simCode) -// case SIMVAR(varKind = DISCRETE()) then -// let offset = match simCode -// case SIMCODE(__) then -// match modelInfo -// case MODELINFO(__) then -// match varInfo -// case VARINFO(__) then numAlgVars -// let &indexTxt += index + ' + ' + offset -// representationArrayName(varKind, type_) - case SIMVAR(__) then - let &indexTxt += index - representationArrayName(varKind, type_) - -// match cref2simvar(cr, simCode) -// case SIMVAR(varKind = DISCRETE()) then -// let offset = -// match simCode -// case (simCode = SIMCODE(modelInfo = MODELINFO(varInfo = VARINFO(__)))) then numAlgVars -// let &indexTxt += index + ' + ' + offset -// representationArrayName(varKind, type_) -// case SIMVAR(__) then -// let &indexTxt += index -// representationArrayName(varKind, type_) -end crefRepresentationArrayAndIndex; - -template representationArrayName(VarKind varKind, Type type_) ::= - match varKind - case VARIABLE(__) then "Y" + representationArrayNameTypePostfix(type_) - case STATE(__) then "X" - case STATE_DER(__) then "Xd" - case DUMMY_DER(__) then "Y" // => algebraics - case DUMMY_STATE(__) then "Y" // => algebraics - case DISCRETE(__) then 'Y<%representationArrayNameTypePostfix(type_)%>/*d*/' - case PARAM(__) then "P" + representationArrayNameTypePostfix(type_) - case EXTOBJ(__) then "EO" - case CONST(__) then "CONST_VAR_KIND" - else "BAD_VARKIND" -end representationArrayName; - -template representationArrayNameTypePostfix(Type type_) ::= - match type_ - case T_INTEGER(__) - case T_ENUMERATION(__) then "I" - case T_BOOL(__) then "B" - case T_REAL(__) then "" - case T_STRING(__) then "S" - else "BAD_ARRAY_NAME_POSTFIX" -end representationArrayNameTypePostfix; - - -template representationCref(ComponentRef inCref, SimCode simCode) ::= - let &indexTxt = buffer "" - let arrAndIdx = crefRepresentationArrayAndIndex(inCref, &indexTxt, simCode) - if indexTxt then - '<%arrAndIdx%>[<% indexTxt %>]' - else - arrAndIdx - //cref2simvar(inCref, simCode) |> SIMVAR(__) => - // '<%representationArrayName(inCref, varKind, type_)%>[<% index %>]' -end representationCref; - -template cref(ComponentRef cr, SimCode simCode) ::= - '/*<% crefStr(cr, simCode) %>*/<% representationCref(cr, simCode) %>' - -/* - match cr - //deprecated: case CREF_IDENT(ident = "xloc") then crefStr(cr, simCode) //TODO: ??xloc - case CREF_IDENT(ident = "time") then "Time" - case CREF_IDENT(ident = "$_lambda") then "_lambda" - //$PRE is handled by representationCref ... - // case CREF_QUAL(ident = "$PRE") then preCref(componentRef, simCode) - else '/*<% crefStr(cr, simCode) %>*/<% representationCref(cr, simCode) %>' - // not needed ... //the space at the start is important to avoid ambiguity with "/" operator to become "//" line comment -*/ -end cref; - -template preCref(ComponentRef cr, SimCode simCode) ::= -'/*pre(<%crefStr(cr, simCode)%>)*/pre<%representationCref(cr, simCode)%>' -end preCref; - -template derCref(ComponentRef cr, SimCode simCode) ::= -'/*derCall!!(<% crefStr(cr, simCode) %>)*/<%representationCref(derComponentRef(cr), simCode)%>' -end derCref; - -/*** not used -template oldCref(ComponentRef cr, SimCode simCode) ::= -'/*old(<%crefStr(cr, simCode)%>)*/old<%representationCref(cr, simCode)%>' -end oldCref; - -template old2Cref(ComponentRef cr, SimCode simCode) ::= -'/*old2(<%crefStr(cr, simCode)%>)*/old2<%representationCref(cr, simCode)%>' -end old2Cref; -***/ - -//TODO: a HACK ? ... used in mixed system only -template crefToReal(ComponentRef cr, SimCode simCode) ::= -<*/<% cref2simvar(cr, simCode) |> SIMVAR(__) => //representationCref(cr, simCode) - '<%representationArrayName(varKind, type_)%>[<% index %>]' - + (match type_ case T_BOOL(__) - then "?1.0:0.0") - %> ->> -end crefToReal; - -//TODO: a HACK ? -template daeExpRealConversionPostfix(Exp exp, SimCode simCode) ::= - match typeof(exp) - case T_BOOL(__) then - "?1.0:0.0" - //TODO: make conversion also for other expressions -end daeExpRealConversionPostfix; - -//TODO: a HACK ? -template convertRealExpForCref(Text realExp, ComponentRef cr, SimCode simCode) ::= - cref2simvar(cr, simCode) |> SIMVAR(__) => - match type_ - case T_BOOL(__) then '(<%realExp%>) != 0.0' - case T_INTEGER(__) then '(int)(<%realExp%>)' - else realExp - -end convertRealExpForCref; - - -template contextCref(ComponentRef cr, Context context, SimCode simCode) - "Generates code for a component reference depending on which context we're in." -::= - match context - case FUNCTION_CONTEXT(__) then crefStr(cr, simCode) - else cref(cr, simCode) -end contextCref; - - -template crefStr(ComponentRef cr, SimCode simCode) - "Generates the name of a variable for variable name array." -::= - match cr - case CREF_IDENT(__) then csharpIdent(ident) + subscriptsStr(subscriptLst, simCode) - case CREF_QUAL(ident = "$DER") then '$der(<%crefStr(componentRef, simCode)%>)' - case CREF_QUAL(ident = "$PRE") then '$pre(<%crefStr(componentRef, simCode)%>)' - case CREF_QUAL(__) then '<%ident%><%subscriptsStr(subscriptLst, simCode)%>.<%crefStr(componentRef, simCode)%>' - else "CREF_NOT_IDENT_OR_QUAL" -end crefStr; - -template crefStrWithDerOnLast(ComponentRef cr, SimCode simCode) - "Generates the name of a variable for variable name array. - It used Dymola's name convention where the der() is on the last component." -::= - match cr - case CREF_IDENT(__) then csharpIdent(ident) + subscriptsStr(subscriptLst, simCode) - case CREF_QUAL(ident = "$DER") then crefStrWithDerOnLastIsDer(componentRef, simCode) - case CREF_QUAL(__) then '<%ident%><%subscriptsStr(subscriptLst, simCode)%>.<%crefStrWithDerOnLast(componentRef, simCode)%>' - else "CREF_NOT_IDENT_OR_QUAL" -end crefStrWithDerOnLast; - -template crefStrWithDerOnLastIsDer(ComponentRef cr, SimCode simCode) - "Helper to crefStrWithDerOnLast." -::= - match cr - case CREF_IDENT(__) then 'der(<%csharpIdent(ident)%><%subscriptsStr(subscriptLst, simCode)%>)' - case CREF_QUAL(ident = "$DER") then - //this one should not happen, but for sure ... - crefStrWithDerOnLastIsDer(componentRef, simCode) - case CREF_QUAL(__) then '<%ident%><%subscriptsStr(subscriptLst, simCode)%>.<%crefStrWithDerOnLastIsDer(componentRef, simCode)%>' - else "CREF_NOT_IDENT_OR_QUAL" -end crefStrWithDerOnLastIsDer; - -template csharpIdent(String ident) - "Generates the name of a variable for variable name array." -::= - match ident - case "string" then "@string" - case "int" then "@int" - else ident -end csharpIdent; - -template subscriptsStr(list subscripts, SimCode simCode) - "Generares subscript part of the name." -::= - if subscripts then - '[<% subscripts |> s => match s - case INDEX(__) - case SLICE(__) then - let &preExp = buffer "" //dummy ?? - daeExp(exp, contextFunction, &preExp, simCode) - case WHOLEDIM(__) then "WHOLEDIM" - else "UNKNOWN_SUBSCRIPT" - ;separator="," %>]' -end subscriptsStr; - - - -// SECTION: GENERAL TEMPLATES, PATHS - -template dotPath(Path it) ::= - match it - case QUALIFIED(__) then '<%name%>.<%dotPath(path)%>' - case IDENT(__) then name - case FULLYQUALIFIED(__) then dotPath(path) -end dotPath; - -//TODO: not 100% back-convertible e.g. Awkward_.Model vs. Awkward._Model, both -> Awkward___Model -template underscorePath(Path it) ::= - match it - case QUALIFIED(__) then '<%System.stringReplace(name, "_", "__")%>_<%underscorePath(path)%>' - case IDENT(__) then System.stringReplace(name, "_", "__") - case FULLYQUALIFIED(__) then underscorePath(path) -end underscorePath; - - -// SECTION: GENERAL TEMPLATES, FUNCTION GENERATION -// not yet implemented - - - -// Codegen.generateStatement -template algStatement(DAE.Statement stmt, Context context, SimCode simCode) ::= - match stmt - case STMT_ASSIGN(exp1 = CREF(componentRef = WILD(__)), exp = e) then - let &preExp = buffer "" - let expPart = daeExp(e, context, &preExp, simCode) - << - <%preExp%> - <%expPart%> - >> - case STMT_ASSIGN(exp1 = CREF(__)) then - let &preExp = buffer "" - let expPart = daeExp(exp, context, &preExp, simCode) - << - <%preExp%> - <%scalarLhsCref(exp1, context, &preExp, simCode)%> = <%expPart%>; - >> - case STMT_ASSIGN(__) then - let &preExp = buffer "" - let expPart1 = daeExp(exp1, context, &preExp, simCode) - let expPart2 = daeExp(exp, context, &preExp, simCode) - << - <%preExp%> - <%expPart1%> = <%expPart2%>; - >> - //works only for array name as IDENT with subscripts - case STMT_ASSIGN_ARR(lhs=CREF(componentRef= cr as CREF_IDENT(subscriptLst=subs as (_ :: _)))) then - let &preExp = buffer "" - let expPart = daeExp(exp, context, &preExp, simCode) - let spec = daeExpCrefRhsIndexSpec(subs, context, &preExp, simCode) - << - <%preExp%> - <%cr.ident%>.AssignSpec(<%spec%>, <%expPart%>.A); - >> - case STMT_ASSIGN_ARR(lhs=CREF(componentRef=cr)) then - let &preExp = buffer "" - let expPart = daeExp(exp, context, &preExp, simCode) - << - <%preExp%> - ArrayCopy(<%expPart%>.A, <%contextCref(cr, context, simCode)%>.A); - >> - case STMT_IF(__) then - let &preExp = buffer "" - let condExp = daeExp(exp, context, &preExp, simCode) - << - <%preExp%> - if (<%condExp%>) { - <%statementLst |> it => algStatement(it, context, simCode) ;separator="\n"%> - } - <%elseExpr(else_, context, simCode)%> - >> - case STMT_FOR(range=rng as RANGE(__)) then - let identType = expType(type_, iterIsArray) //TODO: ?? what is this for ... no array typed iterator is possible ??? - let identTypeShort = expTypeShort(type_) - let stmtStr = (statementLst |> stmt => algStatement(stmt, context, simCode) - ;separator="\n") - algStmtForRange_impl(rng, iter, identType, identTypeShort, stmtStr, context, simCode) - - case s as STMT_FOR(__) then "algStmtForGeneric_NOT_IMPLEMENTED" - // algStmtForGeneric(s, context, &varDecls /*BUFC*/) - - case STMT_WHILE(__) then - let &preExp = buffer "" - let var = daeExp(exp, context, &preExp, simCode) - << - for(;;) { - <%preExp%> - if (!<%var%>) break; - <%statementLst |> stmt => algStatement(stmt, context, simCode) ;separator="\n"%> - } - >> - - case STMT_TUPLE_ASSIGN(__) then "STMT_TUPLE_ASSIGN_NI" - case STMT_ASSERT(source=SOURCE(info=info)) then - assertCommon(cond, msg, info, context, simCode) - case STMT_TERMINATE(__) then "STMT_TERMINATE_NI" - case STMT_WHEN(__) then algStmtWhen(stmt, context, simCode) - case STMT_BREAK(__) then 'break; //break stmt<%\n%>' - case STMT_FAILURE(__) then "STMT_FAILURE_NI" - case STMT_RETURN(__) then "STMT_RETURN_NI" - case STMT_NORETCALL(__) then "STMT_NORETCALL_NI" - case STMT_REINIT(__) then "STMT_REINIT_NI" - - case _ then "NOT_IMPLEMENTED_ALG_STATEMENT" - /* - case STMT_FOR(range = rng as RANGE(__)) then - << - { - <%expTypeA(type_, boolean)%> - _r1 = <%daeExp(rng.exp,isSimulationCode)%>, - _r2 = <%match rng.expOption case SOME(eo) then daeExp(eo,isSimulationCode) else "(1)"%>, - _r3 = <%daeExp(rng.range,isSimulationCode)%>, - <%iter%>; - - for (<%iter%> = _r1; in_range_<%expTypeShort(type_)%>(<%iter%>, _r1, _r3); <%iter%> += _r2) { - <%statementLst |> it => algStatement(it) ;separator="\n" /* ??CONTEXT(codeContext,expContext,IN_FOR_LOOP(loopContext)*/ %> - } - } /*end for*/ - >> - */ -end algStatement; - -//TODO: in_range_integer is not correct against Modelica specification when e.g. 10:1 -//TODO: optimize representation for range, so that template can know that the range is ascendent and/or bounded by a constatnt(not necessary) -template algStmtForRange_impl(Exp range, Ident iterator, String type, String shortType, Text body, Context context, SimCode simCode) - "The implementation of algStmtForRange, which is also used by daeExpReduction." -::= -match range -case RANGE(__) then - let iterName = iterator - let &stopVar = buffer "" - let &preExp = buffer "" - let startValue = daeExp(start, context, &preExp, simCode) - let stopValue = daeExp(stop, context, &preExp, simCode) - match step - case SOME(eo) then - let &stepVar = buffer "" - let stepValue = daeExp(eo, context, &preExp, simCode) - << - <%preExp%> - <%tempDecl(type, &stepVar)%> = <%stepValue%>; <%tempDecl(type, &stopVar)%> = <%stopValue%>; - for(<%type%> <%iterName%> = <%startValue%>;(<%stepVar%> > 0? <%iterName%><=<%stopVar%> : <%stopVar%><=<%iterName%>); <%iterName%> += <%stepVar%>) { - <%body%> - } - >> - else //optimization for 1 step - << - <%preExp%> - <%tempDecl(type, &stopVar)%> = <%stopValue%>; - for(<%type%> <%iterName%> = <%startValue%>; <%iterName%><=<%stopVar%>; <%iterName%> += 1) { - <%body%> - } - >> -end algStmtForRange_impl; - -template elseExpr(DAE.Else it, Context context, SimCode simCode) ::= - match it - case NOELSE(__) then "" - case ELSEIF(__) then - let &preExp = buffer "" - let condExp = daeExp(exp, context, &preExp, simCode) - << - else { - <%preExp%> - if (<%condExp%>) { - <%statementLst |> it => algStatement(it, context, simCode) ;separator="\n"%> - } - <%elseExpr(else_, context, simCode)%> - } - >> - case ELSE(__) then - << - else { - <%statementLst |> it => algStatement(it, context, simCode) ;separator="\n"%> - } - >> -end elseExpr; - - -template algStmtWhen(DAE.Statement when, Context context, SimCode simCode) - "Generates a when algorithm statement." -::= -match context -case SIMULATION_CONTEXT(genDiscrete=true) then - match when - case STMT_WHEN(__) then - let statements = statementLst |> stmt => algStatement(stmt, context, simCode) ;separator="\n" - if initialCall then - << - if(Initial<%if conditions then " || " + whenConditions(conditions, simCode)%>) { - <%statements%> - } - <%algStatementWhenElse(elseWhen, simCode)%> - >> - else - << - if( ! Initial) { - if(<%whenConditions(conditions, simCode)%>) { - <%statements%> - } - <%algStatementWhenElse(elseWhen, simCode)%> - } - >> - - /* - << - if (<%whenConditions(conditions, simCode)%>) { - <% statementLst |> stmt => algStatement(stmt, context, simCode) - ;separator="\n" %> - } - <%algStatementWhenElse(elseWhen, simCode)%> - >> - */ - end match -end algStmtWhen; - - -template algStatementWhenElse(Option stmt, SimCode simCode) - "Helper to algStmtWhen." -::= -match stmt -case SOME(when as STMT_WHEN(__)) then - << - else if (<%whenConditions(when.conditions, simCode)%>) { - <% when.statementLst |> stmt => algStatement(stmt, contextSimulationDiscrete, simCode) - ;separator="\n"%> - } - <%algStatementWhenElse(when.elseWhen, simCode)%> - >> -end algStatementWhenElse; - - -template scalarLhsCref(Exp ecr, Context context, Text &preExp, SimCode simCode) ::= -match ecr -case ecr as CREF(componentRef=CREF_IDENT(subscriptLst=subs)) then - if crefNoSub(ecr.componentRef) then - contextCref(ecr.componentRef, context, simCode) - else - daeExpCrefRhs(ecr, context, &preExp, simCode) -case ecr as CREF(componentRef=CREF_QUAL(__)) then - contextCref(ecr.componentRef, context, simCode) -else - "ONLY_IDENT_OR_QUAL_CREF_SUPPORTED_SLHS" -end scalarLhsCref; - -/* -template scalarLhsCref(ComponentRef it, SimCode simCode) ::= - match it - case CREF_IDENT(__) then replaceDollarWorkaround(ident) - case CREF_QUAL(__) then '<%ident%>.<%scalarLhsCref(componentRef)%>' -end scalarLhsCref; -*/ - -//TODO: this wrong for qualified integers ! -template rhsCref(ComponentRef it, Type ty, SimCode simCode) ::= - match it - case CREF_IDENT(__) then '<%rhsCrefType(ty)%><%replaceDollarWorkaround(ident)%>' - case CREF_QUAL(__) then '<%rhsCrefType(ty)%><%ident%>.<%rhsCref(componentRef,ty, simCode)%>' - case _ then "rhsCref:ERROR" -end rhsCref; - -template rhsCrefType(Type it) ::= - match it - case T_INTEGER(__) then "(int)" - case _ then "" -end rhsCrefType; - - -template replaceDollarWorkaround(String ident) ::= - stringReplace( - stringReplace(ident,"$DER","Der_"), - "$", "") -end replaceDollarWorkaround; - -// SECTION: GENERAL TEMPLATES, EXPRESSIONS - -template daeExp(Exp inExp, Context context, Text &preExp, SimCode simCode) ::= - match inExp - case ICONST(__) then integer - case RCONST(__) then real - case SCONST(__) then '"<%Util.escapeModelicaStringToCString(string)%>"' - case BCONST(__) then if bool then "true" else "false" //"(1)" else "(0)" - case ENUM_LITERAL(__) then '<%index%>' //do not include ... 'ENUM:<%dotPath(name)%><%\n%>' may be embedded in a /* */ comment or VarData name - case CREF(ty = T_FUNCTION_REFERENCE_FUNC(__)) then 'FUNC_REF_NOT_SUPPORTED(cr=<%crefStr(componentRef,simCode)%>)' - case CREF(ty = T_COMPLEX(complexClassType = RECORD(__))) then - match context case FUNCTION_CONTEXT(__) then - daeExpCrefRhs(inExp, context, &preExp, simCode) - else - "daeExpRecordCrefRhs_NOT_YET" //daeExpRecordCrefRhs(t, cr, context, preExp, varDecls) - case CREF(__) then daeExpCrefRhs(inExp, context, &preExp, simCode) - case LBINARY(__) - case BINARY(__) then daeExpBinary(operator, exp1, exp2, context, &preExp, simCode) - case LUNARY(__) - case UNARY(__) then daeExpUnary(operator, exp, context, &preExp, simCode) - case RELATION(__) then daeExpRelation(inExp, context, &preExp, simCode) - case IFEXP(__) then daeExpIf(expCond, expThen, expElse, context, &preExp, simCode) - case CALL(__) then daeExpCall(inExp, context, &preExp, simCode) - // PARTEVALFUNCTION - case ARRAY(__) then daeExpArray(inExp, context, &preExp, simCode) - case MATRIX(__) then daeExpMatrix(inExp, context, &preExp, simCode) - case RANGE(__) then "RANGE_NOT_IMPLEMENTED" - case TUPLE(__) then "TUPLE_NOT_IMPLEMENTED" - case CAST(__) then daeExpCast(inExp, context, &preExp, simCode) - case ASUB(__) then daeExpAsub(inExp, context, &preExp, simCode) - case SIZE(__) then daeExpSize(inExp, context, &preExp, simCode) - case CODE(__) then "CODE_NOT_IMPLEMENTED" - case REDUCTION(__) then "REDUCTION_NOT_IMPLEMENTED" - //case VALUEBLOCK(__) then "VALUEBLOCK_NOT_IMPLEMENTED" - case LIST(__) then "LIST_NOT_IMPLEMENTED" - case CONS(__) then "CONS_NOT_IMPLEMENTED" - case SHARED_LITERAL(__) then '_OMC_LIT<%index%>' - // META_TUPLE - // META_OPTION - // METARECORDCALL - case _ then "UNKNOWN_EXP" -end daeExp; - -template daeExpSize(Exp esize, Context context, Text &preExp, SimCode simCode) - "Generates code for a size expression." -::= - match esize - case SIZE(exp=CREF(__), sz=SOME(dim)) then - let expPart = daeExp(exp, context, &preExp, simCode) - match dim - case ICONST(__) then - '<%expPart%>.size<%integer%>' - else - '<%expPart%>.size(<%daeExp(dim, context, &preExp, simCode)%>)' - else "size_X_NOT_IMPLEMENTED" -end daeExpSize; - - -template daeExpCrefRhs(Exp ecr, Context context, Text &preExp, SimCode simCode) ::= - match ecr - case ecr as CREF(componentRef = cr) then - let box = daeExpCrefRhsArrayBox(ecr, context, &preExp, simCode) - if box then - box - else if crefIsScalar(cr, context) then - //match ecr.ty - //case T_INTEGER(__) then '(int)<%contextCref(cr, context, simCode)%>' - //case T_BOOL(__) then - // match context - // case FUNCTION_CONTEXT(__) then contextCref(cr, context, simCode) //TODO: a hack! - // else '(<%contextCref(cr, context, simCode)%> !=0.0)' - //else - contextCref(cr, context, simCode) - else if crefSubIsScalar(cr) then - // The array subscript results in a scalar - //let ety = match ecr.ty case T_ARRAY(__) then "array" else "noarray" - let arrName = contextCref(crefStripLastSubs(cr), context, simCode) - //let arrayType = expTypeArray(ecr.ty,listLength(crefSubs(cr))) - //let dimsLenStr = listLength(crefSubs(cr)) - //let dimsValuesStr = (crefSubs(cr) |> INDEX(__) => daeExp(exp, context, &preExp, simCode) ;separator=", ") - << - <%arrName%>[<%crefSubs(cr) |> INDEX(__) => daeExp(exp, context, &preExp, simCode) - ;separator=", " - %>] - >> - else - // The array subscript denotes a slice - let arrName = contextCref(crefStripLastSubs(cr), context, simCode) - //let crsubs = crefSubs(cr) - //let arrayType = expTypeArray(ecr.ty, listLength(crsubs)) - let spec = daeExpCrefRhsIndexSpec(crefSubs(cr), context, &preExp, simCode) - '<%arrName%>.Array1Spec(<%spec%>)' - else - "UNKNOWN_RHS_CREF" -end daeExpCrefRhs; - -template daeExpCrefRhsArrayBox(Exp exp, Context context, Text &preExp, SimCode simCode) ::= -match exp -case ecr as CREF(ty=T_ARRAY(ty=aty,dims=dims)) then - match context - case FUNCTION_CONTEXT(__) then "" - else - //case SIMULATION_CONTEXT(__) //TODO: ?? is it the same as "else than FUNCTION_CONTEXT" ? - //case OTHER_CONTEXT(__) then - // For context simulation and other array variables must be boxed into a real_array - // object since they are represented only in a double array. - let &tmpArr = buffer "" - let arrType = expTypeArray(aty, listLength(dims)) - let dimsValuesStr = (dims |> dim => dimension(dim, context, &preExp, simCode) ;separator=", ") - let &indexTxt = buffer "" - let reprArray = crefRepresentationArrayAndIndex(ecr.componentRef, &indexTxt, simCode) - let &preExp += - //match cref2simvar(ecr.componentRef, simCode) case SIMVAR(__) then - '<%tempDecl("var", &tmpArr)%> = new <%arrType%>(<%dimsValuesStr%>, <%indexTxt%>-1, /*<%crefStr(ecr.componentRef, simCode)%>*/<%reprArray%>);<%\n%>' - tmpArr -end daeExpCrefRhsArrayBox; - - -template daeExpCrefRhsIndexSpec(list subs, Context context, Text &preExp, SimCode simCode) ::= - subs |> sub => match sub - case INDEX(__) then - 'new int[]{<%daeExp(exp, context, &preExp, simCode)%>-1}' - case WHOLEDIM(__) then - "null" - case SLICE(__) then - match exp - case ARRAY(scalar=true, ty=T_INTEGER(__)) then - << - new int[]{<% array |> e => '(<%expTypeFromExp(e)%>)<%daeExp(e, context, &preExp, simCode)%>-1' - ;separator="," - %> - >> - else "UKNOWN_SLICE_EXP" - ;separator=", " -end daeExpCrefRhsIndexSpec; - - -template daeExpAsub(Exp aexp, Context context, Text &preExp, SimCode simCode) - "Generates code for an asub expression." -::= - match aexp - case ASUB(exp=RANGE(ty=t), sub={idx}) then - 'ASUB_EASY_CASE' - case ASUB(exp=ASUB( - exp=ASUB( - exp=ASUB(exp=e, sub={ICONST(integer=i)}), - sub={ICONST(integer=j)}), - sub={ICONST(integer=k)}), - sub={ICONST(integer=l)}) then - 'ASUB_4D' - case ASUB(exp=ASUB( - exp=ASUB(exp=e, sub={ICONST(integer=i)}), - sub={ICONST(integer=j)}), - sub={ICONST(integer=k)}) then - 'ASUB_3D' - case ASUB(exp=ASUB(exp=e, sub={ICONST(integer=i)}), - sub={ICONST(integer=j)}) then - '<%daeExp(e, context, &preExp, simCode)%>[<%i%>,<%j%>]' - case ASUB(exp=e, sub={ICONST(integer=i)}) then - 'ASUB_ARRAY' - case ASUB(exp=ecr as CREF(componentRef = cr), sub = subs) then - match context case FUNCTION_CONTEXT(__) then - daeExpCrefRhs(buildCrefExpFromAsub(ecr, subs), context, &preExp, simCode) - else //SIMULATION or OTHER contexts - match ecr.ty - case T_ARRAY(ty = T_REAL(__), dims = dims) then //daeExpCrefRhsArrayBox - let &constSum = buffer "" - let arrayRepr = crefRepresentationArrayAndIndex(cr, &constSum, simCode) - let baseSub = asubSubsripts(dims, subs, &constSum, context, &preExp, simCode) - '/*<%crefStr(cr, simCode)%>[]*/<%arrayRepr%>[<%constSum%><%baseSub%>]' - /* - << - /*<% crefStr(cr, simCode) - %>[!]*/<% cref2simvar(cr, simCode) |> SIMVAR(__) => - let &constSum = buffer index - let baseSub = asubSubsripts(dims, subs, &constSum, context, &preExp, simCode) - << - <%representationArrayName(varKind,type_)%>[<%constSum%><%baseSub%>] - >> - %> - >> - */ - else "ASUB_SIMULATION_OTHER_ERROR" - - - //cref(ecr.componentRef, simCode) - /* - let arrName = daeExpCrefRhs(buildCrefExpFromAsub(ecr, subs), context, &preExp, simCode) - match context case SIMULATION_CONTEXT(__) then - arrayScalarRhs(ecr.ty, subs, arrName, context, &preExp, simCode) - else - arrName - */ - case ASUB(exp=exp as ARRAY(scalar=true), sub={idx}) then - "ASUB_FAST_ONE" - case ASUB(exp=e, sub=indexes) then - << - <%daeExp(e, context, &preExp, simCode) - %>[<%indexes |> index => '<%daeExp(index, context, &preExp, simCode)%>' ;separator=", "%>] - >> - else - 'OTHER_ASUB__ERROR' -end daeExpAsub; - -template asubSubsripts(list dims, list subs, Text &constSum, - Context context, Text &preExp, SimCode simCode) - "Helper to daeExpAsub." -::= - match subs case s :: subsRest then - match dims case _ :: dimsRest then - let subStr = daeExp(s, context, &preExp, simCode) - if dimsRest then //not last - let ds = dimsRest |> dim => dimension(dim, context, &preExp, simCode) ;separator="*" - //if ds then //TODO: assuming every dimension is SOME, is it true ?? - let &constSum += '-(<%ds%>)' //-1 * ds - '+<%subStr%>*(<%ds%>)<% asubSubsripts(dimsRest, subsRest, &constSum, context, &preExp, simCode) %>' - else //the last sub, add it to constSum (better optimization on compilation) - let &constSum += '-1 + <% subStr %>' - "" - else "ERROR_asubSubsripts_not_enough_dims" -end asubSubsripts; - -// TODO: Optimize as in Codegen -// TODO: Use this function in other places where almost the same thing is hard -// coded -// not used yet -template arrayScalarRhs(Type ty, list subs, Text arrName, Context context, - Text &preExp, SimCode simCode) - "Helper to daeExpAsub." -::= - let arrayType = expTypeArray(ty, listLength(subs)) - let dimsValuesStr = (subs |> exp => daeExp(exp, context, &preExp, simCode) - ;separator=", ") - << - (*ASR<%arrayType%>_element_addr(&<%arrName%>, <%/*dimsLen*/%>, <%dimsValuesStr%>)) - >> -end arrayScalarRhs; - - -template daeExpBinary(Operator it, Exp exp1, Exp exp2, Context context, Text &preExp, SimCode simCode) ::= - let e1 = daeExp(exp1, context, &preExp, simCode) - let e2 = daeExp(exp2, context, &preExp, simCode) - match it - case ADD(__) then '(<%e1%> + <%e2%>)' - //TODO FIX: bad type of SUB operator when on bools; the following does not work - //case SUB(ty = T_BOOL(__)) then '((<%e1%>?1.0:0.0) - (<%e2%>?1.0:0.0))' //in InitialResidual() ... - case SUB(__) then - //match expTypeFromExp(exp1) //TODO FIX: bool typed CREF returns "double"; the following is not working, too - //case "bool" then '((<%e1%>?1.0:0.0) - (<%e2%>?1.0:0.0))' //in InitialResidual() ... - //HACK!! - let boolConv = daeExpRealConversionPostfix(exp1, simCode) - '((<%e1%><%boolConv%>) - (<%e2%><%boolConv%>))' - case MUL(__) then '(<%e1%> * <%e2%>)' - case DIV(__) then '(<%e1%> / <%e2%>)' - case POW(__) then 'Math.Pow(<%e1%>, <%e2%>)' - case AND(__) then '(<%e1%> && <%e2%>)' - case OR(__) then '(<%e1%> || <%e2%>)' - case _ then "daeExpBinary:ERR" -end daeExpBinary; - - -template daeExpUnary(Operator it, Exp exp, Context context, Text &preExp, SimCode simCode) ::= - let e = daeExp(exp, context, &preExp, simCode) - match it - case UMINUS(__) then '(-<%e%>)' - case NOT(__) then '(!<%e%>)' - case UMINUS_ARR(__) then "UMINUS_ARR_NOT_IMPLEMENTED" - case _ then "daeExpUnary:ERR" - -end daeExpUnary; - - -template daeExpRelation(Exp inExp, Context context, Text &preExp, SimCode simCode) ::= - match inExp - case RELATION(__) then - //let &e1e2preExp = buffer "" - let simrel = daeExpSimRelation(inExp, context, /*e1, e2, e1e2preExp,*/ &preExp, simCode) - if simrel then simrel - else //non-SIMULATION context or precise equality - //let &preExp += e1e2preExp //if daeExpSimRelation() did not generated anything - let e1 = daeExp(exp1, context, &preExp, simCode) - let e2 = daeExp(exp2, context, &preExp, simCode) - match operator - case LESS(ty = T_BOOL(__)) then '(!<%e1%> && <%e2%>)' - case LESS(ty = T_STRING(__)) then "# string comparison not supported\n" - case LESS(ty = T_INTEGER(__)) - case LESS(ty = T_REAL(__)) - case LESS(ty = T_ENUMERATION(__)) then '(<%e1%> < <%e2%>)' - - case GREATER(ty = T_BOOL(__)) then '(<%e1%> && !<%e2%>)' - case GREATER(ty = T_STRING(__)) then "# string comparison not supported\n" - case GREATER(ty = T_INTEGER(__)) - case GREATER(ty = T_REAL(__)) - case GREATER(ty = T_ENUMERATION(__)) then '(<%e1%> > <%e2%>)' - - case LESSEQ(ty = T_BOOL(__)) then '(!<%e1%> || <%e2%>)' - case LESSEQ(ty = T_STRING(__)) then "# string comparison not supported\n" - case LESSEQ(ty = T_INTEGER(__)) - case LESSEQ(ty = T_REAL(__)) - case LESSEQ(ty = T_ENUMERATION(__)) then '(<%e1%> <= <%e2%>)' - - case GREATEREQ(ty = T_BOOL(__)) then '(<%e1%> || !<%e2%>)' - case GREATEREQ(ty = T_STRING(__)) then "# string comparison not supported\n" - case GREATEREQ(ty = T_INTEGER(__)) - case GREATEREQ(ty = T_REAL(__)) - case GREATEREQ(ty = T_ENUMERATION(__)) then '(<%e1%> >= <%e2%>)' - - case EQUAL(ty = T_BOOL(__)) //***then '((!<%e1%> && !<%e2%>) || (<%e1%> && <%e2%>))' - case EQUAL(ty = T_STRING(__)) - case EQUAL(ty = T_INTEGER(__)) - case EQUAL(ty = T_REAL(__)) - case EQUAL(ty = T_ENUMERATION(__)) then '(<%e1%> == <%e2%>)' - - case NEQUAL(ty = T_BOOL(__)) //***then '((!<%e1%> && <%e2%>) || (<%e1%> && !<%e2%>))' - case NEQUAL(ty = T_STRING(__)) - case NEQUAL(ty = T_INTEGER(__)) - case NEQUAL(ty = T_REAL(__)) - case NEQUAL(ty = T_ENUMERATION(__)) then '(<%e1%> != <%e2%>)' - case _ then "daeExpRelation:ERR" -end daeExpRelation; - -template zeroCrossingValue(Exp inRelationExp, Text e1, Text e2) ::= - match inRelationExp - case rel as RELATION(__) then - //isReal = isReal(exp1) || isReal(exp2) - //let isReal = if isRealType(typeof(rel.exp1)) then true else (if isRealType(typeof(rel.exp2)) then true) - let isReal = if boolOr(isRealType(typeof(rel.exp1)), isRealType(typeof(rel.exp2))) then true - match operator - case LESS(__) case GREATEREQ(__) - // e1 < e2 || e1 >= e2 - then - if isReal then - <] ? (<%e2%> - <%e1%> - (HystRelTol * Math.Abs(<%e1%>) + HystAbsTol)) - : (<%e2%> - <%e1%>)>> - else - '(<%e2%> - <%e1%>)' - case LESSEQ(__) case GREATER(__) - // e1 <= e2 || e1 > e2 - then - if isReal then - <] ? (<%e1%> - <%e2%> - (HystRelTol * Math.Abs(<%e2%>) + HystAbsTol)) - : (<%e1%> - <%e2%>)>> - else - '(<%e1%> - <%e2%>)' - - case EQUAL(__) case NEQUAL(__) - //e1 == e2 || e1 != e2 !!! BE AWARE !!! should not be allowed - then - if isReal then - <] ? (Math.Abs(<%e2%> - <%e1%>) - (HystRelTol * Math.Abs(<%e1%>) + HystAbsTol)) - : Math.Abs(<%e2%> - <%e1%>)>> - else - 'Math.Abs(<%e2%> - <%e1%>)' - - else error(sourceInfo(), "zeroCrossingValue unexpected operator") -end zeroCrossingValue; - -template zeroCrossingRelationOperator(Exp inRelationExp) ::= - match inRelationExp - case RELATION(__) then - match operator - case LESS(__) case GREATER(__) case NEQUAL(__) - then - " > " - case LESSEQ(__) case GREATEREQ(__) case EQUAL(__) - then - " <= " - else error(sourceInfo(), "zeroCrossingRelationOperator unexpected operator") -end zeroCrossingRelationOperator; - -template relationWithZeroCrossing(Exp inRelationExp, Text e1, Text e2) ::= - match inRelationExp - case RELATION(__) then - //relation <%ExpressionDumpTpl.dumpExp(inRelationExp,"\"")%> - << - relsZC[<%index%>] = <%zeroCrossingValue(inRelationExp, e1, e2)%>; - rels[<%index%>] = relsZC[<%index%>]<%zeroCrossingRelationOperator(inRelationExp)%>0.0; - >> -end relationWithZeroCrossing; - -template daeExpSimRelation(Exp inRelationExp, Context context, /*Text e1, Text e2, Text e1e2preExp,*/ Text &preExp, SimCode simCode) ::= -match context -case SIMULATION_CONTEXT(__) -case ALGLOOP_CONTEXT(__) -case ZEROCROSSINGS_CONTEXT(__) -then - match inRelationExp - case rel as RELATION(__) then - let &preExp += - << - //relation[<%rel.index%>]: <%ExpressionDumpTpl.dumpExp(inRelationExp,"\"")%><%\n%> - >> - match rel.index - case -1 then - //maybe, we should just return "" to let it handle by daeExpRelation(), - //but for now, just to see, where those (rel.index=-1) are - //no, we do so, because we see the relation via &preExp - "" - else - match context - case sim as SIMULATION_CONTEXT(__) then - if sim.genDiscrete then - //ZC with hysteresis - let e1 = daeExp(rel.exp1, context, &preExp, simCode) - let e2 = daeExp(rel.exp2, context, &preExp, simCode) - //let &preExp += e1e2preExp - let &preExp += - relationWithZeroCrossing(inRelationExp, e1, e2) + "\n" - 'rels[<%rel.index%>]' - else - //continuous uses preRels only ... funODE, non NLS code - 'preRels[<%rel.index%>]' - case ALGLOOP_CONTEXT(__) then - let &e1e2preExp = buffer "" - let e1 = daeExp(rel.exp1, context, &e1e2preExp, simCode) - let e2 = daeExp(rel.exp2, context, &e1e2preExp, simCode) - if genInitialisation then - let &preExp += e1e2preExp - let &preExp += - relationWithZeroCrossing(inRelationExp, e1, e2) + "\n" - '(IsContinuousEvaluation ? preRels[<%rel.index%>] : rels[<%rel.index%>])' - else - //all the DAE/ODE NLSs - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%>; - if(IsDiscreteEvaluation) { - <%e1e2preExp%> - <%relationWithZeroCrossing(inRelationExp, e1, e2)%> - <%res%> = IsContinuousEvaluation ? preRels[<%rel.index%>] : rels[<%rel.index%>]; - } else - <%res%> = preRels[<%rel.index%>];<%\n%> - >> - res - case ZEROCROSSINGS_CONTEXT(__) then - //zero crossing context only returns the value and do not set anything - let e1 = daeExp(rel.exp1, context, &preExp, simCode) - let e2 = daeExp(rel.exp2, context, &preExp, simCode) - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%> = (<%zeroCrossingValue(rel, e1, e2)%>)<%zeroCrossingRelationOperator(inRelationExp)%>0.0;<%\n%> - >> - res - - /**** old - case sim as SIMULATION_CONTEXT(__) then - if sim.genDiscrete then - if sim.isInitial then - //no ZC with hysteresis - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%> = <%e1%><%op%><%e2%>;//no ZC+H - rels[<%rel.index%>] = <%res%>;<%\n%> - >> - res - else - //ZC with hysteresis - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%> = <%e1%><%op%><%e2%>; //ZC+H - rels[<%rel.index%>] = <%res%>;<%\n%> - >> - res - else - //continuous uses preRels only ... funODE, non NLS code - 'preRels[<%rel.index%>]' - - case ALGLOOP_CONTEXT(__) then - if genInitialisation then - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%>; - if(IsContinuousEvaluation) { - <%res%> = preRels[<%rel.index%>]; - rels[<%rel.index%>] = <%e1%><%op%><%e2%>;//no ZC+H - } else - rels[<%rel.index%>] = <%res%> = <%e1%><%op%><%e2%>;//no ZC+H<%\n%> - >> - res - else - //all the DAE/ODE NLSs - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%>; - if(IsDiscreteEvaluation) { - if(IsContinuousEvaluation) { - <%res%> = preRels[<%rel.index%>]; - rels[<%rel.index%>] = <%e1%><%op%><%e2%>;//ZC+H - } else - rels[<%rel.index%>] = <%res%> = <%e1%><%op%><%e2%>;//ZC+H - } else - <%res%> = preRels[<%rel.index%>];<%\n%> - >> - res - ****/ -/* -case sim as SIMULATION_CONTEXT(__) then - match inExp - case RELATION(__) then - let op = - match operator - case LESS(__) then " < " - case LESSEQ(__) then " <= " - case GREATER(__) then " > " - case GREATEREQ(__) then " >= " - case EQUAL(__) then " == " - case NEQUAL(__) then " != " - else error(sourceInfo(), "daeExpSimRelation unexpected operator") - - match index - case -1 then - '(<%e1%><%op%><%e2%>)/*-1*/ ' - else if sim.genDiscrete then - let &res = buffer "" - let &preExp += - << - <%tempDecl("bool", res)%> = <%e1%><%op%><%e2%>; - rels[<%index%>] = <%res%>;<%\n%> - >> - res - else - 'preRels[<%index%>]' -*/ - /* - let &preExp += - match index - case -1 then - '<%tempDecl("bool", res)%> = <%e1%><%op%><%e2%>;<%\n%>' - else if sim.genDiscrete then - << - <%tempDecl("bool", res)%> = <%e1%><%op%><%e2%>; - rels[<%index%>] = <%res%>;<%\n%> - >> - else - '<%tempDecl("bool", res)%> = rels[<%index%>];<%\n%>' - res - */ - /* - match operator - case LESS(__) then SimRelationSimple(inExp, e1, e2, " < ", &preExp) - case LESSEQ(__) then SimRelationEqual(e1, e2, " <= ", &preExp) - case GREATER(__) then SimRelationSimple(e1, e2, " > ", &preExp) - case GREATEREQ(__) then SimRelationEqual(e1, e2, " >= ", &preExp) - end match - */ -end daeExpSimRelation; - -/* - - template simpleRelationOperator(Exp inRelationExp) ::= - match inRelationExp - case RELATION(__) then - match operator - case LESS(__) then " < " - case LESSEQ(__) then " <= " - case GREATER(__) then " > " - case GREATEREQ(__) then " >= " - case EQUAL(__) then " == /*!!! BE AWARE !!! should not be allowed*/ " - case NEQUAL(__) then " != /*!!! BE AWARE !!! should not be allowed*/ " - else error(sourceInfo(), "simpleRelationOperator unexpected operator") - end simpleRelationOperator; - - template SimRelationSimple(Text e1, Text e2, String op, Text &preExp) ::= - let &res = buffer "" - let &preExp += - << - // RELATION( <%e1%><%op%> <%e2%> ) macro expansion - - >> - //<%tempDecl("bool", res)%> = <%e1%><%op%> <%e2%>; if (!<%res%> && isInUpdate && (<%e1%><%op%>= <%e2%>)) { SwapOldVars(); double res1 = <%e1%> - <%e2%>; SwapOldVars12(); <%res%> = res1<%op%>= (<%e1%> - <%e2%>); SwapOldVars2(); }<%\n%> - res - end SimRelationSimple; - - - template SimRelationEqual(Text e1, Text e2, String op, Text &preExp) ::= - let &res = buffer "" - let &preExp += - << - // RELATION( <%e1%><%op%>= <%e2%> ) macro expansion - <%tempDecl("bool", res)%>; if (isInUpdate) { <%res%> = <%e1%><%op%> <%e2%>; if(!<%res%> && (<%e1%><%op%>= <%e2%>)) { SwapOldVars(); double res1 = <%e1%> - <%e2%>; SwapOldVars12(); <%res%> = res1<%op%>= (<%e1%> - <%e2%>); SwapOldVars2(); } } else <%res%> = <%e1%><%op%>= <%e2%>;<%\n%> - >> - res - end SimRelationEqual; -*/ - -template daeExpIf(Exp cond, Exp then_, Exp else_, Context context, Text &preExp, SimCode simCode) ::= - let condExp = daeExp(cond, context, &preExp, simCode) - let &resVar = buffer "" - let &preExpThen = buffer "" - let eThen = daeExp(then_, context, &preExpThen, simCode) - let &preExpElse = buffer "" - let eElse = daeExp(else_, context, &preExpElse, simCode) - let &preExp += - << - <%tempDecl(expTypeFromExpArrayIf(then_), resVar)%>; - if (<%condExp%><%/*if expTypeFromExp(cond) is "bool" then " != 0.0"*/%>) { //cond type is <%expTypeFromExp(cond)%> - <%preExpThen%> - <%resVar%> = <%eThen%>; - } else { - <%preExpElse%> - <%resVar%> = <%eElse%>; - }<%\n%> - >> - resVar - -/*<< -(<%daeExp(cond, context, &preExp, simCode) - %> ? <%daeExp(then_, context, &preExp, simCode)%> : <%daeExp(else_, context, &preExp, simCode)%>) ->>*/ -end daeExpIf; - - -template daeExpCall(Exp inExp, Context context, Text &preExp, SimCode simCode) ::= - match inExp - // special builtins - case CALL(path=IDENT(name="DIVISION"), - expLst={e1, e2}) then - - let var1 = daeExp(e1, context, &preExp, simCode) - let var2 = daeExp(e2, context, &preExp, simCode) - - match e2 - case RCONST(__) then - //match rr case 0.0 then 'DivBy0(<%var1%>,0.0,"<%msg%>")' - //else - '<%var1%> / <%var2%>' - case _ then - let msg = Util.escapeModelicaStringToCString(ExpressionDumpTpl.dumpExp(e2,"\"")) - let &tmpVar2 = buffer "" - let &preExp += - '<%tempDecl("var", &tmpVar2)%> = <%var2%>; if (<%tmpVar2%> == 0.0) throw new DivideByZeroException("<%msg%>");<%\n%>' - '<%var1%> / <%tmpVar2%>' - end match - - case CALL(path=IDENT(name="DIVISION"), - expLst={e1, e2, e3}) then - << - DEPRECATED DIVISION STYLE - >> - - - - case CALL(path=IDENT(name="der"), expLst={arg as CREF(__)}) then - derCref(arg.componentRef, simCode) - - case CALL(path=IDENT(name="pre"), expLst={arg as CREF(__)}) then - //let retType = expType(arg.ty) - << - <%match arg.ty case T_INTEGER(__) then "(int)" - %><% preCref(arg.componentRef, simCode) %> - >> - - case CALL(path=IDENT(name="integer"), expLst={toBeCasted}) - case CALL(path=IDENT(name="Integer"), expLst={toBeCasted}) then - let castedVar = daeExp(toBeCasted, context, &preExp, simCode) - '((int)<%castedVar%>)' - - //'(/*edge(h[<%idx%>])*/H[<%idx%>]!=0.0 && preH[<%idx%>]==0.0)' - case CALL(path=IDENT(name="edge"), expLst={arg as CREF(__)}) then - << - (/*edge*/<% cref(arg.componentRef, simCode) %> && !(<% preCref(arg.componentRef, simCode) %>)) - >> - case CALL(path=IDENT(name="change"), expLst={arg as CREF(__)}) then - << - (/*change*/<% cref(arg.componentRef, simCode) %> != <% preCref(arg.componentRef, simCode) %>) - >> - - case CALL(path=IDENT(name="max"), expLst={e1,e2}) then - 'Math.Max(<%daeExp(e1, context, &preExp, simCode)%>,<%daeExp(e2, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="min"), expLst={e1,e2}) then - 'Math.Min(<%daeExp(e1, context, &preExp, simCode)%>,<%daeExp(e2, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="mod"), expLst={e1,e2}, attr=attr as CALL_ATTR(__)) then - let var1 = daeExp(e1, context, &preExp, simCode) - let var2 = daeExp(e2, context, &preExp, simCode) - 'Mod_<%expTypeShort(attr.ty)%>(<%var1%>,<%var2%>)' - - //TODO: ignoring the format yet - case CALL(path=IDENT(name="String"), expLst={s, format}) then - let str = daeExp(s, context, &preExp, simCode) - '(<%str%>).ToString()' - - case CALL(path=IDENT(name="abs"), expLst={e1}, attr=CALL_ATTR(ty = T_INTEGER(__))) then - let var1 = daeExp(e1, context, &preExp, simCode) - 'Abs_int(<%var1%>)' - - case CALL(path=IDENT(name="abs"), expLst={s1}) then - 'Math.Abs(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="log"), expLst={s1}) then - 'Math.Log(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="log10"), expLst={s1}) then - 'Math.Log10(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="exp"), expLst={s1}) then - 'Math.Exp(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="sin"), expLst={s1}) then - 'Math.Sin(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="cos"), expLst={s1}) then - 'Math.Cos(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="sqrt"), expLst={s1}) then - 'Math.Sqrt(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="tanh"), expLst={s1}) then - 'Math.Tanh(<%daeExp(s1, context, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="noEvent"), expLst={s1}) then - '(/*noEvent*/<%daeExp(s1, /*context*/ contextOther, &preExp, simCode)%>)' - - case CALL(path=IDENT(name="initial"), expLst={}) then - 'Initial' - - /* Begin code generation of event triggering math functions */ - - case CALL(path=IDENT(name="integer"), expLst={valExp,index}) then - let &preExp += '//event trigger function: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%><%\n%>' - let constIndex = daeExp(index, context, &preExp, simCode) - match context - case SIMULATION_CONTEXT(genDiscrete=true) - case ALGLOOP_CONTEXT(genInitialisation=true) - case ZEROCROSSINGS_CONTEXT(__) - then - let val = daeExp(valExp, context, &preExp, simCode) - '((int) (mathEVPre[<%constIndex%>] = Math.Floor(<%val%>)))' - case SIMULATION_CONTEXT(genDiscrete=false) then - '(int) mathEVPre[<%constIndex%>]' - case ALGLOOP_CONTEXT(genInitialisation=false) then - let &res = buffer "" - let &preExp += - let &preExpVal = buffer "" - let val = daeExp(valExp, context, &preExpVal, simCode) - << - <%tempDecl("int", &res)%>; - if(IsDiscreteEvaluation && !IsContinuousEvaluation) { - <%preExpVal%> - <%res%> = (int) (mathEVPre[<%constIndex%>] = Math.Floor(<%val%>)); - } else { - <%res%> = (int) mathEVPre[<%constIndex%>]; - }<%\n%> - >> - res - else error(sourceInfo(), 'Unexpected context for: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>') - - case CALL(path=IDENT(name="floor"), expLst={valExp,index}, attr=CALL_ATTR(__)) then - let &preExp += '//event trigger function: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%><%\n%>' - let constIndex = daeExp(index, context, &preExp, simCode) - let retType = - match attr.ty - case T_REAL(__) then "" - case T_INTEGER(__) then "(int)" - else error(sourceInfo(), 'Unexpected return type "<%expTypeShort(attr.ty)%>" for floor().') - retType - + ( match context - case SIMULATION_CONTEXT(genDiscrete=true) - case ALGLOOP_CONTEXT(genInitialisation=true) - case ZEROCROSSINGS_CONTEXT(__) - then - let val = daeExp(valExp, context, &preExp, simCode) - '(mathEVPre[<%constIndex%>] = Math.Floor(<%val%>))' - case SIMULATION_CONTEXT(genDiscrete=false) then - 'mathEVPre[<%constIndex%>]' - case ALGLOOP_CONTEXT(genInitialisation=false) then - let &res = buffer "" - let &preExp += - let &preExpVal = buffer "" - let val = daeExp(valExp, context, &preExpVal, simCode) - << - <%tempDecl("double", &res)%>; - if(IsDiscreteEvaluation && !IsContinuousEvaluation) { - <%preExpVal%> - <%res%> = (mathEVPre[<%constIndex%>] = Math.Floor(<%val%>)); - } else { - <%res%> = mathEVPre[<%constIndex%>]; - }<%\n%> - >> - res - else error(sourceInfo(), 'Unexpected context for: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>') - ) - - case CALL(path=IDENT(name="ceil"), expLst={valExp,index}, attr=CALL_ATTR(__)) then - let &preExp += '//event trigger function: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%><%\n%>' - let constIndex = daeExp(index, context, &preExp, simCode) - let retType = - match attr.ty - case T_REAL(__) then "" - case T_INTEGER(__) then "(int)" - else error(sourceInfo(), 'Unexpected return type "<%expTypeShort(attr.ty)%>" for ceil().') - retType - + ( match context - case SIMULATION_CONTEXT(genDiscrete=true) - case ALGLOOP_CONTEXT(genInitialisation=true) - case ZEROCROSSINGS_CONTEXT(__) - then - let val = daeExp(valExp, context, &preExp, simCode) - '(mathEVPre[<%constIndex%>] = Math.Ceiling(<%val%>))' - case SIMULATION_CONTEXT(genDiscrete=false) then - 'mathEVPre[<%constIndex%>]' - case ALGLOOP_CONTEXT(genInitialisation=false) then - let &res = buffer "" - let &preExp += - let &preExpVal = buffer "" - let val = daeExp(valExp, context, &preExpVal, simCode) - << - <%tempDecl("double", &res)%>; - if(IsDiscreteEvaluation && !IsContinuousEvaluation) { - <%preExpVal%> - <%res%> = (mathEVPre[<%constIndex%>] = Math.Ceiling(<%val%>)); - } else { - <%res%> = mathEVPre[<%constIndex%>]; - }<%\n%> - >> - res - else error(sourceInfo(), 'Unexpected context for: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>') - ) - - case CALL(path=IDENT(name="div"), expLst={e1,e2, index}, attr=CALL_ATTR(__)) then - let &preExp += '//event trigger function: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%><%\n%>' - let constIndex = daeExp(index, context, &preExp, simCode) - let stype = expTypeShort(attr.ty) - match context - case SIMULATION_CONTEXT(genDiscrete=true) - case ALGLOOP_CONTEXT(genInitialisation=true) - case ZEROCROSSINGS_CONTEXT(__) - then - let val1 = daeExp(e1, context, &preExp, simCode) - let val2 = daeExp(e2, context, &preExp, simCode) - let &res = buffer "" - let &preExp += - << - <%tempDecl(stype, &res)%> - { var d = <%val2%>; - if (d = 0) throw new DivideByZeroException("event_div() failed at time " + Time + " because denominator is zero!"); - <%res%> = (int) (<%val1%> / d); - mathEVPre[<%constIndex%>] = <%res%>; - } - >> - res - case SIMULATION_CONTEXT(genDiscrete=false) then - '(<%stype%>) mathEVPre[<%constIndex%>]' - case ALGLOOP_CONTEXT(genInitialisation=false) then - let &res = buffer "" - let &preExp += - let &preExpVal = buffer "" - let val1 = daeExp(e1, context, &preExpVal, simCode) - let val2 = daeExp(e2, context, &preExpVal, simCode) - << - <%tempDecl(stype, &res)%>; - if(IsDiscreteEvaluation && !IsContinuousEvaluation) { - <%preExpVal%> - var d = <%val2%>; - if (d = 0) throw new DivideByZeroException("event_div() failed at time " + Time + " because denominator is zero!"); - <%res%> = (int) (<%val1%> / d); - mathEVPre[<%constIndex%>] = <%res%>; - } else { - <%res%> = (<%stype%>) mathEVPre[<%constIndex%>]; - }<%\n%> - >> - res - else error(sourceInfo(), 'Unexpected context for: <%ExpressionDumpTpl.dumpExp(inExp,"\"")%>') - - /* end codegeneration of event triggering math functions */ - - // TODO: add more special builtins (Codegen.generateBuiltinFunction) - // no return calls - case CALL(attr=CALL_ATTR(tuple_=false,ty=T_NORETCALL(__))) then - let argStr = (expLst |> it => daeExp(it, context, &preExp, simCode) ;separator=", ") - let &preExp += '<%underscorePrefix(attr.builtin)%><%underscorePath(path)%>(<%argStr%>);<%\n%>' - << - /* NORETCALL */ - >> - // non tuple calls (single return value) - case CALL(attr=attr as CALL_ATTR(tuple_=false)) then - let argStr = (expLst |> it => daeExp(it, context, &preExp, simCode) ;separator=", ") - let funName = underscorePath(path) - << - <%underscorePrefix(attr.builtin) - %><%funName%>(<%argStr%>)<%if not attr.builtin then '/* !!!TODO:.<%funName%>_rettype_1 */'%> - >> - case _ then "daeExpCall:NOT_YT_IMPLEMENTED" -end daeExpCall; - -template daeExpArray(Exp aexp, Context context, Text &preExp, SimCode simCode) ::= - match hackArrayReverseToCref(aexp, context) - case cr as CREF(__) then daeExpCrefRhs(cr, context, &preExp, simCode) - case a as ARRAY(__) then - if scalar then - let &arrayVar = buffer "" - let params = a.array |> e => '(<%expTypeFromExp(e)%>)<%daeExp(e, context, &preExp, simCode)%>' - ;separator=", " - let &preExp += '<%tempDecl("var",&arrayVar)%> = new <%expTypeArray(a.ty,1)%>(<%listLength(a.array)%>,-1,new[]{<%params%>});<%\n%>' - arrayVar - else - "NON_SCALAR_ARRAY_notYetImplemeted" -end daeExpArray; - -template daeExpMatrix(Exp mexp, Context context, Text &preExp, SimCode simCode) - "Generates code for a cast expression." -::= - match hackMatrixReverseToCref(mexp, context) - case cr as CREF(__) then daeExpCrefRhs(cr, context, &preExp, simCode) - case MATRIX(matrix={{}}) // special case for empty matrix: create dimensional array Real[0,1] - case MATRIX(matrix={}) // special case for empty array: create dimensional array Real[0,1] - then - let &tmp = buffer "" - let &preExp += '<%tempDecl("var",&tmp)%> = new <%expTypeArray(ty,2)%>(0,1);<%\n%>' - tmp - //only scalar orthogonal matrix for now - case m as MATRIX(matrix=(row1::_)) then - let &tmp = buffer "" - let matArr = m.matrix |> row => - (row |> elem => - daeExp(elem, context, &preExp, simCode) - ;separator=", ") - ;separator=",\n" - let &preExp += - << - <%tempDecl("var",&tmp)%> = new <%expTypeArray(m.ty,2)%>(<%listLength(m.matrix)%>,<%listLength(row1)%>,-1, new[]{ - <%matArr ;anchor%> - });<%\n%> - >> - tmp -end daeExpMatrix; - - -template daeExpCast(Exp cexp, Context context, Text &preExp, SimCode simCode) - "Generates code for a cast expression." -::= -match cexp -case CAST(__) then - let expVar = daeExp(exp, context, &preExp, simCode) - match ty - case T_INTEGER(__) then '((int)<%expVar%>)' - case T_REAL(__) then '((double)<%expVar%>)' - else "NOT_IMPLEMENTED_CAST" -end daeExpCast; - - - -template underscorePrefix(Boolean builtin) ::= - match builtin - case true then "" - case false then "_" -end underscorePrefix; - -// SECTION: GENERAL TEMPLATES, TEMPORARY VARIABLES - -//newVar parameter is assumed to be empty or it can hold an identifier prefix -template tempDecl(String ty, Text &newVar) ::= - let &newVar += '_tmp<%System.tmpTick()%>' - << - <%ty%> <%newVar%> - >> -end tempDecl; - - - -// SECTION: GENERAL TEMPLATES, TYPES - -template varType(Variable var) - "Generates type for a variable." -::= -match var -case VARIABLE(__) then - if instDims then - expTypeArray(ty, listLength(instDims)) - else - expTypeArrayIf(ty) -end varType; - -// TODO: Check with Codegen -template expTypeShort(DAE.Type it) ::= - match it - case T_INTEGER(__) then "int" - case T_REAL(__) then "double" - case T_STRING(__) then "string" - case T_BOOL(__) then "bool" - case T_ENUMERATION(__) then "int" - case T_UNKNOWN(__) then "UNKNOWN_TYPE_NOT_SUPPORTED" - case T_ANYTYPE(__) then "ANYTYPE_TYPE_NOT_SUPPORTED" - case T_ARRAY(__) then expTypeShort(ty) - case T_COMPLEX(complexClassType=EXTERNAL_OBJ(__)) then "object" - case T_COMPLEX(__) then '/*struct*/<%underscorePath(ClassInf.getStateName(complexClassType))%>' - case T_METATYPE(__) case T_METABOXED(__) then "META_TYPE_NOT_SUPPORTED" - case T_FUNCTION_REFERENCE_VAR(__) then "FN_PTR_NOT_SUPPORTED" - else "expTypeShort_ERROR" -end expTypeShort; - - -template expType(DAE.Type ty, Boolean isArray) - "Generate type helper." -::= - if isArray - then 'expType_<%expTypeArray(ty,0)%>_NOT_YET' - else expTypeShort(ty) -end expType; - -template expTypeArray(DAE.Type ty, Integer dims) ::= -<< -SimArray<%dims%><<%expTypeShort(ty)%>> ->> -end expTypeArray; - -template expTypeArrayIf(DAE.Type ty) - "Generate type helper." -::= - match ty - case T_ARRAY(__) then expTypeArray(ty, listLength(dims)) - else expTypeShort(ty) -end expTypeArrayIf; - - -template expTypeFromExpArrayIf(Exp exp) ::= - expTypeFromExp(exp) -end expTypeFromExpArrayIf; - - -template expTypeFromExp(Exp it) ::= - match it - case ICONST(__) - case ENUM_LITERAL(__) then "int" - case RCONST(__) then "double" - case SCONST(__) then "string" - case BCONST(__) then "bool" - case BINARY(__) - case UNARY(__) - case LBINARY(__) - case LUNARY(__) then expTypeFromOp(operator) - case RELATION(__) then "bool" //TODO: a HACK, it was expTypeFromOp(operator) - case IFEXP(__) then expTypeFromExp(expThen) - case CALL(attr=attr as CALL_ATTR(__)) then expTypeShort(attr.ty) - case ARRAY(__) - case MATRIX(__) - case RANGE(__) - case CAST(__) - case CREF(__) - case CODE(__) then expTypeShort(ty) - case ASUB(__) then expTypeFromExp(exp) - case REDUCTION(__) then expTypeFromExp(expr) - case _ then "expTypeFromExp:ERROR" -end expTypeFromExp; - - -template expTypeFromOp(Operator it) ::= - match it - case ADD(__) - case SUB(__) - case MUL(__) - case DIV(__) - case POW(__) - case UMINUS(__) - case UMINUS_ARR(__) - case ADD_ARR(__) - case SUB_ARR(__) - case MUL_ARR(__) - case DIV_ARR(__) - case MUL_ARRAY_SCALAR(__) - case ADD_ARRAY_SCALAR(__) - case SUB_SCALAR_ARRAY(__) - case MUL_SCALAR_PRODUCT(__) - case MUL_MATRIX_PRODUCT(__) - case DIV_ARRAY_SCALAR(__) - case DIV_SCALAR_ARRAY(__) - case POW_ARRAY_SCALAR(__) - case POW_SCALAR_ARRAY(__) - case POW_ARR(__) - case POW_ARR2(__) - case LESS(__) - case LESSEQ(__) - case GREATER(__) - case GREATEREQ(__) - case EQUAL(__) - case NEQUAL(__) then expTypeShort(ty) - case AND(__) - case OR(__) - case NOT(__) then "bool" - case _ then "expTypeFromOp:ERROR" -end expTypeFromOp; - -template dimension(Dimension d, Context context, Text &preExp, SimCode simCode) -::= - match d - case DAE.DIM_BOOLEAN(__) then '2' - case DAE.DIM_ENUM(__) then size - case DAE.DIM_EXP(exp=e) then daeExp(e, context, &preExp, simCode) - case DAE.DIM_INTEGER(__) then - if intEq(integer, -1) then - error(sourceInfo(),"Negeative dimension(unknown dimensions) may not be part of generated code. This is most likely an error on the part of OpenModelica. Please submit a detailed bug-report.") - else - integer - case DAE.DIM_UNKNOWN(__) then error(sourceInfo(),"Unknown dimensions may not be part of generated code. This is most likely an error on the part of OpenModelica. Please submit a detailed bug-report.") - else error(sourceInfo(), 'dimension: INVALID_DIMENSION') -end dimension; - - -template error(builtin.SourceInfo srcInfo, String errMessage) -"Example source template error reporting template to be used together with the sourceInfo() magic function. -Usage: error(sourceInfo(), <>) " -::= -let() = Tpl.addSourceTemplateError(errMessage, srcInfo) -<< - -#error <% Error.infoStr(srcInfo) %> <% errMessage %><%\n%> ->> -end error; - -//for completeness; although the error() template above is preferable -template errorMsg(String errMessage) -"Example template error reporting template - that is reporting only the error message without the usage of source information." -::= -let() = Tpl.addTemplateError(errMessage) -<< - -#error <% errMessage %><%\n%> ->> -end errorMsg; - -annotation(__OpenModelica_Interface="backend"); -end CodegenCSharp; -// vim: filetype=susan sw=2 sts=2 diff --git a/OMCompiler/Compiler/Template/Makefile.common b/OMCompiler/Compiler/Template/Makefile.common index a617e7a3371..31c640ab8f3 100644 --- a/OMCompiler/Compiler/Template/Makefile.common +++ b/OMCompiler/Compiler/Template/Makefile.common @@ -2,7 +2,7 @@ GENERATED_FILES_BOOT_STAGE2=AbsynDumpTpl.mo CodegenUtil.mo DAEDumpTpl.mo ExpressionDumpTpl.mo Unparsing.mo SCodeDumpTpl.mo GenerateAPIFunctionsTpl.mo CodegenCFunctions.mo AbsynToJulia.mo AbsynJLDumpTpl.mo GENERATED_FILES=$(GENERATED_FILES_BOOT_STAGE2) CodegenC.mo CodegenUtilSimulation.mo CodegenEmbeddedC.mo CodegenFMUCommon.mo \ -CodegenFMU.mo CodegenFMU1.mo CodegenFMU2.mo CodegenCSharp.mo CodegenCppCommon.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo \ +CodegenFMU.mo CodegenFMU1.mo CodegenFMU2.mo CodegenCppCommon.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo \ CodegenOMSI_common.mo CodegenOMSIC.mo CodegenOMSICpp.mo CodegenOMSIC_Equations.mo CodegenFMUCppHpcom.mo CodegenCppInit.mo \ CodegenMidToC.mo CodegenModelica.mo GraphvizDump.mo GraphMLDumpTpl.mo NFInstDumpTpl.mo SimCodeDump.mo CodegenAdevs.mo CodegenSparseFMI.mo \ CodegenXML.mo CodegenJava.mo CodegenJS.mo VisualXMLTpl.mo \ @@ -61,10 +61,6 @@ CodegenMidToC.mo : CodegenMidToC.tpl SimCodeTV.mo MidCodeTV.mo $(OMC) $< > $@.log || (cat $@.log && false) @echo " " && ($(UNUSED) "$@" || true) -CodegenCSharp.mo : CodegenCSharp.tpl SimCodeTV.mo - @echo " ** CodegenCSharp template compilation ** " - $(OMC) $< > $@.log || (cat $@.log && false) - @echo " " && ($(UNUSED) "$@" || true) # FMU CodegenFMUCommon.mo : CodegenFMUCommon.tpl SimCodeTV.mo SimCodeBackendTV.mo CodegenC.tpl CodegenCFunctions.tpl CodegenUtil.tpl diff --git a/OMCompiler/Compiler/Template/SimCodeTV.mo b/OMCompiler/Compiler/Template/SimCodeTV.mo index c42c14b6689..a8a7a94dc74 100644 --- a/OMCompiler/Compiler/Template/SimCodeTV.mo +++ b/OMCompiler/Compiler/Template/SimCodeTV.mo @@ -1256,11 +1256,6 @@ package SimCodeUtil output String outIndex; end localCref2Index; - function isModelTooBigForCSharpInOneFile - input SimCode.SimCode simCode; - output Boolean outIsTooBig; - end isModelTooBigForCSharpInOneFile; - function codegenExpSanityCheck input DAE.Exp inExp; input SimCodeFunction.Context context; diff --git a/OMCompiler/Compiler/Util/Flags.mo b/OMCompiler/Compiler/Util/Flags.mo index 7620d654e2b..82f557b7dee 100644 --- a/OMCompiler/Compiler/Util/Flags.mo +++ b/OMCompiler/Compiler/Util/Flags.mo @@ -779,7 +779,7 @@ constant ConfigFlag POST_OPT_MODULES = CONFIG_FLAG(16, "postOptModules", constant ConfigFlag SIMCODE_TARGET = CONFIG_FLAG(17, "simCodeTarget", NONE(), EXTERNAL(), STRING_FLAG("C"), - SOME(STRING_OPTION({"None", "Adevs", "C", "Cpp","omsicpp", "CSharp", "ExperimentalEmbeddedC", "Java", "JavaScript", "omsic", "sfmi", "XML", "MidC"})), + SOME(STRING_OPTION({"None", "Adevs", "C", "Cpp","omsicpp", "ExperimentalEmbeddedC", "Java", "JavaScript", "omsic", "sfmi", "XML", "MidC"})), Gettext.gettext("Sets the target language for the code generation.")); diff --git a/OMCompiler/Compiler/boot/LoadCompilerSources.mos b/OMCompiler/Compiler/boot/LoadCompilerSources.mos index c6c555faee6..f8274ed9403 100644 --- a/OMCompiler/Compiler/boot/LoadCompilerSources.mos +++ b/OMCompiler/Compiler/boot/LoadCompilerSources.mos @@ -433,7 +433,6 @@ if true then /* Suppress output */ "../Template/CodegenCppHpcom.mo", "../Template/CodegenCppHpcomOld.mo", "../Template/CodegenCppInit.mo", - "../Template/CodegenCSharp.mo", "../Template/CodegenFMU.mo", "../Template/CodegenFMU1.mo", "../Template/CodegenFMU2.mo", diff --git a/testsuite/openmodelica/bootstrapping/LoadCompilerSources.mos b/testsuite/openmodelica/bootstrapping/LoadCompilerSources.mos index a86d1cce722..9a1e9d27f3c 100644 --- a/testsuite/openmodelica/bootstrapping/LoadCompilerSources.mos +++ b/testsuite/openmodelica/bootstrapping/LoadCompilerSources.mos @@ -187,7 +187,6 @@ if true then /* Suppress output */ prefixPath + "Template/CodegenC.mo", prefixPath + "Template/CodegenCpp.mo", prefixPath + "Template/CodegenCppHpcom.mo", - prefixPath + "Template/CodegenCSharp.mo", prefixPath + "Template/CodegenFMU.mo", prefixPath + "Template/CodegenFMUCpp.mo", prefixPath + "Template/CodegenJava.mo", diff --git a/testsuite/special/MatlabTranslator/LoadCompilerSources.mos b/testsuite/special/MatlabTranslator/LoadCompilerSources.mos index d19943a9160..8c5fafd0b09 100644 --- a/testsuite/special/MatlabTranslator/LoadCompilerSources.mos +++ b/testsuite/special/MatlabTranslator/LoadCompilerSources.mos @@ -189,7 +189,6 @@ if true then /* Suppress output */ prefixPath + "Template/CodegenCppHpcom.mo", prefixPath + "Template/CodegenFMU.mo", prefixPath + "Template/CodegenFMUCpp.mo", - prefixPath + "Template/CodegenCSharp.mo", prefixPath + "Template/CodegenJava.mo", prefixPath + "Template/CodegenJS.mo", prefixPath + "Template/CodegenModelica.mo",