diff --git a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt index 0fba398..9832c5f 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt @@ -56,7 +56,7 @@ class CodeGenerator(val machine: Machine, private fun generateExitActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) { if (handler.target != null) output.apply { val target = handler.getTargetState(sourceState, machine) - val transition = Transition(activeLeafState, sourceState, target) + val transition = Transition(activeLeafState, sourceState, target, handler.target.kind) val exitSet = transition.getExitSet() for (stateToExit in exitSet) { for (exit in stateToExit.handlers.filterIsInstance()) { @@ -70,7 +70,7 @@ class CodeGenerator(val machine: Machine, private fun generateEntryActions(handler: Handler.Event, sourceState: State, activeLeafState: State, output: PrintWriter) { if (handler.target != null) output.apply { val target = handler.getTargetState(sourceState, machine) - val transition = Transition(activeLeafState, sourceState, target) + val transition = Transition(activeLeafState, sourceState, target, handler.target.kind) val entrySet = transition.getEntrySet() val targetLeafState = entrySet.last() println("\t\t\tself->state = ${machine.id}_${targetLeafState.getFullyQualifiedIdString()};") diff --git a/makina-compiler/test/xyz/colinholzman/makina/ExternalTransitionTest.kt b/makina-compiler/test/xyz/colinholzman/makina/ExternalTransitionTest.kt new file mode 100644 index 0000000..57d01e4 --- /dev/null +++ b/makina-compiler/test/xyz/colinholzman/makina/ExternalTransitionTest.kt @@ -0,0 +1,10 @@ +package xyz.colinholzman.makina + +import org.junit.jupiter.api.Test + +class ExternalTransitionTest { + @Test + fun externalTransition() { + externalMakefileTest("./../test/external_transition") + } +} \ No newline at end of file diff --git a/makina-compiler/test/xyz/colinholzman/makina/TransitionTest.kt b/makina-compiler/test/xyz/colinholzman/makina/TransitionTest.kt index 70b79d0..2a62ec2 100644 --- a/makina-compiler/test/xyz/colinholzman/makina/TransitionTest.kt +++ b/makina-compiler/test/xyz/colinholzman/makina/TransitionTest.kt @@ -36,6 +36,7 @@ internal class TransitionTest { assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s121, Target.Kind.EXTERNAL).getExitSet()) assertEquals(listOf(s111), Transition(s111, s111, s111, Target.Kind.EXTERNAL).getExitSet()) assertEquals(listOf(s111, s11, s1), Transition(s111, s1, s1, Target.Kind.EXTERNAL).getExitSet()) + assertEquals(listOf(s21, s2), Transition(s21, s2, s21, Target.Kind.EXTERNAL).getExitSet()) } @Test diff --git a/test/external_transition/.gitignore b/test/external_transition/.gitignore new file mode 100644 index 0000000..0f1f446 --- /dev/null +++ b/test/external_transition/.gitignore @@ -0,0 +1,2 @@ +out +.vscode \ No newline at end of file diff --git a/test/external_transition/makefile b/test/external_transition/makefile new file mode 100644 index 0000000..add4375 --- /dev/null +++ b/test/external_transition/makefile @@ -0,0 +1,16 @@ +.PHONY: test +test: out/test + ./out/test + +out/test: test_driver.c out/test.c out/test.h out + gcc test_driver.c out/test.c -I "." -std=c99 -Wall -Wextra -Werror -o out/test -g + +out/test.c: + java -jar ../../makina-compiler/out/artifacts/makina_compiler_jar/makina-compiler.jar test_source.mkna -o out + +out: + mkdir out + +.PHONY: clean +clean: + rm -rf out diff --git a/test/external_transition/test_driver.c b/test/external_transition/test_driver.c new file mode 100644 index 0000000..a5a1bee --- /dev/null +++ b/test/external_transition/test_driver.c @@ -0,0 +1,99 @@ + +#include +#include +#include +#include "out/test.h" + +static const char *expected_output[] = { + "s1_entry", + "s1_s2_entry", + "s1_s2_e1_guard", + "s1_s2_exit", + "s1_exit", + "s1_entry", + "s1_s2_entry", + "s1_s2_e1_guard", + "s1_s2_exit", + "s1_exit", + "s1_entry", + "s1_s2_entry", + "s1_s2_e2_guard", + "s1_s2_exit", + "s1_exit", + "s1_entry", + "s1_s2_entry", + "s1_s2_e2_guard", + "s1_s2_exit", + "s1_s2_entry" +}; + +#define N_EVENTS (sizeof(expected_output) / sizeof(const char *)) + +static const char *actual_output[N_EVENTS]; + +static size_t output_index = 0; + +#define PUSH_EVENT(e) do { \ + assert(output_index < N_EVENTS); \ + actual_output[output_index++] = e; \ +} while (0) + +int s1_s2_entry(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_entry"); + return 0; +} + +static int guard = 0; + +int s1_s2_e1_guard(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_e1_guard"); + return guard; +} + +int s1_s2_e2_guard(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_e2_guard"); + return guard; +} + +int s1_s2_e1_action(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_e1_action"); + return 0; +} + +int s1_s2_exit(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_exit"); + return 0; +} + +int s1_entry(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_entry"); + return 0; +} + +int s1_exit(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_exit"); + return 0; +} + +int main (void) { + struct test instance; + test_init(&instance); + test_process_event(&instance, &(struct test_event){.id = test_event_e1}); + guard = 1; + test_process_event(&instance, &(struct test_event){.id = test_event_e1}); + guard = 0; + test_process_event(&instance, &(struct test_event){.id = test_event_e2}); + guard = 1; + test_process_event(&instance, &(struct test_event){.id = test_event_e2}); + for (size_t i = 0; i < N_EVENTS; ++i) { + assert(strcmp(expected_output[i], actual_output[i]) == 0); + } + return 0; +} \ No newline at end of file diff --git a/test/external_transition/test_source.mkna b/test/external_transition/test_source.mkna new file mode 100644 index 0000000..cde9d53 --- /dev/null +++ b/test/external_transition/test_source.mkna @@ -0,0 +1,14 @@ +machine test; + +state s1 { + on e1 --> s1; + on e2 --> s2; + entry s1_entry; + state s2 { + entry s1_s2_entry; + on e1 (s1_s2_e1_guard) --> s1; + on e2 (s1_s2_e2_guard) --> s2; + exit s1_s2_exit; + } + exit s1_exit; +}