From e7573743aadb2a39584b956ba3ea9a88e61523cf Mon Sep 17 00:00:00 2001 From: samsonium Date: Mon, 12 Oct 2026 17:20:41 +0300 Subject: [PATCH] feat: implement environment table for vm --- CMakeLists.txt | 1 + include/vm/fzl_vm.h | 4 +- include/vm/fzl_vm_env.h | 52 ++++++++++++++++++++++ src/vm/fzl_vm.c | 28 +++++------- src/vm/fzl_vm_env.c | 97 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 18 deletions(-) create mode 100644 include/vm/fzl_vm_env.h create mode 100644 src/vm/fzl_vm_env.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 1086f30..7807249 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,5 +20,6 @@ add_executable(fzc # Virtual machine add_executable(fz src/vm/fzl_vm.c + src/vm/fzl_vm_env.c src/vm/main.c) diff --git a/include/vm/fzl_vm.h b/include/vm/fzl_vm.h index 31fa17f..ca55dcb 100644 --- a/include/vm/fzl_vm.h +++ b/include/vm/fzl_vm.h @@ -5,6 +5,7 @@ #include // NOTE: move outside compiler scope to common #include #include +#include // VM descriptor typedef struct @@ -26,7 +27,8 @@ typedef struct size_t ctop; // Environment stack - // TODO: implement `estack` and `etop` + fzl_vm_env_t estack[256]; + size_t etop; } fzl_vm_t; // Allocate FZL VM diff --git a/include/vm/fzl_vm_env.h b/include/vm/fzl_vm_env.h new file mode 100644 index 0000000..a50831a --- /dev/null +++ b/include/vm/fzl_vm_env.h @@ -0,0 +1,52 @@ +#ifndef FZL_VM_ENV_H +#define FZL_VM_ENV_H + +#include +#include +#include + +typedef enum +{ + FZL_VM_ENV_WRESULT_OK, + FZL_VM_ENV_WRESULT_ERR, + FZL_VM_ENV_WRESULT_ERR_EXISTS, + FZL_VM_ENV_WRESULT_ERR_NOT_FOUND +} fzl_vm_env_wresult_t; + +// Environment table entry descriptor +typedef struct +{ + char *name; + fzl_value_t value; +} fzl_vm_env_entry_t; + +// Environment table descriptor +typedef struct +{ + size_t size; + size_t remainder; + + fzl_vm_env_entry_t *table; +} fzl_vm_env_t; + +// Allocate env table +fzl_vm_env_t *fzl_mkenv(); + +// Try get value by name +fzl_value_t fzl_env_lookup(fzl_vm_env_t *env, char *name); + +// Check name in env table +bool fzl_env_contains(fzl_vm_env_t *env, char *name); + +// Store new value +fzl_vm_env_wresult_t fzl_env_storevalue(fzl_vm_env_t *env, char *name, + fzl_value_t val); + +// Overwrite existing value +fzl_vm_env_wresult_t fzl_env_writevalue(fzl_vm_env_t *env, char *name, + fzl_value_t newval); + +// Free env table +void fzl_freeenv(fzl_vm_env_t *env); + +#endif // FZL_VM_ENV_H diff --git a/src/vm/fzl_vm.c b/src/vm/fzl_vm.c index 045cc76..7175726 100644 --- a/src/vm/fzl_vm.c +++ b/src/vm/fzl_vm.c @@ -29,8 +29,13 @@ fzl_vm_t *fzl_mkvm(const char *filepath) vm->ops = NULL; vm->ops_count = 0; vm->ip = 0; + vm->dtop = 0; + vm->ctop = 0; + vm->etop = 0; + memset(vm->dstack, 0, sizeof(vm->dstack)); - vm->dtop = 0; + memset(vm->cstack, 0, sizeof(vm->cstack)); + memset(vm->estack, 0, sizeof(vm->estack)); FILE *fd = fopen(filepath, "rb"); if (!fd) @@ -117,6 +122,11 @@ int fzl_vm_run(fzl_vm_t *vm) switch (opcode) { + case FZL_OPCODE_MK_ENVTABLE: + case FZL_OPCODE_STORE: + case FZL_OPCODE_WRITE: + break; + case FZL_OPCODE_CALL_BUILTIN: { uint64_t fn_id = vm->ops[++vm->ip]; @@ -127,24 +137,8 @@ int fzl_vm_run(fzl_vm_t *vm) printf("%s\n", arg.as.s.value); else if (arg.type == FZL_TYPE_CHAR) printf("%c\n", arg.as.c); - else if (arg.type == FZL_TYPE_INT8) - printf("%d\n", arg.as.i8); - else if (arg.type == FZL_TYPE_INT16) - printf("%d\n", arg.as.i16); - else if (arg.type == FZL_TYPE_INT32) - printf("%d\n", arg.as.i32); - else if (arg.type == FZL_TYPE_INT64) - printf("%ld\n", arg.as.i64); else if (arg.type == FZL_TYPE_INT) printf("%ld\n", arg.as.i); - else if (arg.type == FZL_TYPE_UINT8) - printf("%u\n", arg.as.u8); - else if (arg.type == FZL_TYPE_UINT16) - printf("%u\n", arg.as.u16); - else if (arg.type == FZL_TYPE_UINT32) - printf("%u\n", arg.as.u32); - else if (arg.type == FZL_TYPE_UINT64) - printf("%lu\n", arg.as.u64); else if (arg.type == FZL_TYPE_UINT) printf("%lu\n", arg.as.u); else if (arg.type == FZL_TYPE_BOOL) diff --git a/src/vm/fzl_vm_env.c b/src/vm/fzl_vm_env.c new file mode 100644 index 0000000..f2ff358 --- /dev/null +++ b/src/vm/fzl_vm_env.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include +#include +#include + +static const fzl_value_t null = {.type = FZL_TYPE_NULL}; + +fzl_vm_env_t *fzl_mkenv() +{ + fzl_vm_env_t *env = malloc(sizeof(fzl_vm_env_t)); + env->remainder = 2; + env->size = 0; + env->table = malloc(env->remainder * sizeof(fzl_vm_env_entry_t)); + + return env; +} + +// Resize table if size eq to remainder +static void resize_env_if_needed(fzl_vm_env_t *env) +{ + if (env->remainder > env->size) + return; + + env->remainder *= 2; + env->table = realloc(env->table, env->remainder * sizeof(fzl_vm_env_entry_t)); +} + +fzl_value_t fzl_env_lookup(fzl_vm_env_t *env, char *name) +{ + if (!env) + return null; + + for (size_t i = 0; i < env->size; i++) + if (strcmp(env->table[i].name, name) == 0) + return env->table[i].value; + + return (fzl_value_t){.type = FZL_TYPE_NULL}; +} + +bool fzl_env_contains(fzl_vm_env_t *env, char *name) +{ + if (!env) + return false; + + for (size_t i = 0; i < env->size; i++) + if (strcmp(env->table[i].name, name) == 0) + return true; + + return false; +} + +fzl_vm_env_wresult_t fzl_env_storevalue(fzl_vm_env_t *env, char *name, + fzl_value_t val) +{ + if (!env) + return FZL_VM_ENV_WRESULT_ERR; + + resize_env_if_needed(env); + if (fzl_env_contains(env, name)) + return FZL_VM_ENV_WRESULT_ERR_EXISTS; + + env->table[env->size] = (fzl_vm_env_entry_t){.name = name, .value = val}; + + return FZL_VM_ENV_WRESULT_OK; +} + +fzl_vm_env_wresult_t fzl_env_writevalue(fzl_vm_env_t *env, char *name, + fzl_value_t newval) +{ + if (!env) + return FZL_VM_ENV_WRESULT_ERR; + + for (size_t i = 0; i < env->size; i++) + { + if (strcmp(env->table[i].name, name) == 0) + { + env->table[i].value = newval; + return FZL_VM_ENV_WRESULT_OK; + } + } + + return FZL_VM_ENV_WRESULT_ERR_NOT_FOUND; +} + +void fzl_freeenv(fzl_vm_env_t *env) +{ + if (!env) + return; + + if (env->table) + free(env->table); + + free(env); +}