From 4f9278d4b75954906503edaaafc9318cafb81770 Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 17 Mar 2021 15:51:29 +0000 Subject: [PATCH] core state machine macros --- Makefile | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ include/frame.h | 4 +-- include/state.h | 40 +++++++++++++++++++++++++++ src/main.cpp | 18 +++++++++++- src/state.cpp | 6 ++++ 5 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 include/state.h create mode 100644 src/state.cpp diff --git a/Makefile b/Makefile index 939551f..83503bb 100644 --- a/Makefile +++ b/Makefile @@ -1 +1,74 @@ PROJECT=sm +AUTHOR=Avril (Flanchan) + +SRC_C = $(wildcard src/*.c) +SRC_CXX = $(wildcard src/*.cpp) + +INCLUDE=include + +COMMON_FLAGS= -W -Wall -pedantic -fno-strict-aliasing $(addprefix -I,$(INCLUDE)) + +OPT_FLAGS?= -march=native -fgraphite -fopenmp -floop-parallelize-all -ftree-parallelize-loops=4 \ + -floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block \ + -fno-stack-check + +CXX_OPT_FLAGS?= $(OPT_FLAGS) -felide-constructors + +CFLAGS += $(COMMON_FLAGS) --std=gnu11 +CXXFLAGS += $(COMMON_FLAGS) --std=gnu++20 -fno-exceptions +LDFLAGS += + +STRIP=strip + +RELEASE_CFLAGS?= -O3 -flto $(OPT_FLAGS) +RELEASE_CXXFLAGS?= -O3 -flto $(CXX_OPT_FLAGS) +RELEASE_LDFLAGS?= -O3 -flto + +DEBUG_CFLAGS?= -O0 -g -DDEBUG +DEBUG_CXXFLAGS?= $(DEBUG_CFLAGS) +DEBUG_LDFLAGS?= + +# Objects + +OBJ_C = $(addprefix obj/c/,$(SRC_C:.c=.o)) +OBJ_CXX = $(addprefix obj/cxx/,$(SRC_CXX:.cpp=.o)) +OBJ = $(OBJ_C) $(OBJ_CXX) + +# Phonies + +.PHONY: release +release: | dirs $(PROJECT)-release + +.PHONY: debug +debug: | dirs $(PROJECT)-debug + +# Targets + +dirs: + @mkdir -p obj/c{,xx}/src + +obj/c/%.o: %.c + $(CC) -c $< $(CFLAGS) -o $@ $(LDFLAGS) + +obj/cxx/%.o: %.cpp + $(CXX) -c $< $(CXXFLAGS) -o $@ $(LDFLAGS) + +$(PROJECT)-release: CFLAGS+= $(RELEASE_CFLAGS) +$(PROJECT)-release: CXXFLAGS += $(RELEASE_CXXFLAGS) +$(PROJECT)-release: LDFLAGS += $(RELEASE_LDFLAGS) +$(PROJECT)-release: $(OBJ) + $(CXX) $^ $(CXXFLAGS) -o $@ $(LDFLAGS) + $(STRIP) $@ + +$(PROJECT)-debug: CFLAGS+= $(DEBUG_CFLAGS) +$(PROJECT)-debug: CXXFLAGS += $(DEBUG_CXXFLAGS) +$(PROJECT)-debug: LDFLAGS += $(DEBUG_LDFLAGS) +$(PROJECT)-debug: $(OBJ) + $(CXX) $^ $(CXXFLAGS) -o $@ $(LDFLAGS) + +clean-rebuild: + rm -rf obj + +clean: clean-rebuild + rm -f $(PROJECT)-{release,debug,pgo} + diff --git a/include/frame.h b/include/frame.h index c5051f9..038ac0f 100644 --- a/include/frame.h +++ b/include/frame.h @@ -3,7 +3,7 @@ #include "box.h" #include -#define _SM_STACK_SIZE 16 +#define _SM_STACK_SIZE 256 struct _sm_user { bool set ;//: 1; No need for these to be bitfield packed, there's an alignment hole here anyway. @@ -74,7 +74,7 @@ inline void _sm_free(_sm_user* frame) } #define _SM_DEF(T) template<> T* _sm_init(_sm_user* frame, T init); \ - template<> T* _sm_get(_sm_user* frame); + template<> T* _sm_get(_sm_user* frame) _SM_DEF(char); _SM_DEF(unsigned char); diff --git a/include/state.h b/include/state.h new file mode 100644 index 0000000..ef03fc9 --- /dev/null +++ b/include/state.h @@ -0,0 +1,40 @@ +#pragma once + +#include "frame.h" + +typedef void* (*sm_yield)(sm_state* state); //NOTE: This `void*` is a stand-in for this function returning itself. + +template +inline T* _sm_var(sm_state* state, U name, T init) +{ + auto val = &state->current->user.data[name]; + bool set = val->set; + val->set = true; + val->free = false; + return ( ! set ) ? + _sm_init(val, init) : + _sm_get(val); +} +template +inline T* _sm_var(sm_state* state, T init) +{ + static_assert(name < _SM_STACK_SIZE, "Line pseudo-hashmap not yet implemented"); + return _sm_var(state, name, init); +} + +// Pop the current stack frame, and re-set the pointer to the previous one. +void _sm_pop_stack(sm_state* state); + +sm_yield _sm_noop(sm_state*); + +inline sm_yield sm_end() { return (sm_yield)nullptr; } +inline sm_yield sm_continue() { return (sm_yield)_sm_noop; } + +#define SM_VAR_EX(name, init) _sm_var(state, (name), (init)) //TODO: Replace `name' with (__LINE__ % _SM_STACK_SIZE) pseudo-hashmap +#define SM_VAR(init) _sm_var<__LINE__, decltype(init)>(state, (init)) + +#define SM_BEGIN switch(state->current->pc) { case 0: +#define SM_END } _sm_pop_stack(state); return sm_end() + +#define SM_YIELD(v) do { state->current->pc = __LINE__; return (sm_yield)(v); case __LINE__:; } while(0) + diff --git a/src/main.cpp b/src/main.cpp index c88510a..0340cff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,28 @@ -#include +#include #include struct _test { int a, b; }; +sm_yield sm_test(sm_state* state) +{ + int* a = SM_VAR(10); + + SM_BEGIN; + SM_YIELD(sm_continue()); + *a = 5; + SM_YIELD(sm_continue()); + *a = 0; + SM_END; +} + int main() { + + //TODO: `sm_state` creation/initialisation & freeing functions + //TODO: Test `sm_test` + _test hi = { 0, 0 }; auto _a = _sm_init(nullptr, hi); diff --git a/src/state.cpp b/src/state.cpp new file mode 100644 index 0000000..882aaa6 --- /dev/null +++ b/src/state.cpp @@ -0,0 +1,6 @@ +#include + +sm_yield _sm_noop(sm_state*) +{ + return (sm_yield)nullptr; +}