From 892fa3cfbf6c2720642c5893f05ebd251a5c7d5c Mon Sep 17 00:00:00 2001 From: hanez Date: Fri, 1 May 2026 22:19:15 +0200 Subject: [PATCH] Doxygen code comment cleanups and fixes. No code changes. (0.41.5) --- .gitignore | 2 ++ src/bytecode.h | 2 +- src/parser.c | 3 --- src/parser_utils.c | 2 +- src/vm/arithmetic/add.c | 6 +++--- src/vm/arithmetic/div.c | 10 +++++----- src/vm/arithmetic/mul.c | 10 +++++----- src/vm/arithmetic/sub.c | 10 +++++----- src/vm/arrays/apop.c | 6 +++--- src/vm/arrays/clear.c | 6 +++--- src/vm/arrays/contains.c | 6 +++--- src/vm/arrays/enumerate.c | 6 +++--- src/vm/arrays/index_get.c | 6 +++--- src/vm/arrays/index_of.c | 6 +++--- src/vm/arrays/index_set.c | 6 +++--- src/vm/arrays/insert.c | 6 +++--- src/vm/arrays/join.c | 6 +++--- src/vm/arrays/make_array.c | 6 +++--- src/vm/arrays/push.c | 6 +++--- src/vm/arrays/remove.c | 6 +++--- src/vm/arrays/set.c | 6 +++--- src/vm/arrays/slice.c | 6 +++--- src/vm/arrays/zip.c | 6 +++--- src/vm/core/dup.c | 6 +++--- src/vm/core/halt.c | 6 +++--- src/vm/core/load_global.c | 6 +++--- src/vm/core/load_local.c | 6 +++--- src/vm/core/nop.c | 6 +++--- src/vm/core/pop.c | 6 +++--- src/vm/core/return.c | 6 +++--- src/vm/core/store_global.c | 6 +++--- src/vm/core/store_local.c | 6 +++--- src/vm/echo.c | 2 -- src/vm/io/input_line.c | 8 ++++---- src/vm/io/read_file.c | 6 +++--- src/vm/io/write_file.c | 6 +++--- src/vm/len.c | 9 +++------ src/vm/logic/and.c | 6 +++--- src/vm/logic/eq.c | 6 +++--- src/vm/logic/gt.c | 7 +++---- src/vm/logic/gte.c | 6 +++--- src/vm/logic/lt.c | 6 +++--- src/vm/logic/lte.c | 6 +++--- src/vm/logic/neq.c | 6 +++--- src/vm/logic/not.c | 6 +++--- src/vm/logic/or.c | 6 +++--- src/vm/maps/keys.c | 6 +++--- src/vm/maps/make_map.c | 6 +++--- src/vm/maps/values.c | 6 +++--- src/vm/math/abs.c | 3 --- src/vm/math/clamp.c | 3 --- src/vm/math/max.c | 6 +++--- src/vm/math/min.c | 6 +++--- src/vm/math/mod.c | 6 +++--- src/vm/math/pow.c | 6 +++--- src/vm/math/random_int.c | 6 +++--- src/vm/math/random_seed.c | 6 +++--- src/vm/os/clock_mono_ms.c | 6 ++++-- src/vm/pcsc/connect.c | 4 +--- src/vm/pcsc/disconnect.c | 8 +++++--- src/vm/pcsc/establish.c | 4 +--- src/vm/pcsc/list_readers.c | 4 +--- src/vm/pcsc/release.c | 4 +--- src/vm/pcsc/transmit.c | 4 +--- src/vm/print.c | 9 +++------ src/vm/rust/get_sp.c | 5 ++--- src/vm/rust/hello.c | 4 +--- src/vm/rust/hello_args.c | 4 +--- src/vm/rust/hello_args_return.c | 5 ++--- src/vm/rust/set_exit.c | 5 ++--- src/vm/sqlite/close.c | 5 ++--- src/vm/sqlite/exec.c | 5 ++--- src/vm/sqlite/open.c | 5 ++--- src/vm/sqlite/query.c | 5 ++--- src/vm/strings/find.c | 9 +++------ src/vm/strings/regex_match.c | 1 + src/vm/strings/regex_replace.c | 1 + src/vm/strings/regex_search.c | 1 + src/vm/strings/split.c | 9 +++------ src/vm/strings/substr.c | 9 +++------ src/vm/to_number.c | 9 +++------ src/vm/to_string.c | 9 +++------ src/vm/xml/name.c | 5 +++-- src/vm/xml/parse.c | 5 +++-- src/vm/xml/root.c | 5 +++-- src/vm/xml/text.c | 5 +++-- web/images/fun-inverted.png | Bin 0 -> 14762 bytes web/images/fun-square-inverted.png | Bin 0 -> 11660 bytes 88 files changed, 224 insertions(+), 265 deletions(-) create mode 100644 web/images/fun-inverted.png create mode 100644 web/images/fun-square-inverted.png diff --git a/.gitignore b/.gitignore index 76fe259..7204966 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,9 @@ build/* build_debug/* build_release/* cmake_install.cmake +compile_commands.json database.sqlite +defines.txt demo_* dist/ downloaded.png diff --git a/src/bytecode.h b/src/bytecode.h index ad816f2..40f9b43 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -15,7 +15,7 @@ * instruction representation (@ref Instruction), and the owning bytecode * container (@ref Bytecode) together with minimal constructor/manipulation * helpers. The concrete execution semantics for each opcode are implemented - * in the VM (see vm.c and vm/* handlers). + * in the VM (see vm.c and vm/some_file.c handlers). */ #ifndef FUN_BYTECODE_H #define FUN_BYTECODE_H diff --git a/src/parser.c b/src/parser.c index d040f88..1494e8a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -38,9 +38,6 @@ * vm_run(&vm, bc); * bytecode_free(bc); * } - * - * @author Johannes Findeisen - * @date 2025-09-16 */ #include "parser.h" diff --git a/src/parser_utils.c b/src/parser_utils.c index e09152c..94cc9bf 100644 --- a/src/parser_utils.c +++ b/src/parser_utils.c @@ -82,7 +82,7 @@ static void skip_line(const char *src, size_t len, size_t *pos) { } /** - * @brief Skip whitespace, then line (//) and block (/* ... */) comments. + * @brief Skip whitespace, then line and block comments. * Continues until the next non-comment, non-whitespace character. */ static void skip_comments(const char *src, size_t len, size_t *pos) { diff --git a/src/vm/arithmetic/add.c b/src/vm/arithmetic/add.c index f8d0090..3da5df2 100644 --- a/src/vm/arithmetic/add.c +++ b/src/vm/arithmetic/add.c @@ -27,9 +27,9 @@ * - Exits with an error if memory allocation fails during string concatenation. * * Example: - * // Bytecode: OP_ADD - * // Stack before: [2, 3] - * // Stack after: [5] + * - Bytecode: OP_ADD + * - Stack before: [2, 3] + * - Stack after: [5] */ case OP_ADD: { diff --git a/src/vm/arithmetic/div.c b/src/vm/arithmetic/div.c index f2c9018..ddce280 100644 --- a/src/vm/arithmetic/div.c +++ b/src/vm/arithmetic/div.c @@ -26,11 +26,11 @@ * - Raises a runtime error on division by zero (both integer and floating cases). * * Example: - * // Bytecode: OP_DIV - * // Stack before: [10, 2] - * // Stack after: [5] - * // Stack before: [5.0, 2] - * // Stack after: [2.5] + * - Bytecode: OP_DIV + * - Stack before: [10, 2] + * - Stack after: [5] + * - Stack before: [5.0, 2] + * - Stack after: [2.5] */ case OP_DIV: { diff --git a/src/vm/arithmetic/mul.c b/src/vm/arithmetic/mul.c index cd63051..95c1f4b 100644 --- a/src/vm/arithmetic/mul.c +++ b/src/vm/arithmetic/mul.c @@ -25,11 +25,11 @@ * - Raises a runtime error and aborts execution if operands are not numeric. * * Example: - * // Bytecode: OP_MUL - * // Stack before: [3, 4] - * // Stack after: [12] - * // Stack before: [2.5, 4] - * // Stack after: [10.0] + * - Bytecode: OP_MUL + * - Stack before: [3, 4] + * - Stack after: [12] + * - Stack before: [2.5, 4] + * - Stack after: [10.0] */ case OP_MUL: { diff --git a/src/vm/arithmetic/sub.c b/src/vm/arithmetic/sub.c index 8ccbeb5..5e62c77 100644 --- a/src/vm/arithmetic/sub.c +++ b/src/vm/arithmetic/sub.c @@ -25,11 +25,11 @@ * - Raises a runtime error and aborts execution if operands are not numeric. * * Example: - * // Bytecode: OP_SUB - * // Stack before: [10, 4] - * // Stack after: [6] - * // Stack before: [10.0, 3] - * // Stack after: [7.0] + * - Bytecode: OP_SUB + * - Stack before: [10, 4] + * - Stack after: [6] + * - Stack before: [10.0, 3] + * - Stack after: [7.0] */ case OP_SUB: { diff --git a/src/vm/arrays/apop.c b/src/vm/arrays/apop.c index ec3cfb6..e6f2f5e 100644 --- a/src/vm/arrays/apop.c +++ b/src/vm/arrays/apop.c @@ -24,9 +24,9 @@ * - Exits with an error if the array is empty. * * Example: - * // Bytecode: OP_APOP - * // Stack before: [[10, 20, 30]] - * // Stack after: [30] + * - Bytecode: OP_APOP + * - Stack before: [[10, 20, 30]] + * - Stack after: [30] */ case OP_APOP: { diff --git a/src/vm/arrays/clear.c b/src/vm/arrays/clear.c index eb3ccfd..47a5c72 100644 --- a/src/vm/arrays/clear.c +++ b/src/vm/arrays/clear.c @@ -24,9 +24,9 @@ * - Exits with a runtime error if the operand is not an array. * Example: - * // Bytecode: OP_CLEAR - * // Stack before: [[10, 20, 30]] - * // Stack after: [0] + * - Bytecode: OP_CLEAR + * - Stack before: [[10, 20, 30]] + * - Stack after: [0] */ case OP_CLEAR: { diff --git a/src/vm/arrays/contains.c b/src/vm/arrays/contains.c index 1e36a75..8722750 100644 --- a/src/vm/arrays/contains.c +++ b/src/vm/arrays/contains.c @@ -23,9 +23,9 @@ * - Exits with an error if the array is of the wrong type. * * Example: - * // Bytecode: OP_CONTAINS - * // Stack before: [20, [10, 20, 30]] - * // Stack after: [1] + * - Bytecode: OP_CONTAINS + * - Stack before: [20, [10, 20, 30]] + * - Stack after: [1] */ case OP_CONTAINS: { diff --git a/src/vm/arrays/enumerate.c b/src/vm/arrays/enumerate.c index a42c129..aa4cb56 100644 --- a/src/vm/arrays/enumerate.c +++ b/src/vm/arrays/enumerate.c @@ -23,9 +23,9 @@ * - Exits with an error if the array is of the wrong type. * * Example: - * // Bytecode: OP_ENUMERATE - * // Stack before: [[10, 20, 30]] - * // Stack after: [[[0, 10], [1, 20], [2, 30]]] + * - Bytecode: OP_ENUMERATE + * - Stack before: [[10, 20, 30]] + * - Stack after: [[[0, 10], [1, 20], [2, 30]]] */ case OP_ENUMERATE: { diff --git a/src/vm/arrays/index_get.c b/src/vm/arrays/index_get.c index 52a460b..ce02832 100644 --- a/src/vm/arrays/index_get.c +++ b/src/vm/arrays/index_get.c @@ -25,9 +25,9 @@ * is of the wrong type, or if the index is out of bounds. * * Example: - * // Bytecode: OP_INDEX_GET - * // Stack before: [1, [10, 20, 30]] - * // Stack after: [20] + * - Bytecode: OP_INDEX_GET + * - Stack before: [1, [10, 20, 30]] + * - Stack after: [20] */ case OP_INDEX_GET: { diff --git a/src/vm/arrays/index_of.c b/src/vm/arrays/index_of.c index f1bb38f..031e835 100644 --- a/src/vm/arrays/index_of.c +++ b/src/vm/arrays/index_of.c @@ -23,9 +23,9 @@ * - Exits with an error if the array is of the wrong type. * * Example: - * // Bytecode: OP_INDEX_OF - * // Stack before: [20, [10, 20, 30]] - * // Stack after: [1] + * - Bytecode: OP_INDEX_OF + * - Stack before: [20, [10, 20, 30]] + * - Stack after: [1] */ case OP_INDEX_OF: { diff --git a/src/vm/arrays/index_set.c b/src/vm/arrays/index_set.c index 2691ddd..06aa671 100644 --- a/src/vm/arrays/index_set.c +++ b/src/vm/arrays/index_set.c @@ -24,9 +24,9 @@ * is of the wrong type, or if the index is out of bounds. * * Example: - * // Bytecode: OP_INDEX_SET - * // Stack before: [42, 1, [10, 20, 30]] - * // Stack after: [[10, 42, 30]] + * - Bytecode: OP_INDEX_SET + * - Stack before: [42, 1, [10, 20, 30]] + * - Stack after: [[10, 42, 30]] */ case OP_INDEX_SET: { diff --git a/src/vm/arrays/insert.c b/src/vm/arrays/insert.c index 49beed7..6d7ee71 100644 --- a/src/vm/arrays/insert.c +++ b/src/vm/arrays/insert.c @@ -25,9 +25,9 @@ * - Exits with an error if memory allocation fails during the insertion. * * Example: - * // Bytecode: OP_INSERT - * // Stack before: [42, 1, [10, 20, 30]] - * // Stack after: [4] + * - Bytecode: OP_INSERT + * - Stack before: [42, 1, [10, 20, 30]] + * - Stack after: [4] */ case OP_INSERT: { diff --git a/src/vm/arrays/join.c b/src/vm/arrays/join.c index a5031ef..52eb118 100644 --- a/src/vm/arrays/join.c +++ b/src/vm/arrays/join.c @@ -24,9 +24,9 @@ * - Exits with an error if the array or separator is of the wrong type. * * Example: - * // Bytecode: OP_JOIN - * // Stack before: [", ", ["a", "b", "c"]] - * // Stack after: ["a, b, c"] + * - Bytecode: OP_JOIN + * - Stack before: [", ", ["a", "b", "c"]] + * - Stack after: ["a, b, c"] */ case OP_JOIN: { diff --git a/src/vm/arrays/make_array.c b/src/vm/arrays/make_array.c index b454f2b..b775d35 100644 --- a/src/vm/arrays/make_array.c +++ b/src/vm/arrays/make_array.c @@ -24,9 +24,9 @@ * - Exits with an error if `n` is invalid or if memory allocation fails. * * Example: - * // Bytecode: OP_MAKE_ARRAY 3 - * // Stack before: [1, 2, 3] - * // Stack after: [[1, 2, 3]] + * - Bytecode: OP_MAKE_ARRAY 3 + * - Stack before: [1, 2, 3] + * - Stack after: [[1, 2, 3]] */ case OP_MAKE_ARRAY: { diff --git a/src/vm/arrays/push.c b/src/vm/arrays/push.c index 2dd74c9..7d7c45c 100644 --- a/src/vm/arrays/push.c +++ b/src/vm/arrays/push.c @@ -25,9 +25,9 @@ * - Exits with a runtime error if memory allocation fails. * * Example: - * // Bytecode: OP_PUSH - * // Stack before: [42, [10, 20, 30]] - * // Stack after: [4] + * - Bytecode: OP_PUSH + * - Stack before: [42, [10, 20, 30]] + * - Stack after: [4] */ case OP_PUSH: { diff --git a/src/vm/arrays/remove.c b/src/vm/arrays/remove.c index 10da29c..df0fed3 100644 --- a/src/vm/arrays/remove.c +++ b/src/vm/arrays/remove.c @@ -25,9 +25,9 @@ * - Exits with a runtime error if the index is out of bounds. * * Example: - * // Bytecode: OP_REMOVE - * // Stack before: [1, [10, 20, 30]] - * // Stack after: [20] + * - Bytecode: OP_REMOVE + * - Stack before: [1, [10, 20, 30]] + * - Stack after: [20] */ case OP_REMOVE: { diff --git a/src/vm/arrays/set.c b/src/vm/arrays/set.c index bf0e4a5..44c7633 100644 --- a/src/vm/arrays/set.c +++ b/src/vm/arrays/set.c @@ -25,9 +25,9 @@ * - Exits with a runtime error if the index is out of bounds. * * Example: - * // Bytecode: OP_SET - * // Stack before: [42, 1, [10, 20, 30]] - * // Stack after: [42] + * - Bytecode: OP_SET + * - Stack before: [42, 1, [10, 20, 30]] + * - Stack after: [42] */ case OP_SET: { diff --git a/src/vm/arrays/slice.c b/src/vm/arrays/slice.c index e057413..e6aaae8 100644 --- a/src/vm/arrays/slice.c +++ b/src/vm/arrays/slice.c @@ -24,9 +24,9 @@ * - Handles negative indices and out-of-bounds cases gracefully * * Example: - * // Bytecode: OP_SLICE - * // Stack before: [3, 1, [10,20,30,40]] - * // Stack after: [[20,30]] + * - Bytecode: OP_SLICE + * - Stack before: [3, 1, [10,20,30,40]] + * - Stack after: [[20,30]] */ case OP_SLICE: { diff --git a/src/vm/arrays/zip.c b/src/vm/arrays/zip.c index 3a284df..a778689 100644 --- a/src/vm/arrays/zip.c +++ b/src/vm/arrays/zip.c @@ -24,9 +24,9 @@ * - Exits with error if arguments aren't arrays * * Example: - * // Bytecode: OP_ZIP - * // Stack before: [[1,2], ['a','b']] - * // Stack after: [[[1,'a'], [2,'b']]] + * - Bytecode: OP_ZIP + * - Stack before: [[1,2], ['a','b']] + * - Stack after: [[[1,'a'], [2,'b']]] */ case OP_ZIP: { diff --git a/src/vm/core/dup.c b/src/vm/core/dup.c index d6912cc..fc6c95f 100644 --- a/src/vm/core/dup.c +++ b/src/vm/core/dup.c @@ -22,9 +22,9 @@ * - Exits with an error if the stack is empty. * * Example: - * // Bytecode: OP_DUP - * // Stack before: [42] - * // Stack after: [42, 42] + * - Bytecode: OP_DUP + * - Stack before: [42] + * - Stack after: [42, 42] */ case OP_DUP: { diff --git a/src/vm/core/halt.c b/src/vm/core/halt.c index d53a37e..3c8f947 100644 --- a/src/vm/core/halt.c +++ b/src/vm/core/halt.c @@ -18,9 +18,9 @@ * - Stops the VM execution immediately. * * Example: - * // Bytecode: OP_HALT - * // Stack before: [42] - * // Stack after: [42] + * - Bytecode: OP_HALT + * - Stack before: [42] + * - Stack after: [42] */ case OP_HALT: diff --git a/src/vm/core/load_global.c b/src/vm/core/load_global.c index 6c873d8..114855f 100644 --- a/src/vm/core/load_global.c +++ b/src/vm/core/load_global.c @@ -22,9 +22,9 @@ * - Exits with an error if the index is out of bounds. * * Example: - * // Bytecode: OP_LOAD_GLOBAL 0 - * // Stack before: [] - * // Stack after: [global_value] + * - Bytecode: OP_LOAD_GLOBAL 0 + * - Stack before: [] + * - Stack after: [global_value] */ case OP_LOAD_GLOBAL: { diff --git a/src/vm/core/load_local.c b/src/vm/core/load_local.c index b12fcd1..83b5eb2 100644 --- a/src/vm/core/load_local.c +++ b/src/vm/core/load_local.c @@ -22,9 +22,9 @@ * - Exits with an error if the index is out of bounds. * * Example: - * // Bytecode: OP_LOAD_LOCAL 0 - * // Stack before: [] - * // Stack after: [local_value] + * - Bytecode: OP_LOAD_LOCAL 0 + * - Stack before: [] + * - Stack after: [local_value] */ case OP_LOAD_LOCAL: { diff --git a/src/vm/core/nop.c b/src/vm/core/nop.c index eb2331e..f0034e3 100644 --- a/src/vm/core/nop.c +++ b/src/vm/core/nop.c @@ -18,9 +18,9 @@ * - Does nothing. * * Example: - * // Bytecode: OP_NOP - * // Stack before: [42] - * // Stack after: [42] + * - Bytecode: OP_NOP + * - Stack before: [42] + * - Stack after: [42] */ case OP_NOP: diff --git a/src/vm/core/pop.c b/src/vm/core/pop.c index 891b81e..5cc3d02 100644 --- a/src/vm/core/pop.c +++ b/src/vm/core/pop.c @@ -20,9 +20,9 @@ * - Exits with an error if the stack is empty. * * Example: - * // Bytecode: OP_POP - * // Stack before: [42] - * // Stack after: [] + * - Bytecode: OP_POP + * - Stack before: [42] + * - Stack after: [] */ case OP_POP: { diff --git a/src/vm/core/return.c b/src/vm/core/return.c index 32501eb..de442c5 100644 --- a/src/vm/core/return.c +++ b/src/vm/core/return.c @@ -23,9 +23,9 @@ * - Exits with an error if the frame stack is empty. * * Example: - * // Bytecode: OP_RETURN - * // Stack before: [42] - * // Stack after: [42] + * - Bytecode: OP_RETURN + * - Stack before: [42] + * - Stack after: [42] */ case OP_RETURN: { diff --git a/src/vm/core/store_global.c b/src/vm/core/store_global.c index c20b52e..e02deaf 100644 --- a/src/vm/core/store_global.c +++ b/src/vm/core/store_global.c @@ -22,9 +22,9 @@ * - Exits with an error if the index is out of bounds. * * Example: - * // Bytecode: OP_STORE_GLOBAL 0 - * // Stack before: [42] - * // Stack after: [] + * - Bytecode: OP_STORE_GLOBAL 0 + * - Stack before: [42] + * - Stack after: [] */ case OP_STORE_GLOBAL: { diff --git a/src/vm/core/store_local.c b/src/vm/core/store_local.c index 776b713..c731854 100644 --- a/src/vm/core/store_local.c +++ b/src/vm/core/store_local.c @@ -22,9 +22,9 @@ * - Exits with an error if the index is out of bounds. * * Example: - * // Bytecode: OP_STORE_LOCAL 0 - * // Stack before: [42] - * // Stack after: [] + * - Bytecode: OP_STORE_LOCAL 0 + * - Stack before: [42] + * - Stack after: [] */ case OP_STORE_LOCAL: { diff --git a/src/vm/echo.c b/src/vm/echo.c index 1aa041e..148c9aa 100644 --- a/src/vm/echo.c +++ b/src/vm/echo.c @@ -21,8 +21,6 @@ * - Pushes: (none) */ -/* Implements OP_ECHO: print top-of-stack value without trailing newline. */ - case OP_ECHO: { Value v = pop_value(vm); Value snap = deep_copy_value(&v); diff --git a/src/vm/io/input_line.c b/src/vm/io/input_line.c index d6cfb86..66f5e9e 100644 --- a/src/vm/io/input_line.c +++ b/src/vm/io/input_line.c @@ -43,10 +43,10 @@ * - EOF before any character yields an empty string. * * Example: - * // Bytecode: [optional PUSH prompt], OP_INPUT_LINE(operand) - * // operand bit0=1 (has prompt), bit1=2 (hidden) can be combined - * // Stack before (bit0=1): ["Enter password: "] - * // Stack after: ["user-typed-line"] + * - Bytecode: [optional PUSH prompt], OP_INPUT_LINE(operand) + * - operand bit0=1 (has prompt), bit1=2 (hidden) can be combined + * - Stack before (bit0=1): ["Enter password: "] + * - Stack after: ["user-typed-line"] */ case OP_INPUT_LINE: { diff --git a/src/vm/io/read_file.c b/src/vm/io/read_file.c index 8813368..f7b5ed7 100644 --- a/src/vm/io/read_file.c +++ b/src/vm/io/read_file.c @@ -23,9 +23,9 @@ * - Exits with an error if the file path is invalid or the file cannot be read. * * Example: - * // Bytecode: OP_READ_FILE - * // Stack before: ["file.txt"] - * // Stack after: ["file contents"] + * - Bytecode: OP_READ_FILE + * - Stack before: ["file.txt"] + * - Stack after: ["file contents"] */ case OP_READ_FILE: { diff --git a/src/vm/io/write_file.c b/src/vm/io/write_file.c index e77812f..bc99e0d 100644 --- a/src/vm/io/write_file.c +++ b/src/vm/io/write_file.c @@ -23,9 +23,9 @@ * - Exits with an error if the file path is invalid or the file cannot be written. * * Example: - * // Bytecode: OP_WRITE_FILE - * // Stack before: ["file.txt", "data"] - * // Stack after: [1] + * - Bytecode: OP_WRITE_FILE + * - Stack before: ["file.txt", "data"] + * - Stack after: [1] */ case OP_WRITE_FILE: { diff --git a/src/vm/len.c b/src/vm/len.c index 06583f0..78a6eb7 100644 --- a/src/vm/len.c +++ b/src/vm/len.c @@ -23,12 +23,9 @@ * - Exits with an error if the operand is not an array or string. * * Example: - * // Bytecode: OP_LEN - * // Stack before: ["hello"] - * // Stack after: [5] - * - * @author Johannes Findeisen - * @date 2025-09-16 + * - Bytecode: OP_LEN + * - Stack before: ["hello"] + * - Stack after: [5] */ case OP_LEN: { diff --git a/src/vm/logic/and.c b/src/vm/logic/and.c index ddb6123..3e0449f 100644 --- a/src/vm/logic/and.c +++ b/src/vm/logic/and.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are not boolean values. * * Example: - * // Bytecode: OP_AND - * // Stack before: [1, 0] - * // Stack after: [0] + * - Bytecode: OP_AND + * - Stack before: [1, 0] + * - Stack after: [0] */ case OP_AND: { diff --git a/src/vm/logic/eq.c b/src/vm/logic/eq.c index 715a031..4f92022 100644 --- a/src/vm/logic/eq.c +++ b/src/vm/logic/eq.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * // Bytecode: OP_EQ - * // Stack before: [42, 42] - * // Stack after: [1] + * - Bytecode: OP_EQ + * - Stack before: [42, 42] + * - Stack after: [1] */ case OP_EQ: { diff --git a/src/vm/logic/gt.c b/src/vm/logic/gt.c index 3d9691f..9ef2c4f 100644 --- a/src/vm/logic/gt.c +++ b/src/vm/logic/gt.c @@ -23,10 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * ```c - * // Bytecode: OP_GT - * // Stack before: [42, 10] - * // Stack after: [1] + * - Bytecode: OP_GT + * - Stack before: [42, 10] + * - Stack after: [1] */ case OP_GT: { diff --git a/src/vm/logic/gte.c b/src/vm/logic/gte.c index 1121777..67b6c0c 100644 --- a/src/vm/logic/gte.c +++ b/src/vm/logic/gte.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * // Bytecode: OP_GTE - * // Stack before: [42, 42] - * // Stack after: [1] + * - Bytecode: OP_GTE + * - Stack before: [42, 42] + * - Stack after: [1] */ case OP_GTE: { diff --git a/src/vm/logic/lt.c b/src/vm/logic/lt.c index 103f334..6c52085 100644 --- a/src/vm/logic/lt.c +++ b/src/vm/logic/lt.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * // Bytecode: OP_LT - * // Stack before: [10, 42] - * // Stack after: [1] + * - Bytecode: OP_LT + * - Stack before: [10, 42] + * - Stack after: [1] */ case OP_LT: { diff --git a/src/vm/logic/lte.c b/src/vm/logic/lte.c index 721d000..2b9dbf1 100644 --- a/src/vm/logic/lte.c +++ b/src/vm/logic/lte.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * // Bytecode: OP_LTE - * // Stack before: [42, 42] - * // Stack after: [1] + * - Bytecode: OP_LTE + * - Stack before: [42, 42] + * - Stack after: [1] */ case OP_LTE: { diff --git a/src/vm/logic/neq.c b/src/vm/logic/neq.c index 92720a9..8b2b7f2 100644 --- a/src/vm/logic/neq.c +++ b/src/vm/logic/neq.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are of incompatible types. * * Example: - * // Bytecode: OP_NEQ - * // Stack before: [42, 10] - * // Stack after: [1] + * - Bytecode: OP_NEQ + * - Stack before: [42, 10] + * - Stack after: [1] */ case OP_NEQ: { diff --git a/src/vm/logic/not.c b/src/vm/logic/not.c index 8a78370..133c9e3 100644 --- a/src/vm/logic/not.c +++ b/src/vm/logic/not.c @@ -23,9 +23,9 @@ * - Exits with an error if the operand is not a boolean value. * * Example: - * // Bytecode: OP_NOT - * // Stack before: [0] - * // Stack after: [1] + * - Bytecode: OP_NOT + * - Stack before: [0] + * - Stack after: [1] */ case OP_NOT: { diff --git a/src/vm/logic/or.c b/src/vm/logic/or.c index 6c89029..8d1b888 100644 --- a/src/vm/logic/or.c +++ b/src/vm/logic/or.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are not boolean values. * * Example: - * // Bytecode: OP_OR - * // Stack before: [1, 0] - * // Stack after: [1] + * - Bytecode: OP_OR + * - Stack before: [1, 0] + * - Stack after: [1] */ case OP_OR: { diff --git a/src/vm/maps/keys.c b/src/vm/maps/keys.c index 074342e..bdc75ad 100644 --- a/src/vm/maps/keys.c +++ b/src/vm/maps/keys.c @@ -23,9 +23,9 @@ * - Exits with an error if the map is of the wrong type. * * Example: - * // Bytecode: OP_KEYS - * // Stack before: [{"a": 1, "b": 2}] - * // Stack after: [["a", "b"]] + * - Bytecode: OP_KEYS + * - Stack before: [{"a": 1, "b": 2}] + * - Stack after: [["a", "b"]] */ case OP_KEYS: { diff --git a/src/vm/maps/make_map.c b/src/vm/maps/make_map.c index b39f433..11af895 100644 --- a/src/vm/maps/make_map.c +++ b/src/vm/maps/make_map.c @@ -25,9 +25,9 @@ * or if map construction fails. * * Example: - * // Bytecode: OP_MAKE_MAP 2 - * // Stack before: ["key1", 1, "key2", 2] - * // Stack after: [{"key1": 1, "key2": 2}] + * - Bytecode: OP_MAKE_MAP 2 + * - Stack before: ["key1", 1, "key2", 2] + * - Stack after: [{"key1": 1, "key2": 2}] */ case OP_MAKE_MAP: { diff --git a/src/vm/maps/values.c b/src/vm/maps/values.c index 3a2838a..34e405f 100644 --- a/src/vm/maps/values.c +++ b/src/vm/maps/values.c @@ -23,9 +23,9 @@ * - Exits with an error if the map is of the wrong type. * * Example: - * // Bytecode: OP_VALUES - * // Stack before: [{"a": 1, "b": 2}] - * // Stack after: [[1, 2]] + * - Bytecode: OP_VALUES + * - Stack before: [{"a": 1, "b": 2}] + * - Stack after: [[1, 2]] */ case OP_VALUES: { diff --git a/src/vm/math/abs.c b/src/vm/math/abs.c index 537a998..88b2261 100644 --- a/src/vm/math/abs.c +++ b/src/vm/math/abs.c @@ -20,9 +20,6 @@ * * Error Handling: * - Exits if not integer - * - * @author Johannes Findeisen - * @date 2025-10-16 */ case OP_ABS: { diff --git a/src/vm/math/clamp.c b/src/vm/math/clamp.c index c155596..e6cc88f 100644 --- a/src/vm/math/clamp.c +++ b/src/vm/math/clamp.c @@ -21,9 +21,6 @@ * Error Handling: * - Exits if arguments wrong types * - Handles hi < lo case - * - * @author Johannes Findeisen - * @date 2025-10-16 */ case OP_CLAMP: { diff --git a/src/vm/math/max.c b/src/vm/math/max.c index 7b8913a..04421c5 100644 --- a/src/vm/math/max.c +++ b/src/vm/math/max.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are not integers. * * Example: - * // Bytecode: OP_MAX - * // Stack before: [10, 42] - * // Stack after: [42] + * - Bytecode: OP_MAX + * - Stack before: [10, 42] + * - Stack after: [42] */ case OP_MAX: { diff --git a/src/vm/math/min.c b/src/vm/math/min.c index 4e0086b..fcef72a 100644 --- a/src/vm/math/min.c +++ b/src/vm/math/min.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are not integers. * * Example: - * // Bytecode: OP_MIN - * // Stack before: [10, 42] - * // Stack after: [10] + * - Bytecode: OP_MIN + * - Stack before: [10, 42] + * - Stack after: [10] */ case OP_MIN: { diff --git a/src/vm/math/mod.c b/src/vm/math/mod.c index e5213c6..e91d757 100644 --- a/src/vm/math/mod.c +++ b/src/vm/math/mod.c @@ -24,9 +24,9 @@ * - Exits with an error if the second operand is zero. * * Example: - * // Bytecode: OP_MOD - * // Stack before: [10, 3] - * // Stack after: [1] + * - Bytecode: OP_MOD + * - Stack before: [10, 3] + * - Stack after: [1] */ case OP_MOD: { diff --git a/src/vm/math/pow.c b/src/vm/math/pow.c index a2c9b16..a217c00 100644 --- a/src/vm/math/pow.c +++ b/src/vm/math/pow.c @@ -23,9 +23,9 @@ * - Exits with an error if the operands are not integers. * * Example: - * // Bytecode: OP_POW - * // Stack before: [2, 3] - * // Stack after: [8] + * - Bytecode: OP_POW + * - Stack before: [2, 3] + * - Stack after: [8] */ case OP_POW: { diff --git a/src/vm/math/random_int.c b/src/vm/math/random_int.c index 4b7811d..25574e2 100644 --- a/src/vm/math/random_int.c +++ b/src/vm/math/random_int.c @@ -25,9 +25,9 @@ * - Exits with an error if the lower bound is greater than the upper bound. * * Example: - * // Bytecode: OP_RANDOM_INT - * // Stack before: [10, 1] - * // Stack after: [7] + * - Bytecode: OP_RANDOM_INT + * - Stack before: [10, 1] + * - Stack after: [7] */ case OP_RANDOM_INT: { diff --git a/src/vm/math/random_seed.c b/src/vm/math/random_seed.c index c59df89..714f4cf 100644 --- a/src/vm/math/random_seed.c +++ b/src/vm/math/random_seed.c @@ -22,9 +22,9 @@ * - Exits with an error if the seed is not an integer. * * Example: - * // Bytecode: OP_RANDOM_SEED - * // Stack before: [42] - * // Stack after: [] + * - Bytecode: OP_RANDOM_SEED + * - Stack before: [42] + * - Stack after: [] */ case OP_RANDOM_SEED: { diff --git a/src/vm/os/clock_mono_ms.c b/src/vm/os/clock_mono_ms.c index be09e0b..b2aa720 100644 --- a/src/vm/os/clock_mono_ms.c +++ b/src/vm/os/clock_mono_ms.c @@ -11,8 +11,10 @@ * @file clock_mono_ms.c * @brief Implements OP_CLOCK_MONO_MS to push monotonic clock in ms. * - * Stack before: [] - * Stack after: [int ms] + * Example: + * - OP_CLOCK_MONO_MS + * - Stack before: [] + * - Stack after: [int ms] */ #include diff --git a/src/vm/pcsc/connect.c b/src/vm/pcsc/connect.c index 3f79293..5712f67 100644 --- a/src/vm/pcsc/connect.c +++ b/src/vm/pcsc/connect.c @@ -14,9 +14,7 @@ * Connects to a smart card in the specified reader using an existing PC/SC * context. On success, allocates/returns a card handle id from the internal * registry. When PCSC support is disabled at build time, this opcode returns 0. - */ - -/** + * * OP_PCSC_CONNECT: (ctx_id:int, reader_name:any) -> int * * - Pops: reader_name (converted to string), then ctx_id. diff --git a/src/vm/pcsc/disconnect.c b/src/vm/pcsc/disconnect.c index 4c01da2..0f62e3a 100644 --- a/src/vm/pcsc/disconnect.c +++ b/src/vm/pcsc/disconnect.c @@ -14,9 +14,7 @@ * Disconnects a previously connected smart-card handle and frees the * corresponding registry slot. When PCSC support is disabled at build time, * this opcode returns 0 after consuming its argument. - */ - -/** + * * OP_PCSC_DISCONNECT: (handle_id:int) -> int * * - Pops: handle_id. @@ -24,6 +22,10 @@ * - Notes: Uses SCardDisconnect(..., SCARD_LEAVE_CARD). */ +/** + + */ + /* PCSC disconnect */ case OP_PCSC_DISCONNECT: { #ifdef FUN_WITH_PCSC diff --git a/src/vm/pcsc/establish.c b/src/vm/pcsc/establish.c index d6af7c2..a5c0f59 100644 --- a/src/vm/pcsc/establish.c +++ b/src/vm/pcsc/establish.c @@ -15,9 +15,7 @@ * and registers it in the internal PCSC context registry when FUN_WITH_PCSC * is enabled. Returns the allocated context id on success, or 0 on failure. * When PCSC support is disabled at build time, this opcode returns 0. - */ - -/** + * * OP_PCSC_ESTABLISH: () -> int * * - Returns: context id (>0) on success; 0 on error or when disabled. diff --git a/src/vm/pcsc/list_readers.c b/src/vm/pcsc/list_readers.c index 8cbf7e1..f6ff1f7 100644 --- a/src/vm/pcsc/list_readers.c +++ b/src/vm/pcsc/list_readers.c @@ -14,9 +14,7 @@ * Lists available PC/SC reader names for a given context. On success returns * an array of strings. When PCSC support is disabled at build time, returns an * empty array after consuming its argument to keep the stack balanced. - */ - -/** + * * OP_PCSC_LIST_READERS: (ctx_id:int) -> array * * - Pops: ctx_id. diff --git a/src/vm/pcsc/release.c b/src/vm/pcsc/release.c index 72d2c58..179e27f 100644 --- a/src/vm/pcsc/release.c +++ b/src/vm/pcsc/release.c @@ -14,9 +14,7 @@ * Releases a previously established PC/SC context and frees its registry slot. * When PCSC support is disabled at build time, this opcode returns 0 after * consuming its argument. - */ - -/** + * * OP_PCSC_RELEASE: (ctx_id:int) -> int * * - Pops: ctx_id. diff --git a/src/vm/pcsc/transmit.c b/src/vm/pcsc/transmit.c index 5d37368..f1642fa 100644 --- a/src/vm/pcsc/transmit.c +++ b/src/vm/pcsc/transmit.c @@ -15,9 +15,7 @@ * handle. Returns a map with the response bytes and status words. When PCSC * support is disabled at build time, consumes its arguments and returns a map * with code = -2. - */ - -/** + * * OP_PCSC_TRANSMIT: (handle_id:int, apdu:array) -> map * * - Pops: apdu array, then handle_id. diff --git a/src/vm/print.c b/src/vm/print.c index 0c4a78b..ba4e79e 100644 --- a/src/vm/print.c +++ b/src/vm/print.c @@ -19,12 +19,9 @@ * - Prints the value to the output buffer. * * Example: - * // Bytecode: OP_PRINT - * // Stack before: [42] - * // Stack after: [] - * - * @author Johannes Findeisen - * @date 2025-09-16 + * - Bytecode: OP_PRINT + * - Stack before: [42] + * - Stack after: [] */ case OP_PRINT: { diff --git a/src/vm/rust/get_sp.c b/src/vm/rust/get_sp.c index 09c3b42..6cd864c 100644 --- a/src/vm/rust/get_sp.c +++ b/src/vm/rust/get_sp.c @@ -14,9 +14,7 @@ * Delegates to a Rust helper to read the VM's current stack pointer (sp). * When Rust support is disabled, this raises a runtime error and pushes -1 to * signal unavailability. - */ - -/** + * * OP_RUST_GET_SP: () -> int | Nil * * Behavior (FUN_WITH_RUST=ON): @@ -28,6 +26,7 @@ * - Raises a runtime error indicating missing Rust support. * - Pushes integer -1 as a sentinel value. */ + case OP_RUST_GET_SP: { #ifdef FUN_WITH_RUST extern int fun_op_rget_sp(VM * vm); diff --git a/src/vm/rust/hello.c b/src/vm/rust/hello.c index 8cfaa04..c3dc799 100644 --- a/src/vm/rust/hello.c +++ b/src/vm/rust/hello.c @@ -16,9 +16,7 @@ * Rust and pushes it as a VAL_STRING onto the VM stack. When Rust support is * disabled, a runtime error is raised and Nil is pushed to keep stack * consistency. - */ - -/** + * * OP_RUST_HELLO: () -> string | Nil * * Behavior (FUN_WITH_RUST=ON): diff --git a/src/vm/rust/hello_args.c b/src/vm/rust/hello_args.c index 09f9703..104f4ce 100644 --- a/src/vm/rust/hello_args.c +++ b/src/vm/rust/hello_args.c @@ -15,9 +15,6 @@ * string, calls into Rust to print/log it, and pushes Nil. When Rust support is * disabled, the argument is still popped and freed to keep the stack sane, * then Nil is pushed after raising an error message. - */ - -/** * OP_RUST_HELLO_ARGS: (msg:any) -> Nil * * Behavior (FUN_WITH_RUST=ON): @@ -31,6 +28,7 @@ * - Raises a runtime error indicating missing Rust support. * - Pushes Nil. */ + case OP_RUST_HELLO_ARGS: { #ifdef FUN_WITH_RUST Value vmsg = pop_value(vm); diff --git a/src/vm/rust/hello_args_return.c b/src/vm/rust/hello_args_return.c index 8b06521..7b73247 100644 --- a/src/vm/rust/hello_args_return.c +++ b/src/vm/rust/hello_args_return.c @@ -15,9 +15,7 @@ * converts it to a C string, passes it to Rust, and pushes back the string * returned by Rust. If Rust returns NULL or Rust support is disabled, Nil is * pushed. - */ - -/** + * * OP_RUST_HELLO_ARGS_RETURN: (msg:any) -> string | Nil * * Behavior (FUN_WITH_RUST=ON): @@ -33,6 +31,7 @@ * - Raises a runtime error indicating missing Rust support. * - Pushes Nil. */ + case OP_RUST_HELLO_ARGS_RETURN: { #ifdef FUN_WITH_RUST Value vmsg = pop_value(vm); diff --git a/src/vm/rust/set_exit.c b/src/vm/rust/set_exit.c index 27622e0..cd24a9e 100644 --- a/src/vm/rust/set_exit.c +++ b/src/vm/rust/set_exit.c @@ -15,9 +15,7 @@ * vm.exit_code. Pushes Nil afterwards. When Rust support is disabled, the * argument is still popped/freed, a runtime error is raised, and Nil is * pushed to maintain stack discipline. - */ - -/** + * * OP_RUST_SET_EXIT: (code:int) -> Nil * * Behavior (FUN_WITH_RUST=ON): @@ -30,6 +28,7 @@ * - Raises a runtime error indicating missing Rust support. * - Pushes Nil. */ + case OP_RUST_SET_EXIT: { #ifdef FUN_WITH_RUST extern int fun_op_rset_exit(VM * vm); diff --git a/src/vm/sqlite/close.c b/src/vm/sqlite/close.c index 3b5ecc7..f31312f 100644 --- a/src/vm/sqlite/close.c +++ b/src/vm/sqlite/close.c @@ -13,11 +13,10 @@ * * Closes a registered SQLite database handle and unregisters it when * FUN_WITH_SQLITE is enabled. No-op when SQLite support is disabled. - */ - -/** + * * OP_SQLITE_CLOSE: (handle:int) -> Nil */ + case OP_SQLITE_CLOSE: { #ifdef FUN_WITH_SQLITE Value vh = pop_value(vm); diff --git a/src/vm/sqlite/exec.c b/src/vm/sqlite/exec.c index 9ebff9d..3f64c6b 100644 --- a/src/vm/sqlite/exec.c +++ b/src/vm/sqlite/exec.c @@ -13,11 +13,10 @@ * * Executes a SQL statement against an open SQLite handle when * FUN_WITH_SQLITE is enabled. Returns the SQLite result code. - */ - -/** + * * OP_SQLITE_EXEC: (handle:int, sql:string) -> int rc (0=OK) */ + case OP_SQLITE_EXEC: { #ifdef FUN_WITH_SQLITE Value vsql = pop_value(vm); diff --git a/src/vm/sqlite/open.c b/src/vm/sqlite/open.c index ff71228..26ec63b 100644 --- a/src/vm/sqlite/open.c +++ b/src/vm/sqlite/open.c @@ -13,11 +13,10 @@ * * Opens a SQLite database and registers a handle when FUN_WITH_SQLITE is * enabled. On failure or when SQLite support is disabled, pushes 0. - */ - -/** + * * OP_SQLITE_OPEN: (path:string) -> handle:int (>0) or 0 on error */ + case OP_SQLITE_OPEN: { #ifdef FUN_WITH_SQLITE Value vpath = pop_value(vm); diff --git a/src/vm/sqlite/query.c b/src/vm/sqlite/query.c index 1f6fe09..3b4d960 100644 --- a/src/vm/sqlite/query.c +++ b/src/vm/sqlite/query.c @@ -13,11 +13,10 @@ * * Prepares and steps through a SQLite statement to produce an array of row * maps when FUN_WITH_SQLITE is enabled. Returns an empty array otherwise. - */ - -/** + * * OP_SQLITE_QUERY: (handle:int, sql:string) -> array> */ + case OP_SQLITE_QUERY: { #ifdef FUN_WITH_SQLITE Value vsql = pop_value(vm); diff --git a/src/vm/strings/find.c b/src/vm/strings/find.c index 6a1248d..3fdb60d 100644 --- a/src/vm/strings/find.c +++ b/src/vm/strings/find.c @@ -24,12 +24,9 @@ * - Exits with an error if the operands are not strings. * * Example: - * // Bytecode: OP_FIND - * // Stack before: ["world", "hello world"] - * // Stack after: [6] - * - * @author Johannes Findeisen - * @date 2025-10-16 + * - Bytecode: OP_FIND + * - Stack before: ["world", "hello world"] + * - Stack after: [6] */ case OP_FIND: { diff --git a/src/vm/strings/regex_match.c b/src/vm/strings/regex_match.c index d0cab8f..1a785f1 100644 --- a/src/vm/strings/regex_match.c +++ b/src/vm/strings/regex_match.c @@ -31,6 +31,7 @@ * - pattern = "[a-z]+", input = "hello" -> 1 * - pattern = "[a-z]+", input = "hello!" -> 0 (not a full match) */ + /* Regex full-match opcode using POSIX regex */ #ifdef __unix__ #include diff --git a/src/vm/strings/regex_replace.c b/src/vm/strings/regex_replace.c index 368fd28..73f7e87 100644 --- a/src/vm/strings/regex_replace.c +++ b/src/vm/strings/regex_replace.c @@ -31,6 +31,7 @@ * Example: * - pattern = "[0-9]+", repl = "#", input = "a1b22c" -> "a#b#c" */ + /* Regex global replace opcode using POSIX regex */ #ifdef __unix__ #include diff --git a/src/vm/strings/regex_search.c b/src/vm/strings/regex_search.c index 7149729..3ac0ddf 100644 --- a/src/vm/strings/regex_search.c +++ b/src/vm/strings/regex_search.c @@ -34,6 +34,7 @@ * - pattern = "h(ell)o", input = "oh hello!" -> * { match: "hello", start: 3, end: 8, groups: ["ell"] } */ + /* Regex search (first match) opcode using POSIX regex */ #ifdef __unix__ #include diff --git a/src/vm/strings/split.c b/src/vm/strings/split.c index 6806bcb..45a1995 100644 --- a/src/vm/strings/split.c +++ b/src/vm/strings/split.c @@ -24,12 +24,9 @@ * - Exits with an error if the operands are not strings. * * Example: - * // Bytecode: OP_SPLIT - * // Stack before: [", ", "a, b, c"] - * // Stack after: [["a", "b", "c"]] - * - * @author Johannes Findeisen - * @date 2025-10-16 + * - Bytecode: OP_SPLIT + * - Stack before: [", ", "a, b, c"] + * - Stack after: [["a", "b", "c"]] */ case OP_SPLIT: { diff --git a/src/vm/strings/substr.c b/src/vm/strings/substr.c index 6875932..9a5d939 100644 --- a/src/vm/strings/substr.c +++ b/src/vm/strings/substr.c @@ -25,12 +25,9 @@ * - Exits with an error if the start index or length is out of bounds. * * Example: - * // Bytecode: OP_SUBSTR - * // Stack before: [5, 6, "hello world"] - * // Stack after: ["world"] - * - * @author Johannes Findeisen - * @date 2025-10-16 + * - Bytecode: OP_SUBSTR + * - Stack before: [5, 6, "hello world"] + * - Stack after: ["world"] */ case OP_SUBSTR: { diff --git a/src/vm/to_number.c b/src/vm/to_number.c index aa8c135..e17cd43 100644 --- a/src/vm/to_number.c +++ b/src/vm/to_number.c @@ -23,12 +23,9 @@ * - Exits with an error if the conversion fails. * * Example: - * // Bytecode: OP_TO_NUMBER - * // Stack before: ["42"] - * // Stack after: [42] - * - * @author Johannes Findeisen - * @date 2025-10-16 + * - Bytecode: OP_TO_NUMBER + * - Stack before: ["42"] + * - Stack after: [42] */ case OP_TO_NUMBER: { diff --git a/src/vm/to_string.c b/src/vm/to_string.c index 3f34b51..4174f84 100644 --- a/src/vm/to_string.c +++ b/src/vm/to_string.c @@ -29,12 +29,9 @@ * - Exits with an error if memory allocation fails during string creation. * * Example: - * // Bytecode: OP_TO_STRING - * // Stack before: [42] - * // Stack after: ["42"] - * - * @author Johannes Findeisen - * @date 2025-10-16 + * - Bytecode: OP_TO_STRING + * - Stack before: [42] + * - Stack after: ["42"] */ case OP_TO_STRING: { diff --git a/src/vm/xml/name.c b/src/vm/xml/name.c index df2d56b..383b644 100644 --- a/src/vm/xml/name.c +++ b/src/vm/xml/name.c @@ -30,9 +30,10 @@ * stack as usual. * * Example - * // ... stack: [ node_handle ] - * OP_XML_NAME // → [ "book" ] + * - stack: [ node_handle ] + * - OP_XML_NAME → [ "book" ] */ + /* OP_XML_NAME: pops node handle; pushes string */ case OP_XML_NAME: { #ifdef FUN_WITH_XML2 diff --git a/src/vm/xml/parse.c b/src/vm/xml/parse.c index 6f69b95..83bf353 100644 --- a/src/vm/xml/parse.c +++ b/src/vm/xml/parse.c @@ -28,9 +28,10 @@ * - The parser is invoked with XML_PARSE_NONET to disallow network access. * * Example - * // stack: [ "" ] - * OP_XML_PARSE // → [ 1 ] (example handle) + * - stack: [ "" ] + * - OP_XML_PARSE → [ 1 ] (example handle) */ + /* OP_XML_PARSE: pops text string; pushes doc handle (>0) or 0 */ case OP_XML_PARSE: { #ifdef FUN_WITH_XML2 diff --git a/src/vm/xml/root.c b/src/vm/xml/root.c index 68eacc0..70297cd 100644 --- a/src/vm/xml/root.c +++ b/src/vm/xml/root.c @@ -26,9 +26,10 @@ * released by corresponding XML VM opcodes to avoid leaks. * * Example - * // stack: [ doc_handle ] - * OP_XML_ROOT // → [ node_handle ] or [ 0 ] + * - stack: [ doc_handle ] + * - OP_XML_ROOT → [ node_handle ] or [ 0 ] */ + /* OP_XML_ROOT: pops doc handle; pushes node handle (>0) or 0 */ case OP_XML_ROOT: { #ifdef FUN_WITH_XML2 diff --git a/src/vm/xml/text.c b/src/vm/xml/text.c index c03e5a8..33938b2 100644 --- a/src/vm/xml/text.c +++ b/src/vm/xml/text.c @@ -27,9 +27,10 @@ * freed immediately after use. * * Example - * // stack: [ node_handle ] - * OP_XML_TEXT // → [ "Hello world" ] + * - stack: [ node_handle ] + * - OP_XML_TEXT → [ "Hello world" ] */ + /* OP_XML_TEXT: pops node handle; pushes string (concatenate text node children) */ case OP_XML_TEXT: { #ifdef FUN_WITH_XML2 diff --git a/web/images/fun-inverted.png b/web/images/fun-inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..033e5de31a5c5f5b6ebb8ae72c96fb0b86eb2792 GIT binary patch literal 14762 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 Eg6?H?)&Kwi literal 0 HcmV?d00001 diff --git a/web/images/fun-square-inverted.png b/web/images/fun-square-inverted.png new file mode 100644 index 0000000000000000000000000000000000000000..4fdeba10c045a26b3ba8cba99f0e7db408e65f0d GIT binary patch literal 11660 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 literal 0 HcmV?d00001