From bb9e30a1c18746c7c83adccdd0cd167c0d45a575 Mon Sep 17 00:00:00 2001 From: zongor Date: Wed, 11 Jun 2025 22:41:49 -0400 Subject: [PATCH] begin breaking up into modules, add wasm --- .gitignore | 4 +- src/Makefile | 78 ++++++++++++++++++++++----------- src/common.h | 9 ++++ src/main.c | 54 +++++++++++++++++++++++ src/vm.c | 120 ++++++++++++++------------------------------------- src/vm.h | 36 ++++++++++++++++ 6 files changed, 188 insertions(+), 113 deletions(-) create mode 100644 src/common.h create mode 100644 src/main.c create mode 100644 src/vm.h diff --git a/.gitignore b/.gitignore index 6c5caf1..87b3ffe 100644 --- a/.gitignore +++ b/.gitignore @@ -102,4 +102,6 @@ Mkfile.old dkms.conf zre -memory_dump.bin \ No newline at end of file +zre.wasm +memory_dump.bin +src/build/ \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 7daefae..deb0332 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,39 +1,69 @@ -# Compiler and flags -CC = gcc -CFLAGS += -std=c89 -g -Wall -Wextra -Werror -Wno-unused-parameter -LDFLAGS += -LDLIBS += +# Compiler configurations +# ----------------------- +# Native build (gcc) +CC_NATIVE = gcc +CFLAGS_NATIVE = -std=c89 -Wall -Wextra -Werror -Wno-unused-parameter +LDFLAGS_NATIVE = +LDLIBS_NATIVE = + +# WASM build (emscripten) +CC_WASM = emcc +CFLAGS_WASM = -std=c89 -Wall -Wextra -Werror -Wno-unused-parameter #-s WASM=1 +LDFLAGS_WASM = #-s WASM=1 +LDLIBS_WASM = # Source and build configuration +# ---------------------------- SRC = $(wildcard *.c) -OBJ = $(SRC:.c=.o) -EXEC = zre +EXEC_NATIVE = zre +EXEC_WASM = zre.wasm + +# Build directories +OBJ_DIR_NATIVE = build/native/obj +OBJ_DIR_WASM = build/wasm/obj + +# Create output paths +OBJ_NATIVE = $(addprefix $(OBJ_DIR_NATIVE)/,$(notdir $(SRC:.c=.o))) +OBJ_WASM = $(addprefix $(OBJ_DIR_WASM)/,$(notdir $(SRC:.c=.o))) # Phony targets -.PHONY: all clean test install +# ------------- +.PHONY: all clean install wasm -# Default target -all: $(EXEC) +# Default target builds both versions +all: native wasm -# Main build rule -$(EXEC): $(OBJ) - $(CC) $(LDFLAGS) $(OBJ) $(LDLIBS) -o $@ +# Native build rules +# ------------------ +native: $(EXEC_NATIVE) -# Pattern rule for object files -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ +$(EXEC_NATIVE): $(OBJ_NATIVE) + $(CC_NATIVE) $(LDFLAGS_NATIVE) $^ $(LDLIBS_NATIVE) -o $@ -# Test target with dependency -test: $(EXEC) - @echo "Running tests..." - ./$(EXEC) - @echo "Tests completed successfully." +# WASM build rules +# ---------------- +wasm: $(EXEC_WASM) + +$(EXEC_WASM): $(OBJ_WASM) + $(CC_WASM) $(LDFLAGS_WASM) $^ $(LDLIBS_WASM) -o $@ + +# Object file rules +# ----------------- +$(OBJ_DIR_NATIVE)/%.o: %.c + @mkdir -p $(dir $@) + $(CC_NATIVE) $(CFLAGS_NATIVE) -c $< -o $@ + +$(OBJ_DIR_WASM)/%.o: %.c + @mkdir -p $(dir $@) + $(CC_WASM) $(CFLAGS_WASM) -c $< -o $@ # Clean build artifacts +# --------------------- clean: - $(RM) $(OBJ) $(EXEC) + $(RM) -r $(OBJ_DIR_NATIVE) $(OBJ_DIR_WASM) $(EXEC_NATIVE) $(EXEC_WASM) # Install target (example) -install: $(EXEC) +# ------------------------ +install: native install -d $(DESTDIR)/usr/local/bin - install $(EXEC) $(DESTDIR)/usr/local/bin/ + install $(EXEC_NATIVE) $(DESTDIR)/usr/local/bin/ diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..b644b5f --- /dev/null +++ b/src/common.h @@ -0,0 +1,9 @@ +#ifndef ZRE_COMMON_H +#define ZRE_COMMON_H + +#include +#include +#include +#include + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..20d6066 --- /dev/null +++ b/src/main.c @@ -0,0 +1,54 @@ +#include "vm.h" + +/* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */ +#define MEMORY_SIZE 1024 + +int main() { + Data memory[MEMORY_SIZE]; /* Memory array */ + + int i = 0; + memory[i++].u = OP_ADD_F32; + memory[i++].u = 102; + memory[i++].u = 103; + memory[i++].u = 103; + memory[i++].u = OP_SUB; + memory[i++].u = 100; + memory[i++].u = 101; + memory[i++].u = 100; + memory[i++].u = OP_JGZ; + memory[i++].u = 100; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = OP_F32_TO_INT; + memory[i++].u = 103; + memory[i++].u = 0; + memory[i++].u = 103; + memory[i++].u = OP_INT_TO_STRING; + memory[i++].u = 103; + memory[i++].u = 0; + memory[i++].u = 104; + memory[i++].u = OP_PRINT_STRING; + memory[i++].u = 105; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = OP_READ_STRING; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = 109; + memory[i++].u = OP_PRINT_STRING; + memory[i++].u = 110; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = OP_HALT; + memory[i++].u = 0; + memory[i++].u = 0; + memory[i++].u = 0; + memory[100].u = 5; + memory[101].u = 1; + memory[102].f = 5.f; + memory[103].f = 5.f; + + run_vm(memory, MEMORY_SIZE); + + return core_dump(memory, MEMORY_SIZE); +} diff --git a/src/vm.c b/src/vm.c index 34bd671..d71b3d4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1,49 +1,17 @@ -#include -#include -#include -#include +#include "vm.h" #include #include -/* #define MEMORY_SIZE 65536 /\* 64KB memory (adjustable) *\/ */ -#define MEMORY_SIZE 1024 -typedef union { - float f; - uint32_t u; -} Data; -Data memory[MEMORY_SIZE]; /* Memory array */ - -typedef enum { - OP_HALT, /* terminate execution */ - OP_ADD, /* dest = src1 + src2 */ - OP_SUB, /* dest = src1 - src2 */ - OP_MUL, /* dest = src1 * src2 */ - OP_DIV, /* dest = src1 / src2 */ - OP_ADD_F32, /* dest = src1 + src2 */ - OP_SUB_F32, /* dest = src1 - src2 */ - OP_MUL_F32, /* dest = src1 * src2 */ - OP_DIV_F32, /* dest = src1 / src2 */ - OP_F32_TO_INT, /* dest = src1 as int */ - OP_INT_TO_F32, /* dest = src1 as f32 */ - OP_MOV, /* dest = src1 */ - OP_JMP, /* jump to address src1 unconditionally */ - OP_JGZ, /* jump to address dest if src1 > 0 */ - OP_INT_TO_STRING, /* dest = src1 as str */ - OP_F32_TO_STRING, /* dest = src2 as str */ - OP_READ_STRING, - OP_PRINT_STRING, -} Opcode; - -int core_dump() { +int core_dump(Data *memory, uint32_t memory_size) { FILE *file = fopen("memory_dump.bin", "wb"); if (!file) { perror("Failed to open file"); return EXIT_FAILURE; } - size_t written = fwrite(memory, 1, MEMORY_SIZE, file); - if (written != MEMORY_SIZE) { + size_t written = fwrite(memory, 1, memory_size, file); + if (written != memory_size) { fprintf(stderr, "Incomplete write: %zu bytes written out of %u\n", written, - MEMORY_SIZE); + memory_size); fclose(file); return EXIT_FAILURE; } @@ -61,7 +29,7 @@ uint32_t set_char(uint32_t word, int index, uint8_t ch) { } /* Pack string into union-based memory */ -void pack_string(const char *str, uint32_t length, uint32_t dest_addr) { +void pack_string(Data *memory, const char *str, uint32_t length, uint32_t dest_addr) { memory[dest_addr].u = length; uint32_t buffer_addr = dest_addr + 1; int word_index = 0; @@ -89,10 +57,10 @@ void pack_string(const char *str, uint32_t length, uint32_t dest_addr) { } } -void run_vm() { +void run_vm(Data *memory, uint32_t memory_size) { uint32_t pc = 0; /* Program counter */ - while (pc < MEMORY_SIZE - 4) { + while (pc < memory_size - 4) { Opcode opcode = memory[pc].u; uint32_t src1_addr = memory[pc + 1].u; @@ -100,8 +68,8 @@ void run_vm() { uint32_t dest_addr = memory[pc + 3].u; pc += 4; /* Advance to next instruction */ - if (src1_addr >= MEMORY_SIZE || src2_addr >= MEMORY_SIZE || - dest_addr >= MEMORY_SIZE) { + if (src1_addr >= memory_size || src2_addr >= memory_size || + dest_addr >= memory_size) { printf("Invalid memory address!\n"); exit(1); } @@ -173,14 +141,14 @@ void run_vm() { int32_t a = (int32_t)memory[src1_addr].u; char buffer[32]; sprintf(buffer, "%d", a); - pack_string(buffer, strlen(buffer), dest_addr); + pack_string(memory, buffer, strlen(buffer), dest_addr); break; } case OP_F32_TO_STRING: { float a = memory[src1_addr].f; char buffer[32]; sprintf(buffer, "%f", a); - pack_string(buffer, strlen(buffer), dest_addr); + pack_string(memory, buffer, strlen(buffer), dest_addr); break; } case OP_PRINT_STRING: { @@ -229,6 +197,26 @@ void run_vm() { memory[dest_addr].u = length; break; } + case OP_CMP_STRING: { + uint32_t addr1 = src1_addr; + uint32_t addr2 = src2_addr; + uint32_t length1 = memory[src1_addr - 1].u; + int equal = 1; + + uint32_t i; + for (i = 0; i < length1;) { + uint32_t word1 = memory[addr1 + i].u; + uint32_t word2 = memory[addr2 + i].u; + if (word1 != word2) { + equal = 0; + break; + } + if ((word1 & 0xFF) == '\0' && (word2 & 0xFF) == '\0') + break; + } + memory[dest_addr].u = equal; + break; + } default: printf("Unknown opcode: %d\n", opcode); return; @@ -236,47 +224,3 @@ void run_vm() { } } -int main() { - int i = 0; - memory[i++].u = OP_ADD_F32; - memory[i++].u = 102; - memory[i++].u = 103; - memory[i++].u = 103; - memory[i++].u = OP_SUB; - memory[i++].u = 100; - memory[i++].u = 101; - memory[i++].u = 100; - memory[i++].u = OP_JGZ; - memory[i++].u = 100; - memory[i++].u = 0; - memory[i++].u = 0; - memory[i++].u = OP_F32_TO_INT; - memory[i++].u = 103; - memory[i++].u = 0; - memory[i++].u = 103; - memory[i++].u = OP_INT_TO_STRING; - memory[i++].u = 103; - memory[i++].u = 0; - memory[i++].u = 104; - memory[i++].u = OP_PRINT_STRING; - memory[i++].u = 105; - memory[i++].u = 0; - memory[i++].u = 0; - memory[i++].u = OP_READ_STRING; - memory[i++].u = 0; - memory[i++].u = 0; - memory[i++].u = 109; - memory[i++].u = OP_PRINT_STRING; - memory[i++].u = 110; - memory[i++].u = 0; - memory[i++].u = 0; - memory[i++].u = OP_HALT; - memory[100].u = 5; - memory[101].u = 1; - memory[102].f = 5.f; - memory[103].f = 5.f; - - run_vm(); - - return core_dump(); -} diff --git a/src/vm.h b/src/vm.h new file mode 100644 index 0000000..47c0a34 --- /dev/null +++ b/src/vm.h @@ -0,0 +1,36 @@ +#ifndef ZRE_VM_H +#define ZRE_VM_H + +#include "common.h" + +typedef union { + float f; + uint32_t u; +} Data; + +typedef enum { + OP_HALT, /* terminate execution */ + OP_ADD, /* dest = src1 + src2 */ + OP_SUB, /* dest = src1 - src2 */ + OP_MUL, /* dest = src1 * src2 */ + OP_DIV, /* dest = src1 / src2 */ + OP_ADD_F32, /* dest = src1 + src2 */ + OP_SUB_F32, /* dest = src1 - src2 */ + OP_MUL_F32, /* dest = src1 * src2 */ + OP_DIV_F32, /* dest = src1 / src2 */ + OP_F32_TO_INT, /* dest = src1 as int */ + OP_INT_TO_F32, /* dest = src1 as f32 */ + OP_MOV, /* dest = src1 */ + OP_JMP, /* jump to address src1 unconditionally */ + OP_JGZ, /* jump to address dest if src1 > 0 */ + OP_INT_TO_STRING, /* dest = src1 as str */ + OP_F32_TO_STRING, /* dest = src2 as str */ + OP_READ_STRING, + OP_PRINT_STRING, + OP_CMP_STRING, +} Opcode; + +void run_vm(Data *memory, uint32_t memory_size); +int core_dump(Data *memory, uint32_t memory_size); + +#endif