2026-04-10 23:27:55 +02:00
---
layout: page
published: true
noToc: true
noComments: false
noDate: false
title: Fun - Fun Handbook (Second Edition)
subtitle: Comprehensive handbook for the Fun language and VM, install/build, configuration flags, usage, and full feature overview.
description: Comprehensive handbook for the Fun language and VM, install/build, configuration flags, usage, and full feature overview.
permalink: /documentation/handbook/
lang: en
tags:
- documentation
- handbook
- installation
- usage
- introduction
- help
- guide
- howto
- docs
- specifications
- specs
- repl
---
2025-11-26 22:21:31 +01:00
# Fun Handbook (Second Edition)
This is a refreshed, de-duplicated, and fully up-to-date handbook for the Fun programming language and its virtual machine (VM). It keeps the same section layout as the original handbook while consolidating repeated content and documenting all currently available features, including the latest SQLite support.
2025-10-12 23:21:43 +02:00
## Overview
2025-11-26 22:21:31 +01:00
Fun is a small, strict, and simple programming language executed by a stack-based virtual machine. Most of the ecosystem is written in Fun itself; only a minimal core is implemented in C. The design focuses on simplicity, consistency, and joy in coding.
2025-10-12 23:21:43 +02:00
## Introduction
2025-11-26 22:21:31 +01:00
- Dynamic and optionally statically typed
- Type safety
- Written in C (C99) and Fun
- Minimal C core; most core functions and libraries implemented in Fun
- Internal libraries use snake_case for functions even when written in Fun; class names are CamelCase
2025-10-12 23:21:43 +02:00
## Installation
### Requirements
2025-11-26 22:21:31 +01:00
- A C compiler, a libc, and Git
2025-10-12 23:21:43 +02:00
2025-11-28 17:53:10 +01:00
#### FreeBSD:
2025-11-26 22:21:31 +01:00
- CMake
- Clang
2025-10-12 23:21:43 +02:00
2025-11-28 17:53:10 +01:00
#### Linux:
2025-11-26 22:21:31 +01:00
- CMake
- GCC (Clang should also work)
2025-10-12 23:21:43 +02:00
2025-11-28 17:53:10 +01:00
#### Windows:
2025-11-26 22:21:31 +01:00
- Cygwin (not covered in detail here)
- CMake
- GCC via Cygwin
2025-10-12 23:21:43 +02:00
### Build Fun
2025-11-26 22:21:31 +01:00
Linux/UNIX and Cygwin are covered here.
2025-10-12 23:21:43 +02:00
Clone repository:
```
2025-11-26 22:21:31 +01:00
git clone https://git.xw3.org/fun/fun.git
2025-10-12 23:21:43 +02:00
cd fun
```
2025-11-26 22:21:31 +01:00
Configure and build (examples shown with several optional features enabled):
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
# Every -D flag must be NAME=VALUE (e.g., -DFUN_WITH_REPL=ON)
cmake -S . -B build \
-DFUN_DEBUG=OFF \
-DFUN_WITH_REPL=ON \
-DFUN_WITH_JSON=ON \
-DFUN_WITH_PCRE2=ON \
-DFUN_WITH_CURL=ON \
-DFUN_WITH_PCSC=OFF \
-DFUN_WITH_SQLITE=OFF
2025-10-12 23:21:43 +02:00
cmake --build build --target fun
```
2025-11-26 22:21:31 +01:00
Run the demo (without installing):
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
2025-10-12 23:21:43 +02:00
FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./demo.fun
```
2025-11-26 22:21:31 +01:00
Tracing execution:
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
2025-10-12 23:21:43 +02:00
FUN_LIB_DIR="$(pwd)/lib" ./build/fun --trace ./demo.fun
```
2025-11-26 22:21:31 +01:00
Drop into the REPL when an error occurs:
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
2025-10-12 23:21:43 +02:00
FUN_LIB_DIR="$(pwd)/lib" ./build/fun --repl-on-error --trace ./demo.fun
```
2025-11-26 22:21:31 +01:00
Start the REPL directly (build with -DFUN_WITH_REPL=ON):
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
2025-10-12 23:21:43 +02:00
FUN_LIB_DIR="$(pwd)/lib" ./build/fun
```
2025-11-25 00:51:48 +01:00
#### CMake options
2025-11-26 22:21:31 +01:00
Pass all options as -DNAME=VALUE. The most relevant toggles are:
2025-11-25 00:51:48 +01:00
2025-11-26 22:21:31 +01:00
- FUN_DEBUG=ON|OFF — verbose VM debug logging (default OFF)
2025-11-28 17:47:27 +01:00
- FUN_WITH_CURL=ON|OFF — enable CURL (libcurl) support (default OFF)
- FUN_WITH_JSON=ON|OFF — enable JSON (json-c) support (default OFF)
2025-12-09 03:59:49 +01:00
- FUN_WITH_XML2=ON|OFF — enable XML (libxml2) support (default OFF)
2025-11-26 22:21:31 +01:00
- FUN_WITH_PCRE2=ON|OFF — enable PCRE2 (Perl-Compatible Regular Expressions) (default OFF)
2025-11-28 17:47:27 +01:00
- FUN_WITH_PCSC=ON|OFF — enable PC/SC smart card (PCSC lite) support (default OFF)
2025-11-26 22:21:31 +01:00
- FUN_WITH_REPL=ON|OFF — enable the interactive REPL (default OFF)
- FUN_WITH_SQLITE=ON|OFF — enable SQLite (sqlite3) support (default OFF)
2026-01-19 20:45:09 +01:00
- FUN_WITH_INI=ON|OFF — enable INI (iniparser) support (default OFF)
2025-11-25 00:51:48 +01:00
2025-11-26 22:21:31 +01:00
You can also set the default search path for the bundled stdlib with DEFAULT_LIB_DIR:
```
cmake -S . -B build -DDEFAULT_LIB_DIR="/usr/share/fun/lib" -DFUN_WITH_REPL=ON
```
If you encounter a CMake error such as:
2025-11-25 00:51:48 +01:00
CMake Error: Parse error in command line argument: FUN_WITH_JSON
Should be: VAR:type=value
2025-11-26 22:21:31 +01:00
it means you passed a -D option without a value. Always use the form -DNAME=VALUE (e.g., -DFUN_WITH_JSON=ON).
2025-11-25 00:51:48 +01:00
2025-11-26 22:21:31 +01:00
#### SQLite example (optional feature)
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
SQLite support is optional and disabled by default. To build with it and run the example:
2025-10-12 23:21:43 +02:00
2025-11-26 22:21:31 +01:00
```
cmake -S . -B build -DFUN_WITH_SQLITE=ON
cmake --build build --target fun
# Create the sample database (requires the sqlite3 CLI):
2025-11-27 00:42:47 +01:00
sqlite3 ./database.sqlite < ./examples/data/database.sql
2025-11-26 22:21:31 +01:00
# Run the example
FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./examples/sqlite_example.fun
```
2025-12-09 03:59:49 +01:00
#### XML example (optional feature)
XML support (via libxml2) is optional and disabled by default. To build with it and run the example:
```
cmake -S . -B build -DFUN_WITH_XML2=ON
cmake --build build --target fun
# Run the example using the stdlib XML class wrapper
FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./examples/xml_class_example.fun
```
Available VM builtins when built with -DFUN_WITH_XML2=ON:
- xml_parse(text: string) -> doc_handle (int > 0) or 0 on error
- xml_root(doc_handle: int) -> node_handle (int > 0) or 0 if missing
- xml_name(node_handle: int) -> string (node tag name)
- xml_text(node_handle: int) -> string (concatenated text of subtree)
Standard library wrapper (lib/io/xml.fun):
- class XML
- parse(text: string): int (doc handle)
- from_file(path: string): int (doc handle)
- root(doc: int): int (node handle)
- name(node: int): string
- text(node: int): string
Example Fun code:
```
include <io/xml.fun>
xml = XML()
doc = xml.from_file("./examples/data/example.xml")
if (doc == 0)
print("Failed to load XML file")
else
root = xml.root(doc)
print(xml.name(root))
print(xml.text(root))
```
Notes:
- Handles are simple integers managed by the VM; nodes are owned by their document.
- This initial integration focuses on parsing and basic navigation. Attributes, children iteration, and XPath may be added later.
2025-11-26 22:21:31 +01:00
### Install Fun to the OS (optional)
Not recommended during early development, but supported:
```
2025-10-12 23:21:43 +02:00
sudo cmake --build build --target install
```
2025-11-26 22:21:31 +01:00
After installation, FUN_LIB_DIR usually isn’ t needed because libs are placed in the system default directory (e.g., /usr/share/fun/lib).
2025-10-12 23:21:43 +02:00
## Usage
2025-11-26 22:21:31 +01:00
Run a script:
```
2025-10-12 23:21:43 +02:00
fun ./demo.fun
```
2025-11-25 02:17:06 +01:00
## Table of contents
- Language overview and VM internals
- Command line interface and REPL
- Core types and operations
- Built-ins overview (what the VM provides)
- Standard library APIs
- io.console
- io.process
- io.socket
- io.thread
- utils.datetime
- regex
- crypt (MD5, SHA-1/256/384/512)
- encoding.base64
- arrays, strings, maps helpers (hex, range)
- Extra libraries
- JSON (via json-c)
2025-11-26 00:52:59 +01:00
- CURL (via libcurl)
2025-11-25 02:17:06 +01:00
- PCSC (PC/SC smart card)
2025-11-26 22:21:31 +01:00
- SQLite (sqlite3)
- Examples reference
2025-11-25 02:17:06 +01:00
---
## Language overview and VM internals
2025-11-26 22:21:31 +01:00
Fun compiles .fun source files to bytecode and executes them on a stack-based VM. Functions and methods push/pop their arguments and return values on a value stack.
2025-11-25 02:17:06 +01:00
High-level architecture:
2025-11-26 22:21:31 +01:00
- Front-end: parses .fun files, handles includes and constant folding, emits bytecode with debug markers (OP_LINE) used by tracing and REPL-on-error.
- VM core: runs a loop over opcodes (see src/bytecode.h). Values include numbers (integers), strings, arrays, maps, booleans (1/0), functions, and nil.
- Built-ins: I/O, strings, arrays, regex, date/time, OS, networking, threading, and optional JSON/PCRE2/CURL/PCSC/SQLite.
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Selected VM concepts (non-exhaustive):
- Control flow: OP_JUMP, OP_JUMP_IF_FALSE, OP_RETURN
- Arithmetic/logic: OP_ADD/SUB/MUL/DIV, OP_MOD, OP_LT/LTE/GT/GTE, OP_EQ/NEQ, OP_AND/OR/NOT
- Stack helpers: OP_DUP, OP_SWAP, OP_POP
- Arrays: OP_MAKE_ARRAY, OP_INDEX_GET/SET, OP_LEN, OP_PUSH, OP_APOP, OP_INSERT/REMOVE, OP_SLICE
- Strings: OP_SUBSTR, OP_SPLIT, OP_JOIN, OP_FIND
- Maps: OP_MAKE_MAP; index ops shared with arrays
- Conversion/typing: OP_TO_NUMBER, OP_TO_STRING, OP_CAST, OP_TYPEOF, OP_UCLAMP/OP_SCLAMP
- Regex: OP_REGEX_MATCH/SEARCH/REPLACE (requires PCRE2 when built)
- Math: OP_MIN/MAX/CLAMP/ABS/POW, OP_RANDOM_SEED/RANDOM_INT
- Iteration helpers: OP_ENUMERATE, OP_ZIP
- OS/IO/network: sockets, files, processes, environment, threads, etc.
- Optional features: JSON (src/vm/json/*), CURL, PCSC, SQLite (src/vm/sqlite/*)
2025-11-25 02:17:06 +01:00
Error handling and debugging:
2025-11-26 22:21:31 +01:00
- Build with FUN_DEBUG=ON for verbose traces
- Run with --trace to print executed lines/opcodes
- Run with --repl-on-error to drop into an interactive REPL when a runtime error occurs
2025-11-25 02:17:06 +01:00
## Command line interface and REPL
2025-11-26 22:21:31 +01:00
- Run a script: fun path/to/script.fun
- Common options: --trace, --repl-on-error (can be combined). REPL requires FUN_WITH_REPL=ON at build time.
- In trace/REPL-on-error modes, the VM annotates output with file:line and function names for easier debugging (see examples/debug_reporting.fun).
2025-11-25 02:17:06 +01:00
## Core types and operations
Types:
2025-11-26 22:21:31 +01:00
- number: signed integer (with helpers for unsigned behavior)
2026-01-19 20:45:09 +01:00
- float: 64-bit IEEE-754 floating point
2025-11-26 22:21:31 +01:00
- string: immutable bytes; len(s), join, split, substr, find
- array: ordered list; len, push, apop, insert, remove, slice
- map: associative dictionary typically keyed by strings
- boolean: represented as 1 (true) or 0 (false); operators &&, ||, !
- nil: absence of value
2025-11-25 02:17:06 +01:00
2026-01-19 20:45:09 +01:00
Numeric variants:
- byte (uint8)
- Fixed width ints: int8/16/32/64 and uint8/16/32/64
2025-11-25 02:17:06 +01:00
Control flow:
2026-01-19 20:45:09 +01:00
- if/else, while; break, continue; range helpers in utils.range
2025-11-25 02:17:06 +01:00
Functions and classes:
2025-11-26 22:21:31 +01:00
- Define a function: fun name(args) ...
- Define a class: class Name(constructor params) with method definitions fun method(this, ...)
- _construct acts as the constructor if present; methods use explicit this
2025-11-25 02:17:06 +01:00
2026-01-19 20:45:09 +01:00
Exceptions:
- try { ... } catch (e) { ... } finally { ... }
- Throwing/catching is defined by the spec; some runtimes may implement handling progressively. Examples: try_catch_finally.fun
2025-11-25 02:17:06 +01:00
Modules and includes:
2025-11-26 22:21:31 +01:00
- #include <path/to/module.fun> for libs under FUN_LIB_DIR
- #include "relative/path.fun" for local includes
- Namespacing via as: #include <utils/math.fun> as m; then call m.add(...)
2025-11-25 02:17:06 +01:00
## Built-ins overview
Console and I/O:
2025-11-26 22:21:31 +01:00
- print(x) — prints value plus newline
- input(prompt) — read line from stdin
2025-11-25 02:17:06 +01:00
Strings and arrays:
2025-11-26 22:21:31 +01:00
- len(x), join(array, sep), split(text, sep), substr(text, start, len), find(text, needle)
- push(array, v), apop(array), insert(array, i, v), remove(array, i), slice(array, start, end)
2025-11-25 02:17:06 +01:00
Conversion and type:
2025-11-26 22:21:31 +01:00
- to_number(x), to_string(x), cast(value, typeName), typeof(x)
- uclamp(number, bits), sclamp(number, bits)
2025-11-25 02:17:06 +01:00
Math and random:
2025-11-26 22:21:31 +01:00
- min(a,b), max(a,b), clamp(x, lo, hi), abs(x), pow(a,b), random_seed(seed), random_int(lo, hiExclusive)
2025-11-25 02:17:06 +01:00
2026-01-19 20:45:09 +01:00
Bitwise (uint32 operations):
- band(a,b), bor(a,b), bxor(a,b), bnot(a)
- shl(a, s), shr(a, s)
2025-11-26 22:21:31 +01:00
Regex (requires PCRE2 when enabled):
- regex_match(text, pattern) -> 1/0
- regex_search(text, pattern) -> map { match, start, end, groups }
- regex_replace(text, pattern, repl) -> string
2025-11-25 02:17:06 +01:00
OS and processes:
2025-11-26 22:21:31 +01:00
- proc_run(cmd) -> { out: string, code: number }
- system(cmd) -> exit code
- env_get(name), env_set(name, value)
2025-11-25 02:17:06 +01:00
Networking and sockets:
- tcp_connect(host, port) -> fd (>0) or 0
2025-11-26 22:21:31 +01:00
- sock_send(fd, data) -> bytes or -1; sock_recv(fd, maxlen) -> string; sock_close(fd)
- tcp_listen(port, backlog) -> listen fd; tcp_accept(listenFd) -> client fd
- unix_connect(path) -> fd
2025-11-25 02:17:06 +01:00
Threads:
- thread_spawn(func, args) -> thread id; thread_join(id) -> return value
Date and time:
2025-11-26 22:21:31 +01:00
- time_now_ms(), clock_mono_ms(), date_format(ms, fmt)
2025-11-25 02:17:06 +01:00
JSON (optional):
2025-11-26 22:21:31 +01:00
- json_parse(text) -> value or nil
- json_stringify(value, prettyFlag) -> string
- json_from_file(path) -> value or nil
- json_to_file(path, value, prettyFlag) -> 1/0
2025-11-25 02:17:06 +01:00
PC/SC (optional):
- pcsc_establish() -> context id (>0) or 0
2025-11-26 22:21:31 +01:00
- pcsc_list_readers(ctx) -> array of reader names or nil
2025-11-25 02:17:06 +01:00
- pcsc_connect(ctx, readerName) -> handle id (>0) or 0
- pcsc_disconnect(handle) -> 1/0
2025-11-26 22:21:31 +01:00
- pcsc_transmit(handle, bytesArray) -> { data, sw1, sw2, code }
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
SQLite (optional):
- sqlite_open(path) -> handle (>0) or 0 on error
- sqlite_exec(handle, sql) -> rc (0 = SQLITE_OK)
- sqlite_query(handle, sql) -> array of row maps (string keys)
- sqlite_close(handle) -> nil
Note: Optional features depend on the CMake flags used when building.
2025-11-25 02:17:06 +01:00
---
## Standard library APIs
2025-11-26 22:21:31 +01:00
The stdlib provides small wrappers around VM built-ins, typically organized in classes to avoid global name collisions and to offer sensible defaults.
2025-11-25 02:17:06 +01:00
### io.console
Class Console (lib/io/console.fun):
2025-11-26 22:21:31 +01:00
- prompt(text) -> string
- ask(question) -> string
- ask_yes_no(question) -> 1/0 (y/yes vs n/no)
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Example: examples/input_example.fun
2025-11-25 02:17:06 +01:00
### io.process
Class Process (lib/io/process.fun):
2025-11-26 22:21:31 +01:00
- run(cmd) -> { out, code }
- run_merge_stderr(cmd) -> { out, code }
- system(cmd) -> number
- check_call(cmd) -> 1/0
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Example: examples/process_example.fun
2025-11-25 02:17:06 +01:00
### io.socket
Provides TcpClient, TcpServer, UnixClient (lib/io/socket.fun).
2025-11-26 22:21:31 +01:00
TcpClient:
- connect(host, port) -> 1/0; is_connected() -> 1/0
- send(data) -> bytes or -1; recv(maxlen) -> string; recv_all(chunk_size) -> string
2025-11-25 02:17:06 +01:00
- close()
2025-11-26 22:21:31 +01:00
TcpServer(port, backlog):
- listen() -> listen fd or 0; accept() -> client fd
- echo_once(maxlen) -> 1 when handled; serve_forever(maxlen) -> never returns
- close()
UnixClient:
2025-11-25 02:17:06 +01:00
- connect(path), is_connected(), send(data), recv(maxlen), close()
2025-11-26 22:21:31 +01:00
Examples: tcp_http_get.fun, tcp_http_get_class.fun, unix_socket_echo.fun, extra/tcp_echo_server_class.fun
2025-11-25 02:17:06 +01:00
### io.thread
Class Thread (lib/io/thread.fun):
- spawn(func, args) -> thread id; join(id) -> return value
- Aliases: start(func, args), wait(id)
2025-11-26 22:21:31 +01:00
Examples: threads_demo.fun, thread_class_example.fun
2025-11-25 02:17:06 +01:00
### utils.datetime
Class DateTime (lib/utils/datetime.fun):
2025-11-26 22:21:31 +01:00
- now_ms(), mono_ms(), format(ms, fmt), iso_now()
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Example: datetime_basic.fun
2025-11-25 02:17:06 +01:00
### regex
Class Regex (lib/regex.fun):
2025-11-26 22:21:31 +01:00
- match(text, pattern) -> 1/0
- search(text, pattern) -> { match, start, end, groups }
- replace(text, pattern, repl) -> string
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Examples: regex_demo.fun, regex_procedural.fun
2025-11-25 02:17:06 +01:00
### crypt
2025-11-26 22:21:31 +01:00
MD5 (lib/crypt/md5.fun) and SHA family (sha1/sha256/sha384/sha512) provide digest classes and helpers.
Examples: md5_demo.fun, sha1_demo.fun, sha256_demo.fun, sha256_str_demo.fun, sha384_example.fun, sha512_demo.fun, sha512_str_demo.fun
2025-11-25 02:17:06 +01:00
### encoding.base64
2025-11-26 22:21:31 +01:00
Module lib/encoding/base64.fun: base64_encode(string), base64_decode(string)
2025-11-25 02:17:06 +01:00
### arrays, strings, maps helpers
2025-11-26 22:21:31 +01:00
- lib/arrays.fun — array helpers
- lib/strings.fun — string helpers (lower/upper, etc.)
- lib/hex.fun — bytes_to_hex, hex_to_bytes
- lib/utils/range.fun — numeric ranges
- lib/utils/math.fun and lib/math.fun — math helpers
2025-11-25 02:17:06 +01:00
---
## Extra libraries
### JSON (optional)
2026-01-19 20:45:09 +01:00
Build flag: -DFUN_WITH_JSON=ON; requires json-c.
VM API:
- json_parse(text) -> value or nil
- json_stringify(value, prettyFlag) -> string
- json_from_file(path) -> value or nil
- json_to_file(path, value, prettyFlag) -> 1/0
Stdlib wrapper:
- class JSON (lib/io/json.fun) — convenience methods mirroring the VM API.
Example:
```
include <io/json.fun>
j = JSON()
data = j.parse('{"name":"Fun","year":2026,"ok":true,"tags":["vm","lang"]}')
print(typeof(data)) // map
print(data["name"])
ok = j.to_file("./tmp/out.json", data, 1) // pretty = 1
print("saved:", ok)
```
Notes:
- JSON types map to Fun types: object -> map, array -> array, string -> string, number -> number/float, true/false -> 1/0, null -> nil.
- When writing, prettyFlag=1 enables pretty printing.
2025-11-25 02:17:06 +01:00
2026-04-03 19:51:08 +02:00
### cURL (optional)
2025-11-26 00:52:59 +01:00
2026-01-19 20:45:09 +01:00
Build flag: -DFUN_WITH_CURL=ON; requires libcurl.
VM API:
- curl_get(url) -> string (empty string on error)
- curl_post(url, body) -> string (empty string on error)
2025-11-26 22:21:31 +01:00
- curl_download(url, path) -> 1/0
2025-11-26 00:52:59 +01:00
2026-01-19 20:45:09 +01:00
Stdlib wrapper:
- None (call built-ins directly). See examples in examples/extra/.
Example:
```
url = "https://httpbin.org/get"
resp = curl_get(url)
if (len(resp) == 0)
print("GET failed")
else
print(substr(resp, 0, 60), "...")
```
Examples:
- curl_get_json.fun, curl_post.fun, curl_download.fun
2025-11-26 00:52:59 +01:00
2025-11-25 02:17:06 +01:00
### PCSC (optional)
2026-01-19 20:45:09 +01:00
Build flag: -DFUN_WITH_PCSC=ON; requires PC/SC (pcsc-lite).
VM API:
- pcsc_establish() -> context id (>0) or 0
- pcsc_list_readers(ctx) -> array of reader names or nil
- pcsc_connect(ctx, readerName) -> handle id (>0) or 0
- pcsc_disconnect(handle) -> 1/0
- pcsc_transmit(handle, bytesArray) -> { data: array<byte>, sw1: number, sw2: number, code: number }
Stdlib wrapper:
- class PCSC (lib/io/pcsc.fun) — higher-level helpers for listing readers, connecting, and APDU I/O.
Example:
```
include <io/pcsc.fun>
sc = PCSC()
ctx = pcsc_establish()
if (ctx == 0)
print("PCSC not available")
else
readers = pcsc_list_readers(ctx)
if (readers == nil || len(readers) == 0)
print("No readers found")
else
h = pcsc_connect(ctx, readers[0])
if (h)
// Example APDU: GET RESPONSE (illustrative only)
res = pcsc_transmit(h, [0x00, 0xC0, 0x00, 0x00, 0x00])
print("SW:", res["sw1"], res["sw2"], "code:", res["code"])
pcsc_disconnect(h)
```
Examples:
- examples/extra/pcsc_example.fun, examples/extra/pcsc_demo.fun
Notes:
- Smart card operations depend on the reader, card, and drivers installed. Ensure pcscd/service is running.
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
### SQLite (optional)
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Build flag: -DFUN_WITH_SQLITE=ON; requires sqlite3 development headers.
VM API:
- sqlite_open(path) -> handle (>0) or 0
- sqlite_exec(handle, sql) -> rc (0 = SQLITE_OK)
- sqlite_query(handle, sql) -> array of maps (columns as string keys)
- sqlite_close(handle) -> nil
Result mapping notes:
- INTEGER -> number
- FLOAT -> number (floating point)
- TEXT -> string
- NULL -> nil
- BLOB is currently not returned (mapped to nil)
Example flow (examples/sqlite_example.fun):
1) h = sqlite_open("./todo.sqlite")
2) rows = sqlite_query(h, "SELECT id, title, done, created_at FROM tasks ORDER BY id;")
3) rc = sqlite_exec(h, "INSERT INTO tasks (title, done) VALUES ('Try Fun + SQLite', 0);")
4) rows2 = sqlite_query(h, "SELECT count(*) AS cnt FROM tasks;")
5) sqlite_close(h)
2025-11-25 02:17:06 +01:00
2026-01-19 20:45:09 +01:00
### INI (optional)
Build flag: -DFUN_WITH_INI=ON; requires iniparser (>= 4.2.6).
VM API:
- ini_load(path) -> handle (>0) or 0 on error
- ini_free(handle) -> 1/0
- ini_get_string(handle, section, key, default) -> string
- ini_get_int(handle, section, key, defaultNumber) -> number
- ini_get_double(handle, section, key, defaultFloat) -> float
- ini_get_bool(handle, section, key, defaultBool) -> 1/0
- ini_set(handle, section, key, valueString) -> 1/0
- ini_unset(handle, section, key) -> 1/0
- ini_save(handle, path) -> 1/0
Notes:
- Section/key may be looked up flexibly ("section:key" and "section.key").
- Always free handles with ini_free when done.
Example:
```
h = ini_load("./examples/data/example.ini")
if (h == 0)
print("Failed to load INI")
else
host = ini_get_string(h, "server", "host", "localhost")
port = ini_get_int(h, "server", "port", 8080)
print("server:", host, port)
ok = ini_set(h, "server", "host", "127.0.0.1")
if (ok)
ini_save(h, "./tmp/updated.ini")
ini_free(h)
```
### XML (optional)
Build flag: -DFUN_WITH_XML2=ON; requires libxml2.
VM API:
- xml_parse(text) -> doc_handle (>0) or 0 on error
- xml_root(doc_handle) -> node_handle (>0) or 0 if missing
- xml_name(node_handle) -> string
- xml_text(node_handle) -> string
Stdlib wrapper:
- class XML (lib/io/xml.fun)
- parse(text): int
- from_file(path): int
- root(doc): int
- name(node): string
- text(node): string
Example:
```
include <io/xml.fun>
xml = XML()
doc = xml.from_file("./examples/data/example.xml")
if (doc == 0)
print("Failed to load XML file")
else
root = xml.root(doc)
print(xml.name(root))
print(xml.text(root))
```
Notes:
- Handles are integers managed by the VM; nodes belong to their document.
### PCRE2 / Regex (optional)
Build flag: -DFUN_WITH_PCRE2=ON; requires PCRE2 (8-bit API).
VM API:
- regex_match(text, pattern) -> 1/0
- regex_search(text, pattern) -> map { match, start, end, groups }
- regex_replace(text, pattern, repl) -> string
Stdlib wrapper:
- class Regex (lib/regex.fun) providing match/search/replace helpers.
Examples: regex_demo.fun, regex_procedural.fun
Notes:
- Patterns use PCRE2 syntax.
### REPL (optional)
Build flag: -DFUN_WITH_REPL=ON.
Description:
- Enables the interactive Read– Eval– Print Loop and the --repl-on-error mode. No additional VM API functions; this feature is part of the executable.
2025-11-25 02:17:06 +01:00
---
## Examples reference
You can run examples without installing by pointing FUN_LIB_DIR to the repository lib directory:
2026-01-19 20:45:09 +01:00
FUN_LIB_DIR="$(pwd)/lib" ./build/fun examples/<path>.fun
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
Highlights (not exhaustive):
- arrays.fun, arrays_advanced.fun, arrays_iter.fun — array operations
- booleans.fun, boolean_decl.fun — boolean basics
- builtins_conversions.fun, builtins_extended.fun — conversions and math helpers
- builtins_maps_and_more.fun — maps and indexing
- byte_for_demo.fun — bitwise operations
- class_constructor.fun, classes_demo.fun, inheritance_demo.fun — classes
- datetime_basic.fun — date/time utilities
- debug_reporting.fun, repl_on_error.fun — tracing and REPL-on-error
- exit_example.fun — exit codes
- expressions_test.fun — operators
- file_io.fun, file_print_for_file_line_by_line.fun — file I/O
- for_range_test.fun — numeric ranges
- functions_test.fun — functions and higher-order usage
- have_fun.fun — quick sanity check
- if_else_test.fun — branching
- include_lib.fun, include_local.fun, include_namespace.fun — includes and namespacing
2026-01-19 20:45:09 +01:00
- interactive/input_example.fun — console input
- extra/json_showcase.fun — JSON usage
- extra/curl_get_json.fun, extra/curl_post.fun, extra/curl_download.fun — HTTP via CURL
2025-11-26 22:21:31 +01:00
- loops_break_continue.fun, nested_loops.fun, while_test.fun — loops
2026-01-19 20:45:09 +01:00
- crypto/md5_demo.fun, crypto/sha1_demo.fun, crypto/sha256_demo.fun, crypto/sha256_str_demo.fun, crypto/sha384_example.fun, crypto/sha512_demo.fun, crypto/sha512_str_demo.fun — hashing
2025-11-26 22:21:31 +01:00
- objects_basic.fun, objects_more.fun — map/object patterns
- os_env.fun — environment variables
2026-01-19 20:45:09 +01:00
- extra/pcsc_example.fun — smart card demo
2025-11-26 22:21:31 +01:00
- process_example.fun — running external commands
- regex_demo.fun, regex_procedural.fun — regex usage
- stdlib_showcase.fun — tour through stdlib
- strings_test.fun — string operations
- tcp_http_get.fun, tcp_http_get_class.fun — TCP client demos
- thread_class_example.fun, threads_demo.fun — threading
- try_catch_finally.fun, try_catch_with_error.fun — error handling
- typeof.fun, typeof_features.fun — types and casting
- type_safety.fun, type_safety_fails.fun — type safety
- types_integers.fun, signed_ints.fun, uint_types.fun — integers
- unix_socket_echo.fun — UNIX domain sockets
2026-01-19 20:45:09 +01:00
- extra/sqlite_example.fun — SQLite usage
2025-11-25 02:17:06 +01:00
Notes:
2025-11-26 22:21:31 +01:00
- Some examples rely on optional features (JSON, CURL, PCSC, SQLite) and degrade gracefully when disabled.
2025-11-25 02:17:06 +01:00
---
2025-11-26 22:21:31 +01:00
## Internals notes (selected)
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
JSON: src/vm/json/* wraps json-c. OP_JSON_PARSE and friends convert json_object to Fun values and back; stdlib JSON class adds ergonomics.
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
PCSC: The VM interfaces with pcsc-lite/WinSCard and returns maps with data and status words. The stdlib wrapper handles absent hardware defensively.
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
SQLite: src/vm/sqlite/* implements open/exec/query/close using a simple handle registry. Query prepares a statement, steps rows, maps columns by name to values, and returns an array of row maps.
2025-11-25 02:17:06 +01:00
---
2025-11-26 00:57:45 +01:00
## Development
2025-11-26 22:21:31 +01:00
This project follows Semantic Versioning. Commit messages include the version (e.g., 1.2.3). Version bumps are made in CMakeLists.txt for code changes; documentation-only commits include the current version in the message but do not bump it.
2025-11-26 00:57:45 +01:00
### Development systems
2025-11-26 22:21:31 +01:00
- GNU/Linux (glibc, musl), FreeBSD (Clang), Windows (Cygwin + GCC). Other Unix-like systems likely work but are untested.
2025-11-26 00:57:45 +01:00
2025-11-26 22:21:31 +01:00
### Contributing and further reading
2025-11-25 02:17:06 +01:00
2025-11-26 22:21:31 +01:00
- Browse lib/ for stdlib APIs (files often document their own interfaces)
- src/bytecode.h lists supported opcodes; implementations live under src/vm/
- examples/ are the best starting point to learn by doing