Doxygen code comment cleanups and fixes. No code changes. (0.41.5)
This commit is contained in:
parent
4309ec2a52
commit
892fa3cfbf
88 changed files with 224 additions and 265 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -11,7 +11,9 @@ build/*
|
||||||
build_debug/*
|
build_debug/*
|
||||||
build_release/*
|
build_release/*
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
|
compile_commands.json
|
||||||
database.sqlite
|
database.sqlite
|
||||||
|
defines.txt
|
||||||
demo_*
|
demo_*
|
||||||
dist/
|
dist/
|
||||||
downloaded.png
|
downloaded.png
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
* instruction representation (@ref Instruction), and the owning bytecode
|
* instruction representation (@ref Instruction), and the owning bytecode
|
||||||
* container (@ref Bytecode) together with minimal constructor/manipulation
|
* container (@ref Bytecode) together with minimal constructor/manipulation
|
||||||
* helpers. The concrete execution semantics for each opcode are implemented
|
* 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
|
#ifndef FUN_BYTECODE_H
|
||||||
#define FUN_BYTECODE_H
|
#define FUN_BYTECODE_H
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,6 @@
|
||||||
* vm_run(&vm, bc);
|
* vm_run(&vm, bc);
|
||||||
* bytecode_free(bc);
|
* bytecode_free(bc);
|
||||||
* }
|
* }
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-09-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* Continues until the next non-comment, non-whitespace character.
|
||||||
*/
|
*/
|
||||||
static void skip_comments(const char *src, size_t len, size_t *pos) {
|
static void skip_comments(const char *src, size_t len, size_t *pos) {
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@
|
||||||
* - Exits with an error if memory allocation fails during string concatenation.
|
* - Exits with an error if memory allocation fails during string concatenation.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_ADD
|
* - Bytecode: OP_ADD
|
||||||
* // Stack before: [2, 3]
|
* - Stack before: [2, 3]
|
||||||
* // Stack after: [5]
|
* - Stack after: [5]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_ADD: {
|
case OP_ADD: {
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@
|
||||||
* - Raises a runtime error on division by zero (both integer and floating cases).
|
* - Raises a runtime error on division by zero (both integer and floating cases).
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_DIV
|
* - Bytecode: OP_DIV
|
||||||
* // Stack before: [10, 2]
|
* - Stack before: [10, 2]
|
||||||
* // Stack after: [5]
|
* - Stack after: [5]
|
||||||
* // Stack before: [5.0, 2]
|
* - Stack before: [5.0, 2]
|
||||||
* // Stack after: [2.5]
|
* - Stack after: [2.5]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_DIV: {
|
case OP_DIV: {
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
* - Raises a runtime error and aborts execution if operands are not numeric.
|
* - Raises a runtime error and aborts execution if operands are not numeric.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MUL
|
* - Bytecode: OP_MUL
|
||||||
* // Stack before: [3, 4]
|
* - Stack before: [3, 4]
|
||||||
* // Stack after: [12]
|
* - Stack after: [12]
|
||||||
* // Stack before: [2.5, 4]
|
* - Stack before: [2.5, 4]
|
||||||
* // Stack after: [10.0]
|
* - Stack after: [10.0]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MUL: {
|
case OP_MUL: {
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,11 @@
|
||||||
* - Raises a runtime error and aborts execution if operands are not numeric.
|
* - Raises a runtime error and aborts execution if operands are not numeric.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_SUB
|
* - Bytecode: OP_SUB
|
||||||
* // Stack before: [10, 4]
|
* - Stack before: [10, 4]
|
||||||
* // Stack after: [6]
|
* - Stack after: [6]
|
||||||
* // Stack before: [10.0, 3]
|
* - Stack before: [10.0, 3]
|
||||||
* // Stack after: [7.0]
|
* - Stack after: [7.0]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SUB: {
|
case OP_SUB: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with an error if the array is empty.
|
* - Exits with an error if the array is empty.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_APOP
|
* - Bytecode: OP_APOP
|
||||||
* // Stack before: [[10, 20, 30]]
|
* - Stack before: [[10, 20, 30]]
|
||||||
* // Stack after: [30]
|
* - Stack after: [30]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_APOP: {
|
case OP_APOP: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with a runtime error if the operand is not an array.
|
* - Exits with a runtime error if the operand is not an array.
|
||||||
|
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_CLEAR
|
* - Bytecode: OP_CLEAR
|
||||||
* // Stack before: [[10, 20, 30]]
|
* - Stack before: [[10, 20, 30]]
|
||||||
* // Stack after: [0]
|
* - Stack after: [0]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_CLEAR: {
|
case OP_CLEAR: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the array is of the wrong type.
|
* - Exits with an error if the array is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_CONTAINS
|
* - Bytecode: OP_CONTAINS
|
||||||
* // Stack before: [20, [10, 20, 30]]
|
* - Stack before: [20, [10, 20, 30]]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_CONTAINS: {
|
case OP_CONTAINS: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the array is of the wrong type.
|
* - Exits with an error if the array is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_ENUMERATE
|
* - Bytecode: OP_ENUMERATE
|
||||||
* // Stack before: [[10, 20, 30]]
|
* - Stack before: [[10, 20, 30]]
|
||||||
* // Stack after: [[[0, 10], [1, 20], [2, 30]]]
|
* - Stack after: [[[0, 10], [1, 20], [2, 30]]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_ENUMERATE: {
|
case OP_ENUMERATE: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* is of the wrong type, or if the index is out of bounds.
|
* is of the wrong type, or if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_INDEX_GET
|
* - Bytecode: OP_INDEX_GET
|
||||||
* // Stack before: [1, [10, 20, 30]]
|
* - Stack before: [1, [10, 20, 30]]
|
||||||
* // Stack after: [20]
|
* - Stack after: [20]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_INDEX_GET: {
|
case OP_INDEX_GET: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the array is of the wrong type.
|
* - Exits with an error if the array is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_INDEX_OF
|
* - Bytecode: OP_INDEX_OF
|
||||||
* // Stack before: [20, [10, 20, 30]]
|
* - Stack before: [20, [10, 20, 30]]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_INDEX_OF: {
|
case OP_INDEX_OF: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* is of the wrong type, or if the index is out of bounds.
|
* is of the wrong type, or if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_INDEX_SET
|
* - Bytecode: OP_INDEX_SET
|
||||||
* // Stack before: [42, 1, [10, 20, 30]]
|
* - Stack before: [42, 1, [10, 20, 30]]
|
||||||
* // Stack after: [[10, 42, 30]]
|
* - Stack after: [[10, 42, 30]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_INDEX_SET: {
|
case OP_INDEX_SET: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* - Exits with an error if memory allocation fails during the insertion.
|
* - Exits with an error if memory allocation fails during the insertion.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_INSERT
|
* - Bytecode: OP_INSERT
|
||||||
* // Stack before: [42, 1, [10, 20, 30]]
|
* - Stack before: [42, 1, [10, 20, 30]]
|
||||||
* // Stack after: [4]
|
* - Stack after: [4]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_INSERT: {
|
case OP_INSERT: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with an error if the array or separator is of the wrong type.
|
* - Exits with an error if the array or separator is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_JOIN
|
* - Bytecode: OP_JOIN
|
||||||
* // Stack before: [", ", ["a", "b", "c"]]
|
* - Stack before: [", ", ["a", "b", "c"]]
|
||||||
* // Stack after: ["a, b, c"]
|
* - Stack after: ["a, b, c"]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_JOIN: {
|
case OP_JOIN: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with an error if `n` is invalid or if memory allocation fails.
|
* - Exits with an error if `n` is invalid or if memory allocation fails.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MAKE_ARRAY 3
|
* - Bytecode: OP_MAKE_ARRAY 3
|
||||||
* // Stack before: [1, 2, 3]
|
* - Stack before: [1, 2, 3]
|
||||||
* // Stack after: [[1, 2, 3]]
|
* - Stack after: [[1, 2, 3]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MAKE_ARRAY: {
|
case OP_MAKE_ARRAY: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* - Exits with a runtime error if memory allocation fails.
|
* - Exits with a runtime error if memory allocation fails.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_PUSH
|
* - Bytecode: OP_PUSH
|
||||||
* // Stack before: [42, [10, 20, 30]]
|
* - Stack before: [42, [10, 20, 30]]
|
||||||
* // Stack after: [4]
|
* - Stack after: [4]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_PUSH: {
|
case OP_PUSH: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* - Exits with a runtime error if the index is out of bounds.
|
* - Exits with a runtime error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_REMOVE
|
* - Bytecode: OP_REMOVE
|
||||||
* // Stack before: [1, [10, 20, 30]]
|
* - Stack before: [1, [10, 20, 30]]
|
||||||
* // Stack after: [20]
|
* - Stack after: [20]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_REMOVE: {
|
case OP_REMOVE: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* - Exits with a runtime error if the index is out of bounds.
|
* - Exits with a runtime error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_SET
|
* - Bytecode: OP_SET
|
||||||
* // Stack before: [42, 1, [10, 20, 30]]
|
* - Stack before: [42, 1, [10, 20, 30]]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SET: {
|
case OP_SET: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Handles negative indices and out-of-bounds cases gracefully
|
* - Handles negative indices and out-of-bounds cases gracefully
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_SLICE
|
* - Bytecode: OP_SLICE
|
||||||
* // Stack before: [3, 1, [10,20,30,40]]
|
* - Stack before: [3, 1, [10,20,30,40]]
|
||||||
* // Stack after: [[20,30]]
|
* - Stack after: [[20,30]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SLICE: {
|
case OP_SLICE: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with error if arguments aren't arrays
|
* - Exits with error if arguments aren't arrays
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_ZIP
|
* - Bytecode: OP_ZIP
|
||||||
* // Stack before: [[1,2], ['a','b']]
|
* - Stack before: [[1,2], ['a','b']]
|
||||||
* // Stack after: [[[1,'a'], [2,'b']]]
|
* - Stack after: [[[1,'a'], [2,'b']]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_ZIP: {
|
case OP_ZIP: {
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the stack is empty.
|
* - Exits with an error if the stack is empty.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_DUP
|
* - Bytecode: OP_DUP
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: [42, 42]
|
* - Stack after: [42, 42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_DUP: {
|
case OP_DUP: {
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@
|
||||||
* - Stops the VM execution immediately.
|
* - Stops the VM execution immediately.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_HALT
|
* - Bytecode: OP_HALT
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_HALT:
|
case OP_HALT:
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the index is out of bounds.
|
* - Exits with an error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_LOAD_GLOBAL 0
|
* - Bytecode: OP_LOAD_GLOBAL 0
|
||||||
* // Stack before: []
|
* - Stack before: []
|
||||||
* // Stack after: [global_value]
|
* - Stack after: [global_value]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_LOAD_GLOBAL: {
|
case OP_LOAD_GLOBAL: {
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the index is out of bounds.
|
* - Exits with an error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_LOAD_LOCAL 0
|
* - Bytecode: OP_LOAD_LOCAL 0
|
||||||
* // Stack before: []
|
* - Stack before: []
|
||||||
* // Stack after: [local_value]
|
* - Stack after: [local_value]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_LOAD_LOCAL: {
|
case OP_LOAD_LOCAL: {
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@
|
||||||
* - Does nothing.
|
* - Does nothing.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_NOP
|
* - Bytecode: OP_NOP
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_NOP:
|
case OP_NOP:
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
* - Exits with an error if the stack is empty.
|
* - Exits with an error if the stack is empty.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_POP
|
* - Bytecode: OP_POP
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: []
|
* - Stack after: []
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_POP: {
|
case OP_POP: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the frame stack is empty.
|
* - Exits with an error if the frame stack is empty.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_RETURN
|
* - Bytecode: OP_RETURN
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the index is out of bounds.
|
* - Exits with an error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_STORE_GLOBAL 0
|
* - Bytecode: OP_STORE_GLOBAL 0
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: []
|
* - Stack after: []
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_STORE_GLOBAL: {
|
case OP_STORE_GLOBAL: {
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the index is out of bounds.
|
* - Exits with an error if the index is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_STORE_LOCAL 0
|
* - Bytecode: OP_STORE_LOCAL 0
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: []
|
* - Stack after: []
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_STORE_LOCAL: {
|
case OP_STORE_LOCAL: {
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@
|
||||||
* - Pushes: (none)
|
* - Pushes: (none)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Implements OP_ECHO: print top-of-stack value without trailing newline. */
|
|
||||||
|
|
||||||
case OP_ECHO: {
|
case OP_ECHO: {
|
||||||
Value v = pop_value(vm);
|
Value v = pop_value(vm);
|
||||||
Value snap = deep_copy_value(&v);
|
Value snap = deep_copy_value(&v);
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@
|
||||||
* - EOF before any character yields an empty string.
|
* - EOF before any character yields an empty string.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: [optional PUSH prompt], OP_INPUT_LINE(operand)
|
* - Bytecode: [optional PUSH prompt], OP_INPUT_LINE(operand)
|
||||||
* // operand bit0=1 (has prompt), bit1=2 (hidden) can be combined
|
* - operand bit0=1 (has prompt), bit1=2 (hidden) can be combined
|
||||||
* // Stack before (bit0=1): ["Enter password: "]
|
* - Stack before (bit0=1): ["Enter password: "]
|
||||||
* // Stack after: ["user-typed-line"]
|
* - Stack after: ["user-typed-line"]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_INPUT_LINE: {
|
case OP_INPUT_LINE: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the file path is invalid or the file cannot be read.
|
* - Exits with an error if the file path is invalid or the file cannot be read.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_READ_FILE
|
* - Bytecode: OP_READ_FILE
|
||||||
* // Stack before: ["file.txt"]
|
* - Stack before: ["file.txt"]
|
||||||
* // Stack after: ["file contents"]
|
* - Stack after: ["file contents"]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_READ_FILE: {
|
case OP_READ_FILE: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the file path is invalid or the file cannot be written.
|
* - Exits with an error if the file path is invalid or the file cannot be written.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_WRITE_FILE
|
* - Bytecode: OP_WRITE_FILE
|
||||||
* // Stack before: ["file.txt", "data"]
|
* - Stack before: ["file.txt", "data"]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_WRITE_FILE: {
|
case OP_WRITE_FILE: {
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,9 @@
|
||||||
* - Exits with an error if the operand is not an array or string.
|
* - Exits with an error if the operand is not an array or string.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_LEN
|
* - Bytecode: OP_LEN
|
||||||
* // Stack before: ["hello"]
|
* - Stack before: ["hello"]
|
||||||
* // Stack after: [5]
|
* - Stack after: [5]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-09-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_LEN: {
|
case OP_LEN: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are not boolean values.
|
* - Exits with an error if the operands are not boolean values.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_AND
|
* - Bytecode: OP_AND
|
||||||
* // Stack before: [1, 0]
|
* - Stack before: [1, 0]
|
||||||
* // Stack after: [0]
|
* - Stack after: [0]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_AND: {
|
case OP_AND: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_EQ
|
* - Bytecode: OP_EQ
|
||||||
* // Stack before: [42, 42]
|
* - Stack before: [42, 42]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_EQ: {
|
case OP_EQ: {
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* ```c
|
* - Bytecode: OP_GT
|
||||||
* // Bytecode: OP_GT
|
* - Stack before: [42, 10]
|
||||||
* // Stack before: [42, 10]
|
* - Stack after: [1]
|
||||||
* // Stack after: [1]
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_GT: {
|
case OP_GT: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_GTE
|
* - Bytecode: OP_GTE
|
||||||
* // Stack before: [42, 42]
|
* - Stack before: [42, 42]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_GTE: {
|
case OP_GTE: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_LT
|
* - Bytecode: OP_LT
|
||||||
* // Stack before: [10, 42]
|
* - Stack before: [10, 42]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_LT: {
|
case OP_LT: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_LTE
|
* - Bytecode: OP_LTE
|
||||||
* // Stack before: [42, 42]
|
* - Stack before: [42, 42]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_LTE: {
|
case OP_LTE: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are of incompatible types.
|
* - Exits with an error if the operands are of incompatible types.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_NEQ
|
* - Bytecode: OP_NEQ
|
||||||
* // Stack before: [42, 10]
|
* - Stack before: [42, 10]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_NEQ: {
|
case OP_NEQ: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operand is not a boolean value.
|
* - Exits with an error if the operand is not a boolean value.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_NOT
|
* - Bytecode: OP_NOT
|
||||||
* // Stack before: [0]
|
* - Stack before: [0]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_NOT: {
|
case OP_NOT: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are not boolean values.
|
* - Exits with an error if the operands are not boolean values.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_OR
|
* - Bytecode: OP_OR
|
||||||
* // Stack before: [1, 0]
|
* - Stack before: [1, 0]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_OR: {
|
case OP_OR: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the map is of the wrong type.
|
* - Exits with an error if the map is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_KEYS
|
* - Bytecode: OP_KEYS
|
||||||
* // Stack before: [{"a": 1, "b": 2}]
|
* - Stack before: [{"a": 1, "b": 2}]
|
||||||
* // Stack after: [["a", "b"]]
|
* - Stack after: [["a", "b"]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_KEYS: {
|
case OP_KEYS: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* or if map construction fails.
|
* or if map construction fails.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MAKE_MAP 2
|
* - Bytecode: OP_MAKE_MAP 2
|
||||||
* // Stack before: ["key1", 1, "key2", 2]
|
* - Stack before: ["key1", 1, "key2", 2]
|
||||||
* // Stack after: [{"key1": 1, "key2": 2}]
|
* - Stack after: [{"key1": 1, "key2": 2}]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MAKE_MAP: {
|
case OP_MAKE_MAP: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the map is of the wrong type.
|
* - Exits with an error if the map is of the wrong type.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_VALUES
|
* - Bytecode: OP_VALUES
|
||||||
* // Stack before: [{"a": 1, "b": 2}]
|
* - Stack before: [{"a": 1, "b": 2}]
|
||||||
* // Stack after: [[1, 2]]
|
* - Stack after: [[1, 2]]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_VALUES: {
|
case OP_VALUES: {
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,6 @@
|
||||||
*
|
*
|
||||||
* Error Handling:
|
* Error Handling:
|
||||||
* - Exits if not integer
|
* - Exits if not integer
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_ABS: {
|
case OP_ABS: {
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,6 @@
|
||||||
* Error Handling:
|
* Error Handling:
|
||||||
* - Exits if arguments wrong types
|
* - Exits if arguments wrong types
|
||||||
* - Handles hi < lo case
|
* - Handles hi < lo case
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_CLAMP: {
|
case OP_CLAMP: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are not integers.
|
* - Exits with an error if the operands are not integers.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MAX
|
* - Bytecode: OP_MAX
|
||||||
* // Stack before: [10, 42]
|
* - Stack before: [10, 42]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MAX: {
|
case OP_MAX: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are not integers.
|
* - Exits with an error if the operands are not integers.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MIN
|
* - Bytecode: OP_MIN
|
||||||
* // Stack before: [10, 42]
|
* - Stack before: [10, 42]
|
||||||
* // Stack after: [10]
|
* - Stack after: [10]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MIN: {
|
case OP_MIN: {
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
* - Exits with an error if the second operand is zero.
|
* - Exits with an error if the second operand is zero.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_MOD
|
* - Bytecode: OP_MOD
|
||||||
* // Stack before: [10, 3]
|
* - Stack before: [10, 3]
|
||||||
* // Stack after: [1]
|
* - Stack after: [1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_MOD: {
|
case OP_MOD: {
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
* - Exits with an error if the operands are not integers.
|
* - Exits with an error if the operands are not integers.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_POW
|
* - Bytecode: OP_POW
|
||||||
* // Stack before: [2, 3]
|
* - Stack before: [2, 3]
|
||||||
* // Stack after: [8]
|
* - Stack after: [8]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_POW: {
|
case OP_POW: {
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@
|
||||||
* - Exits with an error if the lower bound is greater than the upper bound.
|
* - Exits with an error if the lower bound is greater than the upper bound.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_RANDOM_INT
|
* - Bytecode: OP_RANDOM_INT
|
||||||
* // Stack before: [10, 1]
|
* - Stack before: [10, 1]
|
||||||
* // Stack after: [7]
|
* - Stack after: [7]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RANDOM_INT: {
|
case OP_RANDOM_INT: {
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@
|
||||||
* - Exits with an error if the seed is not an integer.
|
* - Exits with an error if the seed is not an integer.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_RANDOM_SEED
|
* - Bytecode: OP_RANDOM_SEED
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: []
|
* - Stack after: []
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RANDOM_SEED: {
|
case OP_RANDOM_SEED: {
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@
|
||||||
* @file clock_mono_ms.c
|
* @file clock_mono_ms.c
|
||||||
* @brief Implements OP_CLOCK_MONO_MS to push monotonic clock in ms.
|
* @brief Implements OP_CLOCK_MONO_MS to push monotonic clock in ms.
|
||||||
*
|
*
|
||||||
* Stack before: []
|
* Example:
|
||||||
* Stack after: [int ms]
|
* - OP_CLOCK_MONO_MS
|
||||||
|
* - Stack before: []
|
||||||
|
* - Stack after: [int ms]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
* Connects to a smart card in the specified reader using an existing PC/SC
|
* 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
|
* 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.
|
* registry. When PCSC support is disabled at build time, this opcode returns 0.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_CONNECT: (ctx_id:int, reader_name:any) -> int
|
* OP_PCSC_CONNECT: (ctx_id:int, reader_name:any) -> int
|
||||||
*
|
*
|
||||||
* - Pops: reader_name (converted to string), then ctx_id.
|
* - Pops: reader_name (converted to string), then ctx_id.
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
* Disconnects a previously connected smart-card handle and frees the
|
* Disconnects a previously connected smart-card handle and frees the
|
||||||
* corresponding registry slot. When PCSC support is disabled at build time,
|
* corresponding registry slot. When PCSC support is disabled at build time,
|
||||||
* this opcode returns 0 after consuming its argument.
|
* this opcode returns 0 after consuming its argument.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_DISCONNECT: (handle_id:int) -> int
|
* OP_PCSC_DISCONNECT: (handle_id:int) -> int
|
||||||
*
|
*
|
||||||
* - Pops: handle_id.
|
* - Pops: handle_id.
|
||||||
|
|
@ -24,6 +22,10 @@
|
||||||
* - Notes: Uses SCardDisconnect(..., SCARD_LEAVE_CARD).
|
* - Notes: Uses SCardDisconnect(..., SCARD_LEAVE_CARD).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* PCSC disconnect */
|
/* PCSC disconnect */
|
||||||
case OP_PCSC_DISCONNECT: {
|
case OP_PCSC_DISCONNECT: {
|
||||||
#ifdef FUN_WITH_PCSC
|
#ifdef FUN_WITH_PCSC
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,7 @@
|
||||||
* and registers it in the internal PCSC context registry when FUN_WITH_PCSC
|
* 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.
|
* 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.
|
* When PCSC support is disabled at build time, this opcode returns 0.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_ESTABLISH: () -> int
|
* OP_PCSC_ESTABLISH: () -> int
|
||||||
*
|
*
|
||||||
* - Returns: context id (>0) on success; 0 on error or when disabled.
|
* - Returns: context id (>0) on success; 0 on error or when disabled.
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
* Lists available PC/SC reader names for a given context. On success returns
|
* 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
|
* 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.
|
* empty array after consuming its argument to keep the stack balanced.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_LIST_READERS: (ctx_id:int) -> array<string>
|
* OP_PCSC_LIST_READERS: (ctx_id:int) -> array<string>
|
||||||
*
|
*
|
||||||
* - Pops: ctx_id.
|
* - Pops: ctx_id.
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
* Releases a previously established PC/SC context and frees its registry slot.
|
* 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
|
* When PCSC support is disabled at build time, this opcode returns 0 after
|
||||||
* consuming its argument.
|
* consuming its argument.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_RELEASE: (ctx_id:int) -> int
|
* OP_PCSC_RELEASE: (ctx_id:int) -> int
|
||||||
*
|
*
|
||||||
* - Pops: ctx_id.
|
* - Pops: ctx_id.
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,7 @@
|
||||||
* handle. Returns a map with the response bytes and status words. When PCSC
|
* 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
|
* support is disabled at build time, consumes its arguments and returns a map
|
||||||
* with code = -2.
|
* with code = -2.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_PCSC_TRANSMIT: (handle_id:int, apdu:array<int>) -> map
|
* OP_PCSC_TRANSMIT: (handle_id:int, apdu:array<int>) -> map
|
||||||
*
|
*
|
||||||
* - Pops: apdu array, then handle_id.
|
* - Pops: apdu array, then handle_id.
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,9 @@
|
||||||
* - Prints the value to the output buffer.
|
* - Prints the value to the output buffer.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_PRINT
|
* - Bytecode: OP_PRINT
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: []
|
* - Stack after: []
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-09-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_PRINT: {
|
case OP_PRINT: {
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@
|
||||||
* Delegates to a Rust helper to read the VM's current stack pointer (sp).
|
* 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
|
* When Rust support is disabled, this raises a runtime error and pushes -1 to
|
||||||
* signal unavailability.
|
* signal unavailability.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_RUST_GET_SP: () -> int | Nil
|
* OP_RUST_GET_SP: () -> int | Nil
|
||||||
*
|
*
|
||||||
* Behavior (FUN_WITH_RUST=ON):
|
* Behavior (FUN_WITH_RUST=ON):
|
||||||
|
|
@ -28,6 +26,7 @@
|
||||||
* - Raises a runtime error indicating missing Rust support.
|
* - Raises a runtime error indicating missing Rust support.
|
||||||
* - Pushes integer -1 as a sentinel value.
|
* - Pushes integer -1 as a sentinel value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RUST_GET_SP: {
|
case OP_RUST_GET_SP: {
|
||||||
#ifdef FUN_WITH_RUST
|
#ifdef FUN_WITH_RUST
|
||||||
extern int fun_op_rget_sp(VM * vm);
|
extern int fun_op_rget_sp(VM * vm);
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,7 @@
|
||||||
* Rust and pushes it as a VAL_STRING onto the VM stack. When Rust support is
|
* 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
|
* disabled, a runtime error is raised and Nil is pushed to keep stack
|
||||||
* consistency.
|
* consistency.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_RUST_HELLO: () -> string | Nil
|
* OP_RUST_HELLO: () -> string | Nil
|
||||||
*
|
*
|
||||||
* Behavior (FUN_WITH_RUST=ON):
|
* Behavior (FUN_WITH_RUST=ON):
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,6 @@
|
||||||
* string, calls into Rust to print/log it, and pushes Nil. When Rust support is
|
* 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,
|
* disabled, the argument is still popped and freed to keep the stack sane,
|
||||||
* then Nil is pushed after raising an error message.
|
* then Nil is pushed after raising an error message.
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_RUST_HELLO_ARGS: (msg:any) -> Nil
|
* OP_RUST_HELLO_ARGS: (msg:any) -> Nil
|
||||||
*
|
*
|
||||||
* Behavior (FUN_WITH_RUST=ON):
|
* Behavior (FUN_WITH_RUST=ON):
|
||||||
|
|
@ -31,6 +28,7 @@
|
||||||
* - Raises a runtime error indicating missing Rust support.
|
* - Raises a runtime error indicating missing Rust support.
|
||||||
* - Pushes Nil.
|
* - Pushes Nil.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RUST_HELLO_ARGS: {
|
case OP_RUST_HELLO_ARGS: {
|
||||||
#ifdef FUN_WITH_RUST
|
#ifdef FUN_WITH_RUST
|
||||||
Value vmsg = pop_value(vm);
|
Value vmsg = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,7 @@
|
||||||
* converts it to a C string, passes it to Rust, and pushes back the string
|
* 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
|
* returned by Rust. If Rust returns NULL or Rust support is disabled, Nil is
|
||||||
* pushed.
|
* pushed.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_RUST_HELLO_ARGS_RETURN: (msg:any) -> string | Nil
|
* OP_RUST_HELLO_ARGS_RETURN: (msg:any) -> string | Nil
|
||||||
*
|
*
|
||||||
* Behavior (FUN_WITH_RUST=ON):
|
* Behavior (FUN_WITH_RUST=ON):
|
||||||
|
|
@ -33,6 +31,7 @@
|
||||||
* - Raises a runtime error indicating missing Rust support.
|
* - Raises a runtime error indicating missing Rust support.
|
||||||
* - Pushes Nil.
|
* - Pushes Nil.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RUST_HELLO_ARGS_RETURN: {
|
case OP_RUST_HELLO_ARGS_RETURN: {
|
||||||
#ifdef FUN_WITH_RUST
|
#ifdef FUN_WITH_RUST
|
||||||
Value vmsg = pop_value(vm);
|
Value vmsg = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,7 @@
|
||||||
* vm.exit_code. Pushes Nil afterwards. When Rust support is disabled, the
|
* 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
|
* argument is still popped/freed, a runtime error is raised, and Nil is
|
||||||
* pushed to maintain stack discipline.
|
* pushed to maintain stack discipline.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_RUST_SET_EXIT: (code:int) -> Nil
|
* OP_RUST_SET_EXIT: (code:int) -> Nil
|
||||||
*
|
*
|
||||||
* Behavior (FUN_WITH_RUST=ON):
|
* Behavior (FUN_WITH_RUST=ON):
|
||||||
|
|
@ -30,6 +28,7 @@
|
||||||
* - Raises a runtime error indicating missing Rust support.
|
* - Raises a runtime error indicating missing Rust support.
|
||||||
* - Pushes Nil.
|
* - Pushes Nil.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_RUST_SET_EXIT: {
|
case OP_RUST_SET_EXIT: {
|
||||||
#ifdef FUN_WITH_RUST
|
#ifdef FUN_WITH_RUST
|
||||||
extern int fun_op_rset_exit(VM * vm);
|
extern int fun_op_rset_exit(VM * vm);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,10 @@
|
||||||
*
|
*
|
||||||
* Closes a registered SQLite database handle and unregisters it when
|
* Closes a registered SQLite database handle and unregisters it when
|
||||||
* FUN_WITH_SQLITE is enabled. No-op when SQLite support is disabled.
|
* FUN_WITH_SQLITE is enabled. No-op when SQLite support is disabled.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_SQLITE_CLOSE: (handle:int) -> Nil
|
* OP_SQLITE_CLOSE: (handle:int) -> Nil
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SQLITE_CLOSE: {
|
case OP_SQLITE_CLOSE: {
|
||||||
#ifdef FUN_WITH_SQLITE
|
#ifdef FUN_WITH_SQLITE
|
||||||
Value vh = pop_value(vm);
|
Value vh = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,10 @@
|
||||||
*
|
*
|
||||||
* Executes a SQL statement against an open SQLite handle when
|
* Executes a SQL statement against an open SQLite handle when
|
||||||
* FUN_WITH_SQLITE is enabled. Returns the SQLite result code.
|
* FUN_WITH_SQLITE is enabled. Returns the SQLite result code.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_SQLITE_EXEC: (handle:int, sql:string) -> int rc (0=OK)
|
* OP_SQLITE_EXEC: (handle:int, sql:string) -> int rc (0=OK)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SQLITE_EXEC: {
|
case OP_SQLITE_EXEC: {
|
||||||
#ifdef FUN_WITH_SQLITE
|
#ifdef FUN_WITH_SQLITE
|
||||||
Value vsql = pop_value(vm);
|
Value vsql = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,10 @@
|
||||||
*
|
*
|
||||||
* Opens a SQLite database and registers a handle when FUN_WITH_SQLITE is
|
* Opens a SQLite database and registers a handle when FUN_WITH_SQLITE is
|
||||||
* enabled. On failure or when SQLite support is disabled, pushes 0.
|
* enabled. On failure or when SQLite support is disabled, pushes 0.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_SQLITE_OPEN: (path:string) -> handle:int (>0) or 0 on error
|
* OP_SQLITE_OPEN: (path:string) -> handle:int (>0) or 0 on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SQLITE_OPEN: {
|
case OP_SQLITE_OPEN: {
|
||||||
#ifdef FUN_WITH_SQLITE
|
#ifdef FUN_WITH_SQLITE
|
||||||
Value vpath = pop_value(vm);
|
Value vpath = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,10 @@
|
||||||
*
|
*
|
||||||
* Prepares and steps through a SQLite statement to produce an array of row
|
* 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.
|
* maps when FUN_WITH_SQLITE is enabled. Returns an empty array otherwise.
|
||||||
*/
|
*
|
||||||
|
|
||||||
/**
|
|
||||||
* OP_SQLITE_QUERY: (handle:int, sql:string) -> array<map<string,any>>
|
* OP_SQLITE_QUERY: (handle:int, sql:string) -> array<map<string,any>>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SQLITE_QUERY: {
|
case OP_SQLITE_QUERY: {
|
||||||
#ifdef FUN_WITH_SQLITE
|
#ifdef FUN_WITH_SQLITE
|
||||||
Value vsql = pop_value(vm);
|
Value vsql = pop_value(vm);
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,9 @@
|
||||||
* - Exits with an error if the operands are not strings.
|
* - Exits with an error if the operands are not strings.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_FIND
|
* - Bytecode: OP_FIND
|
||||||
* // Stack before: ["world", "hello world"]
|
* - Stack before: ["world", "hello world"]
|
||||||
* // Stack after: [6]
|
* - Stack after: [6]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_FIND: {
|
case OP_FIND: {
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
* - pattern = "[a-z]+", input = "hello" -> 1
|
* - pattern = "[a-z]+", input = "hello" -> 1
|
||||||
* - pattern = "[a-z]+", input = "hello!" -> 0 (not a full match)
|
* - pattern = "[a-z]+", input = "hello!" -> 0 (not a full match)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Regex full-match opcode using POSIX regex */
|
/* Regex full-match opcode using POSIX regex */
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
* Example:
|
* Example:
|
||||||
* - pattern = "[0-9]+", repl = "#", input = "a1b22c" -> "a#b#c"
|
* - pattern = "[0-9]+", repl = "#", input = "a1b22c" -> "a#b#c"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Regex global replace opcode using POSIX regex */
|
/* Regex global replace opcode using POSIX regex */
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
* - pattern = "h(ell)o", input = "oh hello!" ->
|
* - pattern = "h(ell)o", input = "oh hello!" ->
|
||||||
* { match: "hello", start: 3, end: 8, groups: ["ell"] }
|
* { match: "hello", start: 3, end: 8, groups: ["ell"] }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Regex search (first match) opcode using POSIX regex */
|
/* Regex search (first match) opcode using POSIX regex */
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,9 @@
|
||||||
* - Exits with an error if the operands are not strings.
|
* - Exits with an error if the operands are not strings.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_SPLIT
|
* - Bytecode: OP_SPLIT
|
||||||
* // Stack before: [", ", "a, b, c"]
|
* - Stack before: [", ", "a, b, c"]
|
||||||
* // Stack after: [["a", "b", "c"]]
|
* - Stack after: [["a", "b", "c"]]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SPLIT: {
|
case OP_SPLIT: {
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,9 @@
|
||||||
* - Exits with an error if the start index or length is out of bounds.
|
* - Exits with an error if the start index or length is out of bounds.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_SUBSTR
|
* - Bytecode: OP_SUBSTR
|
||||||
* // Stack before: [5, 6, "hello world"]
|
* - Stack before: [5, 6, "hello world"]
|
||||||
* // Stack after: ["world"]
|
* - Stack after: ["world"]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_SUBSTR: {
|
case OP_SUBSTR: {
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,9 @@
|
||||||
* - Exits with an error if the conversion fails.
|
* - Exits with an error if the conversion fails.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_TO_NUMBER
|
* - Bytecode: OP_TO_NUMBER
|
||||||
* // Stack before: ["42"]
|
* - Stack before: ["42"]
|
||||||
* // Stack after: [42]
|
* - Stack after: [42]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_TO_NUMBER: {
|
case OP_TO_NUMBER: {
|
||||||
|
|
|
||||||
|
|
@ -29,12 +29,9 @@
|
||||||
* - Exits with an error if memory allocation fails during string creation.
|
* - Exits with an error if memory allocation fails during string creation.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* // Bytecode: OP_TO_STRING
|
* - Bytecode: OP_TO_STRING
|
||||||
* // Stack before: [42]
|
* - Stack before: [42]
|
||||||
* // Stack after: ["42"]
|
* - Stack after: ["42"]
|
||||||
*
|
|
||||||
* @author Johannes Findeisen
|
|
||||||
* @date 2025-10-16
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OP_TO_STRING: {
|
case OP_TO_STRING: {
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,10 @@
|
||||||
* stack as usual.
|
* stack as usual.
|
||||||
*
|
*
|
||||||
* Example
|
* Example
|
||||||
* // ... stack: [ node_handle ]
|
* - stack: [ node_handle ]
|
||||||
* OP_XML_NAME // → [ "book" ]
|
* - OP_XML_NAME → [ "book" ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* OP_XML_NAME: pops node handle; pushes string */
|
/* OP_XML_NAME: pops node handle; pushes string */
|
||||||
case OP_XML_NAME: {
|
case OP_XML_NAME: {
|
||||||
#ifdef FUN_WITH_XML2
|
#ifdef FUN_WITH_XML2
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,10 @@
|
||||||
* - The parser is invoked with XML_PARSE_NONET to disallow network access.
|
* - The parser is invoked with XML_PARSE_NONET to disallow network access.
|
||||||
*
|
*
|
||||||
* Example
|
* Example
|
||||||
* // stack: [ "<root/>" ]
|
* - stack: [ "<root/>" ]
|
||||||
* OP_XML_PARSE // → [ 1 ] (example handle)
|
* - OP_XML_PARSE → [ 1 ] (example handle)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* OP_XML_PARSE: pops text string; pushes doc handle (>0) or 0 */
|
/* OP_XML_PARSE: pops text string; pushes doc handle (>0) or 0 */
|
||||||
case OP_XML_PARSE: {
|
case OP_XML_PARSE: {
|
||||||
#ifdef FUN_WITH_XML2
|
#ifdef FUN_WITH_XML2
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,10 @@
|
||||||
* released by corresponding XML VM opcodes to avoid leaks.
|
* released by corresponding XML VM opcodes to avoid leaks.
|
||||||
*
|
*
|
||||||
* Example
|
* Example
|
||||||
* // stack: [ doc_handle ]
|
* - stack: [ doc_handle ]
|
||||||
* OP_XML_ROOT // → [ node_handle ] or [ 0 ]
|
* - OP_XML_ROOT → [ node_handle ] or [ 0 ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* OP_XML_ROOT: pops doc handle; pushes node handle (>0) or 0 */
|
/* OP_XML_ROOT: pops doc handle; pushes node handle (>0) or 0 */
|
||||||
case OP_XML_ROOT: {
|
case OP_XML_ROOT: {
|
||||||
#ifdef FUN_WITH_XML2
|
#ifdef FUN_WITH_XML2
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,10 @@
|
||||||
* freed immediately after use.
|
* freed immediately after use.
|
||||||
*
|
*
|
||||||
* Example
|
* Example
|
||||||
* // stack: [ node_handle ]
|
* - stack: [ node_handle ]
|
||||||
* OP_XML_TEXT // → [ "Hello world" ]
|
* - OP_XML_TEXT → [ "Hello world" ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* OP_XML_TEXT: pops node handle; pushes string (concatenate text node children) */
|
/* OP_XML_TEXT: pops node handle; pushes string (concatenate text node children) */
|
||||||
case OP_XML_TEXT: {
|
case OP_XML_TEXT: {
|
||||||
#ifdef FUN_WITH_XML2
|
#ifdef FUN_WITH_XML2
|
||||||
|
|
|
||||||
BIN
web/images/fun-inverted.png
Normal file
BIN
web/images/fun-inverted.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
web/images/fun-square-inverted.png
Normal file
BIN
web/images/fun-square-inverted.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Loading…
Add table
Add a link
Reference in a new issue