Skip to content

Commit

Permalink
- Add half-implemented API call generateScriptingAPI
Browse files Browse the repository at this point in the history
- Handle variables with dimension false and true in SimCode


git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@23500 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Nov 21, 2014
1 parent 70cc730 commit 64f76ac
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 72 deletions.
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/Absyn.mo
Expand Up @@ -2821,7 +2821,7 @@ end pathTwoLastIdents;
public function pathLastIdent
"Returns the last ident (after last dot) in a path"
input Path inPath;
output Ident outIdent;
output String outIdent;
algorithm
outIdent := match(inPath)
local
Expand Down
9 changes: 7 additions & 2 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -100,17 +100,22 @@ algorithm
outSubscripts := List.map(inIntegers, intSubscript);
end intSubscripts;

public function subscriptInt
protected function subscriptInt
"Tries to convert a subscript to an integer index."
input DAE.Subscript inSubscript;
output Integer outInteger;
algorithm
outInteger := match(inSubscript)
local
Integer x;

Boolean b;
case DAE.INDEX(exp = DAE.ICONST(integer = x)) then x;
case DAE.INDEX(exp = DAE.ENUM_LITERAL(index = x)) then x;
case DAE.INDEX(exp = DAE.BCONST(bool = b)) then if b then 1 else 0;
else
equation
Error.addInternalError("subscriptInt failed: " + ExpressionDump.printSubscriptStr(inSubscript), sourceInfo());
then fail();

end match;
end subscriptInt;
Expand Down
14 changes: 14 additions & 0 deletions Compiler/FrontEnd/ModelicaBuiltin.mo
Expand Up @@ -3354,6 +3354,20 @@ annotation(
</html>"), preferredView="text");
end getClassInformation;

function generateScriptingAPI
input TypeName cl;
output Boolean success;
output String moFile;
output String qtFile;
external "builtin";
annotation(
Documentation(info="<html>
<p><b>Work in progress</b></p>
<p>Returns OpenModelica.Scripting API entry points for the classes that we can automatically generate entry points for.</p>
<p>The entry points are MetaModelica code calling CevalScript directly, and Qt/C++ code that calls the MetaModelica code.</p>
</html>"), preferredView="text");
end generateScriptingAPI;

end Scripting;

package UsersGuide
Expand Down
63 changes: 61 additions & 2 deletions Compiler/Script/CevalScript.mo
Expand Up @@ -95,6 +95,7 @@ import FInst;
import FGraph;
import FGraphDump;
import GC;
import GenerateAPIFunctionsTpl;
import Global;
import GlobalScriptUtil;
import Graph;
Expand Down Expand Up @@ -902,7 +903,8 @@ algorithm
GlobalScript.SimulationOptions simOpt;
Real startTime,stopTime,tolerance,reltol,reltolDiffMinMax,rangeDelta;
DAE.Exp startTimeExp,stopTimeExp,toleranceExp,intervalExp;
DAE.Type tp;
DAE.Type tp, ty;
list<DAE.Type> tys;
Absyn.Class absynClass;
Absyn.ClassDef cdef;
Absyn.Exp aexp;
Expand Down Expand Up @@ -947,7 +949,7 @@ algorithm
list<tuple<Absyn.Path,list<String>>> uses;
Config.LanguageStandard oldLanguageStd;
SCode.Element cl;
list<SCode.Element> cls;
list<SCode.Element> cls, elts;
list<String> names, namesPublic, namesProtected, namesChanged, fileNames;
HashSetString.HashSet hashSetString;
list<Boolean> blst;
Expand Down Expand Up @@ -2165,6 +2167,34 @@ algorithm
then
(cache,Values.BOOL(false),st);

case (cache,env,"generateScriptingAPI",{Values.CODE(Absyn.C_TYPENAME(className))},st as GlobalScript.SYMBOLTABLE(ast = p),_)
algorithm
(scodeP,st) := GlobalScriptUtil.symbolTableToSCode(st);
elts := match SCodeUtil.getElementWithPathCheckBuiltin(scodeP, className)
case SCode.CLASS(classDef=SCode.PARTS(elementLst=elts)) then elts;
case cl equation Error.addSourceMessage(Error.INTERNAL_ERROR, {Absyn.pathString(className) + " does not contain SCode.PARTS"}, SCode.elementInfo(cl)); then fail();
end match;
tys := {};
for elt in elts loop
_ := matchcontinue elt
case SCode.CLASS(partialPrefix=SCode.NOT_PARTIAL(), restriction=SCode.R_FUNCTION(SCode.FR_EXTERNAL_FUNCTION()))
algorithm
(cache, ty, _) := Lookup.lookupType(cache, env, Absyn.suffixPath(className, elt.name), NONE() /*SOME(elt.info)*/);
if isSimpleAPIFunction(ty) then
tys := ty::tys;
print("Found type: " + Types.unparseType(ty) + "\n");
end if;
then ();
else ();
end matchcontinue;
end for;
print("Found a total of " + String(listLength(tys)) + " functions to generate API for\n");
s1 := Tpl.tplString(GenerateAPIFunctionsTpl.getCevalScriptInterface, tys);
then (cache,Values.TUPLE({Values.BOOL(true),Values.STRING(s1),Values.STRING("")}),st);

case (cache,env,"generateScriptingAPI",{Values.CODE(Absyn.C_TYPENAME(className))},st as GlobalScript.SYMBOLTABLE(ast = p),_)
then (cache,Values.TUPLE({Values.BOOL(false),Values.STRING(""),Values.STRING("")}),st);

case (cache,_,"generateEntryPoint",{Values.STRING(filename),Values.CODE(Absyn.C_TYPENAME(path)),Values.STRING(str)},st as GlobalScript.SYMBOLTABLE(),_)
equation
str = Tpl.tplString2(CodegenC.generateEntryPoint, path, str);
Expand Down Expand Up @@ -7970,5 +8000,34 @@ algorithm
end matchcontinue;
end getClassComment;

function isSimpleAPIFunction
input DAE.Type ty;
output Boolean b;
algorithm
b := match ty
case DAE.T_FUNCTION(functionAttributes=DAE.FUNCTION_ATTRIBUTES(isBuiltin=DAE.FUNCTION_BUILTIN())) then
isSimpleAPIFunctionArg(ty.funcResultType) and
min(match fa case DAE.FUNCARG() then isSimpleAPIFunctionArg(fa.ty); end match for fa in ty.funcArg);
else false;
end match;
end isSimpleAPIFunction;

function isSimpleAPIFunctionArg
input DAE.Type ty;
output Boolean b;
algorithm
b := match ty
case DAE.T_INTEGER() then true;
case DAE.T_REAL() then true;
case DAE.T_BOOL() then true;
case DAE.T_STRING() then true;
case DAE.T_NORETCALL() then true;
case DAE.T_ARRAY() then isSimpleAPIFunctionArg(ty.ty);
case DAE.T_CODE(ty=DAE.C_TYPENAME()) then true;
case DAE.T_TUPLE() then min(isSimpleAPIFunctionArg(t) for t in ty.types);
else false;
end match;
end isSimpleAPIFunctionArg;

annotation(__OpenModelica_Interface="backend");
end CevalScript;
73 changes: 7 additions & 66 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -890,8 +890,7 @@ algorithm
// failure
case (_, fn, _, _, _, _, _,_)
equation
str = "./Compiler/BackEnd/SimCodeUtil.mo: function elaborateFunction failed for function: \n" + DAEDump.dumpFunctionStr(fn);
Error.addMessage(Error.INTERNAL_ERROR, {str});
Error.addInternalError("function elaborateFunction failed for function: \n" + DAEDump.dumpFunctionStr(fn), sourceInfo());
then
fail();
end matchcontinue;
Expand Down Expand Up @@ -980,7 +979,7 @@ algorithm
case (_)
equation
// TODO: ArrayEqn fails here
Error.addMessage(Error.INTERNAL_ERROR, {"./Compiler/BackEnd/SimCodeUtil.mo: function daeInOutSimVar failed\n"});
Error.addInternalError("function daeInOutSimVar failed\n", sourceInfo());
then
fail();
end matchcontinue;
Expand Down Expand Up @@ -1332,8 +1331,8 @@ algorithm
then (exp, t);
case (exp, _)
equation
msg = "./Compiler/BackEnd/SimCodeUtil.mo: function replaceLiteralExp failed. Falling back to not replacing "+ExpressionDump.printExpStr(exp)+".";
Error.addMessage(Error.INTERNAL_ERROR, {msg});
msg = "function replaceLiteralExp failed. Falling back to not replacing "+ExpressionDump.printExpStr(exp)+".";
Error.addInternalError(msg, sourceInfo());
then (inExp,inTpl);
end matchcontinue;
end replaceLiteralExp;
Expand Down Expand Up @@ -1750,7 +1749,7 @@ algorithm
then (simCode, (highestSimEqIndex, equationSccMapping));

else equation
Error.addMessage(Error.INTERNAL_ERROR, {"./Compiler/BackEnd/SimCodeUtil.mo: function createSimCode failed [Transformation from optimised DAE to simulation code structure failed]"});
Error.addInternalError("function createSimCode failed [Transformation from optimised DAE to simulation code structure failed]", sourceInfo());
then fail();
end matchcontinue;
end createSimCode;
Expand Down Expand Up @@ -6984,15 +6983,14 @@ algorithm
next = listLength(extObjVars);
numOptimizeConstraints = listLength(realOptimizeConstraintsVars);
numOptimizeFinalConstraints = listLength(realOptimizeFinalConstraintsVars);

varInfo = createVarInfo(dlow, nx, ny, ndy, np, na, next, numOutVars, numInVars, numInitialEquations, numInitialAlgorithms,
ny_int, np_int, na_int, ny_bool, np_bool, na_bool, ny_string, np_string, na_string, numStateSets, numOptimizeConstraints, numOptimizeFinalConstraints);
then
SimCode.MODELINFO(class_, description, directory, varInfo, vars, functions, labels);

else
equation
Error.addMessage(Error.INTERNAL_ERROR, {"./Compiler/BackEnd/SimCodeUtil.mo: function createModelInfo failed"});
Error.addInternalError("createModelInfo failed", sourceInfo());
then
fail();
end matchcontinue;
Expand Down Expand Up @@ -7715,63 +7713,6 @@ algorithm
list<SimCodeVar.SimVar> realOptimizeConstraintsVars;
list<SimCodeVar.SimVar> realOptimizeFinalConstraintsVars;
HashSet.HashSet set;
// runtime CPP, there it is not necesarry to sort the arrays because different memory management
/*case (true, SimCodeVar.SIMVARS(stateVars, derivativeVars, algVars, intAlgVars, boolAlgVars, inputVars,
outputVars, aliasVars, intAliasVars, boolAliasVars, paramVars, intParamVars, boolParamVars,
stringAlgVars, stringParamVars, stringAliasVars, extObjVars, constVars, intConstVars, boolConstVars, stringConstVars, jacobianVars))
equation
// but for runtime CPP also the incomplete arrays need one special element to generate the array
// search all arrays with array information
set = HashSet.emptyHashSet();
set = List.fold(stateVars, collectArrayFirstVars, set);
set = List.fold(derivativeVars, collectArrayFirstVars, set);
set = List.fold(algVars, collectArrayFirstVars, set);
set = List.fold(intAlgVars, collectArrayFirstVars, set);
set = List.fold(boolAlgVars, collectArrayFirstVars, set);
set = List.fold(inputVars, collectArrayFirstVars, set);
set = List.fold(outputVars, collectArrayFirstVars, set);
set = List.fold(aliasVars, collectArrayFirstVars, set);
set = List.fold(intAliasVars, collectArrayFirstVars, set);
set = List.fold(boolAliasVars, collectArrayFirstVars, set);
set = List.fold(paramVars, collectArrayFirstVars, set);
set = List.fold(intParamVars, collectArrayFirstVars, set);
set = List.fold(boolParamVars, collectArrayFirstVars, set);
set = List.fold(stringAlgVars, collectArrayFirstVars, set);
set = List.fold(stringParamVars, collectArrayFirstVars, set);
set = List.fold(stringAliasVars, collectArrayFirstVars, set);
set = List.fold(extObjVars, collectArrayFirstVars, set);
set = List.fold(constVars, collectArrayFirstVars, set);
set = List.fold(intConstVars, collectArrayFirstVars, set);
set = List.fold(boolConstVars, collectArrayFirstVars, set);
set = List.fold(stringConstVars, collectArrayFirstVars, set);
set = List.fold(jacobianVars, collectArrayFirstVars, set);
// add array information to incomplete arrays
(stateVars, set) = List.mapFold(stateVars, setArrayElementnoFirst, set);
(derivativeVars, set) = List.mapFold(derivativeVars, setArrayElementnoFirst, set);
(algVars, set) = List.mapFold(algVars, setArrayElementnoFirst, set);
(intAlgVars, set) = List.mapFold(intAlgVars, setArrayElementnoFirst, set);
(boolAlgVars, set) = List.mapFold(boolAlgVars, setArrayElementnoFirst, set);
(inputVars, set) = List.mapFold(inputVars, setArrayElementnoFirst, set);
(outputVars, set) = List.mapFold(outputVars, setArrayElementnoFirst, set);
(aliasVars, set) = List.mapFold(aliasVars, setArrayElementnoFirst, set);
(intAliasVars, set) = List.mapFold(intAliasVars, setArrayElementnoFirst, set);
(boolAliasVars, set) = List.mapFold(boolAliasVars, setArrayElementnoFirst, set);
(paramVars, set) = List.mapFold(paramVars, setArrayElementnoFirst, set);
(intParamVars, set) = List.mapFold(intParamVars, setArrayElementnoFirst, set);
(boolParamVars, set) = List.mapFold(boolParamVars, setArrayElementnoFirst, set);
(stringAlgVars, set) = List.mapFold(stringAlgVars, setArrayElementnoFirst, set);
(stringParamVars, set) = List.mapFold(stringParamVars, setArrayElementnoFirst, set);
(stringAliasVars, set) = List.mapFold(stringAliasVars, setArrayElementnoFirst, set);
(extObjVars, set) = List.mapFold(extObjVars, setArrayElementnoFirst, set);
(constVars, set) = List.mapFold(constVars, setArrayElementnoFirst, set);
(intConstVars, set) = List.mapFold(intConstVars, setArrayElementnoFirst, set);
(boolConstVars, set) = List.mapFold(boolConstVars, setArrayElementnoFirst, set);
(stringConstVars, set) = List.mapFold(stringConstVars, setArrayElementnoFirst, set);
(jacobianVars, set) = List.mapFold(jacobianVars, setArrayElementnoFirst, set);
then SimCodeVar.SIMVARS(stateVars, derivativeVars, algVars, intAlgVars, boolAlgVars, inputVars,
outputVars, aliasVars, intAliasVars, boolAliasVars, paramVars, intParamVars, boolParamVars,
stringAlgVars, stringParamVars, stringAliasVars, extObjVars, constVars, intConstVars, boolConstVars, stringConstVars, jacobianVars);
*/// other runtimes
case (SimCodeVar.SIMVARS(stateVars, derivativeVars, algVars, discreteAlgVars, intAlgVars, boolAlgVars, inputVars,
outputVars, aliasVars, intAliasVars, boolAliasVars, paramVars, intParamVars, boolParamVars,
stringAlgVars, stringParamVars, stringAliasVars, extObjVars, constVars, intConstVars, boolConstVars, stringConstVars, jacobianVars, realOptimizeConstraintsVars,realOptimizeFinalConstraintsVars))
Expand Down Expand Up @@ -8695,7 +8636,7 @@ algorithm

else
equation
print("./Compiler/BackEnd/SimCodeUtil.mo: function getCrefFromExp failed: input was not of type DAE.CREF");
Error.addInternalError("function getCrefFromExp failed: input was not of type DAE.CREF", sourceInfo());
then
fail();
end match;
Expand Down
41 changes: 41 additions & 0 deletions Compiler/Template/GenerateAPIFunctionsTpl.tpl
@@ -0,0 +1,41 @@
package GenerateAPIFunctionsTpl

import interface SimCodeTV;

template getCevalScriptInterface(list<DAE.Type> tys)
::=
let funcs = tys |> ty as T_FUNCTION(source=path::_) => '<%getCevalScriptInterfaceFunc(pathLastIdent(path), ty.funcArg, ty.funcResultType)%><%\n%>'
<<
import Absyn;
import CevalScript;
import GlobalScript;
import Parser;

protected

constant Absyn.Msg dummyMsg = Absyn.MSG(SOURCEINFO("<interactive>",false,1,1,1,1,0.0));

public

<%funcs%>
>>
end getCevalScriptInterface;

template getCevalScriptInterfaceFunc(String name, list<DAE.FuncArg> args, DAE.Type res)
::=
<<
function <%name%>
input GlobalScript.SymbolTable st;
input ...;
output GlobalScript.SymbolTable outSymTab;
output ...;
algorithm
(_,...,outSymTab) := CevalScript.cevalInteractiveFunctions2(FCore.emptyCache(), FGraph.empty(), "<%name%>", {...}, st, dummyMsg);
end <%name%>;
>>
end getCevalScriptInterfaceFunc;

annotation(__OpenModelica_Interface="backend");
end GenerateAPIFunctionsTpl;

// vim: filetype=susan sw=2 sts=2
7 changes: 6 additions & 1 deletion Compiler/Template/Makefile.common
@@ -1,6 +1,6 @@
.PHONY : all

GENERATED_FILES=AbsynDumpTpl.mo CodegenUtil.mo CodegenC.mo CodegenFMU.mo CodegenCSharp.mo CodegenQSS.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo CodegenModelica.mo DAEDumpTpl.mo ExpressionDumpTpl.mo GraphvizDump.mo GraphMLDumpTpl.mo NFInstDumpTpl.mo SimCodeDump.mo Unparsing.mo SCodeDumpTpl.mo CodegenAdevs.mo CodegenSparseFMI.mo CodegenXML.mo CodegenJava.mo CodegenJS.mo TplCodegen.mo TaskSystemDump.mo
GENERATED_FILES=AbsynDumpTpl.mo CodegenUtil.mo CodegenC.mo CodegenFMU.mo CodegenCSharp.mo CodegenQSS.mo CodegenCpp.mo CodegenCppHpcom.mo CodegenFMUCpp.mo CodegenModelica.mo DAEDumpTpl.mo ExpressionDumpTpl.mo GraphvizDump.mo GraphMLDumpTpl.mo NFInstDumpTpl.mo SimCodeDump.mo Unparsing.mo SCodeDumpTpl.mo CodegenAdevs.mo CodegenSparseFMI.mo CodegenXML.mo CodegenJava.mo CodegenJS.mo TplCodegen.mo TaskSystemDump.mo GenerateAPIFunctionsTpl.mo

all : $(GENERATED_FILES)

Expand Down Expand Up @@ -129,5 +129,10 @@ TaskSystemDump.mo : TaskSystemDump.tpl SimCodeTV.mo CodegenUtil.tpl SCodeDumpTpl
$(OMC) $< > $@.log || (cat $@.log && false)
@echo " "

GenerateAPIFunctionsTpl.mo : GenerateAPIFunctionsTpl.tpl SimCodeTV.mo
@echo " ** GenerateAPIFunctionsTpl template compilation ** "
$(OMC) $< > $@.log || (cat $@.log && false)
@echo " "

clean:
rm -f $(GENERATED_FILES)
5 changes: 5 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -1132,6 +1132,11 @@ package Absyn
output String outString;
end pathString2NoLeadingDot;

function pathLastIdent
input Path inPath;
output String str;
end pathLastIdent;

constant builtin.SourceInfo dummyInfo;
end Absyn;

Expand Down
1 change: 1 addition & 0 deletions Compiler/boot/LoadCompilerSources.mos
Expand Up @@ -208,6 +208,7 @@ if true then /* Suppress output */
"../Template/CodegenXML.mo",
"../Template/DAEDumpTpl.mo",
"../Template/ExpressionDumpTpl.mo",
"../Template/GenerateAPIFunctionsTpl.mo",
"../Template/GraphvizDump.mo",
"../Template/GraphMLDumpTpl.mo",
"../Template/NFInstDumpTpl.mo",
Expand Down

0 comments on commit 64f76ac

Please sign in to comment.