From 0cd51937eaa2b0cc3d2da98aafc1f951728ff939 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 12 Nov 2025 11:10:14 +0100 Subject: [PATCH 01/15] Initial work on making primitives a vector in the interpreter --- src/Debug/debugger.cpp | 4 +- src/Interpreter/interpreter.h | 57 +++++++++++++++ src/Primitives/emulated.cpp | 127 ++-------------------------------- src/Primitives/primitives.h | 74 ++++++++++++++++---- src/WARDuino.h | 16 ----- src/WARDuino/WARDuino.cpp | 14 ++-- src/WARDuino/internals.h | 16 +++++ 7 files changed, 146 insertions(+), 162 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index bafa6957..61e672ac 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -922,7 +922,7 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray, this->channel->write("%s", addComma ? "," : ""); this->channel->write("\"io\": ["); bool comma = false; - std::vector external_state = get_io_state(m); + std::vector external_state = m->warduino->interpreter->get_io_state(m); for (auto state_elem : external_state) { this->channel->write("%s{", comma ? ", " : ""); this->channel->write( @@ -1383,7 +1383,7 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { state_elem.output ? "output" : "input", state_elem.value); } - restore_external_state(m, external_state); + m->warduino->interpreter->restore_external_state(m, external_state); break; } case overridesState: { diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index d11260d3..0d246cc7 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -1,8 +1,10 @@ #pragma once #include +#include #include "../WARDuino/internals.h" +//#include "../Utils/macros.h" class Interpreter { public: @@ -54,6 +56,61 @@ class Interpreter { static void report_overflow(Module *m, uint8_t *maddr); + void register_primitive(const PrimitiveEntry &entry) { + primitives.push_back(entry); + } + + //------------------------------------------------------ + // resolving the primitives + //------------------------------------------------------ + // ReSharper disable once CppDFAConstantFunctionResult + bool resolve_primitive(const char *symbol, Primitive *val) { + //debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + + for (auto &primitive : primitives) { + // printf("Checking %s = %s \n", symbol, primitive.name); + if (!strcmp(symbol, primitive.name)) { + //debug("FOUND PRIMITIVE\n"); + *val = primitive.f; + return true; + } + } + //FATAL("Could not find primitive %s \n", symbol); + return false; + // return false; // unreachable + } + + //------------------------------------------------------ + // Restore external state when restoring a snapshot + //------------------------------------------------------ + void restore_external_state(Module *m, + const std::vector &external_state) { + std::set prim_names; + for (uint32_t i = 0; i < m->import_count; i++) { + prim_names.emplace(m->functions[i].import_field); + } + + for (PrimitiveEntry &p : primitives) { + if (prim_names.find(p.name) != prim_names.end()) { + if (p.f_reverse) { + printf("EMU: Reversing state for primitive %s\n", p.name); + p.f_reverse(m, external_state); + } + } + } + } + + std::vector get_io_state(Module *) const { + std::vector ioState; + for (auto &primitive : primitives) { + if (primitive.f_serialize_state) { + primitive.f_serialize_state(ioState); + } + } + return ioState; + } + protected: private: + std::vector primitives; }; diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index cfcd171b..07e2ef9d 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -27,77 +27,6 @@ #include "../WARDuino/CallbackHandler.h" #include "primitives.h" -#define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 37 - -#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) - -// Global index for installing primitives -int prim_index = 0; - -double sensor_emu = 0; - -/* - Private macros to install a primitive -*/ -#define install_primitive(prim_name) \ - { \ - dbg_info("installing primitive number: %d of %d with name: %s\n", \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \ - if (prim_index < ALL_PRIMITIVES) { \ - PrimitiveEntry *p = &primitives[prim_index++]; \ - p->name = #prim_name; \ - p->t = &(prim_name##_type); \ - p->f = &(prim_name); \ - p->f_reverse = nullptr; \ - p->f_serialize_state = nullptr; \ - } else { \ - FATAL("prim_index out of bounds"); \ - } \ - } - -#define install_primitive_reverse(prim_name) \ - { \ - PrimitiveEntry *p = &primitives[prim_index - 1]; \ - p->f_reverse = &(prim_name##_reverse); \ - p->f_serialize_state = &(prim_name##_serialize); \ - } - -#define def_prim(function_name, type) \ - Type function_name##_type = type; \ - bool function_name([[maybe_unused]] Module *m) - -#define def_prim_reverse(function_name) \ - void function_name##_reverse(Module *m, \ - std::vector external_state) - -#define def_prim_serialize(function_name) \ - void function_name##_serialize( \ - std::vector &external_state) - -// TODO: use fp -#define pop_args(n) m->sp -= n -#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value -#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg -#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg -#define pushUInt64(arg) \ - m->stack[++m->sp].value_type = I64; \ - m->stack[m->sp].value.uint64 = arg -#define arg0 get_arg(m, 0) -#define arg1 get_arg(m, 1) -#define arg2 get_arg(m, 2) -#define arg3 get_arg(m, 3) -#define arg4 get_arg(m, 4) -#define arg5 get_arg(m, 5) -#define arg6 get_arg(m, 6) -#define arg7 get_arg(m, 7) -#define arg8 get_arg(m, 8) -#define arg9 get_arg(m, 9) - -// The primitive table -PrimitiveEntry primitives[ALL_PRIMITIVES]; - -// uint32_t param_arr_len0[0] = {}; uint32_t param_I32_arr_len1[1] = {I32}; uint32_t param_I32_arr_len2[2] = {I32, I32}; @@ -220,6 +149,8 @@ Type NoneToOneU64 = {.form = FUNC, .results = param_I64_arr_len1, .mask = 0x82000}; +double sensor_emu = 0; + def_prim(init_pixels, NoneToNoneU32) { printf("init_pixels \n"); return true; @@ -634,7 +565,7 @@ def_prim(chip_ledc_attach_pin, twoToNoneU32) { //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ -void install_primitives() { +void install_primitives(Interpreter *interpreter) { dbg_info("INSTALLING PRIMITIVES\n"); dbg_info("INSTALLING FAKE ARDUINO\n"); install_primitive(abort); @@ -653,8 +584,7 @@ void install_primitives() { install_primitive(http_post); install_primitive(chip_pin_mode); - install_primitive(chip_digital_write); - install_primitive_reverse(chip_digital_write); + install_reversible_primitive(chip_digital_write); install_primitive(chip_delay); install_primitive(chip_digital_read); install_primitive(chip_analog_read); @@ -688,25 +618,6 @@ void install_primitives() { install_primitive(ev3_touch_sensor); } -//------------------------------------------------------ -// resolving the primitives -//------------------------------------------------------ -// ReSharper disable once CppDFAConstantFunctionResult -bool resolve_primitive(char *symbol, Primitive *val) { - debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); - - for (auto &primitive : primitives) { - // printf("Checking %s = %s \n", symbol, primitive.name); - if (!strcmp(symbol, primitive.name)) { - debug("FOUND PRIMITIVE\n"); - *val = primitive.f; - return true; - } - } - FATAL("Could not find primitive %s \n", symbol); - // return false; // unreachable -} - Memory external_mem{}; // ReSharper disable once CppDFAConstantFunctionResult @@ -728,34 +639,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { // return false; // unreachable } -//------------------------------------------------------ -// Restore external state when restoring a snapshot -//------------------------------------------------------ -void restore_external_state(Module *m, - const std::vector &external_state) { - std::set prim_names; - for (uint32_t i = 0; i < m->import_count; i++) { - prim_names.emplace(m->functions[i].import_field); - } - - for (PrimitiveEntry &p : primitives) { - if (prim_names.find(p.name) != prim_names.end()) { - if (p.f_reverse) { - printf("EMU: Reversing state for primitive %s\n", p.name); - p.f_reverse(m, external_state); - } - } - } -} - -std::vector get_io_state(Module *) { - std::vector ioState; - for (auto &primitive : primitives) { - if (primitive.f_serialize_state) { - primitive.f_serialize_state(ioState); - } - } - return ioState; -} - #endif // ARDUINO diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 0a9509e9..67f5c85a 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -1,18 +1,8 @@ #ifndef WARDUINO_PRIM_H #define WARDUINO_PRIM_H -#include "../Utils/macros.h" #include "../WARDuino.h" -/** - * Find a primitive function by looking it up - * - * @param symbol name of primitive function - * @param val location to store a pointer to the function - * @return true if function is found and assigned to val - */ -bool resolve_primitive(char *symbol, Primitive *val); - /** * Handle import of memory by keeping a array of 256 pages. * If more imports of memory are needed, this should be replaced by a @@ -25,12 +15,12 @@ bool resolve_primitive(char *symbol, Primitive *val); */ bool resolve_external_memory(char *symbol, Memory **val); -void install_primitives(); +void install_primitives(Interpreter *interpreter); -std::vector get_io_state(Module *m); +/*std::vector get_io_state(Module *m); void restore_external_state(Module *m, - const std::vector &external_state); + const std::vector &external_state);*/ inline void create_stack(std::vector *) {} @@ -70,7 +60,7 @@ void create_stack(std::vector *stack, T value, Ts... args) { template void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { Primitive primitive; - resolve_primitive((char *)function_name.c_str(), &primitive); + m->warduino->interpreter->resolve_primitive(function_name.c_str(), &primitive); std::vector argStack; create_stack(&argStack, args...); @@ -81,4 +71,60 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { primitive(m); } +#define _install_primitive(prim_name) \ + /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/\ + PrimitiveEntry p; \ + p.name = #prim_name; \ + p.t = &(prim_name##_type); \ + p.f = &(prim_name); \ + p.f_reverse = nullptr; \ + p.f_serialize_state = nullptr; \ + interpreter->register_primitive(p); \ + +#define install_primitive(prim_name) \ +{ \ + /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/\ + _install_primitive(prim_name) \ +} + +#define install_reversible_primitive(prim_name) \ +{ \ + _install_primitive(prim_name) \ + p.f_reverse = &(prim_name##_reverse); \ + p.f_serialize_state = &(prim_name##_serialize); \ +} + +#define def_prim(function_name, type) \ + Type function_name##_type = type; \ + bool function_name([[maybe_unused]] Module *m) + +#define def_prim_reverse(function_name) \ + void function_name##_reverse(Module *m, \ + std::vector external_state) + +#define def_prim_serialize(function_name) \ + void function_name##_serialize( \ + std::vector &external_state) + +// TODO: use fp +#define pop_args(n) m->sp -= n +#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value +#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg +#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg +#define pushUInt64(arg) \ + m->stack[++m->sp].value_type = I64; \ + m->stack[m->sp].value.uint64 = arg +#define arg0 get_arg(m, 0) +#define arg1 get_arg(m, 1) +#define arg2 get_arg(m, 2) +#define arg3 get_arg(m, 3) +#define arg4 get_arg(m, 4) +#define arg5 get_arg(m, 5) +#define arg6 get_arg(m, 6) +#define arg7 get_arg(m, 7) +#define arg8 get_arg(m, 8) +#define arg9 get_arg(m, 9) + #endif diff --git a/src/WARDuino.h b/src/WARDuino.h index 2069eda6..92ba863e 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -63,22 +63,6 @@ extern char exception[512]; void skip_immediates(uint8_t **pos); -typedef bool (*Primitive)(Module *); - -struct IOStateElement { - std::string key; - bool output; - int value; -}; - -typedef struct PrimitiveEntry { - const char *name; - Primitive f; - void (*f_reverse)(Module *m, std::vector); - void (*f_serialize_state)(std::vector &); - Type *t; -} PrimitiveEntry; - class WARDuino { private: static WARDuino *singleton; diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index ae41c1fe..8707555a 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -16,13 +16,13 @@ char exception[512]; // UTIL -bool resolvesym(char *filename, char *symbol, uint8_t external_kind, void **val, +bool resolvesym(Interpreter *interpreter, char *filename, char *symbol, uint8_t external_kind, void **val, char **err) { if (nullptr != filename && !strcmp(filename, "env")) { switch (external_kind) { case 0x00: // Function { - return resolve_primitive(symbol, (Primitive *)val); + return interpreter->resolve_primitive(symbol, (Primitive *)val); break; } case 0x01: // Table @@ -435,7 +435,7 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, // TODO add special case form primitives with resolvePrim do { // Try using module as handle filename - if (resolvesym(import_module, import_field, + if (resolvesym(m->warduino->interpreter, import_module, import_field, external_kind, &val, &err)) { break; } @@ -449,7 +449,7 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, sym[sidx] = '_'; } } - if (resolvesym(nullptr, sym, external_kind, &val, + if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, &err)) { break; } @@ -460,7 +460,7 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, (strncmp("env", import_module, 4) == 0) && (strncmp("_", import_field, 1) == 0)) { sprintf(sym, "%s", import_field + 1); - if (resolvesym(nullptr, sym, external_kind, &val, + if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, &err)) { break; } @@ -469,7 +469,7 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, // Try the plain symbol by itself with module // name/handle sprintf(sym, "%s", import_field); - if (resolvesym(nullptr, sym, external_kind, &val, + if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, &err)) { break; } @@ -894,7 +894,7 @@ void WARDuino::unload_module(Module *m) { WARDuino::WARDuino() { this->debugger = new Debugger(0); this->interpreter = new Interpreter(); - install_primitives(); + install_primitives(this->interpreter); initTypes(); } diff --git a/src/WARDuino/internals.h b/src/WARDuino/internals.h index d0f6b263..a22952ce 100644 --- a/src/WARDuino/internals.h +++ b/src/WARDuino/internals.h @@ -130,3 +130,19 @@ typedef struct Module { char *exception = nullptr; // exception is set when the program fails } Module; + +typedef bool (*Primitive)(Module *); + +struct IOStateElement { + std::string key; + bool output; + int value; +}; + +typedef struct PrimitiveEntry { + const char *name; + Primitive f; + void (*f_reverse)(Module *m, std::vector); + void (*f_serialize_state)(std::vector &); + Type *t; +} PrimitiveEntry; From 3aa599396656323b50eb3b40256a0803ecad44cf Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 15:25:27 +0100 Subject: [PATCH 02/15] Also move types into primitives.h --- src/Debug/debugger.cpp | 1 - src/Primitives/emulated.cpp | 123 ------------------------------------ src/Primitives/primitives.h | 123 +++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 125 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 61e672ac..3d949758 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -11,7 +11,6 @@ #endif #include "../Memory/mem.h" -#include "../Primitives/primitives.h" #include "../Utils//util.h" #include "../Utils/macros.h" #include "../WARDuino/CallbackHandler.h" diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 07e2ef9d..d1424d67 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -1,4 +1,3 @@ -#include "../Interpreter/instructions.h" #ifndef ARDUINO /** @@ -27,128 +26,6 @@ #include "../WARDuino/CallbackHandler.h" #include "primitives.h" -uint32_t param_arr_len0[0] = {}; -uint32_t param_I32_arr_len1[1] = {I32}; -uint32_t param_I32_arr_len2[2] = {I32, I32}; -uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; -uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; -uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, - I32, I32, I32, I32, I32}; - -uint32_t param_I64_arr_len1[1] = {I64}; - -Type oneToNoneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 0, - .results = nullptr, - .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ -}; - -Type twoToNoneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 0, - .results = nullptr, - .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ -}; - -Type threeToNoneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 0, - .results = nullptr, - .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToNoneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 0, - .results = nullptr, - .mask = - 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ -}; - -Type oneToOneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type oneToOneI32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type twoToOneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type threeToOneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToOneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ -}; - -Type tenToOneU32 = { - .form = FUNC, - .param_count = 10, - .params = param_I32_arr_len10, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ -}; - -Type NoneToNoneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 0, - .results = nullptr, - .mask = 0x80000}; - -Type NoneToOneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81000}; - -Type NoneToOneU64 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I64_arr_len1, - .mask = 0x82000}; - double sensor_emu = 0; def_prim(init_pixels, NoneToNoneU32) { diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 67f5c85a..2a747901 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -1,7 +1,7 @@ #ifndef WARDUINO_PRIM_H #define WARDUINO_PRIM_H -#include "../WARDuino.h" +#include "../WARDuino/internals.h" /** * Handle import of memory by keeping a array of 256 pages. @@ -127,4 +127,125 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { #define arg8 get_arg(m, 8) #define arg9 get_arg(m, 9) +inline uint32_t param_arr_len0[0] = {}; +inline uint32_t param_I32_arr_len1[1] = {I32}; +inline uint32_t param_I32_arr_len2[2] = {I32, I32}; +inline uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; +inline uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; +inline uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, + I32, I32, I32, I32, I32}; +inline uint32_t param_I64_arr_len1[1] = {I64}; + +inline Type oneToNoneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 0, + .results = nullptr, + .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ +}; + +inline Type twoToNoneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 0, + .results = nullptr, + .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ +}; + +inline Type threeToNoneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 0, + .results = nullptr, + .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ +}; + +inline Type fourToNoneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 0, + .results = nullptr, + .mask = + 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ +}; + +inline Type oneToOneU32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +inline Type oneToOneI32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +inline Type twoToOneU32 = { + .form = FUNC, + .param_count = 2, + .params = param_I32_arr_len2, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ +}; + +inline Type threeToOneU32 = { + .form = FUNC, + .param_count = 3, + .params = param_I32_arr_len3, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ +}; + +inline Type fourToOneU32 = { + .form = FUNC, + .param_count = 4, + .params = param_I32_arr_len4, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ +}; + +inline Type tenToOneU32 = { + .form = FUNC, + .param_count = 10, + .params = param_I32_arr_len10, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ +}; + +inline Type NoneToNoneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 0, + .results = nullptr, + .mask = 0x80000}; + +inline Type NoneToOneU32 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81000}; + +inline Type NoneToOneU64 = {.form = FUNC, + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I64_arr_len1, + .mask = 0x82000}; + #endif From 334e9fe18c5838dcd6f98eafa328f020b99b4eba Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 15:26:25 +0100 Subject: [PATCH 03/15] clang-format --- src/Debug/debugger.cpp | 6 ++- src/Interpreter/interpreter.h | 12 +++--- src/Primitives/primitives.h | 81 +++++++++++++++++------------------ src/WARDuino/WARDuino.cpp | 21 ++++----- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/src/Debug/debugger.cpp b/src/Debug/debugger.cpp index 3d949758..a7ce896f 100644 --- a/src/Debug/debugger.cpp +++ b/src/Debug/debugger.cpp @@ -921,7 +921,8 @@ void Debugger::inspect(Module *m, const uint16_t sizeStateArray, this->channel->write("%s", addComma ? "," : ""); this->channel->write("\"io\": ["); bool comma = false; - std::vector external_state = m->warduino->interpreter->get_io_state(m); + std::vector external_state = + m->warduino->interpreter->get_io_state(m); for (auto state_elem : external_state) { this->channel->write("%s{", comma ? ", " : ""); this->channel->write( @@ -1382,7 +1383,8 @@ bool Debugger::saveState(Module *m, uint8_t *interruptData) { state_elem.output ? "output" : "input", state_elem.value); } - m->warduino->interpreter->restore_external_state(m, external_state); + m->warduino->interpreter->restore_external_state( + m, external_state); break; } case overridesState: { diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index 0d246cc7..839cf5f5 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -4,7 +4,7 @@ #include #include "../WARDuino/internals.h" -//#include "../Utils/macros.h" +// #include "../Utils/macros.h" class Interpreter { public: @@ -65,17 +65,17 @@ class Interpreter { //------------------------------------------------------ // ReSharper disable once CppDFAConstantFunctionResult bool resolve_primitive(const char *symbol, Primitive *val) { - //debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + // debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); for (auto &primitive : primitives) { // printf("Checking %s = %s \n", symbol, primitive.name); if (!strcmp(symbol, primitive.name)) { - //debug("FOUND PRIMITIVE\n"); + // debug("FOUND PRIMITIVE\n"); *val = primitive.f; return true; } } - //FATAL("Could not find primitive %s \n", symbol); + // FATAL("Could not find primitive %s \n", symbol); return false; // return false; // unreachable } @@ -83,8 +83,8 @@ class Interpreter { //------------------------------------------------------ // Restore external state when restoring a snapshot //------------------------------------------------------ - void restore_external_state(Module *m, - const std::vector &external_state) { + void restore_external_state( + Module *m, const std::vector &external_state) { std::set prim_names; for (uint32_t i = 0; i < m->import_count; i++) { prim_names.emplace(m->functions[i].import_field); diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 2a747901..210a8378 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -20,7 +20,8 @@ void install_primitives(Interpreter *interpreter); /*std::vector get_io_state(Module *m); void restore_external_state(Module *m, - const std::vector &external_state);*/ + const std::vector +&external_state);*/ inline void create_stack(std::vector *) {} @@ -60,7 +61,8 @@ void create_stack(std::vector *stack, T value, Ts... args) { template void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { Primitive primitive; - m->warduino->interpreter->resolve_primitive(function_name.c_str(), &primitive); + m->warduino->interpreter->resolve_primitive(function_name.c_str(), + &primitive); std::vector argStack; create_stack(&argStack, args...); @@ -71,30 +73,27 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { primitive(m); } -#define _install_primitive(prim_name) \ +#define _install_primitive(prim_name) \ /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/\ - PrimitiveEntry p; \ - p.name = #prim_name; \ - p.t = &(prim_name##_type); \ - p.f = &(prim_name); \ - p.f_reverse = nullptr; \ - p.f_serialize_state = nullptr; \ - interpreter->register_primitive(p); \ - -#define install_primitive(prim_name) \ -{ \ - /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/\ - _install_primitive(prim_name) \ -} - -#define install_reversible_primitive(prim_name) \ -{ \ - _install_primitive(prim_name) \ - p.f_reverse = &(prim_name##_reverse); \ - p.f_serialize_state = &(prim_name##_serialize); \ -} + prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ + PrimitiveEntry p; \ + p.name = #prim_name; \ + p.t = &(prim_name##_type); \ + p.f = &(prim_name); \ + p.f_reverse = nullptr; \ + p.f_serialize_state = nullptr; \ + interpreter->register_primitive(p); + +#define install_primitive(prim_name) \ + {/*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ + _install_primitive(prim_name)} + +#define install_reversible_primitive(prim_name) \ + { \ + _install_primitive(prim_name) p.f_reverse = &(prim_name##_reverse); \ + p.f_serialize_state = &(prim_name##_serialize); \ + } #define def_prim(function_name, type) \ Type function_name##_type = type; \ @@ -133,7 +132,7 @@ inline uint32_t param_I32_arr_len2[2] = {I32, I32}; inline uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; inline uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; inline uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, - I32, I32, I32, I32, I32}; + I32, I32, I32, I32, I32}; inline uint32_t param_I64_arr_len1[1] = {I64}; inline Type oneToNoneU32 = { @@ -228,24 +227,24 @@ inline Type tenToOneU32 = { }; inline Type NoneToNoneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 0, - .results = nullptr, - .mask = 0x80000}; + .param_count = 0, + .params = nullptr, + .result_count = 0, + .results = nullptr, + .mask = 0x80000}; inline Type NoneToOneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81000}; + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I32_arr_len1, + .mask = 0x81000}; inline Type NoneToOneU64 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I64_arr_len1, - .mask = 0x82000}; + .param_count = 0, + .params = nullptr, + .result_count = 1, + .results = param_I64_arr_len1, + .mask = 0x82000}; #endif diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 8707555a..6bf005e5 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -16,8 +16,8 @@ char exception[512]; // UTIL -bool resolvesym(Interpreter *interpreter, char *filename, char *symbol, uint8_t external_kind, void **val, - char **err) { +bool resolvesym(Interpreter *interpreter, char *filename, char *symbol, + uint8_t external_kind, void **val, char **err) { if (nullptr != filename && !strcmp(filename, "env")) { switch (external_kind) { case 0x00: // Function @@ -435,8 +435,9 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, // TODO add special case form primitives with resolvePrim do { // Try using module as handle filename - if (resolvesym(m->warduino->interpreter, import_module, import_field, - external_kind, &val, &err)) { + if (resolvesym(m->warduino->interpreter, import_module, + import_field, external_kind, &val, + &err)) { break; } @@ -449,8 +450,8 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, sym[sidx] = '_'; } } - if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, - &err)) { + if (resolvesym(m->warduino->interpreter, nullptr, sym, + external_kind, &val, &err)) { break; } @@ -460,8 +461,8 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, (strncmp("env", import_module, 4) == 0) && (strncmp("_", import_field, 1) == 0)) { sprintf(sym, "%s", import_field + 1); - if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, - &err)) { + if (resolvesym(m->warduino->interpreter, nullptr, + sym, external_kind, &val, &err)) { break; } } @@ -469,8 +470,8 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, // Try the plain symbol by itself with module // name/handle sprintf(sym, "%s", import_field); - if (resolvesym(m->warduino->interpreter, nullptr, sym, external_kind, &val, - &err)) { + if (resolvesym(m->warduino->interpreter, nullptr, sym, + external_kind, &val, &err)) { break; } From 19b5d611c6f8276372e02cc31072a22e59e34567 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 15:32:59 +0100 Subject: [PATCH 04/15] Remove duplicate pushUInt32 definition --- src/WARDuino/WARDuino.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 6bf005e5..2268b06c 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -11,7 +11,6 @@ #include "../Utils/util.h" #define UNDEF (uint32_t)(-1) -#define pushUInt32(m, arg) m->stack[++(m)->sp].value.uint32 = arg char exception[512]; From 085fb19862eeaf680d3ad21c2ada344f807fcdbe Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 16:16:33 +0100 Subject: [PATCH 05/15] Init PrimitiveEntry p --- src/Primitives/primitives.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 210a8378..203b029d 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -60,9 +60,12 @@ void create_stack(std::vector *stack, T value, Ts... args) { template void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { - Primitive primitive; - m->warduino->interpreter->resolve_primitive(function_name.c_str(), - &primitive); + Primitive primitive = {}; + if (!m->warduino->interpreter->resolve_primitive(function_name.c_str(), + &primitive)) { + printf("Failed to resolve primitive %s\n", function_name.c_str()); + return; + } std::vector argStack; create_stack(&argStack, args...); @@ -76,7 +79,7 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { #define _install_primitive(prim_name) \ /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ - PrimitiveEntry p; \ + PrimitiveEntry p = {}; \ p.name = #prim_name; \ p.t = &(prim_name##_type); \ p.f = &(prim_name); \ From ae4fb1ca68bba061afa20cb0ccce1511052d7d15 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 16:26:51 +0100 Subject: [PATCH 06/15] Fix missing vector and string includes --- src/WARDuino/internals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WARDuino/internals.h b/src/WARDuino/internals.h index a22952ce..a4b9e5a7 100644 --- a/src/WARDuino/internals.h +++ b/src/WARDuino/internals.h @@ -1,5 +1,7 @@ #pragma once #include +#include +#include // Structures typedef struct Type { From 2076779550efa2e12466425736473257ef5b9d84 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 16:28:36 +0100 Subject: [PATCH 07/15] Fix missing cstring include --- src/Interpreter/interpreter.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index 839cf5f5..c9329ebc 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include "../WARDuino/internals.h" From b7cd6d3ab2645f0d586185ada848aebe408b6cdd Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 16:42:14 +0100 Subject: [PATCH 08/15] Remove duplicate code from arduino.cpp --- src/Primitives/arduino.cpp | 257 +------------------------------------ 1 file changed, 2 insertions(+), 255 deletions(-) diff --git a/src/Primitives/arduino.cpp b/src/Primitives/arduino.cpp index f66ed4d8..50ade8ad 100644 --- a/src/Primitives/arduino.cpp +++ b/src/Primitives/arduino.cpp @@ -129,199 +129,6 @@ int resolve_isr(int pin) { return -1; } -// Primitives - -#define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 38 - -#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) - -// Global index for installing primitives -int prim_index = 0; - -/* - Private macros to install a primitive -*/ -#define install_primitive(prim_name) \ - { \ - dbg_info("installing primitive number: %d of %d with name: %s\n", \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \ - if (prim_index < ALL_PRIMITIVES) { \ - PrimitiveEntry *p = &primitives[prim_index++]; \ - p->name = #prim_name; \ - p->t = &(prim_name##_type); \ - p->f = &(prim_name); \ - p->f_reverse = nullptr; \ - p->f_serialize_state = nullptr; \ - } else { \ - FATAL("prim_index out of bounds"); \ - } \ - } - -#define install_primitive_reverse(prim_name) \ - { \ - PrimitiveEntry *p = &primitives[prim_index - 1]; \ - p->f_reverse = &(prim_name##_reverse); \ - p->f_serialize_state = &(prim_name##_serialize); \ - } - -#define def_prim(function_name, type) \ - Type function_name##_type = type; \ - bool function_name(Module *m) - -#define def_prim_reverse(function_name) \ - void function_name##_reverse(Module *m, \ - std::vector external_state) - -#define def_prim_serialize(function_name) \ - void function_name##_serialize( \ - std::vector &external_state) - -// TODO: use fp -#define pop_args(n) m->sp -= n -#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value -#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg -#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg -#define pushUInt64(arg) \ - m->stack[++m->sp].value_type = I64; \ - m->stack[m->sp].value.uint64 = arg -#define arg0 get_arg(m, 0) -#define arg1 get_arg(m, 1) -#define arg2 get_arg(m, 2) -#define arg3 get_arg(m, 3) -#define arg4 get_arg(m, 4) -#define arg5 get_arg(m, 5) -#define arg6 get_arg(m, 6) -#define arg7 get_arg(m, 7) -#define arg8 get_arg(m, 8) -#define arg9 get_arg(m, 9) - -// The primitive table -PrimitiveEntry primitives[ALL_PRIMITIVES]; - -// -uint32_t param_arr_len0[0] = {}; -uint32_t param_I32_arr_len1[1] = {I32}; -uint32_t param_I32_arr_len2[2] = {I32, I32}; -uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; -uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; -uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, - I32, I32, I32, I32, I32}; - -uint32_t param_I64_arr_len1[1] = {I64}; - -Type oneToNoneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 0, - .results = nullptr, - .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ -}; - -Type twoToNoneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 0, - .results = nullptr, - .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ -}; - -Type threeToNoneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 0, - .results = nullptr, - .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToNoneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 0, - .results = nullptr, - .mask = - 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ -}; - -Type oneToOneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type oneToOneI32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type twoToOneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type threeToOneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToOneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ -}; - -Type tenToOneU32 = { - .form = FUNC, - .param_count = 10, - .params = param_I32_arr_len10, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ -}; - -Type NoneToNoneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 0, - .results = nullptr, - .mask = 0x80000}; - -Type NoneToOneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81000}; - -Type NoneToOneU64 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I64_arr_len1, - .mask = 0x82000}; - // Util function declarations void connect(const String ssid, const String password); @@ -983,7 +790,7 @@ void install_isrs() { install_isr(39); } -void install_primitives() { +void install_primitives(Interpreter *interpreter) { dbg_info("INSTALLING PRIMITIVES\n"); install_primitive(abort); install_primitive(millis); @@ -1001,8 +808,7 @@ void install_primitives() { install_primitive(http_post); install_primitive(chip_pin_mode); - install_primitive(chip_digital_write); - install_primitive_reverse(chip_digital_write); + install_reversible_primitive(chip_digital_write); install_primitive(chip_delay); install_primitive(chip_digital_read); install_primitive(chip_analog_read); @@ -1038,24 +844,6 @@ void install_primitives() { install_isrs(); } -//------------------------------------------------------ -// resolving the primitives -//------------------------------------------------------ -bool resolve_primitive(char *symbol, Primitive *val) { - debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); - - for (auto &primitive : primitives) { - // printf("Checking %s = %s \n", symbol, primitive.name); - if (!strcmp(symbol, primitive.name)) { - debug("FOUND PRIMITIVE\n"); - *val = primitive.f; - return true; - } - } - FATAL("Could not find primitive %s \n", symbol); - return false; -} - Memory external_mem{}; bool resolve_external_memory(char *symbol, Memory **val) { @@ -1075,44 +863,3 @@ bool resolve_external_memory(char *symbol, Memory **val) { FATAL("Could not find memory %s \n", symbol); return false; } - -//------------------------------------------------------ -// Restore external state when restoring a snapshot -//------------------------------------------------------ -void restore_external_state(Module *m, - const std::vector &external_state) { - uint8_t opcode = *m->pc_ptr; - // TODO: Maybe primitives can also be called using the other call - // instructions such as call_indirect - // maybe there should just be a function that checks if a certain function - // is being called that handles all these cases? - if (opcode == 0x10) { // call opcode - uint8_t *pc_copy = m->pc_ptr + 1; - uint32_t fidx = read_LEB_32(&pc_copy); - if (fidx < m->import_count) { - for (auto &primitive : primitives) { - if (!strcmp(primitive.name, m->functions[fidx].import_field)) { - if (primitive.f_reverse) { - debug("Reversing action for primitive %s\n", - primitive.name); - primitive.f_reverse(m, external_state); - } - return; - } - } - } - } -} - -//------------------------------------------------------ -// Serialize external state into a snapshot -//------------------------------------------------------ -std::vector get_io_state(Module *m) { - std::vector ioState; - for (auto &primitive : primitives) { - if (primitive.f_serialize_state) { - primitive.f_serialize_state(ioState); - } - } - return ioState; -} From 34bac328731743da8d96fc437261d7b2fc562f2b Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 16:56:46 +0100 Subject: [PATCH 09/15] Remove duplicate code for ESP-IDF --- src/Primitives/idf.cpp | 251 +---------------------------------------- 1 file changed, 1 insertion(+), 250 deletions(-) diff --git a/src/Primitives/idf.cpp b/src/Primitives/idf.cpp index bcba2739..f7fe412a 100644 --- a/src/Primitives/idf.cpp +++ b/src/Primitives/idf.cpp @@ -27,199 +27,6 @@ #include "driver/gpio.h" #include "primitives.h" -#define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 4 - -#define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) - -// Global index for installing primitives -int prim_index = 0; - -double sensor_emu = 0; - -/* - Private macros to install a primitive -*/ -#define install_primitive(prim_name) \ - { \ - dbg_info("installing primitive number: %d of %d with name: %s\n", \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \ - if (prim_index < ALL_PRIMITIVES) { \ - PrimitiveEntry *p = &primitives[prim_index++]; \ - p->name = #prim_name; \ - p->t = &(prim_name##_type); \ - p->f = &(prim_name); \ - p->f_reverse = nullptr; \ - p->f_serialize_state = nullptr; \ - } else { \ - FATAL("prim_index out of bounds"); \ - } \ - } - -#define install_primitive_reverse(prim_name) \ - { \ - PrimitiveEntry *p = &primitives[prim_index - 1]; \ - p->f_reverse = &(prim_name##_reverse); \ - p->f_serialize_state = &(prim_name##_serialize); \ - } - -#define def_prim(function_name, type) \ - Type function_name##_type = type; \ - bool function_name(Module *m) - -#define def_prim_reverse(function_name) \ - void function_name##_reverse(Module *m, \ - std::vector external_state) - -#define def_prim_serialize(function_name) \ - void function_name##_serialize( \ - std::vector &external_state) - -// TODO: use fp -#define pop_args(n) m->sp -= n -#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value -#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg -#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg -#define pushUInt64(arg) \ - m->stack[++m->sp].value_type = I64; \ - m->stack[m->sp].value.uint64 = arg -#define arg0 get_arg(m, 0) -#define arg1 get_arg(m, 1) -#define arg2 get_arg(m, 2) -#define arg3 get_arg(m, 3) -#define arg4 get_arg(m, 4) -#define arg5 get_arg(m, 5) -#define arg6 get_arg(m, 6) -#define arg7 get_arg(m, 7) -#define arg8 get_arg(m, 8) -#define arg9 get_arg(m, 9) - -// The primitive table -PrimitiveEntry primitives[ALL_PRIMITIVES]; - -// -uint32_t param_arr_len0[0] = {}; -uint32_t param_I32_arr_len1[1] = {I32}; -uint32_t param_I32_arr_len2[2] = {I32, I32}; -uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; -uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; -uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, - I32, I32, I32, I32, I32}; - -uint32_t param_I64_arr_len1[1] = {I64}; - -Type oneToNoneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 0, - .results = nullptr, - .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ -}; - -Type twoToNoneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 0, - .results = nullptr, - .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ -}; - -Type threeToNoneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 0, - .results = nullptr, - .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToNoneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 0, - .results = nullptr, - .mask = - 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ -}; - -Type oneToOneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type oneToOneI32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type twoToOneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type threeToOneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToOneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ -}; - -Type tenToOneU32 = { - .form = FUNC, - .param_count = 10, - .params = param_I32_arr_len10, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ -}; - -Type NoneToNoneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 0, - .results = nullptr, - .mask = 0x80000}; - -Type NoneToOneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81000}; - -Type NoneToOneU64 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I64_arr_len1, - .mask = 0x82000}; - def_prim(chip_delay, oneToNoneU32) { vTaskDelay(arg0.uint32 / portTICK_PERIOD_MS); pop_args(1); @@ -249,7 +56,7 @@ def_prim(chip_digital_read, oneToOneU32) { //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ -void install_primitives() { +void install_primitives(Interpreter *interpreter) { dbg_info("INSTALLING PRIMITIVES\n"); install_primitive(chip_delay); install_primitive(chip_pin_mode); @@ -257,24 +64,6 @@ void install_primitives() { install_primitive(chip_digital_read); } -//------------------------------------------------------ -// resolving the primitives -//------------------------------------------------------ -bool resolve_primitive(char *symbol, Primitive *val) { - debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); - - for (auto &primitive : primitives) { - // printf("Checking %s = %s \n", symbol, primitive.name); - if (!strcmp(symbol, primitive.name)) { - debug("FOUND PRIMITIVE\n"); - *val = primitive.f; - return true; - } - } - FATAL("Could not find primitive %s \n", symbol); - return false; -} - Memory external_mem = {0, 0, 0, nullptr}; bool resolve_external_memory(char *symbol, Memory **val) { @@ -295,42 +84,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { return false; } -//------------------------------------------------------ -// Restore external state when restoring a snapshot -//------------------------------------------------------ -void restore_external_state(Module *m, - const std::vector &external_state) { - uint8_t opcode = *m->pc_ptr; - // TODO: Maybe primitives can also be called using the other call - // instructions such as call_indirect - // maybe there should just be a function that checks if a certain function - // is being called that handles all these cases? - if (opcode == 0x10) { // call opcode - uint8_t *pc_copy = m->pc_ptr + 1; - uint32_t fidx = read_LEB_32(&pc_copy); - if (fidx < m->import_count) { - for (auto &primitive : primitives) { - if (!strcmp(primitive.name, m->functions[fidx].import_field)) { - if (primitive.f_reverse) { - debug("Reversing action for primitive %s\n", - primitive.name); - primitive.f_reverse(m, external_state); - } - return; - } - } - } - } -} - -std::vector get_io_state(Module *m) { - std::vector ioState; - for (auto &primitive : primitives) { - if (primitive.f_serialize_state) { - primitive.f_serialize_state(ioState); - } - } - return ioState; -} - #endif // ARDUINO From c4e39071ffa7f11ee02fca60728ffc26be708a47 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Thu, 13 Nov 2025 17:05:06 +0100 Subject: [PATCH 10/15] Remove duplicate code for Zephyr --- src/Primitives/primitives.h | 9 ++ src/Primitives/zephyr.cpp | 260 +----------------------------------- 2 files changed, 12 insertions(+), 257 deletions(-) diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 203b029d..4abfd905 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -236,6 +236,15 @@ inline Type NoneToNoneU32 = {.form = FUNC, .results = nullptr, .mask = 0x80000}; +inline Type oneToNoneI32 = { + .form = FUNC, + .param_count = 1, + .params = param_I32_arr_len1, + .result_count = 0, + .results = nullptr, + .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ +}; + inline Type NoneToOneU32 = {.form = FUNC, .param_count = 0, .params = nullptr, diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 7e80619e..4f0ed3c6 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -33,209 +33,6 @@ #include "Mindstorms/uart_sensor.h" #include "primitives.h" -#define OBB_PRIMITIVES 0 -#ifdef CONFIG_BOARD_STM32L496G_DISCO -#define OBB_PRIMITIVES 8 -#endif -#define ALL_PRIMITIVES OBB_PRIMITIVES + 7 - -// Global index for installing primitives -int prim_index = 0; - -double sensor_emu = 0; - -/* - Private macros to install a primitive -*/ -#define install_primitive(prim_name) \ - { \ - dbg_info("installing primitive number: %d of %d with name: %s\n", \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \ - if (prim_index < ALL_PRIMITIVES) { \ - PrimitiveEntry *p = &primitives[prim_index++]; \ - p->name = #prim_name; \ - p->t = &(prim_name##_type); \ - p->f = &(prim_name); \ - p->f_reverse = nullptr; \ - p->f_serialize_state = nullptr; \ - } else { \ - FATAL("prim_index out of bounds"); \ - } \ - } - -#define install_primitive_reverse(prim_name) \ - { \ - PrimitiveEntry *p = &primitives[prim_index - 1]; \ - p->f_reverse = &(prim_name##_reverse); \ - p->f_serialize_state = &(prim_name##_serialize); \ - } - -#define def_prim(function_name, type) \ - Type function_name##_type = type; \ - bool function_name(Module *m) - -#define def_prim_reverse(function_name) \ - void function_name##_reverse(Module *m, \ - std::vector external_state) - -#define def_prim_serialize(function_name) \ - void function_name##_serialize( \ - std::vector &external_state) - -// TODO: use fp -#define pop_args(n) m->sp -= n -#define get_arg(m, arg) m->stack[(m)->sp - (arg)].value -#define pushUInt32(arg) m->stack[++m->sp].value.uint32 = arg -#define pushInt32(arg) m->stack[++m->sp].value.int32 = arg -#define pushUInt64(arg) \ - m->stack[++m->sp].value_type = I64; \ - m->stack[m->sp].value.uint64 = arg -#define arg0 get_arg(m, 0) -#define arg1 get_arg(m, 1) -#define arg2 get_arg(m, 2) -#define arg3 get_arg(m, 3) -#define arg4 get_arg(m, 4) -#define arg5 get_arg(m, 5) -#define arg6 get_arg(m, 6) -#define arg7 get_arg(m, 7) -#define arg8 get_arg(m, 8) -#define arg9 get_arg(m, 9) - -// The primitive table -PrimitiveEntry primitives[ALL_PRIMITIVES]; - -// -uint32_t param_arr_len0[0] = {}; -uint32_t param_I32_arr_len1[1] = {I32}; -uint32_t param_I32_arr_len2[2] = {I32, I32}; -uint32_t param_I32_arr_len3[3] = {I32, I32, I32}; -uint32_t param_I32_arr_len4[4] = {I32, I32, I32, I32}; -uint32_t param_I32_arr_len10[10] = {I32, I32, I32, I32, I32, - I32, I32, I32, I32, I32}; - -uint32_t param_I64_arr_len1[1] = {I64}; - -Type oneToNoneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 0, - .results = nullptr, - .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ -}; - -Type oneToNoneI32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 0, - .results = nullptr, - .mask = 0x8001 /* 0x800 = no return ; 1 = I32*/ -}; - -Type twoToNoneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 0, - .results = nullptr, - .mask = 0x80011 /* 0x800 = no return ; 1 = I32; 1 = I32*/ -}; - -Type threeToNoneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 0, - .results = nullptr, - .mask = 0x800111 /* 0x800 = no return ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToNoneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 0, - .results = nullptr, - .mask = - 0x8001111 /* 0x800 = no return ; 1 = I32; 1 = I32; 1 = I32; 1 = I32*/ -}; - -Type oneToOneU32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type oneToOneI32 = { - .form = FUNC, - .param_count = 1, - .params = param_I32_arr_len1, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x80011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type twoToOneU32 = { - .form = FUNC, - .param_count = 2, - .params = param_I32_arr_len2, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81011 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32*/ -}; - -Type threeToOneU32 = { - .form = FUNC, - .param_count = 3, - .params = param_I32_arr_len3, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x810111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32*/ -}; - -Type fourToOneU32 = { - .form = FUNC, - .param_count = 4, - .params = param_I32_arr_len4, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111 /* 0x8 1=I32 0=endRet ; 1=I32; 1=I32; 1=I32; 1=I32*/ -}; - -Type tenToOneU32 = { - .form = FUNC, - .param_count = 10, - .params = param_I32_arr_len10, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x8101111111111 /* 0x8 1=I32 0=endRet ; 10 params 1=I32*/ -}; - -Type NoneToNoneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 0, - .results = nullptr, - .mask = 0x80000}; - -Type NoneToOneU32 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I32_arr_len1, - .mask = 0x81000}; - -Type NoneToOneU64 = {.form = FUNC, - .param_count = 0, - .params = nullptr, - .result_count = 1, - .results = param_I64_arr_len1, - .mask = 0x82000}; - def_prim(chip_delay, oneToNoneU32) { k_yield(); k_msleep(arg0.uint32); @@ -560,12 +357,11 @@ def_prim(ev3_touch_sensor, oneToOneU32) { //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ -void install_primitives() { +void install_primitives(Interpreter *interpreter) { dbg_info("INSTALLING PRIMITIVES\n"); install_primitive(chip_delay); install_primitive(chip_pin_mode); - install_primitive(chip_digital_write); - install_primitive_reverse(chip_digital_write); + install_reversible_primitive(chip_digital_write); install_primitive(chip_digital_read); install_primitive(print_string); install_primitive(print_int); @@ -575,8 +371,7 @@ void install_primitives() { install_primitive(drive_motor); install_primitive(stop_motor); install_primitive(drive_motor_ms); - install_primitive(drive_motor_degrees); - install_primitive_reverse(drive_motor_degrees); + install_reversible_primitive(drive_motor_degrees); install_primitive(read_uart_sensor); install_primitive(setup_uart_sensor); @@ -589,24 +384,6 @@ void install_primitives() { #endif } -//------------------------------------------------------ -// resolving the primitives -//------------------------------------------------------ -bool resolve_primitive(char *symbol, Primitive *val) { - debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); - - for (auto &primitive : primitives) { - // printf("Checking %s = %s \n", symbol, primitive.name); - if (!strcmp(symbol, primitive.name)) { - debug("FOUND PRIMITIVE\n"); - *val = primitive.f; - return true; - } - } - FATAL("Could not find primitive %s \n", symbol); - return false; -} - Memory external_mem = {0, 0, 0, nullptr}; bool resolve_external_memory(char *symbol, Memory **val) { @@ -627,35 +404,4 @@ bool resolve_external_memory(char *symbol, Memory **val) { return false; } -//------------------------------------------------------ -// Restore external state when restoring a snapshot -//------------------------------------------------------ -void restore_external_state(Module *m, - const std::vector &external_state) { - std::set prim_names; - for (uint32_t i = 0; i < m->import_count; i++) { - prim_names.emplace(m->functions[i].import_field); - } - - for (PrimitiveEntry &p : primitives) { - if (prim_names.find(p.name) != prim_names.end()) { - printf("%s\n", p.name); - if (p.f_reverse) { - printf("Reversing action for primitive %s\n", p.name); - p.f_reverse(m, external_state); - } - } - } -} - -std::vector get_io_state(Module *) { - std::vector ioState; - for (auto &primitive : primitives) { - if (primitive.f_serialize_state) { - primitive.f_serialize_state(ioState); - } - } - return ioState; -} - #endif // ARDUINO From 7aea9309c9335263169ab03550ae0dceec5683f5 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 24 Nov 2025 18:17:13 +0100 Subject: [PATCH 11/15] Fix reverse not being installed correctly Tested this in the emulator, and it works fine, since the code is shared now it should also work on physical hardware. --- src/Primitives/primitives.h | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 4abfd905..1e09ba9a 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -76,7 +76,7 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { primitive(m); } -#define _install_primitive(prim_name) \ +#define _init_primitive(prim_name) \ /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ PrimitiveEntry p = {}; \ @@ -84,18 +84,19 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { p.t = &(prim_name##_type); \ p.f = &(prim_name); \ p.f_reverse = nullptr; \ - p.f_serialize_state = nullptr; \ - interpreter->register_primitive(p); - -#define install_primitive(prim_name) \ - {/*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ - _install_primitive(prim_name)} - -#define install_reversible_primitive(prim_name) \ - { \ - _install_primitive(prim_name) p.f_reverse = &(prim_name##_reverse); \ - p.f_serialize_state = &(prim_name##_serialize); \ + p.f_serialize_state = nullptr; + +#define install_primitive(prim_name) \ + { /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ + prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ + _init_primitive(prim_name) interpreter->register_primitive(p); \ + } + +#define install_reversible_primitive(prim_name) \ + { \ + _init_primitive(prim_name) p.f_reverse = &(prim_name##_reverse); \ + p.f_serialize_state = &(prim_name##_serialize); \ + interpreter->register_primitive(p); \ } #define def_prim(function_name, type) \ From e57fa3f3b623f99012546e3f183ab185576b48d3 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 24 Nov 2025 18:25:38 +0100 Subject: [PATCH 12/15] Minor cleanup TODO: Fix prints in the Interpreter class --- src/Interpreter/interpreter.h | 2 +- src/Primitives/primitives.h | 30 ++++++++++++------------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index c9329ebc..1f6f181c 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -94,7 +94,7 @@ class Interpreter { for (PrimitiveEntry &p : primitives) { if (prim_names.find(p.name) != prim_names.end()) { if (p.f_reverse) { - printf("EMU: Reversing state for primitive %s\n", p.name); + printf("Reversing state for primitive %s\n", p.name); p.f_reverse(m, external_state); } } diff --git a/src/Primitives/primitives.h b/src/Primitives/primitives.h index 1e09ba9a..c2960ee4 100644 --- a/src/Primitives/primitives.h +++ b/src/Primitives/primitives.h @@ -1,6 +1,7 @@ #ifndef WARDUINO_PRIM_H #define WARDUINO_PRIM_H +#include "../Utils/macros.h" #include "../WARDuino/internals.h" /** @@ -17,12 +18,6 @@ bool resolve_external_memory(char *symbol, Memory **val); void install_primitives(Interpreter *interpreter); -/*std::vector get_io_state(Module *m); - -void restore_external_state(Module *m, - const std::vector -&external_state);*/ - inline void create_stack(std::vector *) {} template @@ -76,24 +71,23 @@ void invoke_primitive(Module *m, const std::string &function_name, Ts... args) { primitive(m); } -#define _init_primitive(prim_name) \ - /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ - PrimitiveEntry p = {}; \ - p.name = #prim_name; \ - p.t = &(prim_name##_type); \ - p.f = &(prim_name); \ - p.f_reverse = nullptr; \ +#define _init_primitive(prim_name) \ + PrimitiveEntry p = {}; \ + p.name = #prim_name; \ + p.t = &(prim_name##_type); \ + p.f = &(prim_name); \ + p.f_reverse = nullptr; \ p.f_serialize_state = nullptr; -#define install_primitive(prim_name) \ - { /*dbg_info("installing primitive number: %d of %d with name: %s\n", \ \ - prim_index + 1, ALL_PRIMITIVES, #prim_name); \*/ \ - _init_primitive(prim_name) interpreter->register_primitive(p); \ +#define install_primitive(prim_name) \ + { \ + dbg_info("installing primitive %s\n", #prim_name); \ + _init_primitive(prim_name) interpreter->register_primitive(p); \ } #define install_reversible_primitive(prim_name) \ { \ + dbg_info("installing reversible primitive %s\n", #prim_name); \ _init_primitive(prim_name) p.f_reverse = &(prim_name##_reverse); \ p.f_serialize_state = &(prim_name##_serialize); \ interpreter->register_primitive(p); \ From f8fe0ecabb0051c35325943ccc8012865a1c9307 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 24 Nov 2025 18:31:50 +0100 Subject: [PATCH 13/15] Fix debug prints in resolve_primitive --- src/Interpreter/interpreter.h | 13 ++++++------- src/Utils/macros.h | 2 +- src/WARDuino/CallbackHandler.cpp | 1 + src/WARDuino/WARDuino.cpp | 7 ++++--- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index 1f6f181c..ee647354 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -4,8 +4,8 @@ #include #include +#include "../Utils/macros.h" #include "../WARDuino/internals.h" -// #include "../Utils/macros.h" class Interpreter { public: @@ -66,19 +66,18 @@ class Interpreter { //------------------------------------------------------ // ReSharper disable once CppDFAConstantFunctionResult bool resolve_primitive(const char *symbol, Primitive *val) { - // debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); for (auto &primitive : primitives) { // printf("Checking %s = %s \n", symbol, primitive.name); if (!strcmp(symbol, primitive.name)) { - // debug("FOUND PRIMITIVE\n"); + debug("FOUND PRIMITIVE\n"); *val = primitive.f; return true; } } - // FATAL("Could not find primitive %s \n", symbol); - return false; - // return false; // unreachable + FATAL("Could not find primitive %s \n", symbol); + return false; // unreachable } //------------------------------------------------------ @@ -94,7 +93,7 @@ class Interpreter { for (PrimitiveEntry &p : primitives) { if (prim_names.find(p.name) != prim_names.end()) { if (p.f_reverse) { - printf("Reversing state for primitive %s\n", p.name); + dbg_info("Reversing state for primitive %s\n", p.name); p.f_reverse(m, external_state); } } diff --git a/src/Utils/macros.h b/src/Utils/macros.h index 4b765f0d..d70c4bb3 100644 --- a/src/Utils/macros.h +++ b/src/Utils/macros.h @@ -2,7 +2,7 @@ #include -#include "../WARDuino.h" +#include "../WARDuino/internals.h" #ifndef DEBUG #define DEBUG 0 diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 28e0bc3b..561502f7 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -5,6 +5,7 @@ #include "../Debug/debugger.h" #include "../Interpreter/interpreter.h" #include "../Utils/macros.h" +#include "../WARDuino.h" void push_guard(Module *m) { if (m == nullptr) { diff --git a/src/WARDuino/WARDuino.cpp b/src/WARDuino/WARDuino.cpp index 2268b06c..c049105e 100644 --- a/src/WARDuino/WARDuino.cpp +++ b/src/WARDuino/WARDuino.cpp @@ -622,9 +622,10 @@ void WARDuino::instantiate_module(Module *m, uint8_t *bytes, // Allocate memory // for (uint32_t c=0; cmemory.bytes = (uint8_t *)acalloc( - m->memory.pages * PAGE_SIZE, 1, // sizeof(uint32_t), - "Module->memory.bytes"); + m->memory.bytes = + (uint8_t *)acalloc(m->memory.pages * PAGE_SIZE, + 1, // sizeof(uint32_t), + "Module->memory.bytes"); //} break; } From ef63660b807232374f82ea148dd2abf7c6dcf8e6 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 24 Nov 2025 18:38:43 +0100 Subject: [PATCH 14/15] Fix INFO/DEBUG/TRACE/WARN build --- src/Interpreter/interpreter.h | 2 +- src/WARDuino.h | 26 -------------------------- src/WARDuino/CallbackHandler.cpp | 2 +- src/WARDuino/internals.h | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Interpreter/interpreter.h b/src/Interpreter/interpreter.h index ee647354..fa8c5eb9 100644 --- a/src/Interpreter/interpreter.h +++ b/src/Interpreter/interpreter.h @@ -66,7 +66,7 @@ class Interpreter { //------------------------------------------------------ // ReSharper disable once CppDFAConstantFunctionResult bool resolve_primitive(const char *symbol, Primitive *val) { - debug("Resolve primitives (%d) for %s \n", ALL_PRIMITIVES, symbol); + debug("Resolve primitive %s\n", symbol); for (auto &primitive : primitives) { // printf("Checking %s = %s \n", symbol, primitive.name); diff --git a/src/WARDuino.h b/src/WARDuino.h index 92ba863e..1adf4c10 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -23,32 +23,6 @@ #define CALLSTACK_SIZE 0x100 // 4096 #define BR_TABLE_SIZE 0x100 // 65536 -#define I32 0x7f // -0x01 -#define I64 0x7e // -0x02 -#define F32 0x7d // -0x03 -#define F64 0x7c // -0x04 - -#define I32_8 0x7b // -0x05 -#define I32_16 0x7a // -0x06 -#define I64_8 0x79 // -0x07 -#define I64_16 0x78 // -0x08 -#define I64_32 0x77 // -0x09 - -#define I32_8_s 0x7b // -0x05 -#define I32_8_u 0x7a // -0x06 -#define I32_16_s 0x79 // -0x07 -#define I32_16_u 0x78 // -0x08 -#define I64_8_s 0x77 // -0x09 -#define I64_8_u 0x76 // -0x0a -#define I64_16_s 0x75 // -0x0b -#define I64_16_u 0x74 // -0x0c -#define I64_32_s 0x73 // -0x0d -#define I64_32_u 0x72 // -0x0e - -#define ANYFUNC 0x70 // -0x10 -#define FUNC 0x60 // -0x20 -#define BLOCK 0x40 // -0x40 - #ifdef ARDUINO #define EVENTS_SIZE 10 #else diff --git a/src/WARDuino/CallbackHandler.cpp b/src/WARDuino/CallbackHandler.cpp index 561502f7..0c87d76f 100644 --- a/src/WARDuino/CallbackHandler.cpp +++ b/src/WARDuino/CallbackHandler.cpp @@ -195,7 +195,7 @@ Callback::Callback(Module *m, std::string id, uint32_t tidx) { void Callback::resolve_event(const Event &e) { dbg_trace("Callback(%s, %i): resolving Event(%s, \"%s\")\n", topic.c_str(), - table_index, e.topic.c_str(), e.payload); + table_index, e.topic.c_str(), e.payload.c_str()); // Copy topic and payload to linear memory uint32_t start = 10000; // TODO use reserved area in linear memory diff --git a/src/WARDuino/internals.h b/src/WARDuino/internals.h index a4b9e5a7..b355da28 100644 --- a/src/WARDuino/internals.h +++ b/src/WARDuino/internals.h @@ -3,6 +3,32 @@ #include #include +#define I32 0x7f // -0x01 +#define I64 0x7e // -0x02 +#define F32 0x7d // -0x03 +#define F64 0x7c // -0x04 + +#define I32_8 0x7b // -0x05 +#define I32_16 0x7a // -0x06 +#define I64_8 0x79 // -0x07 +#define I64_16 0x78 // -0x08 +#define I64_32 0x77 // -0x09 + +#define I32_8_s 0x7b // -0x05 +#define I32_8_u 0x7a // -0x06 +#define I32_16_s 0x79 // -0x07 +#define I32_16_u 0x78 // -0x08 +#define I64_8_s 0x77 // -0x09 +#define I64_8_u 0x76 // -0x0a +#define I64_16_s 0x75 // -0x0b +#define I64_16_u 0x74 // -0x0c +#define I64_32_s 0x73 // -0x0d +#define I64_32_u 0x72 // -0x0e + +#define ANYFUNC 0x70 // -0x10 +#define FUNC 0x60 // -0x20 +#define BLOCK 0x40 // -0x40 + // Structures typedef struct Type { uint8_t form; From bddce1aaeb8e52bed56506d8c184ef1c3f015688 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 24 Nov 2025 18:40:56 +0100 Subject: [PATCH 15/15] Fix missing cstdint include in internals.h Also removed some other unnecessary header files in WARDuino.h. --- src/WARDuino.h | 6 ------ src/WARDuino/internals.h | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/WARDuino.h b/src/WARDuino.h index 1adf4c10..e2d283d6 100644 --- a/src/WARDuino.h +++ b/src/WARDuino.h @@ -1,11 +1,5 @@ #pragma once -#include -#include -#include -#include -#include -#include #include #include "Debug/debugger.h" diff --git a/src/WARDuino/internals.h b/src/WARDuino/internals.h index b355da28..de7617c7 100644 --- a/src/WARDuino/internals.h +++ b/src/WARDuino/internals.h @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include