From 58a26ca05aacb4736e9e7e652badd43a8085d1f1 Mon Sep 17 00:00:00 2001 From: physick Date: Sun, 12 Jul 2026 11:13:08 +0500 Subject: rudimentary code execution --- .gitignore | 1 + README.md | 13 ++++++++++ build.zig | 12 ++++++++++ src/main.c | 1 - src/scenes/puzzleScene.c | 7 ++++++ src/ui_elements/TextEditor.c | 27 +++++++++++++++++++++ src/ui_elements/UI.h | 1 + src/utils/stringBuilder.c | 30 ++++++++++++++++++++++++ src/utils/stringBuilder.h | 14 +++++++++++ src/wren_inter/wren_inter.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/wren_inter/wren_inter.h | 6 +++++ 11 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100644 src/utils/stringBuilder.c create mode 100644 src/utils/stringBuilder.h create mode 100644 src/wren_inter/wren_inter.c create mode 100644 src/wren_inter/wren_inter.h diff --git a/.gitignore b/.gitignore index e9f0827..2ae7fc3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ zig-out .zig-cache game.a raylib +wren :w diff --git a/README.md b/README.md new file mode 100644 index 0000000..9ffa910 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Building + +## Dependencies +You will have to build wren yourself. To do that, you have to clone the wren repo +in this directory with +``` +git clone https://github.com/wren-lang/wren.git +``` + +Then just build it for your OS. The build system will take care of the rest. + +## Windows +For windows you have to clone the dll's in the output lib yourself diff --git a/build.zig b/build.zig index b5bbf33..874aaff 100644 --- a/build.zig +++ b/build.zig @@ -14,6 +14,8 @@ pub fn build(b: *std.Build) void { root.addCSourceFiles(.{ .files = &[_][]const u8 { "src/main.c", + "src/utils/stringBuilder.c", + "src/wren_inter/wren_inter.c", "src/resources/resources.c", "src/ui_elements/UI.c", "src/ui_elements/TextEditor.c", @@ -24,6 +26,7 @@ pub fn build(b: *std.Build) void { } }); + // Linking raylib if (builtin.target.os.tag == .windows) { // If you are building on windows you need to provide your own // raylib. Put it in the raylib dir @@ -34,6 +37,15 @@ pub fn build(b: *std.Build) void { root.linkSystemLibrary("raylib", .{.needed = true}); root.addIncludePath(b.path("include/")); + // Linking wren. They do not provide system-wide libraries so you have to + // provide them yourself + root.addIncludePath(b.path("wren/src/include/")); + root.addLibraryPath(b.path("wren/lib/")); + root.linkSystemLibrary("wren", .{ + .needed = true, + .preferred_link_mode = .static, + }); + const exe = b.addExecutable(.{ .name = "game", .root_module = root, diff --git a/src/main.c b/src/main.c index 8aa83e5..f9653e7 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ - #include #include #include "scenes/scenes.h" diff --git a/src/scenes/puzzleScene.c b/src/scenes/puzzleScene.c index 9f7b4d7..7c4e1b2 100644 --- a/src/scenes/puzzleScene.c +++ b/src/scenes/puzzleScene.c @@ -1,8 +1,10 @@ #include +#include #include #include "scenes.h" #include "../resources/resources.h" #include "../ui_elements/UI.h" +#include "../wren_inter/wren_inter.h" typedef struct { Puzzle *PuzzlePtr; @@ -85,6 +87,11 @@ bool drawPuzzleScene(void *self) { bool updatePuzzleScene(void *self) { puzzleSceneData *data = ((Scene *)self)->data; HandleKeyboard(data->EditorInfo); + if (IsKeyPressed(KEY_F5)) { + char *txt = GetText(data->EditorInfo); + EvaluateScript(txt); + free(txt); + } return true; } diff --git a/src/ui_elements/TextEditor.c b/src/ui_elements/TextEditor.c index 620abea..1097f1c 100644 --- a/src/ui_elements/TextEditor.c +++ b/src/ui_elements/TextEditor.c @@ -507,3 +507,30 @@ void DrawTextArea(TextArea *ta, Rectangle rec) { } EndScissorMode(); } + +char *GetText(TextArea *ta) { + size_t size = 0; + TextNode *node = ta->StartNode; + while (node != NULL) { + size += node->len + 1; + node = node->NextNode; + } + + char *outp = malloc(size + 1); + if (outp == NULL) { + TraceLog(LOG_ERROR, "Failed to create a text from a text area"); + return NULL; + } + + size_t idx = 0; + node = ta->StartNode; + while (node != NULL) { + memcpy(outp + idx, node->text, node->len); + idx += node->len + 1; + outp[idx - 1] = '\n'; + node = node->NextNode; + } + outp[size] = 0x0; + + return outp; +} diff --git a/src/ui_elements/UI.h b/src/ui_elements/UI.h index 9f126c3..f461cf5 100644 --- a/src/ui_elements/UI.h +++ b/src/ui_elements/UI.h @@ -58,6 +58,7 @@ void InsertChar(TextArea *ta, char new_char); void DeleteChar(TextArea *ta); void HandleKeyboard(TextArea *ta); +char *GetText(TextArea *ta); void FreeTextArea(TextArea *ta); #endif // UI_ELEMENTS_H diff --git a/src/utils/stringBuilder.c b/src/utils/stringBuilder.c new file mode 100644 index 0000000..805fb34 --- /dev/null +++ b/src/utils/stringBuilder.c @@ -0,0 +1,30 @@ +#include "stringBuilder.h" +#include +#include + +void AppendStringBuilder(StringBuilder *sb, const char *str, char separator) { + size_t str_len = strlen(str); + if (sb->val == NULL) { + sb->val = malloc(str_len + 1); + if (sb->val == NULL) return; + memcpy(sb->val, str, str_len); + sb->len = str_len; + } else { + char *appended = realloc(sb->val, sb->len + str_len + 2); + if (appended == NULL) return; + sb->val = appended; + + sb->val[sb->len] = separator; + memcpy(sb->val + sb->len + 1, str, str_len); + sb->len = sb->len + str_len + 1; + } + sb->val[sb->len] = 0x0; +} + +void FreeStringBuilder(StringBuilder *sb) { + if (sb->val != NULL) { + free(sb->val); + sb->val = NULL; + } + sb->len = 0; +} diff --git a/src/utils/stringBuilder.h b/src/utils/stringBuilder.h new file mode 100644 index 0000000..a9730a2 --- /dev/null +++ b/src/utils/stringBuilder.h @@ -0,0 +1,14 @@ +#ifndef SB_H +#define SB_H + +#include + +typedef struct { + char *val; + size_t len; +} StringBuilder; + +void AppendStringBuilder(StringBuilder *sb, const char *str, char separator); +void FreeStringBuilder(StringBuilder *sb); + +#endif // SB_H diff --git a/src/wren_inter/wren_inter.c b/src/wren_inter/wren_inter.c new file mode 100644 index 0000000..a1b48e2 --- /dev/null +++ b/src/wren_inter/wren_inter.c @@ -0,0 +1,56 @@ +#include "wren_inter.h" +#include "../utils/stringBuilder.h" +#include +#include +#include + +StringBuilder stdout_sb = {0}; + +void writeFn(WrenVM* vm, const char* text) { + AppendStringBuilder(&stdout_sb, text, '\n'); +} + +void errorFn(WrenVM* vm, WrenErrorType errorType, + const char* module, const int line, + const char* msg) +{ + switch (errorType) + { + case WREN_ERROR_COMPILE: + { + TraceLog(LOG_ERROR, "[%s line %d] [Error] %s", module, line, msg); + } break; + case WREN_ERROR_STACK_TRACE: + { + TraceLog(LOG_ERROR, "[%s line %d] in %s", module, line, msg); + } break; + case WREN_ERROR_RUNTIME: + { + TraceLog(LOG_ERROR, "[Runtime Error] %s", msg); + } break; + } +} + +void EvaluateScript(char *script) { + TraceLog(LOG_INFO, "Evaluating %s...", script); + FreeStringBuilder(&stdout_sb); + WrenConfiguration config; + wrenInitConfiguration(&config); + config.writeFn = writeFn; + config.errorFn = errorFn; + + WrenVM* vm = wrenNewVM(&config); + if (vm == NULL) { + TraceLog(LOG_ERROR, "Failed to initialize a wren vm"); + return; + } + + WrenInterpretResult result = wrenInterpret(vm, "main", script); + switch (result) { + case WREN_RESULT_SUCCESS: break; + case WREN_RESULT_COMPILE_ERROR: break; + case WREN_RESULT_RUNTIME_ERROR: break; + } + printf("Wren outp: %s", stdout_sb.val); + wrenFreeVM(vm); +} diff --git a/src/wren_inter/wren_inter.h b/src/wren_inter/wren_inter.h new file mode 100644 index 0000000..9601209 --- /dev/null +++ b/src/wren_inter/wren_inter.h @@ -0,0 +1,6 @@ +#ifndef WREN_INTER_H +#define WREN_INTER_H + +void EvaluateScript(char *script); + +#endif // WREN_INTER_H -- cgit v1.3