Handbook update. No code changes. (0.37.57)
This commit is contained in:
parent
d5f4a51d12
commit
de50e11148
1 changed files with 269 additions and 14 deletions
283
docs/handbook.md
283
docs/handbook.md
|
|
@ -100,6 +100,8 @@ Pass all options as -DNAME=VALUE. The most relevant toggles are:
|
||||||
- FUN_WITH_REPL=ON|OFF — enable the interactive REPL (default OFF)
|
- FUN_WITH_REPL=ON|OFF — enable the interactive REPL (default OFF)
|
||||||
- FUN_WITH_SQLITE=ON|OFF — enable SQLite (sqlite3) support (default OFF)
|
- FUN_WITH_SQLITE=ON|OFF — enable SQLite (sqlite3) support (default OFF)
|
||||||
- FUN_WITH_TCLTK=ON|OFF — enable Tk (GUI via Tcl/Tk) support (default OFF)
|
- FUN_WITH_TCLTK=ON|OFF — enable Tk (GUI via Tcl/Tk) support (default OFF)
|
||||||
|
- FUN_WITH_INI=ON|OFF — enable INI (iniparser) support (default OFF)
|
||||||
|
- FUN_WITH_NOTCURSES=ON|OFF — enable Notcurses TUI support (default OFF)
|
||||||
|
|
||||||
You can also set the default search path for the bundled stdlib with DEFAULT_LIB_DIR:
|
You can also set the default search path for the bundled stdlib with DEFAULT_LIB_DIR:
|
||||||
|
|
||||||
|
|
@ -321,20 +323,29 @@ Error handling and debugging:
|
||||||
|
|
||||||
Types:
|
Types:
|
||||||
- number: signed integer (with helpers for unsigned behavior)
|
- number: signed integer (with helpers for unsigned behavior)
|
||||||
|
- float: 64-bit IEEE-754 floating point
|
||||||
- string: immutable bytes; len(s), join, split, substr, find
|
- string: immutable bytes; len(s), join, split, substr, find
|
||||||
- array: ordered list; len, push, apop, insert, remove, slice
|
- array: ordered list; len, push, apop, insert, remove, slice
|
||||||
- map: associative dictionary typically keyed by strings
|
- map: associative dictionary typically keyed by strings
|
||||||
- boolean: represented as 1 (true) or 0 (false); operators &&, ||, !
|
- boolean: represented as 1 (true) or 0 (false); operators &&, ||, !
|
||||||
- nil: absence of value
|
- nil: absence of value
|
||||||
|
|
||||||
|
Numeric variants:
|
||||||
|
- byte (uint8)
|
||||||
|
- Fixed width ints: int8/16/32/64 and uint8/16/32/64
|
||||||
|
|
||||||
Control flow:
|
Control flow:
|
||||||
- if/else, while; range helpers in utils.range
|
- if/else, while; break, continue; range helpers in utils.range
|
||||||
|
|
||||||
Functions and classes:
|
Functions and classes:
|
||||||
- Define a function: fun name(args) ...
|
- Define a function: fun name(args) ...
|
||||||
- Define a class: class Name(constructor params) with method definitions fun method(this, ...)
|
- Define a class: class Name(constructor params) with method definitions fun method(this, ...)
|
||||||
- _construct acts as the constructor if present; methods use explicit this
|
- _construct acts as the constructor if present; methods use explicit this
|
||||||
|
|
||||||
|
Exceptions:
|
||||||
|
- try { ... } catch (e) { ... } finally { ... }
|
||||||
|
- Throwing/catching is defined by the spec; some runtimes may implement handling progressively. Examples: try_catch_finally.fun
|
||||||
|
|
||||||
Modules and includes:
|
Modules and includes:
|
||||||
- #include <path/to/module.fun> for libs under FUN_LIB_DIR
|
- #include <path/to/module.fun> for libs under FUN_LIB_DIR
|
||||||
- #include "relative/path.fun" for local includes
|
- #include "relative/path.fun" for local includes
|
||||||
|
|
@ -357,6 +368,10 @@ Conversion and type:
|
||||||
Math and random:
|
Math and random:
|
||||||
- min(a,b), max(a,b), clamp(x, lo, hi), abs(x), pow(a,b), random_seed(seed), random_int(lo, hiExclusive)
|
- min(a,b), max(a,b), clamp(x, lo, hi), abs(x), pow(a,b), random_seed(seed), random_int(lo, hiExclusive)
|
||||||
|
|
||||||
|
Bitwise (uint32 operations):
|
||||||
|
- band(a,b), bor(a,b), bxor(a,b), bnot(a)
|
||||||
|
- shl(a, s), shr(a, s)
|
||||||
|
|
||||||
Regex (requires PCRE2 when enabled):
|
Regex (requires PCRE2 when enabled):
|
||||||
- regex_match(text, pattern) -> 1/0
|
- regex_match(text, pattern) -> 1/0
|
||||||
- regex_search(text, pattern) -> map { match, start, end, groups }
|
- regex_search(text, pattern) -> map { match, start, end, groups }
|
||||||
|
|
@ -491,20 +506,99 @@ Module lib/encoding/base64.fun: base64_encode(string), base64_decode(string)
|
||||||
|
|
||||||
### JSON (optional)
|
### JSON (optional)
|
||||||
|
|
||||||
Build flag: -DFUN_WITH_JSON=ON; requires json-c. VM functions: json_parse, json_stringify, json_from_file, json_to_file. Stdlib class JSON wraps these with light ergonomics. Example: examples/json_showcase.fun.
|
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.
|
||||||
|
|
||||||
### CURL (optional)
|
### CURL (optional)
|
||||||
|
|
||||||
Build flag: -DFUN_WITH_CURL=ON; requires libcurl. VM provides:
|
Build flag: -DFUN_WITH_CURL=ON; requires libcurl.
|
||||||
- curl_get(url) -> string ("" on error)
|
|
||||||
- curl_post(url, body) -> string ("" on error)
|
VM API:
|
||||||
|
- curl_get(url) -> string (empty string on error)
|
||||||
|
- curl_post(url, body) -> string (empty string on error)
|
||||||
- curl_download(url, path) -> 1/0
|
- curl_download(url, path) -> 1/0
|
||||||
|
|
||||||
Examples: curl_get_json.fun, curl_post.fun, curl_download.fun
|
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
|
||||||
|
|
||||||
### PCSC (optional)
|
### PCSC (optional)
|
||||||
|
|
||||||
Build flag: -DFUN_WITH_PCSC=ON; provides pcsc_* built-ins and a stdlib wrapper class PCSC. Example: pcsc_example.fun.
|
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.
|
||||||
|
|
||||||
### SQLite (optional)
|
### SQLite (optional)
|
||||||
|
|
||||||
|
|
@ -530,13 +624,174 @@ Example flow (examples/sqlite_example.fun):
|
||||||
4) rows2 = sqlite_query(h, "SELECT count(*) AS cnt FROM tasks;")
|
4) rows2 = sqlite_query(h, "SELECT count(*) AS cnt FROM tasks;")
|
||||||
5) sqlite_close(h)
|
5) sqlite_close(h)
|
||||||
|
|
||||||
|
### 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)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Notcurses (optional)
|
||||||
|
|
||||||
|
Build flag: -DFUN_WITH_NOTCURSES=ON; requires notcurses (pkg-config: notcurses or notcurses-core).
|
||||||
|
|
||||||
|
VM API:
|
||||||
|
- nc_init() -> 1/0 (initialize TUI; call once)
|
||||||
|
- nc_draw_text(x, y, text) -> 0 on success, -1 on error
|
||||||
|
- nc_clear() -> 0 on success, -1 on error
|
||||||
|
- nc_getch(timeout_ms) -> key code (int), -1 if timeout/no input
|
||||||
|
- nc_shutdown() -> 1/0 (restore terminal)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
if (nc_init())
|
||||||
|
nc_draw_text(2, 1, "Fun + Notcurses")
|
||||||
|
print("Press any key...")
|
||||||
|
k = nc_getch(0) // 0 = blocking
|
||||||
|
nc_shutdown()
|
||||||
|
else
|
||||||
|
print("Notcurses init failed")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### libSQL (optional)
|
||||||
|
|
||||||
|
Build flag: -DFUN_WITH_LIBSQL=ON; requires libSQL client (compatible with sqlite3 C API).
|
||||||
|
|
||||||
|
VM API:
|
||||||
|
- libsql_open(path_or_url) -> handle (>0) or 0 on error
|
||||||
|
- libsql_close(handle) -> nil
|
||||||
|
- libsql_exec(handle, sql) -> rc (0 on success)
|
||||||
|
- libsql_query(handle, sql) -> array of row maps
|
||||||
|
|
||||||
|
Example flow:
|
||||||
|
1) h = libsql_open("./database.sqlite")
|
||||||
|
2) rows = libsql_query(h, "SELECT id, title FROM tasks;")
|
||||||
|
3) rc = libsql_exec(h, "INSERT INTO tasks (title) VALUES ('Try libSQL');")
|
||||||
|
4) libsql_close(h)
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### Tcl/Tk GUI (optional)
|
||||||
|
|
||||||
|
Build flag: -DFUN_WITH_TCLTK=ON; requires Tcl/Tk (8.6+).
|
||||||
|
|
||||||
|
VM API:
|
||||||
|
- tk_title(title) -> rc
|
||||||
|
- tk_label(id, text) -> rc
|
||||||
|
- tk_button(id, text) -> rc
|
||||||
|
- tk_pack(id) -> rc
|
||||||
|
- tk_loop() -> nil (enters event loop)
|
||||||
|
|
||||||
|
Stdlib wrapper:
|
||||||
|
- class TK (lib/ui/tk.fun) mirrors the VM API.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
include <ui/tk.fun>
|
||||||
|
|
||||||
|
tk = TK()
|
||||||
|
tk.title("Fun + Tk GUI")
|
||||||
|
tk.label("hello", "Hello, world!")
|
||||||
|
tk.pack("hello")
|
||||||
|
tk.button("ok", "OK")
|
||||||
|
tk.pack("ok")
|
||||||
|
tk.loop()
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Ensure Tcl/Tk runtime libraries are available on your system.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Examples reference
|
## Examples reference
|
||||||
|
|
||||||
You can run examples without installing by pointing FUN_LIB_DIR to the repository lib directory:
|
You can run examples without installing by pointing FUN_LIB_DIR to the repository lib directory:
|
||||||
|
|
||||||
FUN_LIB_DIR="$(pwd)/lib" ./build/fun examples/<name>.fun
|
FUN_LIB_DIR="$(pwd)/lib" ./build/fun examples/<path>.fun
|
||||||
|
|
||||||
Highlights (not exhaustive):
|
Highlights (not exhaustive):
|
||||||
- arrays.fun, arrays_advanced.fun, arrays_iter.fun — array operations
|
- arrays.fun, arrays_advanced.fun, arrays_iter.fun — array operations
|
||||||
|
|
@ -555,14 +810,14 @@ Highlights (not exhaustive):
|
||||||
- have_fun.fun — quick sanity check
|
- have_fun.fun — quick sanity check
|
||||||
- if_else_test.fun — branching
|
- if_else_test.fun — branching
|
||||||
- include_lib.fun, include_local.fun, include_namespace.fun — includes and namespacing
|
- include_lib.fun, include_local.fun, include_namespace.fun — includes and namespacing
|
||||||
- input_example.fun — console input
|
- interactive/input_example.fun — console input
|
||||||
- json_showcase.fun — JSON usage
|
- extra/json_showcase.fun — JSON usage
|
||||||
- curl_get_json.fun, curl_post.fun, curl_download.fun — HTTP via CURL
|
- extra/curl_get_json.fun, extra/curl_post.fun, extra/curl_download.fun — HTTP via CURL
|
||||||
- loops_break_continue.fun, nested_loops.fun, while_test.fun — loops
|
- loops_break_continue.fun, nested_loops.fun, while_test.fun — loops
|
||||||
- md5_demo.fun, sha1_demo.fun, sha256_demo.fun, sha256_str_demo.fun, sha384_example.fun, sha512_demo.fun, sha512_str_demo.fun — hashing
|
- 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
|
||||||
- objects_basic.fun, objects_more.fun — map/object patterns
|
- objects_basic.fun, objects_more.fun — map/object patterns
|
||||||
- os_env.fun — environment variables
|
- os_env.fun — environment variables
|
||||||
- pcsc_example.fun — smart card demo
|
- extra/pcsc_example.fun — smart card demo
|
||||||
- process_example.fun — running external commands
|
- process_example.fun — running external commands
|
||||||
- regex_demo.fun, regex_procedural.fun — regex usage
|
- regex_demo.fun, regex_procedural.fun — regex usage
|
||||||
- stdlib_showcase.fun — tour through stdlib
|
- stdlib_showcase.fun — tour through stdlib
|
||||||
|
|
@ -574,7 +829,7 @@ Highlights (not exhaustive):
|
||||||
- type_safety.fun, type_safety_fails.fun — type safety
|
- type_safety.fun, type_safety_fails.fun — type safety
|
||||||
- types_integers.fun, signed_ints.fun, uint_types.fun — integers
|
- types_integers.fun, signed_ints.fun, uint_types.fun — integers
|
||||||
- unix_socket_echo.fun — UNIX domain sockets
|
- unix_socket_echo.fun — UNIX domain sockets
|
||||||
- sqlite_example.fun — SQLite usage
|
- extra/sqlite_example.fun — SQLite usage
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Some examples rely on optional features (JSON, CURL, PCSC, SQLite) and degrade gracefully when disabled.
|
- Some examples rely on optional features (JSON, CURL, PCSC, SQLite) and degrade gracefully when disabled.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue