From 9e006df2c10b49c125e549a51c86c0f52e08d171 Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 28 Mar 2021 12:12:51 -0400 Subject: [PATCH] Added 'final' test. --- .../xyz/colinholzman/makina/CodeGenerator.kt | 42 +++++------ .../test/xyz/colinholzman/makina/FinalTest.kt | 10 +++ test/final/.gitignore | 2 + test/final/makefile | 16 +++++ test/final/test_driver.c | 70 +++++++++++++++++++ test/final/test_source.mkna | 15 ++++ 6 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 makina-compiler/test/xyz/colinholzman/makina/FinalTest.kt create mode 100644 test/final/.gitignore create mode 100644 test/final/makefile create mode 100644 test/final/test_driver.c create mode 100644 test/final/test_source.mkna diff --git a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt index 893499f..f097e28 100644 --- a/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt +++ b/makina-compiler/src/xyz/colinholzman/makina/CodeGenerator.kt @@ -95,29 +95,31 @@ class CodeGenerator(val machine: Machine, for (activeAtomicState in machine.states.filter { it.isAtomic() }) { println("static int ${machine.id}_${activeAtomicState.getFullyQualifiedIdString()}($machineStructName *self, $machineEventName *event) {") println("\tif (!self || !event) return -1;") - val config = activeAtomicState.getStateConfiguration() - println("\tswitch (event->id) {") - val handlerGroups = config.getHandlers().groupByIdAndRemoveRedundantHandlers() - for (entry in handlerGroups) { - val eventId = entry.key - println("\tcase ${machine.id}_event_$eventId:") - for (handlerStatePair in entry.value) { - val sourceState = handlerStatePair.first - val handler = handlerStatePair.second - val guard = if (handler.guard != null) "${handler.guard}(self, event)" else "1" - println("\t\tif ($guard) {") - generateExitActions(handler, sourceState, activeAtomicState, output) - if (handler.action != null) { - println("\t\t\t${handler.action}(self, event);") + if (!activeAtomicState.final) { + val config = activeAtomicState.getStateConfiguration() + println("\tswitch (event->id) {") + val handlerGroups = config.getHandlers().groupByIdAndRemoveRedundantHandlers() + for (entry in handlerGroups) { + val eventId = entry.key + println("\tcase ${machine.id}_event_$eventId:") + for (handlerStatePair in entry.value) { + val sourceState = handlerStatePair.first + val handler = handlerStatePair.second + val guard = if (handler.guard != null) "${handler.guard}(self, event)" else "1" + println("\t\tif ($guard) {") + generateExitActions(handler, sourceState, activeAtomicState, output) + if (handler.action != null) { + println("\t\t\t${handler.action}(self, event);") + } + generateEntryActions(handler, sourceState, activeAtomicState, output) + println("\t\t\tbreak;") + println("\t\t}") } - generateEntryActions(handler, sourceState, activeAtomicState, output) - println("\t\t\tbreak;") - println("\t\t}") + println("\t\tbreak;") } - println("\t\tbreak;") + println("\tdefault: break;") + println("\t}") } - println("\tdefault: break;") - println("\t}") println("\treturn 0;") println("}") println() diff --git a/makina-compiler/test/xyz/colinholzman/makina/FinalTest.kt b/makina-compiler/test/xyz/colinholzman/makina/FinalTest.kt new file mode 100644 index 0000000..4308e0f --- /dev/null +++ b/makina-compiler/test/xyz/colinholzman/makina/FinalTest.kt @@ -0,0 +1,10 @@ +package xyz.colinholzman.makina + +import org.junit.jupiter.api.Test + +class FinalTest { + @Test + fun final() { + externalMakefileTest("./../test/final") + } +} diff --git a/test/final/.gitignore b/test/final/.gitignore new file mode 100644 index 0000000..0f1f446 --- /dev/null +++ b/test/final/.gitignore @@ -0,0 +1,2 @@ +out +.vscode \ No newline at end of file diff --git a/test/final/makefile b/test/final/makefile new file mode 100644 index 0000000..add4375 --- /dev/null +++ b/test/final/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/final/test_driver.c b/test/final/test_driver.c new file mode 100644 index 0000000..71c8725 --- /dev/null +++ b/test/final/test_driver.c @@ -0,0 +1,70 @@ + +#include +#include +#include +#include "out/test.h" + +static const char *expected_output[] = { + "s1_entry", + "s1_s2_entry", + "s1_s2_exit", + "f_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; +} + +int s1_s2_exit(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_s2_exit"); + return 0; +} + +int f_entry(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("f_entry"); + return 0; +} + +int s1_e1_action(struct test *self, struct test_event *event) { + (void)self; (void)event; + PUSH_EVENT("s1_e1_action"); + 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}); + test_process_event(&instance, &(struct test_event){.id = test_event_e1}); + 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/final/test_source.mkna b/test/final/test_source.mkna new file mode 100644 index 0000000..3a95d1f --- /dev/null +++ b/test/final/test_source.mkna @@ -0,0 +1,15 @@ +machine test; + +state s1 { + on e1 s1_e1_action; + entry s1_entry; + state s2 { + entry s1_s2_entry; + on e1 -> f; + exit s1_s2_exit; + } + final state f { + entry f_entry; + } + exit s1_exit; +}