From ebae80cf44f543ece1549c03a11d8388a918d23a Mon Sep 17 00:00:00 2001 From: hanez Date: Thu, 11 Dec 2025 01:28:38 +0100 Subject: [PATCH] Some housekeeping. (0.37.2) --- CMakeLists.txt | 2 +- src/jsonc.c | 111 --------------------------------- src/pcsc.c | 74 ---------------------- src/tk_embed.c | 0 src/vm.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 162 insertions(+), 188 deletions(-) delete mode 100644 src/jsonc.c delete mode 100644 src/pcsc.c delete mode 100644 src/tk_embed.c diff --git a/CMakeLists.txt b/CMakeLists.txt index cd001ab..ad5119f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.37.1 LANGUAGES C) +project(fun VERSION 0.37.2 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/src/jsonc.c b/src/jsonc.c deleted file mode 100644 index 5cb24c1..0000000 --- a/src/jsonc.c +++ /dev/null @@ -1,111 +0,0 @@ -/** - * This file is part of the Fun programming language. - * https://fun-lang.xyz/ - * - * Copyright 2025 Johannes Findeisen - * Licensed under the terms of the Apache-2.0 license. - * https://opensource.org/license/apache-2-0 - * - * Added: 2025-11-24 - */ - -/* json-c helpers and VM opcode cases (included from vm.c) */ - -#include "value.h" -#include "vm.h" - -#ifdef FUN_WITH_JSON - #include - #include -#endif - -/* --- Conversion helpers between json-c and Fun Value --- */ -#ifdef FUN_WITH_JSON -static Value json_to_fun(json_object *j) { - if (!j) return make_nil(); - enum json_type t = json_object_get_type(j); - switch (t) { - case json_type_null: return make_nil(); - case json_type_boolean: return make_bool(json_object_get_boolean(j)); - case json_type_double: return make_float(json_object_get_double(j)); - case json_type_int: return make_int((int64_t)json_object_get_int64(j)); - case json_type_string: return make_string(json_object_get_string(j)); - case json_type_array: { - size_t n = json_object_array_length(j); - if (n == 0) { - return make_array_from_values(NULL, 0); - } - Value *vals = (Value*)malloc(sizeof(Value) * n); - if (!vals) return make_array_from_values(NULL, 0); - for (size_t i = 0; i < n; ++i) { - json_object *item = json_object_array_get_idx(j, (int)i); - vals[i] = json_to_fun(item); - } - Value arr = make_array_from_values(vals, (int)n); - for (size_t i = 0; i < n; ++i) free_value(vals[i]); - free(vals); - return arr; - } - case json_type_object: { - Value map = make_map_empty(); - json_object_object_foreach(j, key, val) { - (void)map_set(&map, key, json_to_fun(val)); - } - return map; - } - default: - return make_nil(); - } -} - -static json_object* fun_to_json(const Value *v) { - switch (v->type) { - case VAL_NIL: return json_object_new_null(); - case VAL_BOOL: return json_object_new_boolean(v->i ? 1 : 0); - case VAL_INT: return json_object_new_int64(v->i); - case VAL_FLOAT: return json_object_new_double(v->d); - case VAL_STRING: return json_object_new_string(v->s ? v->s : ""); - case VAL_ARRAY: { - json_object *arr = json_object_new_array(); - int n = array_length(v); - for (int i = 0; i < n; ++i) { - Value item; - if (array_get_copy(v, i, &item)) { - json_object_array_add(arr, fun_to_json(&item)); - free_value(item); - } else { - json_object_array_add(arr, json_object_new_null()); - } - } - return arr; - } - case VAL_MAP: { - json_object *obj = json_object_new_object(); - /* We don't have an iterator API; use keys() helper */ - Value keys = map_keys_array(v); - int kn = array_length(&keys); - for (int i = 0; i < kn; ++i) { - Value k; - if (!array_get_copy(&keys, i, &k)) continue; - if (k.type == VAL_STRING && k.s) { - Value val; - if (map_get_copy(v, k.s, &val)) { - json_object_object_add(obj, k.s, fun_to_json(&val)); - free_value(val); - } else { - json_object_object_add(obj, k.s, json_object_new_null()); - } - } - free_value(k); - } - free_value(keys); - return obj; - } - default: - /* Fallback: stringify unsupported types */ - return json_object_new_string(""); - } -} -#endif /* FUN_WITH_JSON */ - -/* Note: The VM opcode case handlers are included from vm/vm switch via vm/json/ops.c */ diff --git a/src/pcsc.c b/src/pcsc.c deleted file mode 100644 index 1f72f45..0000000 --- a/src/pcsc.c +++ /dev/null @@ -1,74 +0,0 @@ -/** - * This file is part of the Fun programming language. - * https://fun-lang.xyz/ - * - * Copyright 2025 Johannes Findeisen - * Licensed under the terms of the Apache-2.0 license. - * https://opensource.org/license/apache-2-0 - * - * Added: 2025-10-02 - */ - - /* PCSC helpers: registries and helper functions. - * Included at file scope from vm.c. - */ -#ifdef FUN_WITH_PCSC - #if defined(__has_include) - #if __has_include() - #include - #include - #elif __has_include() - #include - #else - #error "FUN_WITH_PCSC is enabled but PCSC headers were not found" - #endif - #else - #include - #include - #endif - #include - - typedef struct { - SCARDCONTEXT ctx; - int in_use; - } pcsc_ctx_entry; - - typedef struct { - SCARDHANDLE h; - DWORD proto; - int in_use; - } pcsc_card_entry; - - static pcsc_ctx_entry g_pcsc_ctx[8]; - static pcsc_card_entry g_pcsc_card[32]; - - static int pcsc_alloc_ctx_slot(void) { - for (int i = 0; i < (int)(sizeof(g_pcsc_ctx)/sizeof(g_pcsc_ctx[0])); ++i) { - if (!g_pcsc_ctx[i].in_use) { g_pcsc_ctx[i].in_use = 1; g_pcsc_ctx[i].ctx = 0; return i + 1; } - } - return 0; - } - - static int pcsc_alloc_card_slot(void) { - for (int i = 0; i < (int)(sizeof(g_pcsc_card)/sizeof(g_pcsc_card[0])); ++i) { - if (!g_pcsc_card[i].in_use) { g_pcsc_card[i].in_use = 1; g_pcsc_card[i].h = 0; g_pcsc_card[i].proto = 0; return i + 1; } - } - return 0; - } - - static pcsc_ctx_entry* pcsc_get_ctx(int id) { - if (id <= 0) return NULL; - int idx = id - 1; - if (idx < 0 || idx >= (int)(sizeof(g_pcsc_ctx)/sizeof(g_pcsc_ctx[0]))) return NULL; - if (!g_pcsc_ctx[idx].in_use) return NULL; - return &g_pcsc_ctx[idx]; - } - - static pcsc_card_entry* pcsc_get_card(int id) { - if (id <= 0) return NULL; - int idx = id - 1; - if (idx < 0 || idx >= (int)(sizeof(g_pcsc_card)/sizeof(g_pcsc_card[0]))) return NULL; - if (!g_pcsc_card[idx].in_use) return NULL; - return &g_pcsc_card[idx]; - } -#endif /* FUN_WITH_PCSC */ diff --git a/src/tk_embed.c b/src/tk_embed.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/vm.c b/src/vm.c index 62f4f6f..7ecc8fb 100644 --- a/src/vm.c +++ b/src/vm.c @@ -20,12 +20,171 @@ #include "iter.c" #include "map.c" #include "string.c" -#include "pcsc.c" -#include "jsonc.c" +#include "value.h" +#include "vm.h" + +#ifdef FUN_WITH_PCSC + /* PCSC helpers: registries and helper functions. + * Included at file scope from vm.c. */ + #if defined(__has_include) + #if __has_include() + #include + #include + #elif __has_include() + #include + #else + #error "FUN_WITH_PCSC is enabled but PCSC headers were not found" + #endif + #else + #include + #include + #endif + #include + + typedef struct { + SCARDCONTEXT ctx; + int in_use; + } pcsc_ctx_entry; + + typedef struct { + SCARDHANDLE h; + DWORD proto; + int in_use; + } pcsc_card_entry; + + static pcsc_ctx_entry g_pcsc_ctx[8]; + static pcsc_card_entry g_pcsc_card[32]; + + static int pcsc_alloc_ctx_slot(void) { + for (int i = 0; i < (int)(sizeof(g_pcsc_ctx)/sizeof(g_pcsc_ctx[0])); ++i) { + if (!g_pcsc_ctx[i].in_use) { g_pcsc_ctx[i].in_use = 1; g_pcsc_ctx[i].ctx = 0; return i + 1; } + } + return 0; + } + + static int pcsc_alloc_card_slot(void) { + for (int i = 0; i < (int)(sizeof(g_pcsc_card)/sizeof(g_pcsc_card[0])); ++i) { + if (!g_pcsc_card[i].in_use) { g_pcsc_card[i].in_use = 1; g_pcsc_card[i].h = 0; g_pcsc_card[i].proto = 0; return i + 1; } + } + return 0; + } + + static pcsc_ctx_entry* pcsc_get_ctx(int id) { + if (id <= 0) return NULL; + int idx = id - 1; + if (idx < 0 || idx >= (int)(sizeof(g_pcsc_ctx)/sizeof(g_pcsc_ctx[0]))) return NULL; + if (!g_pcsc_ctx[idx].in_use) return NULL; + return &g_pcsc_ctx[idx]; + } + + static pcsc_card_entry* pcsc_get_card(int id) { + if (id <= 0) return NULL; + int idx = id - 1; + if (idx < 0 || idx >= (int)(sizeof(g_pcsc_card)/sizeof(g_pcsc_card[0]))) return NULL; + if (!g_pcsc_card[idx].in_use) return NULL; + return &g_pcsc_card[idx]; + } +#endif + +#ifdef FUN_WITH_JSON +/* json-c helpers and VM opcode cases (included from vm.c) */ #include "value.h" #include "vm.h" +#include +#include + +/* --- Conversion helpers between json-c and Fun Value --- */ +static Value json_to_fun(json_object *j) { + if (!j) return make_nil(); + enum json_type t = json_object_get_type(j); + switch (t) { + case json_type_null: return make_nil(); + case json_type_boolean: return make_bool(json_object_get_boolean(j)); + case json_type_double: return make_float(json_object_get_double(j)); + case json_type_int: return make_int((int64_t)json_object_get_int64(j)); + case json_type_string: return make_string(json_object_get_string(j)); + case json_type_array: { + size_t n = json_object_array_length(j); + if (n == 0) { + return make_array_from_values(NULL, 0); + } + Value *vals = (Value*)malloc(sizeof(Value) * n); + if (!vals) return make_array_from_values(NULL, 0); + for (size_t i = 0; i < n; ++i) { + json_object *item = json_object_array_get_idx(j, (int)i); + vals[i] = json_to_fun(item); + } + Value arr = make_array_from_values(vals, (int)n); + for (size_t i = 0; i < n; ++i) free_value(vals[i]); + free(vals); + return arr; + } + case json_type_object: { + Value map = make_map_empty(); + json_object_object_foreach(j, key, val) { + (void)map_set(&map, key, json_to_fun(val)); + } + return map; + } + default: + return make_nil(); + } +} + +static json_object* fun_to_json(const Value *v) { + switch (v->type) { + case VAL_NIL: return json_object_new_null(); + case VAL_BOOL: return json_object_new_boolean(v->i ? 1 : 0); + case VAL_INT: return json_object_new_int64(v->i); + case VAL_FLOAT: return json_object_new_double(v->d); + case VAL_STRING: return json_object_new_string(v->s ? v->s : ""); + case VAL_ARRAY: { + json_object *arr = json_object_new_array(); + int n = array_length(v); + for (int i = 0; i < n; ++i) { + Value item; + if (array_get_copy(v, i, &item)) { + json_object_array_add(arr, fun_to_json(&item)); + free_value(item); + } else { + json_object_array_add(arr, json_object_new_null()); + } + } + return arr; + } + case VAL_MAP: { + json_object *obj = json_object_new_object(); + /* We don't have an iterator API; use keys() helper */ + Value keys = map_keys_array(v); + int kn = array_length(&keys); + for (int i = 0; i < kn; ++i) { + Value k; + if (!array_get_copy(&keys, i, &k)) continue; + if (k.type == VAL_STRING && k.s) { + Value val; + if (map_get_copy(v, k.s, &val)) { + json_object_object_add(obj, k.s, fun_to_json(&val)); + free_value(val); + } else { + json_object_object_add(obj, k.s, json_object_new_null()); + } + } + free_value(k); + } + free_value(keys); + return obj; + } + default: + /* Fallback: stringify unsupported types */ + return json_object_new_string(""); + } +} + +/* Note: The VM opcode case handlers are included from vm/vm switch via vm/json/ops.c */ +#endif + #ifdef FUN_WITH_TCLTK #include #include