From 6a39862787e656c98455dd065e9a85da388dcf8c Mon Sep 17 00:00:00 2001 From: hanez Date: Thu, 28 May 2026 01:27:08 +0200 Subject: [PATCH] ./examples/features.fun and ./web/features/features.md update. (0.41.16) --- CMakeLists.txt | 2 +- examples/features.fun | 335 +++++++++++++++++++++++++------- web/features/features.md | 398 ++++++++++++++++++++++++++++++++------- 3 files changed, 599 insertions(+), 136 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c754fc..9936ea2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.41.15 LANGUAGES C) +project(fun VERSION 0.41.16 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/examples/features.fun b/examples/features.fun index 483219e..9ebce9d 100755 --- a/examples/features.fun +++ b/examples/features.fun @@ -10,48 +10,120 @@ print("") // ============================================ print("1. Strong Type System:") string name = "Fun Language" -float version = 0.3 +float version = 0.41 boolean is_awesome = true +number meaning = 42 items = [1, 2, 3, 4, 5] config = {"debug": true, "port": 8080} +nil_val = nil -print(" Language: " + name + " v" + to_string(version)) +print(" Language: " + name + " v" + fun_version()) print(" Awesome: " + to_string(is_awesome)) +print(" Nil: " + to_string(nil_val)) print("") // ============================================ -// 2. Modern Array Operations +// 2. Type Introspection // ============================================ -print("2. Array Operations:") +print("2. Type Introspection:") +number check_int = 42 +string check_str = "hello" +check_arr = [1, 2, 3] +check_map = {"key": "value"} +check_float = 3.14 + +print(" typeof(42) = " + typeof(check_int)) +print(" typeof(\"hello\") = " + typeof(check_str)) +print(" typeof([1,2,3]) = " + typeof(check_arr)) +print(" typeof(map) = " + typeof(check_map)) +print(" typeof(3.14) = " + typeof(check_float)) +print("") + +// ============================================ +// 3. Conversion & Casting +// ============================================ +print("3. Conversion & Casting:") +print(" to_string(42) = " + to_string(42)) +print(" to_number(\"99\") = " + to_string(to_number("99"))) +casted = cast(1, "boolean") +print(" cast(1, \"boolean\") = " + to_string(casted)) +casted2 = cast("42", "number") +print(" cast(\"42\", \"number\") = " + to_string(casted2)) +print("") + +// ============================================ +// 4. String Manipulation +// ============================================ +print("4. String Operations:") +string text = "Hello, Fun Language!" +print(" Original: " + text) +print(" Length: " + to_string(len(text))) +print(" Substr(0,5): " + substr(text, 0, 5)) +print(" Find(\"Fun\"): " + to_string(find(text, "Fun"))) +parts = split(text, " ") +print(" Split by space: " + to_string(parts)) +joined = join(parts, "-") +print(" Join with '-': " + joined) +print("") + +// ============================================ +// 5. Modern Array Operations +// ============================================ +print("5. Array Operations:") numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(" Original: " + to_string(numbers)) +print(" Length: " + to_string(len(numbers))) +print(" Index 0: " + to_string(numbers[0])) +print(" Index last: " + to_string(numbers[len(numbers) - 1])) -// Array helpers from spec: push, join, map, filter, reduce -joined = join([10, 20, 30], ", ") -print(" Joined: " + joined) +// Slice syntax arr[start:end] +sliced = numbers[2:7] +print(" Slice [2:7]: " + to_string(sliced)) -// Iterate arrays -print(" Iteration:") -for item in ["apple", "banana", "cherry"] - print(" " + item) +// Mutating array ops +arr = [10, 20, 30] +push(arr, 40) +print(" After push(40): " + to_string(arr)) +removed = pop(arr) +print(" Popped: " + to_string(removed) + ", arr: " + to_string(arr)) +insert(arr, 1, 15) +print(" After insert(1, 15): " + to_string(arr)) +removed = remove(arr, 0) +print(" Removed at 0: " + to_string(removed) + ", arr: " + to_string(arr)) + +// Search & utility +print(" Contains 20? " + to_string(contains(arr, 20))) +print(" Index of 20? " + to_string(indexOf(arr, 20))) +print(" Enumerate: " + to_string(enumerate(["a", "b", "c"]))) +print(" Zip: " + to_string(zip([1, 2, 3], ["x", "y", "z"]))) +clear(arr) +print(" After clear: " + to_string(arr)) print("") // ============================================ -// 3. Maps (Dictionaries) +// 6. Maps (Dictionaries) // ============================================ -print("3. Map Operations:") +print("6. Map Operations:") person = {"name": "Alice", "age": 30, "role": "Developer"} print(" Person: " + to_string(person)) print(" Has 'age' key: " + to_string(has(person, "age"))) print(" Keys: " + to_string(keys(person))) print(" Values: " + to_string(values(person))) + +// Bracket access and assignment +print(" person[\"name\"]: " + person["name"]) +person["age"] = 31 +print(" Updated age: " + to_string(person["age"])) + +// Object property access (dot notation) +print(" person.name: " + person.name) print("") // ============================================ -// 4. Object-Oriented Programming +// 7. Object-Oriented Programming // ============================================ -print("4. Classes & Objects:") +print("7. Classes & Objects:") class Counter(number initial, string label) count = 0 @@ -78,9 +150,9 @@ counter.display() print("") // ============================================ -// 5. Inheritance +// 8. Inheritance // ============================================ -print("5. Inheritance:") +print("8. Inheritance:") class Animal(string type) species = "" @@ -107,9 +179,9 @@ print(" Species: " + dog.species) print("") // ============================================ -// 6. Error Handling +// 9. Error Handling & Exceptions // ============================================ -print("6. Exception Handling:") +print("9. Exception Handling:") try print(" Attempting risky operation...") @@ -122,51 +194,63 @@ finally print("") // ============================================ -// 7. String Manipulation +// 10. Comparison & Logical Operators // ============================================ -print("7. String Features:") -string text = "Hello, Fun Language!" -print(" Original: " + text) -// Note: Using stdlib functions (assumed to exist in utils modules) -// len, substr, find, split would come from stdlib +print("10. Comparison & Logical Operators:") +number a = 10 +number b = 20 +print(" a=10, b=20") +print(" a < b: " + to_string(a < b)) +print(" a <= b: " + to_string(a <= b)) +print(" a > b: " + to_string(a > b)) +print(" a >= b: " + to_string(a >= b)) +print(" a == b: " + to_string(a == b)) +print(" a != b: " + to_string(a != b)) +print(" a < b && a > 0: " + to_string(a < b && a > 0)) +print(" a > b || a > 0: " + to_string(a > b || a > 0)) +print(" !true: " + to_string(!true)) +print(" Ternary (a < b ? \"yes\" : \"no\"): " + (a < b ? "yes" : "no")) print("") // ============================================ -// 8. Mathematical Operations +// 11. Control Flow: if/else if/else // ============================================ -print("8. Math Functions:") -float x = 16.7 -print(" x = " + to_string(x)) -// Note: Math functions like sqrt, floor, ceil, abs, gcd, lcm -// would come from stdlib or similar +print("11. If/Else If/Else:") +number score = 85 + +if score >= 90 + print(" Grade: A") +else if score >= 80 + print(" Grade: B") +else if score >= 70 + print(" Grade: C") +else + print(" Grade: F") print("") // ============================================ -// 9. Bitwise Operations +// 12. Control Flow: Loops // ============================================ -print("9. Bitwise Operations:") -number bits1 = 12 -number bits2 = 10 -print(" 12 & 10 = " + to_string(band(bits1, bits2))) -print(" 12 | 10 = " + to_string(bor(bits1, bits2))) -print(" 12 ^ 10 = " + to_string(bxor(bits1, bits2))) -print(" 12 << 2 = " + to_string(shl(bits1, 2))) -print(" ~12 = " + to_string(bnot(bits1))) -print("") +print("12. Loop Variants:") -// ============================================ -// 10. Control Flow -// ============================================ -print("10. Control Flow:") +// For-each with array +print(" For-each array:") +for item in ["apple", "banana", "cherry"] + print(" " + item) -// For loop with array -print(" Countdown:") -for i in [5, 4, 3, 2, 1] - print(" " + to_string(i) + "...") -print(" Liftoff!") +// For-range loop +print(" For-range 0..4:") +for i in range(0, 5) + print(" " + to_string(i)) + +// For-map loop +print(" For-map key, value:") +config_map = {"a": 1, "b": 2, "c": 3} +for (k, v) in config_map + print(" " + k + " = " + to_string(v)) // While with break/continue -print(" Skip evens:") +print(" While with break/continue:") number n = 0 while n < 10 n = n + 1 @@ -178,24 +262,55 @@ while n < 10 print("") // ============================================ -// 11. Type Introspection +// 13. Mathematical Operations // ============================================ -print("11. Type Introspection:") -number check_int = 42 -string check_str = "hello" -check_arr = [1, 2, 3] -check_map = {"key": "value"} +print("13. Math Functions:") +number mx = -16 +print(" abs(-16) = " + to_string(abs(mx))) +print(" min(10, 20) = " + to_string(min(10, 20))) +print(" max(10, 20) = " + to_string(max(10, 20))) +print(" clamp(50, 0, 10) = " + to_string(clamp(50, 0, 10))) +print(" pow(2, 10) = " + to_string(pow(2, 10))) +print(" sqrt(144) = " + to_string(sqrt(144))) +print(" floor(3.7) = " + to_string(floor(3.7))) +print(" ceil(3.2) = " + to_string(ceil(3.2))) +print(" round(3.5) = " + to_string(round(3.5))) +print(" trunc(3.9) = " + to_string(trunc(3.9))) +print(" sin(0) = " + to_string(sin(0))) +print(" cos(0) = " + to_string(cos(0))) +print(" gcd(12, 8) = " + to_string(gcd(12, 8))) +print(" lcm(12, 8) = " + to_string(lcm(12, 8))) +print(" isqrt(50) = " + to_string(isqrt(50))) +print(" sign(-42) = " + to_string(sign(-42))) +print(" fmin(3.1, 2.9) = " + to_string(fmin(3.1, 2.9))) +print(" fmax(3.1, 2.9) = " + to_string(fmax(3.1, 2.9))) -print(" typeof(42) = " + typeof(check_int)) -print(" typeof(\"hello\") = " + typeof(check_str)) -print(" typeof([1,2,3]) = " + typeof(check_arr)) -print(" typeof(map) = " + typeof(check_map)) +// Random (deterministic for demo) +random_seed(42) +print(" random_int(1, 100) = " + to_string(random_int(1, 100))) +print(" random_number(8) = " + random_number(8)) print("") // ============================================ -// 12. Functional Programming +// 14. Bitwise Operations // ============================================ -print("12. Higher-Order Functions:") +print("14. Bitwise Operations:") +number bits1 = 12 // 1100 +number bits2 = 10 // 1010 +print(" 12 & 10 = " + to_string(band(bits1, bits2))) +print(" 12 | 10 = " + to_string(bor(bits1, bits2))) +print(" 12 ^ 10 = " + to_string(bxor(bits1, bits2))) +print(" ~12 = " + to_string(bnot(bits1))) +print(" 12 << 2 = " + to_string(shl(bits1, 2))) +print(" 12 >> 2 = " + to_string(shr(bits1, 2))) +print(" rol(0x80000001, 1) = " + to_string(rol(0x80000001, 1))) +print(" ror(0x80000001, 1) = " + to_string(ror(0x80000001, 1))) +print("") + +// ============================================ +// 15. Functional & Higher-Order Programming +// ============================================ +print("15. Higher-Order Functions:") fun double(n) return n * 2 @@ -208,28 +323,112 @@ print(" apply_twice(5, double) = " + to_string(result)) print("") // ============================================ -// 13. Array Operations with Spec Functions +// 16. Array Higher-Order Functions // ============================================ -print("13. Array Higher-Order Functions:") +print("16. Array Higher-Order Functions:") nums = [1, 2, 3, 4, 5] fun square(x) return x * x squared = map(nums, square) -print(" Squared: " + to_string(squared)) +print(" map(nums, square): " + to_string(squared)) fun is_even(x) return x % 2 == 0 evens = filter(nums, is_even) -print(" Evens: " + to_string(evens)) +print(" filter(nums, is_even): " + to_string(evens)) fun sum(acc, x) return acc + x total = reduce(nums, 0, sum) -print(" Sum: " + to_string(total)) +print(" reduce(nums, 0, sum): " + to_string(total)) +print("") + +// ============================================ +// 17. File I/O +// ============================================ +print("17. File I/O:") +write_file("/tmp/fun_demo.txt", "Hello from Fun!") +content = read_file("/tmp/fun_demo.txt") +print(" Written and read back: " + content) +print("") + +// ============================================ +// 18. Environment & OS +// ============================================ +print("18. Environment & OS:") +print(" HOME: " + env("HOME")) +print(" Version: " + fun_version()) + +// List directory (non-empty /tmp assumed) +listing = os_list_dir("/tmp") +print(" /tmp has " + to_string(len(listing)) + " entries") + +// Run a command and capture output +proc_result = proc_run("echo hello from fun") +print(" proc_run output: " + proc_result["out"]) + +// System call exit code +sys_code = system("true") +print(" system(\"true\") exit: " + to_string(sys_code)) +print("") + +// ============================================ +// 19. Date, Time & Sleep +// ============================================ +print("19. Date, Time & Sleep:") +now = time_now_ms() +print(" Now (epoch ms): " + to_string(now)) +print(" Date formatted: " + date_format(now, "%Y-%m-%d %H:%M:%S")) + +mono = clock_mono_ms() +print(" Monotonic ms: " + to_string(mono)) + +// Short sleep to demonstrate +sleep(10) +after = clock_mono_ms() +diff = after - mono +print(" Slept 10 ms, elapsed: " + to_string(diff) + " ms") +print("") + +// ============================================ +// 20. Echo (print without newline) +// ============================================ +print("20. Echo (no newline):") +echo(" Hello, ") +echo("world") +print("!") +print("") + +// ============================================ +// 21. Threading +// ============================================ +print("21. Threading:") + +fun worker(id) + print(" Thread " + to_string(id) + " says hi!") + return id * 2 + +t1 = thread_spawn(worker, [1]) +t2 = thread_spawn(worker, [2]) +r1 = thread_join(t1) +r2 = thread_join(t2) +print(" Joined thread results: " + to_string(r1) + ", " + to_string(r2)) +print("") + +// ============================================ +// 22. Type-Safe Integer Clamping +// ============================================ +print("22. Integer Clamping:") +byte val = 300 +print(" byte val = 300 -> clamped to " + to_string(val)) +int8 signed = 200 +print(" int8 val = 200 -> clamped to " + to_string(signed)) +uint16 big = 70000 +print(" uint16 val = 70000 -> clamped to " + to_string(big)) print("") // ============================================ diff --git a/web/features/features.md b/web/features/features.md index b96a6e3..0642b34 100644 --- a/web/features/features.md +++ b/web/features/features.md @@ -24,103 +24,367 @@ tags: - cgi --- -This page summarizes the core capabilities of Fun: the language, its virtual machine/runtime, tooling, build options, and the surrounding ecosystem. For in‑depth pages, see also: +This page summarizes the core capabilities of Fun: the language, its virtual machine/runtime, tooling, build options, and the surrounding ecosystem. -- VM opcodes overview: /documentation/opcodes/ -- Optional extensions catalog: /documentation/extensions/ +--- ## Language -- Simple, expressive syntax designed for scripting and embedding -- First‑class functions and function calls -- Variables, locals and globals with stack‑based execution model -- Control flow: conditional jumps, returns, and basic boolean operators -- Arrays and maps as primary collection types (literal construction, indexing, slicing, membership) -- Strings with common operations (substring, find, split, join) -- Arithmetic and bitwise integer operations (add, sub, mul, div, mod; band, bor, bxor, shifts, rotations) -- Exceptions and error handling primitives (throw/try semantics at VM level) -- Regular expressions support via optional PCRE2 extension (see Extensions) +### Syntax & Structure +- Indentation-based block structure (strict 2-space indent) +- Line comments (`//`) and block comments (`/* */`) +- Optional shebang (`#!`) line for script execution +- Unicode string support via UTF-8 throughout +- `exit` statement with optional exit code -Notes: +### Type System +- **Dynamic typing** with optional **static type annotations** +- **Value types:** Integer (signed 64-bit), Float (double), Boolean, String, Array, Map, Function, Nil +- **Type annotations:** `number`, `string`, `boolean`, `float`, `nil`, `array`, `map`, `class` +- **Fixed-width integer types:** `byte` / `uint8`, `uint16`, `uint32`, `uint64`, `int8`, `int16`, `int32`, `int64` — with automatic range clamping +- **Type aliases:** `sint8`–`sint64` as synonyms for `int8`–`int64` +- `typeof()` runtime type introspection +- `to_string()` and `to_number()` conversion functions +- `cast(value, typeName)` explicit type casting -- See the opcode index for the precise stack behavior of each operation: /documentation/opcodes/ +### Variables & Scope +- Global and local (per-function) variable scoping +- Auto-declaration on first assignment +- Typed variable declarations: `string name = "Fun"` +- Up to 128 globals, 64 locals per frame, 128 call frames + +### Operators + +**Arithmetic:** `+`, `-`, `*`, `/`, `%` (addition also concatenates strings) + +**Comparison:** `<`, `<=`, `>`, `>=`, `==`, `!=` + +**Logical:** `&&` (and), `||` (or), `!` (not) — short-circuit evaluation + +**Bitwise (32-bit):** `band()`, `bor()`, `bxor()`, `bnot()`, `shl()`, `shr()`, `rol()`, `ror()` + +**Ternary:** `condition ? true_expr : false_expr` + +### Data Structures + +**Arrays:** +- Literal syntax: `[1, 2, 3]` +- Index get/set: `arr[0]`, `arr[0] = value` +- Slice syntax: `arr[start:end]` +- Negative indices for end-relative access +- Built-in operations: `len()`, `push()`, `pop()`, `insert()`, `remove()`, `slice()`, `contains()`, `indexOf()`, `clear()`, `enumerate()`, `zip()`, `join()`, `map()`, `filter()`, `reduce()` + +**Maps (dictionaries):** +- Literal syntax: `{"key": value, ...}` +- Bracket access/assignment: `map["key"]`, `map["key"] = value` +- Dot property access: `map.key` +- Built-in operations: `has()`, `keys()`, `values()` + +### Strings +- Double and single-quoted string literals +- Concatenation with `+` +- Built-in operations: `len()`, `substr()`, `find()`, `split()`, `join()` + +### Control Flow +- `if` / `else if` / `else` conditional chains +- `while` loops with `break` and `continue` +- `for var in array` — array iteration +- `for var in range(start, end)` — numeric range iteration (`[start, end)`) +- `for (key, value) in map` — map key-value iteration +- `match` expression (stdlib `lib/utils/match.fun`) + +### Functions +- Named function definitions: `fun name(params) body` +- Anonymous function literals: `fn(params) body` +- First-class functions (pass as arguments, store in variables) +- Recursion support +- Return with `return expr` (or implicit nil) + +### Object-Oriented Programming +- Class definitions: `class Name(typed params) body` +- Constructor method: `_construct(this, ...)` — auto-invoked on instantiation +- Methods: `fun method(this, ...)` inside class body +- Field access and mutation via `this.field` +- Property access via dot notation: `obj.field` +- Method call sugar: `obj.method(args)` (auto-binds `this`) +- Single inheritance: `class Child(...) extends Parent` +- Method overriding in subclasses + +### Error Handling +- `try` / `catch` / `finally` blocks +- Error variable binding: `catch err` +- `throw` opcode for raising exceptions +- Per-frame try-stack for nested exception handlers + +### Pattern Matching & Regex (Built-in POSIX) +- `regex_match(str, pattern)` — full match test (returns 1/0) +- `regex_search(str, pattern)` — first match with groups (returns map) +- `regex_replace(str, pattern, replacement)` — global search and replace + +### Functional Programming +- First-class and anonymous functions +- `map(array, fn)` — transform each element +- `filter(array, fn)` — keep matching elements +- `reduce(array, init, fn)` — accumulate values +- Higher-order functions (functions that accept or return functions) +- `enumerate()` and `zip()` iteration helpers + +### Concurrency +- `thread_spawn(fn, args)` — spawn a thread, returns thread ID +- `thread_join(id)` — join a thread, returns its result +- Cooperative async scheduler (stdlib `lib/async/scheduler.fun`) + +--- ## Virtual Machine & Runtime -- Compact stack‑based bytecode VM implemented in C (C99) -- Deterministic execution model with explicit opcodes for core language features -- Efficient array and map primitives with indexing and mutation opcodes -- Built‑in string operations and regex integration (with extension) -- Minimal error model integrated with VM (throw/try handlers) +### Architecture +- Compact stack-based bytecode VM written in **C99** +- Tagged union value type supporting 8 runtime types +- ~220 opcodes covering all language features +- Separate operand stack (1024 entries), call frames (128 max), and globals (128) +- Each frame has 64 local slots and a 16-entry try/catch stack -## Standard Library (Core) +### Memory & Performance +- Deterministic execution model +- Reference-counted arrays and maps +- Function/data sectioning with linker GC for small binaries +- LTO (Link-Time Optimization) support for Release builds -Core functionality available out of the box in the VM and library modules: +### Debugging & Tracing +- Built-in debugger with breakpoints (up to 64) +- Step, next, finish, and continue commands +- `--trace` / `-t` flag for opcode-level execution tracing +- Per-opcode execution counters (compile-time `FUN_TRACE`) +- `--repl-on-error` flag: drops into interactive REPL on runtime error with stack preserved +- Stack trace printing on errors +- Source line mapping in error messages (includes include-file resolution) -- Arrays: create, push/pop, insert/remove, slice, contains, join, enumerate -- Maps: create, has_key, keys, values -- Strings: substr, find, split, replace (with regex), join -- Math and bitwise ops over fixed‑width integers used by the VM +### I/O & Platform +- `print()` — output with newline +- `echo()` — output without newline (immediate flush) +- `read_file(path)` — read entire file into string +- `write_file(path, data)` — write string to file +- `input_line()` — read a line from stdin (with optional prompt) +- `env(name)` / `env_all()` — get environment variables +- `proc_run(cmd)` — run command, capture stdout+exit code +- `system(cmd)` — run command via shell, returns exit code +- `os_list_dir(path)` — list directory entries -See the opcode list for the canonical reference: /documentation/opcodes/ +### Date, Time & Random +- `time_now_ms()` — wall clock in milliseconds since Unix epoch +- `clock_mono_ms()` — monotonic clock for interval measurement +- `date_format(ms, fmt)` — format timestamps via strftime +- `sleep(ms)` — suspend execution +- `random_seed(seed)` — seed the PRNG +- `random_int(lo, hi)` — random integer in `[lo, hi)` +- `random_number(len)` — cryptographically random hex string + +### Networking (Built-in, Unix) +- `sock_tcp_listen(port, backlog)` — TCP server socket +- `sock_tcp_accept(listen_fd)` — accept client connection +- `sock_tcp_connect(host, port)` — TCP client connection +- `sock_send(fd, data)` / `sock_recv(fd, maxlen)` — send/receive data +- `sock_unix_listen(path, backlog)` / `sock_unix_connect(path)` — Unix domain sockets +- `sock_close(fd)` — close socket +- `fd_set_nonblock(fd, on)` — non-blocking mode +- `fd_poll_read(fd, timeout_ms)` / `fd_poll_write(fd, timeout_ms)` — I/O readiness polling + +### Serial Communication (Unix) +- `serial_open(path, baud_rate)` — open serial port +- `serial_config(fd, data_bits, parity, stop_bits, flow_control)` — configure +- `serial_send(fd, data)` / `serial_recv(fd, maxlen)` — send/receive +- `serial_close(fd)` — close + +### Integer Utilities +- `sclamp(value, bits)` / `uclamp(value, bits)` — signed/unsigned bit-width clamping +- Integer type declarations (`byte`, `uint8`–`uint64`, `int8`–`int64`) with automatic range clamping +- `gcd(a, b)`, `lcm(a, b)` — greatest common divisor, least common multiple +- `isqrt(x)` — integer square root +- `sign(x)` — signum (-1, 0, 1) + +--- + +## Standard Library + +The standard library is written primarily in **Fun itself** and lives in `lib/`: + +### Strings (`lib/strings.fun`) +- `str_ltrim`, `str_rtrim`, `str_trim` — whitespace trimming +- `str_starts_with`, `str_ends_with` — prefix/suffix checking +- `str_split` — single-character delimiter splitting +- `str_replace_all` — global substring replacement +- `str_to_lower`, `str_to_upper` — ASCII case conversion +- `str_repeat` — string repetition +- `string_to_bytes_ascii` — ASCII string to byte array + +### Arrays (`lib/arrays.fun`) +- `array_slice`, `array_reverse`, `array_concat` — slicing and combining +- `array_index_of`, `array_contains` — searching +- `array_unique` — deduplication +- `array_flatten1` — flatten one level of nesting + +### Math (`lib/math.fun`) +- `abs`, `clamp`, `gcd`, `lcm`, `powi` (integer exponentiation) +- `min3`, `max3`, `array_min`, `array_max` + +### Hex (`lib/hex.fun`) +- `hex_to_dec`, `dec_to_hex`, `hex_to_bytes`, `bytes_to_hex` + +### Encoding (`lib/encoding/base64.fun`) +- `b64_encode_bytes`, `b64_decode_to_bytes` — Base64 encoding/decoding + +### Cryptography (Pure Fun implementations in `lib/crypt/`) +- **MD5** — `MD5` class (`lib/crypt/md5.fun`) +- **SHA-1** — `SHA1` class (`lib/crypt/sha1.fun`) +- **SHA-256** — `SHA256` class (`lib/crypt/sha256.fun`) +- **SHA-384** — `SHA384` class (`lib/crypt/sha384.fun`) +- **SHA-512** — `SHA512` class (`lib/crypt/sha512.fun`) +- **CRC-32** — `CRC32` class (IEEE 802.3) +- **CRC-32C** — `CRC32C` class (Castagnoli) +- **AES-256** — `AES256` class (ECB mode) + +### Functional Utilities +- **Option type** (`lib/utils/option.fun`): `some()`, `none()`, `is_some`, `is_none`, `unwrap`, `unwrap_or`, `option_map`, `and_then`, `or_else`, `try_get` +- **Result type** (`lib/utils/result.fun`): `ok()`, `err()`, `is_ok`, `is_err`, `unwrap`, `unwrap_or`, `result_map`, `map_err`, `and_then`, `or_else`, `to_option` +- **Pattern matching** (`lib/utils/match.fun`): `match(value, cases)` with `is`, `when`, `else` patterns + +### Range Utilities (`lib/utils/range.fun`) +- `range(n)` — `[0, n)` +- `range2(start, end)` — `[start, end)` +- `range3(start, end, step)` — stepped range + +### Date/Time (`lib/utils/datetime.fun`) +- `DateTime` class with `now_ms`, `mono_ms`, `format`, `iso_now`, `iso_from`, `date_str`, `time_str`, `today_str`, `start_timer`, `elapsed_ms`, `sleep_ms`, `sleep_s` + +### CLI (`lib/cli.fun`) +- `argv()` — retrieve command-line arguments +- `parse_args(args)` — parse flags and positional arguments + +### Console (`lib/io/console.fun`) +- `Console` class with `prompt`, `ask`, `ask_hidden`, `ask_yes_no`, `term_cols`, `progress` (progress bar) + +### Process (`lib/io/process.fun`) +- `Process` class wrapping `proc_run` and `system` + +### Thread (`lib/io/thread.fun`) +- `Thread` class wrapping `thread_spawn` / `thread_join` + +### Socket Classes (`lib/io/socket.fun`) +- `TcpClient` — TCP client with connect/send/recv/close/recv_all +- `TcpServer` — TCP server with listen/accept/close +- `UnixClient` — Unix domain socket client + +### Serial (`lib/io/serial.fun`) +- `Serial` class wrapping serial port operations + +### Async Scheduler (`lib/async/scheduler.fun`) +- Cooperative multitasking with `task_spawn`, `co_yield`, `run_once`, `run_until_done` +- I/O readiness polling: `await_read`, `await_write` + +### Networking / Web +- **CGI** (`lib/net/cgi.fun`): full CGI request parsing, response generation, URL encoding/decoding +- **HTTP Server** (`lib/net/http_server.fun`): static file serving with `.fun` script execution +- **HTTP CGI Server** (`lib/net/http_cgi_server.fun`): CGI-based HTTP server +- **IRC Client** (`lib/net/irc.fun`): IRC protocol client with message parsing + +--- + +## Optional Extensions (Build-time) + +Enabled via CMake flags; each wraps a mature C library: + +| Extension | CMake Flag | Library | Features | +|-----------|-----------|---------|----------| +| **JSON** | `FUN_WITH_JSON` | json-c | `json_parse()`, `json_stringify()`, `json_from_file()`, `json_to_file()` | +| **cURL** | `FUN_WITH_CURL` | libcurl | `curl_get()`, `curl_post()`, `curl_download()` | +| **SQLite** | `FUN_WITH_SQLITE` | libsqlite3 | `sqlite_open()`, `sqlite_close()`, `sqlite_exec()`, `sqlite_query()` | +| **PCRE2** | `FUN_WITH_PCRE2` | libpcre2 | `pcre2_test()`, `pcre2_match()`, `pcre2_find_all()` — with flags (i, m, s, u, x) | +| **OpenSSL** | `FUN_WITH_OPENSSL` | libcrypto | `openssl_md5()`, `openssl_sha256()`, `openssl_sha512()`, `openssl_ripemd160()` | +| **INI** | `FUN_WITH_INI` | iniparser 4.2.6 | `ini_load()`, `ini_get_string/int/double/bool()`, `ini_set()`, `ini_unset()`, `ini_save()` | +| **XML** | `FUN_WITH_XML2` | libxml2 | `xml_parse()`, `xml_root()`, `xml_name()`, `xml_text()` | +| **PC/SC** | `FUN_WITH_PCSC` | libpcsclite | `pcsc_establish()`, `pcsc_list_readers()`, `pcsc_connect()`, `pcsc_transmit()`, etc. | +| **KCGI** | `FUN_WITH_KCGI` | libkcgi | `kcgi_parse()`, `kcgi_reply_start()`, `kcgi_write()`, `kcgi_end()` | + +Each extension also has a corresponding **stdlib wrapper class** in `lib/io/` or `lib/net/`: +- `JSON` class (`lib/io/json.fun`) +- `INI` class (`lib/io/ini.fun`) +- `XML` class (`lib/io/xml.fun`) +- `PCSC` / `PCSC2` classes (`lib/io/pcsc.fun`) +- `PCRE2` class (`lib/regex/pcre2.fun`) +- `KCGI` class (`lib/net/kcgi.fun`) + +--- + +## FFI / Interop (Experimental) + +### Rust FFI (`FUN_WITH_RUST`) +- Cargo-based Rust static library linked into the VM +- Demo opcodes: `rust_hello()`, `rust_hello_args()`, `rust_hello_args_return()`, `rust_get_sp()`, `rust_set_exit()` +- Rust has unsafe access to VM internals via raw pointer and struct offset APIs + +### C++ FFI (`FUN_WITH_CPP`) +- C++ static library linked into the VM +- Demo opcode: `cpp_add(a, b)` + +--- ## Tooling -- Fun interpreter/runtime executable (target: fun) -- REPL and small tools (targets: repl, funstx, examples under examples/) -- Test binaries (target: fun_test, test_opcodes) -- Formatting helper target (target: format) using clang‑format -- Make‑like aggregate build target (target: build) +- **`fun`** — Interpreter/REPL. Runs `.fun` scripts or starts interactive REPL +- **`funstx`** — Syntax checker with optional `--fix` mode +- **REPL** — Interactive shell with history (1000 lines), multi-line input, tab completion, and commands: `:help`, `:env`, `:load`, `:run`, `:edit`, `:save`, `:clear`, `:exit`, `:quit`, `:debug`, `:import`, `:export`, `:type`, `:trace`, `:reload` +- **Test harnesses** — `fun_test` (bytecode-level tests) and `test_opcodes` (opcode exercisers) +- **CTest integration** — crypto example scripts run as automated tests +- **clang-format** target for consistent C source formatting -## Build System & Options +--- -Fun uses CMake and exposes toggles that mirror the project’s optionality at build time: +## Build System -- FUN_DEBUG — enable extra diagnostics in builds -- FUN_USE_MUSL — build against musl when available -- FUN_WITH_CPP — enable C++ interop/components where applicable -- FUN_WITH_RUST — build and link an optional Rust static library with opcode examples -- FUN_BUILD_DOCS — generate documentation (Doxygen/website pipelines) -- FUN_WITH_* — per‑extension toggles (see Extensions section) +- **CMake** 3.10+ with C99 standard +- Build toggles: `FUN_DEBUG`, `FUN_USE_MUSL`, `FUN_WITH_REPL`, `FUN_WITH_CPP`, `FUN_WITH_RUST`, `FUN_BUILD_DOCS` +- Per-extension toggles for all optional libraries +- Release builds with LTO, function/data sectioning, and `--gc-sections` +- Doxygen documentation generation +- Install targets for binaries, libraries, examples, man pages +- Uninstall target with safe directory cleanup -Targets available for CI/workflows include Experimental/Continuous/Nightly aggregates, plus unit tests and coverage helpers (see CMake targets). +--- ## Portability -- Written in portable C99 -- Designed to build on common Linux environments; musl support available +- Written in **C99** with POSIX extensions +- Primary target: **Linux** (glibc and musl) +- Partial **Windows** support +- Platform abstraction for threading, sockets, serial I/O +- Builds with GCC and Clang -## Extensions (Optional, Build‑time) - -Fun ships with optional integrations that can be enabled per environment. Highlights include: - -- cURL (HTTP client) -- INI (iniparser) -- JSON (json‑c) -- libxml2 (XML) -- SQLite -- PCRE2 (Perl‑compatible regex) -- PC/SC (Smart cards) -- OpenSSL (crypto/TLS) -- kcgi (CGI/web helper) - -See the full catalog with enable/requirement notes: /documentation/extensions/ - -## Web/CGI - -- Optional kcgi integration for building CGI‑style programs and simple web endpoints (see Extensions) -- Website sources under web/ with Jekyll layouts; generated site in web/_site/ +--- ## Testing -- Unit and VM‑level opcode tests (targets: fun_test, test_opcodes) -- Example scripts under examples/ exercised by CI and manual runs +- Unit tests for VM opcodes and bytecode execution +- CTest integration runs example scripts as automated tests +- Example scripts in `examples/` (90+ files) cover all language features +- Crypto self-tests for MD5, SHA-1/256/384/512, CRC-32/CRC-32C, AES-256 +- Include-line mapping regression test +- KCGI smoke test (when enabled) + +--- ## Documentation -- Doxygen configuration for API references (Doxyfile) -- Human‑readable docs under web/documentation/ (opcodes, extensions, etc.) +- Jekyll-based website under `web/` with full documentation +- Doxygen API reference +- Language specification documents (`spec/`) +- Over 90 annotated example scripts +- Handbook, type system guide, REPL guide, testing guide +- Opcode reference with stack effect documentation +- Changelog and semantic versioning + +--- ## Licensing -- Licensed under an OSI‑approved license; see LICENSE at the repository root +- **Apache 2.0** — fully open source, freely usable and modifiable