From 6767ae6a2bf8ce5c54705d95aa814c85a37ae22a Mon Sep 17 00:00:00 2001 From: Fabian Vu <Fabian.Vu@hhu.de> Date: Thu, 31 Oct 2024 14:00:40 +0100 Subject: [PATCH] Support generation of external functions (must be implemented) for Java --- .../generators/MachineGenerator.java | 16 +++++++++- .../generators/OperationGenerator.java | 2 ++ .../generators/SubstitutionGenerator.java | 3 +- .../hhu/stups/codegenerator/CppTemplate.stg | 5 ++- .../hhu/stups/codegenerator/JavaTemplate.stg | 31 ++++++++++++++++--- .../de/hhu/stups/codegenerator/TsTemplate.stg | 3 ++ .../codegenerator/java/TestMachines.java | 5 +++ .../hhu/stups/codegenerator/Lift_External.mch | 15 +++++++++ 8 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/de/hhu/stups/codegenerator/Lift_External.mch diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/MachineGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/MachineGenerator.java index c5265a128..836aa2e9b 100755 --- a/src/main/java/de/hhu/stups/codegenerator/generators/MachineGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/MachineGenerator.java @@ -276,6 +276,13 @@ public class MachineGenerator implements AbstractVisitor<String, Void> { TemplateHandler.add(machine, "props", modelCheckingGenerator.generateModelCheckingProBProp(node)); } TemplateHandler.add(machine, "machineString", modelCheckingGenerator.generateToString()); + TemplateHandler.add(machine, "externalFunctions", machineNode.getOperations() + .stream() + .filter(op -> op.getName().startsWith("EXTERNAL_")) + .map(op -> generateExternalFunction(op.getName(), op.getParams() + .stream() + .map(DeclarationNode::getName).collect(Collectors.toList()))) + .collect(Collectors.toList())); generateBody(node, machine); return machine.render(); } @@ -365,6 +372,13 @@ public class MachineGenerator implements AbstractVisitor<String, Void> { TemplateHandler.add(machine, "structs", recordStructGenerator.generateStructs()); } + private String generateExternalFunction(String name, List<String> parameters) { + ST template = currentGroup.getInstanceOf("external_function"); + TemplateHandler.add(template, "name", name); + TemplateHandler.add(template, "parameters", parameters); + return template.render(); + } + private List<String> generateProjectionClasses() { List<String> projectionClasses = new ArrayList<>(); for(OperationNode operation : machineNode.getOperations()) { @@ -428,7 +442,6 @@ public class MachineGenerator implements AbstractVisitor<String, Void> { } private String generateCopyConstructor(MachineNode node) { - ST template = currentGroup.getInstanceOf("copy_constructor"); TemplateHandler.add(template, "machine", nameHandler.handle(node.getName())); List<DeclarationNode> parameters = new ArrayList<>(node.getConstants()); @@ -444,6 +457,7 @@ public class MachineGenerator implements AbstractVisitor<String, Void> { TemplateHandler.add(template, "parameters", declarationGenerator.generateDeclarations(parameters, OperationGenerator.DeclarationType.PARAMETER, false)); TemplateHandler.add(template, "assignments", assignments); + TemplateHandler.add(template, "hasExternals", node.getOperations().stream().anyMatch(op -> op.getName().startsWith("EXTERNAL_"))); return template.render(); diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/OperationGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/OperationGenerator.java index 2ef5b5469..54d851f26 100644 --- a/src/main/java/de/hhu/stups/codegenerator/generators/OperationGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/OperationGenerator.java @@ -121,7 +121,9 @@ public class OperationGenerator { .filter(identifier -> !globals.contains(identifier.getName())) .collect(Collectors.toList()), DeclarationType.LOCAL_DECLARATION, false)); TemplateHandler.add(operation, "operationName", nameHandler.handleIdentifier(node.getName(), INCLUDED_MACHINES)); + TemplateHandler.add(operation, "isExternal", node.getName().startsWith("EXTERNAL_")); TemplateHandler.add(operation, "parameters", declarationGenerator.generateDeclarations(node.getParams(), DeclarationType.PARAMETER, false)); + TemplateHandler.add(operation, "parameterNames", node.getParams().stream().map(DeclarationNode::getName).collect(Collectors.toList())); TemplateHandler.add(operation, "returnParameters", declarationGenerator.generateDeclarations(node.getOutputParams(), DeclarationType.PARAMETER, true)); return operation; } diff --git a/src/main/java/de/hhu/stups/codegenerator/generators/SubstitutionGenerator.java b/src/main/java/de/hhu/stups/codegenerator/generators/SubstitutionGenerator.java index 15d3733d2..927c971bd 100644 --- a/src/main/java/de/hhu/stups/codegenerator/generators/SubstitutionGenerator.java +++ b/src/main/java/de/hhu/stups/codegenerator/generators/SubstitutionGenerator.java @@ -162,7 +162,8 @@ public class SubstitutionGenerator { TemplateHandler.add(initialization, "copy", copy); TemplateHandler.add(initialization, "forVisualization", machineGenerator.isForVisualisation()); TemplateHandler.add(initialization, "forModelChecking", machineGenerator.isForModelChecking()); - + TemplateHandler.add(initialization, "hasExternalFunctions", machineGenerator.getMachineNode().getOperations() + .stream().anyMatch(op -> op.getName().startsWith("EXTERNAL_"))); return initialization.render(); } diff --git a/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg index 4807e7844..2a6377c51 100644 --- a/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg +++ b/src/main/resources/de/hhu/stups/codegenerator/CppTemplate.stg @@ -1792,4 +1792,7 @@ include_initialization() ::= << transition_cache_declaration(type, identifier, operationHasParams) ::= << >> -set_initialization(identifier, type, enums) ::= <<>> \ No newline at end of file +set_initialization(identifier, type, enums) ::= <<>> + +external_function(name, parameters) ::= << +>> \ No newline at end of file diff --git a/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg index 599d193c4..fc4b0607e 100644 --- a/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg +++ b/src/main/resources/de/hhu/stups/codegenerator/JavaTemplate.stg @@ -3,7 +3,7 @@ abstract, assert, boolean, break, byte, case, catch, char, class, continue, defa >> -machine(forModelChecking, imports, machine, projectionClasses, structs, constants_declarations, includes, enums, sets, declarations, initialization, mainMethod, copyConstructor, operations, addition, getters, transitions, projection, invariant, copy, hash_equal, modelcheck, lambdaFunctions, choicePoints, choicePointsGetters, choicePointOperationFlags, choicePointOperationFlagGetters, choicePointOperationFlagResets, choicePointOperationTriggered, choicePointOperationTriggeredResets, choicePointOperationTriggeredFlags, choicePointOperationApplies) ::= << +machine(forModelChecking, imports, machine, projectionClasses, structs, constants_declarations, includes, enums, sets, declarations, initialization, mainMethod, copyConstructor, operations, addition, getters, transitions, projection, invariant, copy, hash_equal, modelcheck, lambdaFunctions, choicePoints, choicePointsGetters, choicePointOperationFlags, choicePointOperationFlagGetters, choicePointOperationFlagResets, choicePointOperationTriggered, choicePointOperationTriggeredResets, choicePointOperationTriggeredFlags, choicePointOperationApplies, externalFunctions) ::= << <imports; separator="\n"> <if(forModelChecking)> import java.util.HashMap; @@ -36,6 +36,13 @@ import de.hhu.stups.btypes.BUtils; public class <machine> { + <if(externalFunctions)> + public interface ExternalFunctionsInterface { + <externalFunctions; separator="\n"> + } + + private final ExternalFunctionsInterface _externalFunctions; + <endif> <if(forModelChecking)> private static final Var ASSOC; @@ -283,7 +290,7 @@ record(struct, parameters) ::= << new <struct>(<parameters; separator=", ">) >> -initialization(machine, properties, values, body, iterationConstruct, propertiesCheck) ::= << +initialization(machine, properties, values, body, iterationConstruct, propertiesCheck, hasExternalFunctions) ::= << <if(properties)> <if(values)> static { @@ -299,7 +306,10 @@ static { <endif> <endif> -public <machine>() { +public <machine>(<if(hasExternalFunctions)>ExternalFunctionsInterface _externalFunctions<endif>) { + <if(hasExternalFunctions)> + this._externalFunctions = _externalFunctions; + <endif> <body> } >> @@ -307,11 +317,15 @@ public <machine>() { method() ::= << >> -operation(returnType, operationName, parameters, locals, body, return) ::= << +operation(returnType, operationName, parameters, locals, body, return, isExternal, parameterNames) ::= << public <returnType> <operationName>(<parameters; separator=", ">) { + <if(isExternal)> + _externalFunctions.<operationName>(<parameterNames; separator=", ">); + <else> <locals; separator="\n"> <body> <return> + <endif> } >> @@ -523,8 +537,11 @@ public boolean <invariantFunction>() { } >> -copy_constructor(machine, assignments) ::= << +copy_constructor(machine, assignments, hasExternals) ::= << public <machine>(<machine> copy) { + <if(hasExternals)> + this._externalFunctions = copy._externalFunctions; + <endif> <assignments; separator="\n"> } >> @@ -1849,3 +1866,7 @@ transition_cache_declaration(type, identifier, operationHasParams) ::= << >> set_initialization(identifier, type, enums) ::= <<>> + +external_function(name, parameters) ::= << +void <name>(<parameters; separator=",">); +>> \ No newline at end of file diff --git a/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg b/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg index 653161df6..5704ddb90 100755 --- a/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg +++ b/src/main/resources/de/hhu/stups/codegenerator/TsTemplate.stg @@ -1442,3 +1442,6 @@ transition_cache_declaration(type, identifier, operationHasParams) ::= << >> set_initialization(identifier, type, enums) ::= <<>> + +external_function(name, parameters) ::= << +>> \ No newline at end of file diff --git a/src/test/java/de/hhu/stups/codegenerator/java/TestMachines.java b/src/test/java/de/hhu/stups/codegenerator/java/TestMachines.java index d8ca22ef2..7a7dae359 100644 --- a/src/test/java/de/hhu/stups/codegenerator/java/TestMachines.java +++ b/src/test/java/de/hhu/stups/codegenerator/java/TestMachines.java @@ -662,6 +662,11 @@ public class TestMachines extends TestJava { testJavaMC("Lift_MC_Large"); } + @Test + public void testLift_MC_External() throws Exception { + testJava("Lift_External"); + } + @Ignore @Test public void testNondeterministic_MC() throws Exception { diff --git a/src/test/resources/de/hhu/stups/codegenerator/Lift_External.mch b/src/test/resources/de/hhu/stups/codegenerator/Lift_External.mch new file mode 100644 index 000000000..45c8853ff --- /dev/null +++ b/src/test/resources/de/hhu/stups/codegenerator/Lift_External.mch @@ -0,0 +1,15 @@ +MACHINE Lift_External + +VARIABLES floor + +INVARIANT floor : 0..100 /* NAT */ + +INITIALISATION floor := 0 + +OPERATIONS + + inc = PRE floor<100 THEN floor := floor + 1 END ; + dec = PRE floor>0 THEN floor := floor - 1 END; + EXTERNAL_SEND = skip + +END \ No newline at end of file -- GitLab