Added basic threading support, changed license back to Apache-2.0 and many fixes. (0.15.0)
This commit is contained in:
parent
6bd13f6e96
commit
299771f091
158 changed files with 909 additions and 323 deletions
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "bytecode.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#ifndef FUN_BYTECODE_H
|
||||
|
|
@ -35,7 +35,7 @@ typedef enum {
|
|||
OP_EQ, // a == b -> push 1/0
|
||||
OP_NEQ, // a != b -> push 1/0
|
||||
|
||||
OP_POP, // discard top of stack
|
||||
OP_POP, // dApache-2.0ard top of stack
|
||||
OP_JUMP, // unconditional jump
|
||||
OP_JUMP_IF_FALSE, // jump if top of stack is false (0)
|
||||
|
||||
|
|
@ -115,6 +115,11 @@ typedef enum {
|
|||
// OS
|
||||
OP_ENV, // pops name string; pushes value string (or "")
|
||||
|
||||
// Threads
|
||||
OP_THREAD_SPAWN, // operand: 0=no args, 1=has args; pops [args?], fn; pushes thread id (int>0)
|
||||
OP_THREAD_JOIN, // pops thread id; waits; pushes result value (or Nil)
|
||||
OP_SLEEP_MS, // pops milliseconds; sleeps; pushes Nil (for statement POP safety)
|
||||
|
||||
// Bitwise (32-bit) and shifts/rotates
|
||||
OP_BAND, // pops b, a; pushes (uint32_t)(a & b)
|
||||
OP_BOR, // pops b, a; pushes (uint32_t)(a | b)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "bytecode.h"
|
||||
|
|
@ -118,7 +118,7 @@ int main(void) {
|
|||
bytecode_add_instruction(bc, OP_PRINT, 0); // top=1
|
||||
|
||||
bytecode_add_instruction(bc, OP_LOAD_CONST, c1);
|
||||
bytecode_add_instruction(bc, OP_POP, 0); // discard 1 (stack now empty)
|
||||
bytecode_add_instruction(bc, OP_POP, 0); // dApache-2.0ard 1 (stack now empty)
|
||||
|
||||
// ---------- HALT ----------
|
||||
bytecode_add_instruction(bc, OP_HALT, 0);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
43
src/parser.c
43
src/parser.c
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -798,7 +798,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
|
||||
/* Append via insert: res.insert(index=len(res), value) */
|
||||
bytecode_add_instruction(bc, OP_INSERT, 0);
|
||||
/* discard returned new length */
|
||||
/* dApache-2.0ard returned new length */
|
||||
bytecode_add_instruction(bc, OP_POP, 0);
|
||||
|
||||
/* i++ */
|
||||
|
|
@ -877,7 +877,7 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
|
||||
/* Append via insert: res.insert(index=len(res), value) */
|
||||
bytecode_add_instruction(bc, OP_INSERT, 0);
|
||||
/* discard returned new length */
|
||||
/* dApache-2.0ard returned new length */
|
||||
bytecode_add_instruction(bc, OP_POP, 0);
|
||||
|
||||
int c1 = bytecode_add_constant(bc, make_int(1));
|
||||
|
|
@ -1029,6 +1029,39 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* threading */
|
||||
if (strcmp(name, "thread_spawn") == 0) {
|
||||
(*pos)++; /* '(' */
|
||||
/* thread_spawn(fn [, args]) */
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "thread_spawn expects function as first arg"); free(name); return 0; }
|
||||
int hasArgs = 0;
|
||||
skip_spaces(src, len, pos);
|
||||
if (*pos < len && src[*pos] == ',') {
|
||||
(*pos)++;
|
||||
skip_spaces(src, len, pos);
|
||||
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "thread_spawn second arg must be array or value"); free(name); return 0; }
|
||||
hasArgs = 1;
|
||||
}
|
||||
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after thread_spawn args"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_THREAD_SPAWN, hasArgs ? 1 : 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(name, "thread_join") == 0) {
|
||||
(*pos)++; /* '(' */
|
||||
if (!emit_expression(bc, src, len, pos) || !consume_char(src, len, pos, ')')) { parser_fail(*pos, "thread_join expects 1 arg (thread id)"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_THREAD_JOIN, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
if (strcmp(name, "sleep") == 0) {
|
||||
(*pos)++; /* '(' */
|
||||
if (!emit_expression(bc, src, len, pos) || !consume_char(src, len, pos, ')')) { parser_fail(*pos, "sleep expects 1 arg (milliseconds)"); free(name); return 0; }
|
||||
bytecode_add_instruction(bc, OP_SLEEP_MS, 0);
|
||||
free(name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* bitwise ops (32-bit) */
|
||||
if (strcmp(name, "band") == 0) {
|
||||
(*pos)++; /* '(' */
|
||||
|
|
@ -2317,7 +2350,7 @@ static void parse_simple_statement(Bytecode *bc, const char *src, size_t len, si
|
|||
/* rewind to statement start and emit as expression */
|
||||
local_pos = *pos;
|
||||
if (emit_expression(bc, src, len, &local_pos)) {
|
||||
bytecode_add_instruction(bc, OP_POP, 0); /* discard return value */
|
||||
bytecode_add_instruction(bc, OP_POP, 0); /* dApache-2.0ard return value */
|
||||
}
|
||||
*pos = local_pos;
|
||||
skip_to_eol(src, len, pos);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
* - Optional shebang on the first line.
|
||||
* - Optional single function wrapper: fun <ident>() { ... }
|
||||
* - print("...") statements inside function or at top-level.
|
||||
* Produces bytecode that executes all discovered print statements and halts.
|
||||
* Produces bytecode that executes all dApache-2.0overed print statements and halts.
|
||||
*
|
||||
* Returns: newly allocated Bytecode*, or NULL on error.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "vm.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#include "value.h"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
21
src/vm.c
21
src/vm.c
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/* Bring in split-out built-ins without changing the build system yet */
|
||||
|
|
@ -18,6 +18,9 @@
|
|||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Threading internals (registry and platform glue) */
|
||||
#include "vm/os/thread_common.c"
|
||||
|
||||
/* Track the currently running VM to annotate error messages */
|
||||
static VM *g_active_vm = NULL;
|
||||
|
||||
|
|
@ -268,7 +271,7 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
#include "vm/bitwise/shr.c"
|
||||
#include "vm/bitwise/rol.c"
|
||||
#include "vm/bitwise/ror.c"
|
||||
|
||||
|
||||
#include "vm/core/call.c"
|
||||
#include "vm/core/dup.c"
|
||||
#include "vm/core/halt.c"
|
||||
|
|
@ -283,11 +286,10 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
#include "vm/core/store_global.c"
|
||||
#include "vm/core/store_local.c"
|
||||
#include "vm/core/swap.c"
|
||||
|
||||
|
||||
#include "vm/io/read_file.c"
|
||||
#include "vm/io/write_file.c"
|
||||
#include "vm/os/env.c"
|
||||
|
||||
|
||||
#include "vm/logic/and.c"
|
||||
#include "vm/logic/eq.c"
|
||||
#include "vm/logic/gt.c"
|
||||
|
|
@ -302,7 +304,7 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
#include "vm/maps/keys.c"
|
||||
#include "vm/maps/make_map.c"
|
||||
#include "vm/maps/values.c"
|
||||
|
||||
|
||||
#include "vm/math/abs.c"
|
||||
#include "vm/math/clamp.c"
|
||||
#include "vm/math/max.c"
|
||||
|
|
@ -312,6 +314,11 @@ void vm_run(VM *vm, Bytecode *entry) {
|
|||
#include "vm/math/random_int.c"
|
||||
#include "vm/math/random_seed.c"
|
||||
|
||||
#include "vm/os/env.c"
|
||||
#include "vm/os/sleep_ms.c"
|
||||
#include "vm/os/thread_join.c"
|
||||
#include "vm/os/thread_spawn.c"
|
||||
|
||||
#include "vm/strings/find.c"
|
||||
#include "vm/strings/split.c"
|
||||
#include "vm/strings/substr.c"
|
||||
|
|
|
|||
5
src/vm.h
5
src/vm.h
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
#ifndef FUN_VM_H
|
||||
|
|
@ -34,6 +34,7 @@ static const char *opcode_names[] = {
|
|||
"MIN","MAX","CLAMP","ABS","POW","RANDOM_SEED","RANDOM_INT",
|
||||
"MAKE_MAP","KEYS","VALUES","HAS_KEY",
|
||||
"READ_FILE","WRITE_FILE","ENV",
|
||||
"THREAD_SPAWN","THREAD_JOIN","SLEEP_MS",
|
||||
"BAND","BOR","BXOR","BNOT","SHL","SHR","ROTL","ROTR"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-29
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
case OP_LINE: {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
// Get environment variables of the operation system.
|
||||
|
|
|
|||
27
src/vm/os/sleep_ms.c
Normal file
27
src/vm/os/sleep_ms.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* This file is part of the Fun programming language.
|
||||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-30
|
||||
*/
|
||||
|
||||
case OP_SLEEP_MS: {
|
||||
Value ms = pop_value(vm);
|
||||
if (ms.type != VAL_INT) {
|
||||
fprintf(stderr, "Runtime type error: sleep(ms) expects Number (milliseconds)\n");
|
||||
free_value(ms);
|
||||
/* push Nil so caller-side POP is safe */
|
||||
push_value(vm, make_nil());
|
||||
break;
|
||||
}
|
||||
long t = (long)ms.i;
|
||||
if (t > 0) fun_sleep_ms(t);
|
||||
free_value(ms);
|
||||
/* push Nil so statement POP does not underflow */
|
||||
push_value(vm, make_nil());
|
||||
break;
|
||||
}
|
||||
261
src/vm/os/thread_common.c
Normal file
261
src/vm/os/thread_common.c
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
/**
|
||||
* This file is part of the Fun programming language.
|
||||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-30
|
||||
*/
|
||||
|
||||
/* Cross-platform minimal threading support embedded into vm.c TU */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
typedef HANDLE fun_thread_handle_t;
|
||||
typedef DWORD fun_thread_ret_t;
|
||||
#define FUN_THREAD_CALL WINAPI
|
||||
#define fun_sleep_ms(ms) Sleep((DWORD)(ms))
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
typedef pthread_t fun_thread_handle_t;
|
||||
typedef void* fun_thread_ret_t;
|
||||
#define FUN_THREAD_CALL
|
||||
static inline void fun_sleep_ms(long ms) {
|
||||
if (ms <= 0) return;
|
||||
struct timespec ts;
|
||||
ts.tv_sec = ms / 1000;
|
||||
ts.tv_nsec = (ms % 1000) * 1000000L;
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FUN_MAX_THREADS
|
||||
#define FUN_MAX_THREADS 64
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
fun_thread_handle_t handle;
|
||||
int used;
|
||||
int done;
|
||||
Value result; /* owned */
|
||||
#ifdef _WIN32
|
||||
DWORD threadId;
|
||||
#endif
|
||||
} FunThreadEntry;
|
||||
|
||||
static FunThreadEntry g_threads[FUN_MAX_THREADS];
|
||||
|
||||
#ifdef _WIN32
|
||||
static CRITICAL_SECTION g_thr_lock;
|
||||
static int g_thr_lock_inited = 0;
|
||||
static void fun_thr_lock_init(void) {
|
||||
if (!g_thr_lock_inited) {
|
||||
InitializeCriticalSection(&g_thr_lock);
|
||||
g_thr_lock_inited = 1;
|
||||
}
|
||||
}
|
||||
static void fun_lock(void) { if (!g_thr_lock_inited) fun_thr_lock_init(); EnterCriticalSection(&g_thr_lock); }
|
||||
static void fun_unlock(void) { LeaveCriticalSection(&g_thr_lock); }
|
||||
#else
|
||||
static pthread_mutex_t g_thr_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void fun_lock(void) { pthread_mutex_lock(&g_thr_lock); }
|
||||
static void fun_unlock(void) { pthread_mutex_unlock(&g_thr_lock); }
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
Bytecode *fn; /* function to call */
|
||||
int argc;
|
||||
Value *args; /* array of argc Values (owned by task, will be freed) */
|
||||
int slot; /* registry slot */
|
||||
} FunTask;
|
||||
|
||||
#ifdef _WIN32
|
||||
static fun_thread_ret_t FUN_THREAD_CALL fun_thread_main(LPVOID param)
|
||||
#else
|
||||
static fun_thread_ret_t fun_thread_main(void *param)
|
||||
#endif
|
||||
{
|
||||
FunTask *task = (FunTask*)param;
|
||||
VM tvm;
|
||||
vm_init(&tvm);
|
||||
|
||||
/* Build wrapper: LOAD_CONST <fn>; LOAD_CONST <arg0> ...; CALL argc; HALT */
|
||||
Bytecode *wrap = bytecode_new();
|
||||
int cFn = bytecode_add_constant(wrap, copy_value(&(Value){ .type = VAL_FUNCTION, .fn = task->fn }));
|
||||
bytecode_add_instruction(wrap, OP_LOAD_CONST, cFn);
|
||||
for (int i = 0; i < task->argc; ++i) {
|
||||
int cArg = bytecode_add_constant(wrap, deep_copy_value(&task->args[i]));
|
||||
bytecode_add_instruction(wrap, OP_LOAD_CONST, cArg);
|
||||
}
|
||||
bytecode_add_instruction(wrap, OP_CALL, task->argc);
|
||||
bytecode_add_instruction(wrap, OP_HALT, 0);
|
||||
|
||||
vm_run(&tvm, wrap);
|
||||
|
||||
/* Take the top of stack as result if present, else Nil */
|
||||
Value res = make_nil();
|
||||
if (tvm.sp >= 0) {
|
||||
res = deep_copy_value(&tvm.stack[tvm.sp]);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
for (int i = 0; i < task->argc; ++i) {
|
||||
free_value(task->args[i]);
|
||||
}
|
||||
free(task->args);
|
||||
bytecode_free(wrap);
|
||||
|
||||
/* store result */
|
||||
fun_lock();
|
||||
g_threads[task->slot].result = res;
|
||||
g_threads[task->slot].done = 1;
|
||||
fun_unlock();
|
||||
|
||||
free(task);
|
||||
|
||||
#ifdef _WIN32
|
||||
return 0;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int fun_alloc_thread_slot(void) {
|
||||
fun_lock();
|
||||
int idx = -1;
|
||||
for (int i = 0; i < FUN_MAX_THREADS; ++i) {
|
||||
if (!g_threads[i].used) { g_threads[i].used = 1; g_threads[i].done = 0; g_threads[i].result = make_nil(); idx = i; break; }
|
||||
}
|
||||
fun_unlock();
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int fun_thread_spawn(Value fnVal, Value argsMaybe, int hasArgs) {
|
||||
if (fnVal.type != VAL_FUNCTION || !fnVal.fn) {
|
||||
fprintf(stderr, "Runtime error: thread_spawn expects Function as first argument\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Collect args */
|
||||
int argc = 0;
|
||||
Value *args = NULL;
|
||||
|
||||
if (hasArgs) {
|
||||
if (argsMaybe.type == VAL_ARRAY && argsMaybe.arr) {
|
||||
int n = array_length(&argsMaybe);
|
||||
if (n > 0) {
|
||||
args = (Value*)calloc((size_t)n, sizeof(Value));
|
||||
if (!args) n = 0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
Value vi;
|
||||
if (array_get_copy(&argsMaybe, i, &vi)) {
|
||||
args[i] = deep_copy_value(&vi);
|
||||
free_value(vi);
|
||||
} else {
|
||||
args[i] = make_nil();
|
||||
}
|
||||
}
|
||||
argc = n;
|
||||
}
|
||||
} else if (argsMaybe.type != VAL_NIL) {
|
||||
args = (Value*)calloc(1, sizeof(Value));
|
||||
if (args) {
|
||||
args[0] = deep_copy_value(&argsMaybe);
|
||||
argc = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int slot = fun_alloc_thread_slot();
|
||||
if (slot < 0) {
|
||||
fprintf(stderr, "Runtime error: too many threads\n");
|
||||
/* free args */
|
||||
for (int i = 0; i < argc; ++i) free_value(args[i]);
|
||||
free(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
FunTask *task = (FunTask*)calloc(1, sizeof(FunTask));
|
||||
if (!task) {
|
||||
for (int i = 0; i < argc; ++i) free_value(args[i]);
|
||||
free(args);
|
||||
fun_lock(); g_threads[slot].used = 0; fun_unlock();
|
||||
return 0;
|
||||
}
|
||||
task->fn = fnVal.fn;
|
||||
task->argc = argc;
|
||||
task->args = args;
|
||||
task->slot = slot;
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE h = CreateThread(NULL, 0, fun_thread_main, (LPVOID)task, 0, &g_threads[slot].threadId);
|
||||
if (!h) {
|
||||
fprintf(stderr, "Runtime error: CreateThread failed\n");
|
||||
for (int i = 0; i < argc; ++i) free_value(args[i]);
|
||||
free(args);
|
||||
free(task);
|
||||
fun_lock(); g_threads[slot].used = 0; fun_unlock();
|
||||
return 0;
|
||||
}
|
||||
fun_lock(); g_threads[slot].handle = h; fun_unlock();
|
||||
#else
|
||||
pthread_t tid;
|
||||
int rc = pthread_create(&tid, NULL, fun_thread_main, (void*)task);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Runtime error: pthread_create failed\n");
|
||||
for (int i = 0; i < argc; ++i) free_value(args[i]);
|
||||
free(args);
|
||||
free(task);
|
||||
fun_lock(); g_threads[slot].used = 0; fun_unlock();
|
||||
return 0;
|
||||
}
|
||||
fun_lock(); g_threads[slot].handle = tid; fun_unlock();
|
||||
#endif
|
||||
|
||||
return slot + 1; /* external thread id: 1..N */
|
||||
}
|
||||
|
||||
static Value fun_thread_join(int tid) {
|
||||
if (tid <= 0 || tid > FUN_MAX_THREADS) {
|
||||
fprintf(stderr, "Runtime error: thread_join invalid id %d\n", tid);
|
||||
return make_nil();
|
||||
}
|
||||
int idx = tid - 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
fun_lock();
|
||||
HANDLE h = g_threads[idx].handle;
|
||||
int used = g_threads[idx].used;
|
||||
fun_unlock();
|
||||
if (!used || !h) return make_nil();
|
||||
WaitForSingleObject(h, INFINITE);
|
||||
CloseHandle(h);
|
||||
#else
|
||||
fun_lock();
|
||||
pthread_t h = g_threads[idx].handle;
|
||||
int used = g_threads[idx].used;
|
||||
fun_unlock();
|
||||
if (!used) return make_nil();
|
||||
pthread_join(h, NULL);
|
||||
#endif
|
||||
|
||||
/* fetch result and free slot */
|
||||
fun_lock();
|
||||
Value res = deep_copy_value(&g_threads[idx].result);
|
||||
free_value(g_threads[idx].result);
|
||||
g_threads[idx].result = make_nil();
|
||||
g_threads[idx].used = 0;
|
||||
g_threads[idx].done = 0;
|
||||
#ifdef _WIN32
|
||||
g_threads[idx].threadId = 0;
|
||||
#endif
|
||||
fun_unlock();
|
||||
|
||||
return res;
|
||||
}
|
||||
24
src/vm/os/thread_join.c
Normal file
24
src/vm/os/thread_join.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* This file is part of the Fun programming language.
|
||||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-30
|
||||
*/
|
||||
|
||||
case OP_THREAD_JOIN: {
|
||||
Value vtid = pop_value(vm);
|
||||
if (vtid.type != VAL_INT) {
|
||||
fprintf(stderr, "Runtime type error: thread_join expects thread id (int)\n");
|
||||
push_value(vm, make_nil());
|
||||
free_value(vtid);
|
||||
break;
|
||||
}
|
||||
Value res = fun_thread_join((int)vtid.i);
|
||||
free_value(vtid);
|
||||
push_value(vm, res); /* takes ownership */
|
||||
break;
|
||||
}
|
||||
24
src/vm/os/thread_spawn.c
Normal file
24
src/vm/os/thread_spawn.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* This file is part of the Fun programming language.
|
||||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*
|
||||
* Added: 2025-09-30
|
||||
*/
|
||||
|
||||
case OP_THREAD_SPAWN: {
|
||||
/* operand: 0 -> no args; 1 -> has args array or single arg */
|
||||
Value argsMaybe = make_nil();
|
||||
if (inst.operand == 1) {
|
||||
argsMaybe = pop_value(vm); /* maybe array or scalar */
|
||||
}
|
||||
Value fnv = pop_value(vm);
|
||||
int tid = fun_thread_spawn(fnv, argsMaybe, inst.operand == 1);
|
||||
free_value(fnv);
|
||||
if (inst.operand == 1) free_value(argsMaybe);
|
||||
push_value(vm, make_int(tid));
|
||||
break;
|
||||
}
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
case OP_SCLAMP: {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
case OP_TYPEOF: {
|
||||
|
|
@ -23,4 +23,4 @@ case OP_TYPEOF: {
|
|||
push_value(vm, make_string(tname));
|
||||
free_value(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* https://hanez.org/project/fun/
|
||||
*
|
||||
* Copyright 2025 Johannes Findeisen <you@hanez.org>
|
||||
* Licensed under the terms of the ISC license.
|
||||
* https://opensource.org/license/isc-license-txt
|
||||
* Licensed under the terms of the Apache-2.0 license.
|
||||
* https://opensource.org/license/apache-2-0
|
||||
*/
|
||||
|
||||
case OP_UCLAMP: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue