From 02f0c07bce79b29fa11f3a8dc3be3bbdf9cd0e19 Mon Sep 17 00:00:00 2001 From: hanez Date: Sat, 11 Apr 2026 02:38:47 +0200 Subject: [PATCH] Documentation fixes. No code changes. (0.40.5) --- web/_layouts/post.html | 2 +- web/_posts/2025-10-08-init.md | 2 + .../2026-01-25-announcing-fun-0.37.62.md | 38 +++---- web/_posts/2026-04-10-website-relocation.md | 5 +- web/css/main.scss | 2 +- web/documentation/arrays.md | 59 ++++------ web/documentation/asyncio.md | 42 +++---- web/documentation/build.md | 30 ++--- web/documentation/cli.md | 17 +-- web/documentation/documentation.md | 4 +- web/documentation/examples.md | 30 ++--- web/documentation/faq.md | 21 ++-- web/documentation/fun.md | 30 ++--- web/documentation/funstx.md | 6 +- web/documentation/handbook.md | 103 ++++++------------ web/documentation/includes.md | 20 ++-- web/documentation/internals.md | 18 +-- web/documentation/maps.md | 60 ++++------ web/documentation/numbers.md | 72 ++++-------- web/documentation/repl.md | 42 +++---- web/documentation/rust.md | 18 +-- web/documentation/stdlib.md | 6 +- web/documentation/strings.md | 42 +++---- web/documentation/testing.md | 24 ++-- web/documentation/troubleshooting.md | 24 ++-- web/documentation/types.md | 36 ++---- web/documentation/website.md | 10 +- web/index.md | 4 +- 28 files changed, 271 insertions(+), 496 deletions(-) diff --git a/web/_layouts/post.html b/web/_layouts/post.html index cf5e77c..673d229 100644 --- a/web/_layouts/post.html +++ b/web/_layouts/post.html @@ -8,7 +8,7 @@ layout: default

{% if page.date %}{{ page.date | date: "%b %-d, %Y %H:%M:%S" }}{% endif %} {% if page.date and page.date_updated %} - {% endif %} {% if page.date_updated %}Edited: {{ page.date_updated | date: "%b %-d, %Y %H:%M:%S" }}{% endif %} - {% if page.date or page.date_updated %} ({{ page.date | date: "%Z" }}){% endif %}{% if page.author %}, {{ page.author }}{% endif %}

+ {% if page.date or page.date_updated %} ({{ page.date | date: "%Z" }}){% endif %}{% if page.author %}, {{ page.author }}{% endif %}

{{ content }} diff --git a/web/_posts/2025-10-08-init.md b/web/_posts/2025-10-08-init.md index 4c853a1..f7b03e1 100644 --- a/web/_posts/2025-10-08-init.md +++ b/web/_posts/2025-10-08-init.md @@ -2,6 +2,8 @@ layout: post published: true author: hanez +author_email: you@hanez.org +author_url: https://hanez.org title: Init Fun! description: Blog - Init Fun! date: 2025-10-05 diff --git a/web/_posts/2026-01-25-announcing-fun-0.37.62.md b/web/_posts/2026-01-25-announcing-fun-0.37.62.md index 51d92aa..16c4e2d 100644 --- a/web/_posts/2026-01-25-announcing-fun-0.37.62.md +++ b/web/_posts/2026-01-25-announcing-fun-0.37.62.md @@ -2,11 +2,13 @@ layout: post published: true author: hanez +author_email: you@hanez.org +author_url: https://hanez.org noToc: false title: Announcing Fun 0.37.62 description: Homepage and Blog date: 2026-01-25 -date_updated: 2026-01-31 21:45:03 +date_updated: 2026-04-11 00:56:03 categories: - news - project @@ -54,26 +56,22 @@ This release brings Fun closer to its vision with significant language enhanceme - Private members by convention (leading underscore) - Dot-call syntax sugar for clean method invocations: obj.method(a, b) -
-class Counter
+
class Counter
   value = 0
   fun inc(this)
     this.value = this.value + 1
     return this.value
 
 c = Counter()
-print(c.inc())  // 1
-
+print(c.inc()) // 1
### Module System - Namespaced includes with #include as alias for clean imports - Organize code into reusable modules without naming conflicts -
-#include  as m
-print(m.add(2, 3))  // 5
-
+
#include  as m
+print(m.add(2, 3))  // 5
### Enhanced Type System @@ -87,14 +85,12 @@ print(m.add(2, 3)) // 5 - Thread primitives: thread_spawn, thread_join, and sleep - Write concurrent programs with ease -
-fun square(n)
+
fun square(n)
   sleep(100)
   return n * n
 
 tid = thread_spawn(square, 5)
-print(thread_join(tid))  // 25
-
+print(thread_join(tid)) // 25
### Control Flow Improvements @@ -146,22 +142,21 @@ Important: Fun is not developed on third-party Git servers like GitHub or GitLab If you're curious about Fun, check out: -- [Website](https://fun-lang.xyz) - [Git Repository](https://git.xw3.org/fun/fun){:class="git"} -- [Fun Handbook](https://fun-lang.xyz/documentation/handbook/){:class="git"} -- [Fun REPL Guide](https://fun-lang.xyz/documentation/repl/){:class="git"} +- [Fun Handbook](/documentation/handbook/) +- [Fun REPL Guide](/documentation/repl/) - [Specification v0.3](https://git.xw3.org/fun/fun/src/branch/main/spec/v0.3.md){:class="git"} - [Examples](https://git.xw3.org/fun/fun/src/branch/main/examples){:class="git"} - [Standard Library](https://git.xw3.org/fun/fun/src/branch/main/lib){:class="git"} -- [Community](https://fun-lang.xyz/community/) +- [Community](/community/) The examples directory contains demonstrations of most Fun features, from basic "Hello, World!" to threading, networking, classes, and more. The lib directory includes modules written in Fun itself — and in the future, most enhancements will be written in Fun rather than C. ### For Developers -- [Fun Internals](https://fun-lang.xyz/documentation/internals/){:class="git"} -- [Fun Opcodes](https://fun-lang.xyz/documentation/opcodes/){:class="git"} -- [Basic Rust Opcodes Support](https://fun-lang.xyz/documentation/rust/){:class="git"} +- [Fun Internals](/documentation/internals/){:class="git"} +- [Fun Opcodes](/documentation/opcodes/){:class="git"} +- [Basic Rust Opcodes Support](/documentation/rust/){:class="git"} ### The Road Ahead @@ -173,5 +168,4 @@ Fun is and will always be 100% free under the terms of the [Apache-2.0 License]( Happy hacking, and remember: Fun is Fun! -Johannes Findeisen (hanez) - [hanez@fun-lang.org](mailto:hanez@fun-lang.org){:class="mail"} - +Johannes Findeisen (hanez) - [hanez@fun-lang.xyz](mailto:hanez@fun-lang.xyz){:class="mail"} diff --git a/web/_posts/2026-04-10-website-relocation.md b/web/_posts/2026-04-10-website-relocation.md index 3b91fa7..5f75692 100644 --- a/web/_posts/2026-04-10-website-relocation.md +++ b/web/_posts/2026-04-10-website-relocation.md @@ -2,6 +2,8 @@ layout: post published: true author: hanez +author_email: you@hanez.org +author_url: https://hanez.org noToc: false title: Moving the Website to the Project Root description: Relocating the fun-lang.xyz source code for easier maintenance. @@ -23,6 +25,7 @@ We've recently completed a significant change to our project structure: the sour The main reason for merging this code into the root of the Fun project is that it is much easier for me to maintain the whole project this way. Having everything in one place simplifies our development workflow: + - **Unified Versioning:** All project components, including the website and its documentation, now share the same version control history. - **Simplified Maintenance:** Updating documentation and the website together ensures that the online presence stays in sync with the language's development. - **Streamlined Workflow:** It's now possible to update the language, its libraries, the documentation, and the blog in a single commit if needed. @@ -31,7 +34,7 @@ Having everything in one place simplifies our development workflow: You can now find the website source in the `./web/` directory of the repository. It continues to use the [Jekyll](https://jekyllrb.com/){:class="ext"} static site generator. -For those interested in the technical details or looking to contribute to the website, we have added a new documentation file: [docs/website.md](https://git.xw3.org/fun/fun/src/branch/main/docs/website.md){:class="git"}. This document covers the technology stack, the directory structure, and the available `Makefile` targets for local development and deployment. +For those interested in the technical details or looking to contribute to the website, we have added a new documentation file: [/web/documentation/website/](../documentation/website/){:class="git"}. This document covers the technology stack, the directory structure, and the available `Makefile` targets for local development and deployment. ### What changes for you? diff --git a/web/css/main.scss b/web/css/main.scss index 01b4373..22441cd 100644 --- a/web/css/main.scss +++ b/web/css/main.scss @@ -15,7 +15,7 @@ $background-color: #565656; $headline-color: #bc6c21; //#b40000; $hover-color: #bc6c21; $topbutton-color: $headline-color; -$brand-color: #1fa2af; +$brand-color: #3d0e51; $brand-color-light: lighten($brand-color, 40%); $grey-color: #828282; $grey-color-light: #e8e8e8; diff --git a/web/documentation/arrays.md b/web/documentation/arrays.md index c21d3e4..c1b54f7 100644 --- a/web/documentation/arrays.md +++ b/web/documentation/arrays.md @@ -31,8 +31,7 @@ This guide focuses on arrays: creation, indexing, mutation, iteration, slicing, ## Creating arrays -``` -// literals +
// literals
 a = [1, 2, 3]
 b = ["alpha", "beta"]
 empty = []
@@ -42,30 +41,27 @@ grid = [[1,2], [3,4]]
 
 print(typeof(a))   // "array"
 print(len(a))      // 3
-```
+
Tip: Prefer square‑bracket literals for clarity and performance versus building via repeated push in a hot loop. ## Indexing (0‑based) and assignment -``` -a = [10, 20, 30] +
a = [10, 20, 30]
 print(a[0])   // 10
 print(a[2])   // 30
 
 // update in place
 a[1] = 42
 print(a)      // [10, 42, 30]
-```
-
+
Notes: - Valid indices are 0..len(a)-1. Using an invalid index raises a runtime error. - Assignment updates the existing array; references pointing to it observe the change. ## Appending, popping, inserting, removing -``` -a = [1] +
a = [1]
 
 // append to end; returns new length
 push(a, 7)          // => 2, a is now [1, 7]
@@ -79,12 +75,10 @@ insert(a, 1, 99)    // a => [1, 99, 2, 3]
 
 // remove at index (shifts left)
 remove(a, 2)        // a => [1, 99, 3]
-```
-
+
## Slicing and concatenation -``` -a = [0,1,2,3,4] +
a = [0,1,2,3,4]
 
 // slice(startInclusive, endExclusive)
 head = slice(a, 0, 3)   // [0,1,2]
@@ -93,14 +87,12 @@ mid  = slice(a, 1, 4)   // [1,2,3]
 // concat: join two arrays
 b = ["x", "y"]
 ab = concat(a, b)       // [0,1,2,3,4,"x","y"]
-```
-
+
Slicing returns a new array. The original is unchanged. ## Iteration patterns -``` -a = ["a", "b", "c"] +
a = ["a", "b", "c"]
 
 // index‑based loop
 for i = 0; i < len(a); i = i + 1 {
@@ -114,14 +106,12 @@ for pair in it.enumerate(a) {
   val = pair[1]
   print(to_string(idx) + ":" + val)
 }
-```
-
+
## Copying vs. referencing Arrays are reference types. Assigning just copies the reference, not the contents: -``` -orig = [1, 2] +
orig = [1, 2]
 alias = orig        // points to the same array
 alias[0] = 9
 print(orig)         // [9, 2]
@@ -131,17 +121,14 @@ copy = slice(orig, 0, len(orig))
 copy[1] = 7
 print(orig)         // [9, 2]
 print(copy)         // [9, 7]
-```
-
+
Shallow copies duplicate the top‑level array but not nested structures. ## Equality -``` -print([1,2] == [1,2]) // true +
print([1,2] == [1,2])   // true
 print([1,2] == [2,1])   // false
-```
-
+
Array equality compares length and element‑wise equality recursively. ## Common utilities @@ -160,19 +147,16 @@ Check your lib directory (e.g., lib/utils) for additional helpers. ## Error handling and bounds -``` -a = [0] +
a = [0]
 // a[1] is out of range → runtime error
-```
-
+
Tips: - Guard indices: if i < 0 or i >= len(a) { /* handle */ } - Use remove/insert carefully inside loops; indices of following items change. ## Interop with maps and strings -``` -// arrays of maps +
// arrays of maps
 users = [ {"name":"Ada"}, {"name":"Lin"} ]
 print(users[1]["name"])    // Lin
 
@@ -180,8 +164,7 @@ print(users[1]["name"])    // Lin
 #include  as su  // adjust if present in your tree
 parts = su.split("a,b,c", ",")    // ["a","b","c"]
 csv   = su.join(parts, ",")       // "a,b,c"
-```
-
+
## Performance tips - Preallocate by building from literals or chunked appends rather than one‑by‑one in very tight loops. @@ -190,8 +173,7 @@ csv = su.join(parts, ",") // "a,b,c" ## Examples -``` -// filter even numbers +
// filter even numbers
 src = [0,1,2,3,4,5]
 dst = []
 for i = 0; i < len(src); i = i + 1 {
@@ -210,8 +192,7 @@ for i = 0; i < len(nested); i = i + 1 {
   }
 }
 print(flat) // [1,2,3,4,5]
-```
-
+
## See also - types.md — broader overview of core types with quick array examples. diff --git a/web/documentation/asyncio.md b/web/documentation/asyncio.md index d1d5c9b..6dcfc06 100644 --- a/web/documentation/asyncio.md +++ b/web/documentation/asyncio.md @@ -57,18 +57,15 @@ Tip: Always check return values. In non-blocking mode, partial writes and short ## Typical patterns 1) Connect and switch to non-blocking -``` -fd = tcp_connect(host, port) +
fd = tcp_connect(host, port)
 if (fd == 0)
   // handle connect error
 ok = fd_set_nonblock(fd, 1)
 if (ok == 0)
   // handle mode switch error
-```
-
+
2) Non-blocking write loop with readiness polling -``` -remaining = req +
remaining = req
 while (len(remaining) > 0)
   wr = fd_poll_write(fd, 1000)  // wait up to 1s
   if (wr < 0)
@@ -79,11 +76,9 @@ while (len(remaining) > 0)
   if (n < 0)
     // send error; abort
   remaining = substr(remaining, n, len(remaining) - n)
-```
-
+
3) Non-blocking read-until-close -``` -buf = "" +
buf = ""
 while (true)
   rd = fd_poll_read(fd, 2000)  // wait up to 2s
   if (rd < 0)
@@ -99,8 +94,7 @@ while (true)
   if (len(data) == 0)
     break  // closed
   buf = buf + data
-```
-
+
## Timeouts and responsiveness - timeout_ms controls how long poll waits. Use small timeouts inside loops to interleave work across multiple sockets or tasks. @@ -125,20 +119,14 @@ Because Fun keeps the primitives low-level and explicit, you can build simple co - lib/net/http_cgi_server.fun — Library helpers used by the server examples Run client example from a build tree: -``` -FUN_LIB_DIR=./lib ./build/fun examples/io/async_http_client.fun -``` - +
FUN_LIB_DIR=./lib ./build/fun examples/io/async_http_client.fun
+
If installed system-wide, just: -``` -fun /usr/share/fun/examples/io/async_http_client.fun -``` - +
fun /usr/share/fun/examples/io/async_http_client.fun
+
Or to try the await-style client using the cooperative scheduler: -``` -FUN_LIB_DIR=./lib ./build/fun examples/io/await_http_client.fun -``` - +
FUN_LIB_DIR=./lib ./build/fun examples/io/await_http_client.fun
+
## Cooperative scheduler helpers (library-level) The file lib/async/scheduler.fun provides a minimal cooperative scheduler built on the existing primitives. There is no VM-level suspension: each task is a small state machine advanced one step per tick. API summary: @@ -159,8 +147,7 @@ The file lib/async/scheduler.fun provides a minimal cooperative scheduler built - Mark the task to be skipped for roughly ms milliseconds; cleared automatically when it wakes. Example skeleton using the scheduler: -``` -#include +
#include 
 
 fun my_task_step(t)
   if (t.phase == nil)
@@ -205,8 +192,7 @@ fun my_task_step(t)
 
 task = task_spawn(my_task_step, {})
 run_until_done()
-```
-
+
This approach is 100% compatible with current runtimes and serves as a stepping stone towards potential future VM-level async/await opcodes. ## Error handling and cleanup diff --git a/web/documentation/build.md b/web/documentation/build.md index 3abb6f3..5b7e0e3 100644 --- a/web/documentation/build.md +++ b/web/documentation/build.md @@ -61,45 +61,35 @@ These are defined as `CACHE` variables, so they will persist in your `CMakeCache When configuring, the build prints a summary like: -``` -==== Fun build options ==== +
==== Fun build options ====
   FUN_DEBUG: ENABLED|DISABLED
   FUN_USE_MUSL: ENABLED|DISABLED
   FUN_WITH_CPP: ENABLED|DISABLED
   FUN_WITH_RUST: ENABLED|DISABLED
 ===========================
-```
-
+
## Example commands Use the CLion-provided build directories or your own. Typical invocations: ### Debug -``` -cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \ +
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug \
   -DFUN_DEBUG=ON -DFUN_WITH_RUST=OFF
 cmake --build build --target build
-```
-
+
### Release -``` -cmake -S . -B build_release -DCMAKE_BUILD_TYPE=Release \ +
cmake -S . -B build_release -DCMAKE_BUILD_TYPE=Release \
   -DFUN_DEBUG=OFF -DFUN_WITH_RUST=OFF
 cmake --build build_release --target build
-```
-
+
### Enabling optional extensions -``` -cmake -S . -B build_release -DCMAKE_BUILD_TYPE=Release \ +
cmake -S . -B build_release -DCMAKE_BUILD_TYPE=Release \
   -DFUN_WITH_CPP=ON -DFUN_WITH_RUST=ON -DFUN_WITH_OPENSSL=ON
 cmake --build build_release --target build
-```
-
+
### Customizing VM limits -``` -cmake -S . -B build_custom -DSTACK_SIZE=4096 -DMAX_GLOBALS=512 +
cmake -S . -B build_custom -DSTACK_SIZE=4096 -DMAX_GLOBALS=512
 cmake --build build_custom --target fun
-```
-
+
If `FUN_WITH_RUST` is enabled, ensure `cargo` is available in PATH; the build will invoke it and link the produced static library. If `FUN_WITH_OPENSSL` is enabled, CMake must detect your system OpenSSL (libcrypto). diff --git a/web/documentation/cli.md b/web/documentation/cli.md index 4789326..8b8fcb8 100644 --- a/web/documentation/cli.md +++ b/web/documentation/cli.md @@ -29,10 +29,8 @@ Reference for the `fun` command-line interface. For a complete usage guide (including REPL details, environment variables, include paths, examples, and install locations), see [fun.md](./fun/). ## Synopsis -``` -fun [options] [-- args...] -``` - +
fun [options]  [-- args...]
+
If no script is supplied and interactive mode is available, `fun` starts a REPL (see [repl.md](./repl/)). ## Common options @@ -54,11 +52,8 @@ See also: [includes.md](./includes/) for namespaced includes and search order. ## Examples Run a script: -``` -FUN_LIB_DIR=./lib ./build/fun examples/hello.fun -``` - +
FUN_LIB_DIR=./lib ./build/fun examples/hello.fun
+
Start the REPL: -``` -./build/fun -i -``` +
./build/fun -i
+
\ No newline at end of file diff --git a/web/documentation/documentation.md b/web/documentation/documentation.md index 0711adc..9f54448 100644 --- a/web/documentation/documentation.md +++ b/web/documentation/documentation.md @@ -5,7 +5,7 @@ noToc: false noComments: false noDate: false title: Fun - Documentation -subtitle: Detailed documentation for the Fun programming language. +subtitle: Detailed documentation for the Fun programming language.

The documentation is always a work in progress! It will always be behind the development of the code. It will be 100% aligned with a 1.0 release... ;) description: The Fun Documentation Index permalink: /documentation/ lang: en @@ -68,7 +68,7 @@ The examples directory contains demonstrations of most Fun features, from basic ## Examples - - [examples/README/](./examples/README/) - Catalog of all example scripts under ./examples/: what each area contains, how to run them, required env vars, and extension requirements. + - [examples/](./examples/) - Catalog of all example scripts under [https://git.xw3.org/fun/fun/src/branch/main/examples](https://git.xw3.org/fun/fun/src/branch/main/examples){:class="git"}: what each area contains, how to run them, required env vars, and extension requirements. ## External extensions diff --git a/web/documentation/examples.md b/web/documentation/examples.md index c2e8d97..e689517 100644 --- a/web/documentation/examples.md +++ b/web/documentation/examples.md @@ -33,35 +33,27 @@ All commands assume you are in the repository root. Example (Linux/macOS/BSD): -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun examples/include_lib.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun examples/include_lib.fun
+
Windows (PowerShell): -``` -$env:FUN_LIB_DIR = "$PWD/lib" +
$env:FUN_LIB_DIR = "$PWD/lib"
 ./build/fun.exe .\examples\include_lib.fun
-```
-
+
## Interactive showcase: play.fun The script `./play.fun` discovers all `.fun` files under `./examples` and offers to run them one by one: -``` -./play.fun -``` - +
./play.fun
+
Notes: - The script auto-picks your interpreter (FUN_BIN env or `fun` in PATH) and ensures `FUN_LIB_DIR=./lib` so examples resolve includes correctly. - It shows the exit code for each run and summarizes failures at the end. Tip: you can run specific examples directly too: -``` -FUN_LIB_DIR="$(pwd)/lib" fun examples/crypto/openssl_md5.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" fun examples/crypto/openssl_md5.fun
+
## Example categories Browse the `examples/` tree for areas of interest: @@ -77,9 +69,7 @@ Browse the `examples/` tree for areas of interest: Place your `.fun` files anywhere under `examples/` to have them picked up by `play.fun`. Use quoted includes for project-local helpers and angle brackets for stdlib modules: -``` -#include "examples/my_lib/common.fun" +
#include "examples/my_lib/common.fun"
 #include 
-```
-
+
If you add an example showcasing a new feature, also consider adding a brief note to the relevant doc (types.md, includes.md, opcodes.md, etc.). diff --git a/web/documentation/faq.md b/web/documentation/faq.md index 0e7fbf3..7d42bf5 100644 --- a/web/documentation/faq.md +++ b/web/documentation/faq.md @@ -18,24 +18,27 @@ tags: - quick --- - Answers to common questions. ## I built Fun but includes aren't found + Set `FUN_LIB_DIR` to the repository's `./lib` directory when running without installation: -``` -FUN_LIB_DIR=./lib ./build/fun examples/hello.fun -``` -See [includes.md](./includes/). +
FUN_LIB_DIR=./lib ./build/fun examples/hello.fun
+
+See [includes/](../includes/). ## How do I start the REPL? -Run `fun -i` (or run `fun` without a script, depending on version). See [repl.md](./repl/). + +Run `fun -i` (or run `fun` without a script, depending on version). See [repl/](../repl/). ## Which build target should I use? -Use the aggregate `build` target to build `fun`, `fun_test`, and `test_opcodes`. See [build.md](./build/). + +Use the aggregate `build` target to build `fun`, `fun_test`, and `test_opcodes`. See [build/](../build/). ## Where are the standard libraries? -Under [`./lib/`](../lib/). See [stdlib.md](./stdlib/) for an overview. + +Under [https://git.xw3.org/fun/fun/src/branch/main/lib](https://git.xw3.org/fun/fun/src/branch/main/lib){:class="git"}. See [stdlib/](../stdlib/) for an overview. ## Where can I find internals and opcodes? -Browse [src/vm](../src/vm/) and [internals.md](./internals/) / [opcodes.md](./opcodes/). + +Browse [https://git.xw3.org/fun/fun/src/branch/main/src/vm](https://git.xw3.org/fun/fun/src/branch/main/src/vm/) and [internals/](../internals/) / [opcodes/](../opcodes/). diff --git a/web/documentation/fun.md b/web/documentation/fun.md index 677450f..45642db 100644 --- a/web/documentation/fun.md +++ b/web/documentation/fun.md @@ -27,10 +27,8 @@ tags: This document explains how to use the `fun` binary after building or installing it: invocation patterns, options, environment variables, include/search paths, REPL, and examples. ## Synopsis -``` -fun [options] [] [-- args...] -``` - +
fun [options] [] [-- args...]
+
- If `` is provided, `fun` runs the script. - If omitted and the build enables the REPL, `fun` starts an interactive session. @@ -66,20 +64,14 @@ Useful commands/patterns in REPL: ## Running scripts Basic run (installed system‑wide): -``` -fun /usr/share/fun/examples/hello.fun -``` - +
fun /usr/share/fun/examples/hello.fun
+
Running from a build tree (not installed): -``` -FUN_LIB_DIR=./lib /path/to/build_dir/fun examples/hello.fun -``` - +
FUN_LIB_DIR=./lib /path/to/build_dir/fun examples/hello.fun
+
Passing arguments to scripts (arguments after `--` are forwarded to the script environment): -``` -fun myscript.fun -- arg1 arg2 -``` - +
fun myscript.fun -- arg1 arg2
+
## Build and install locations - Build targets: `fun` is produced by the `fun` target. In CLion/CMake, typical build directories are `build_debug` or `build_release`. - Install locations (by default): @@ -88,11 +80,9 @@ fun myscript.fun -- arg1 arg2 - Examples (optional): `/usr/share/fun/examples` To stage an install without touching the system: -``` -DESTDIR=./tmp/stage cmake --build --target install +
DESTDIR=./tmp/stage cmake --build  --target install
 ./tmp/stage/usr/bin/fun ./examples/hello.fun
-```
-
+
## See also - `documentation/cli.md` — concise CLI reference (synopsis/options/exit codes) - `documentation/funstx.md` — syntax checker for `.fun` files with optional `--fix` diff --git a/web/documentation/funstx.md b/web/documentation/funstx.md index e126b92..4d29679 100644 --- a/web/documentation/funstx.md +++ b/web/documentation/funstx.md @@ -36,10 +36,8 @@ funstx is a small command‑line tool that parses .fun source files to verify sy ## Usage -``` -funstx [--fix] [file2.fun ...] -``` - +
funstx [--fix]  [file2.fun ...]
+
- Provide one or more .fun files to check. - Add `--fix` to attempt safe, automatic corrections before re‑checking. diff --git a/web/documentation/handbook.md b/web/documentation/handbook.md index 3e4a201..4e44c8b 100644 --- a/web/documentation/handbook.md +++ b/web/documentation/handbook.md @@ -64,16 +64,12 @@ Linux/UNIX and Cygwin are covered here. Clone repository: -``` -git clone https://git.xw3.org/fun/fun.git +
git clone https://git.xw3.org/fun/fun.git
 cd fun
-```
-
+
Configure and build (examples shown with several optional features enabled): -``` - -cmake -S . -B build \ +
cmake -S . -B build \
   -DFUN_DEBUG=OFF \
   -DFUN_WITH_REPL=ON \
   -DFUN_WITH_JSON=ON \
@@ -82,32 +78,23 @@ cmake -S . -B build \
   -DFUN_WITH_PCSC=OFF \
   -DFUN_WITH_SQLITE=OFF
 cmake --build build --target fun
-```
-
+
Run the demo (without installing): -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./demo.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./demo.fun
+
Tracing execution: -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun --trace ./demo.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun --trace ./demo.fun
+
Drop into the REPL when an error occurs: -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun --repl-on-error --trace ./demo.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun --repl-on-error --trace ./demo.fun
+
Start the REPL directly (build with -DFUN_WITH_REPL=ON): -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun
+
#### CMake options Pass all options as -DNAME=VALUE. The most relevant toggles are: @@ -124,10 +111,8 @@ Pass all options as -DNAME=VALUE. The most relevant toggles are: 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 -``` - +
cmake -S . -B build -DDEFAULT_LIB_DIR="/usr/share/fun/lib" -DFUN_WITH_REPL=ON
+
If you encounter a CMake error such as: CMake Error: Parse error in command line argument: FUN_WITH_JSON @@ -139,8 +124,7 @@ it means you passed a -D option without a value. Always use the form -DNAME=VALU SQLite support is optional and disabled by default. To build with it and run the example: -``` -cmake -S . -B build -DFUN_WITH_SQLITE=ON +
cmake -S . -B build -DFUN_WITH_SQLITE=ON
 cmake --build build --target fun
 
 
@@ -148,20 +132,17 @@ sqlite3 ./database.sqlite < ./examples/data/database.sql
 
 
 FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./examples/sqlite_example.fun
-```
-
+
#### 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 -S . -B build -DFUN_WITH_XML2=ON
 cmake --build build --target fun
 
 
 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 @@ -177,8 +158,7 @@ Standard library wrapper (lib/io/xml.fun): - text(node: int): string Example Fun code: -``` -include +
include 
 
 xml = XML()
 doc = xml.from_file("./examples/data/example.xml")
@@ -188,8 +168,7 @@ 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. @@ -198,20 +177,16 @@ Notes: Not recommended during early development, but supported: -``` -sudo cmake --build build --target install -``` - +
sudo cmake --build build --target install
+
After installation, FUN_LIB_DIR usually isn’t needed because libs are placed in the system default directory (e.g., /usr/share/fun/lib). ## Usage Run a script: -``` -fun ./demo.fun -``` - +
fun ./demo.fun
+
## Table of contents - Language overview and VM internals @@ -470,8 +445,7 @@ Stdlib wrapper: - class JSON (lib/io/json.fun) — convenience methods mirroring the VM API. Example: -``` -include +
include 
 
 j = JSON()
 data = j.parse('{"name":"Fun","year":2026,"ok":true,"tags":["vm","lang"]}')
@@ -480,8 +454,7 @@ 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. @@ -499,15 +472,13 @@ Stdlib wrapper: - None (call built-ins directly). See examples in examples/extra/. Example: -``` -url = "https://httpbin.org/get" +
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 @@ -526,8 +497,7 @@ Stdlib wrapper: - class PCSC (lib/io/pcsc.fun) — higher-level helpers for listing readers, connecting, and APDU I/O. Example: -``` -include +
include 
 
 sc = PCSC()
 ctx = pcsc_establish()
@@ -544,8 +514,7 @@ else
       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 @@ -596,8 +565,7 @@ Notes: - Always free handles with ini_free when done. Example: -``` -h = ini_load("./examples/data/example.ini") +
h = ini_load("./examples/data/example.ini")
 if (h == 0)
   print("Failed to load INI")
 else
@@ -608,8 +576,7 @@ else
   if (ok)
     ini_save(h, "./tmp/updated.ini")
   ini_free(h)
-```
-
+
### XML (optional) Build flag: -DFUN_WITH_XML2=ON; requires libxml2. @@ -629,8 +596,7 @@ Stdlib wrapper: - text(node): string Example: -``` -include +
include 
 
 xml = XML()
 doc = xml.from_file("./examples/data/example.xml")
@@ -640,8 +606,7 @@ 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. diff --git a/web/documentation/includes.md b/web/documentation/includes.md index 2f68cb3..acd2c06 100644 --- a/web/documentation/includes.md +++ b/web/documentation/includes.md @@ -4,7 +4,7 @@ published: true noToc: false noComments: false noDate: false -title: Fun - Includes in Fun: local vs. system and the FUN_LIB_DIR environment variable +title: Fun - Includes in Fun, local vs. system and the FUN_LIB_DIR environment variable subtitle: Using local vs. system includes, FUN_LIB_DIR, DEFAULT_LIB_DIR, and namespaced includes with `as`. description: Using local vs. system includes, FUN_LIB_DIR, DEFAULT_LIB_DIR, and namespaced includes with `as`. permalink: /documentation/includes/ @@ -39,8 +39,7 @@ This document explains how to use local and system includes in Fun source files Use double quotes to include files relative to the directory you execute `fun` from. Example: -``` -#include "examples/include_local_util.fun" +
#include "examples/include_local_util.fun"
 
 print("== include local demo ==")
 greet("Fun")
@@ -48,8 +47,7 @@ greet("Fun")
 number a = 2
 number b = 3
 print("sum(" + to_string(a) + ", " + to_string(b) + ") = " + to_string(sum(a, b)))
-```
-
+
- Resolution rule: quoted includes are read directly from the given path relative to `$PWD`. - Typical use: including helper modules that live within your project tree. @@ -58,8 +56,7 @@ print("sum(" + to_string(a) + ", " + to_string(b) + ") = " + to_string(sum(a, b) Use angle brackets to include modules from the Fun standard library or any library directory you point `FUN_LIB_DIR` to. Example: -``` -#include +
#include 
 #include 
 
 print("== include lib demo ==")
@@ -69,8 +66,7 @@ number x = 10
 number y = 32
 print("add(" + to_string(x) + ", " + to_string(y) + ") = " + to_string(add(x, y)))
 print("times(" + to_string(x) + ", " + to_string(y) + ") = " + to_string(times(x, y)))
-```
-
+
Resolution order for `#include <...>`: 1) `FUN_LIB_DIR` (environment variable), with automatic handling of trailing `/` or `\` @@ -84,8 +80,7 @@ If the file cannot be read from any location, an "Include error" is printed with You can import a module into a namespace to avoid symbol collisions or to make intent explicit. Examples: -``` -// Import stdlib helpers under alias 'm' +
// Import stdlib helpers under alias 'm'
 #include  as m
 print("m.add(2, 3) = " + to_string(m.add(2, 3)))
 print("m.times(4, 5) = " + to_string(m.times(4, 5)))
@@ -95,8 +90,7 @@ print("m.times(4, 5) = " + to_string(m.times(4, 5)))
 print(mod.hello("Fun"))
 g = mod.Greeter("Hi")
 g.say("World")
-```
-
+
Rules: - `as` must be followed by a valid identifier (letters, digits, underscore, starting with a letter or underscore). - Works for both local (`"..."`) and system (`<...>`) includes. diff --git a/web/documentation/internals.md b/web/documentation/internals.md index 53ac324..e96a5e7 100644 --- a/web/documentation/internals.md +++ b/web/documentation/internals.md @@ -351,8 +351,7 @@ This provides zero‑copy hand‑off without coupling VMs or their collectors. #### Minimal API (illustrative) -```c -// Zero-copy shared buffers (immutable inside VMs) +
// Zero-copy shared buffers (immutable inside VMs)
 fun_shared_buffer_t* fun_shared_buffer_new(size_t n);
 void* fun_shared_buffer_data(fun_shared_buffer_t*);
 void fun_shared_buffer_retain(fun_shared_buffer_t*);
@@ -362,8 +361,7 @@ void fun_shared_buffer_release(fun_shared_buffer_t*);
 fun_port_t* fun_port_create(fun_vm_t*);
 int fun_send(fun_port_t*, fun_value_t value);      // can carry a shared buffer handle
 int fun_recv(fun_port_t*, fun_value_t* out, uint64_t timeout_ms);
-```
-
+
#### Practical usage tips - Default to isolates + ports for logic; use `fun_shared_buffer` only for large payloads (images, tensors, blobs). @@ -393,8 +391,7 @@ We don’t expose shared mutability to VMs. The trick is: publish‑as‑immutab #### Typical pattern (no locks needed) -```c -fun_shared_buffer_t* b = fun_shared_buffer_new(n); +
fun_shared_buffer_t* b = fun_shared_buffer_new(n);
 void* p = fun_shared_buffer_data(b);
 memcpy(p, src, n);                  // fill while private
 
@@ -411,8 +408,7 @@ if (fun_recv(port, &v, 1000) == 0) {
   …
   fun_shared_buffer_release(r);
 }
-```
-
+
#### When would the host ever sync? - Only if you choose shared mutability outside the VM (e.g., a lock‑free ring buffer you manage). For that, we expose optional helpers (`fun_atomic_*`, `fun_mutex_t`, `fun_rwlock_t`), but they’re not required for the standard zero‑copy path. @@ -477,8 +473,7 @@ It depends on what “shared” means. Our design keeps per‑VM GCs independent ### Minimal API surface (illustrative) -```c -// Create/destroy VMs +
// Create/destroy VMs
 fun_vm_t* vm = fun_vm_create(const fun_vm_config_t*);
 void fun_vm_destroy(fun_vm_t*);
 
@@ -500,8 +495,7 @@ fun_shared_buffer_t* fun_shared_buffer_new(size_t n);
 void* fun_shared_buffer_data(fun_shared_buffer_t*);
 void fun_shared_buffer_retain(fun_shared_buffer_t*);
 void fun_shared_buffer_release(fun_shared_buffer_t*);
-```
-
+
### Glossary - GC: garbage collection. In our context, each `fun_vm_t` isolate has its own GC (stop‑the‑world, per‑VM). There is no global stop‑the‑world and no global lock; a GC pause in one VM does not affect others. diff --git a/web/documentation/maps.md b/web/documentation/maps.md index 1641154..6d9c16f 100644 --- a/web/documentation/maps.md +++ b/web/documentation/maps.md @@ -33,29 +33,24 @@ This guide focuses on maps: creation, reading/writing by key, checking key prese ## Creating maps -``` -// literals +
// literals
 user = { "name": "Ada", "age": 37 }
 empty = {}
 
 print(typeof(user))     // "map"
-```
-
+
Nested structures are natural and common: -``` -book = { +
book = {
   "title": "Fun Handbook",
   "meta": { "pages": 120, "isbn": "123-456" },
   "tags": ["lang", "vm"]
 }
 print(book["meta"]["pages"])   // 120
-```
-
+
## Getting and setting by key -``` -profile = { "name": "Lin" } +
profile = { "name": "Lin" }
 
 // read existing key
 print(profile["name"])       // Lin
@@ -67,35 +62,29 @@ print(profile["email"])      // nil
 profile["email"] = "lin@example.org"
 profile["name"]  = "Linus"
 print(profile)                 // {"name":"Linus","email":"lin@example.org"}
-```
-
+
Notes: - Using a non‑string key is allowed only if your build/runtime supports it; most code uses string keys for portability. - Missing keys produce nil. Compare against nil before converting or indexing: -``` -v = profile["phone"] +
v = profile["phone"]
 if v == nil { print("no phone on file") }
-```
-
+
## Checking key existence Use has(m, key) to check if a key is present (returns 1 or 0): -``` -cfg = { "debug": 1 } +
cfg = { "debug": 1 }
 print(has(cfg, "debug"))   // 1
 print(has(cfg, "port"))    // 0
 
 if has(cfg, "port") { print(cfg["port"]) } else { print("using default port") }
-```
-
+
## Iterating maps Maps are not inherently ordered. To iterate, first obtain an array of keys or values. -``` -user = { "name": "Ada", "age": 38 } +
user = { "name": "Ada", "age": 38 }
 
 // iterate known keys (explicit order you choose)
 order = ["name", "age"]
@@ -114,8 +103,7 @@ for i = 0; i < len(ks); i = i + 1 {
 // values only
 vs = values(user)         // -> ["Ada", 38]
 for i = 0; i < len(vs); i = i + 1 { print(to_string(vs[i])) }
-```
-
+
Tip: - If you need deterministic output, either define the order array explicitly or sort the result of keys(user) using your available utilities before looping. @@ -123,8 +111,7 @@ Tip: Maps are reference types. Assigning copies the reference, not the contents: -``` -orig = { "a": 1 } +
orig = { "a": 1 }
 alias = orig
 alias["a"] = 9
 print(orig["a"])   // 9
@@ -138,17 +125,14 @@ for i = 0; i < len(ks); i = i + 1 { k = ks[i]; dst[k] = src[k] }
 dst["x"] = 7
 print(src["x"])     // 1
 print(dst["x"])     // 7
-```
-
+
Shallow copies duplicate only the top‑level mapping; nested arrays/maps inside are still shared unless you clone them manually. ## Equality -``` -print({"a":1,"b":2} == {"b":2,"a":1}) // true +
print({"a":1,"b":2} == {"b":2,"a":1})  // true
 print({"a":1} == {"a":2})                // false
-```
-
+
Map equality compares sets of keys and their corresponding values for equality (order does not matter). ## Common utilities @@ -164,8 +148,7 @@ Check your lib or VM docs (e.g., src/vm/maps) and documentation/types.md for ava ## Interop with arrays and strings -``` -// maps inside arrays +
// maps inside arrays
 users = [ {"name":"Ada"}, {"name":"Lin"} ]
 for i = 0; i < len(users); i = i + 1 {
   print(users[i]["name"])   // Ada, Lin
@@ -180,8 +163,7 @@ print(m["nums"])           // [1,2,3,4]
 // JSON interop is typically via lib/io/json.fun (if enabled in your build)
 #include  as json    // adjust to your tree and build flags
 s = json.stringify({"ok":1})     // "{"ok":1}"
-```
-
+
## Error handling and edge cases - Accessing a missing key returns nil. Guard before arithmetic or nested indexing. @@ -196,8 +178,7 @@ s = json.stringify({"ok":1}) // "{"ok":1}" ## Examples -``` -// merge defaults into config (without overwriting explicit keys) +
// merge defaults into config (without overwriting explicit keys)
 defaults = { "host":"127.0.0.1", "port":8080, "debug":0 }
 cfg      = { "port": 9000 }
 
@@ -216,8 +197,7 @@ for i = 0; i < len(rows); i = i + 1 {
   by_id[r["id"]] = r
 }
 print(by_id["u2"]["name"])  // Lin
-```
-
+
## See also - types.md — broader overview of core types with quick map examples. diff --git a/web/documentation/numbers.md b/web/documentation/numbers.md index bc0e52f..ca69c85 100644 --- a/web/documentation/numbers.md +++ b/web/documentation/numbers.md @@ -38,96 +38,79 @@ This guide covers the numeric types in Fun, with a focus on the integer "number" - number: signed integer (implementation‑defined width; use uclamp/sclamp for fixed‑width interop) - float: IEEE‑754 double precision (64‑bit) -``` -an = 42 // number +
an = 42            // number
 af = 3.14159       // float
 print(typeof(an))  // "number"
 print(typeof(af))  // "float"
-```
-
+
## Literals - Integer (number): 0, 1, -7, 120 - Floating point (float): 0.0, 1.5, -2.75, 1e3, -4.2e-1 -``` -x = 10 +
x = 10
 y = 2.5
 z = -3
-```
-
+
## Arithmetic Basic arithmetic works as you’d expect: -``` -a = 7 +
a = 7
 b = 2
 print(a + b)   // 9
 print(a - b)   // 5
 print(a * b)   // 14
 print(a % b)   // 1 (modulo)
-```
-
+
Division and result type: -``` -// If you need a fractional result, ensure a float is involved +
// If you need a fractional result, ensure a float is involved
 print(7 / 2)                    // implementation may yield 3 or 3.5 depending on numeric rules
 print(cast(7, "float") / 2)    // 3.5 (recommended when you need fractions)
 print(7 / 2.0)                  // 3.5
-```
-
+
Mixing numbers and floats promotes the operation to float semantics: -``` -print(2 + 0.5) // 2.5 -``` - +
print(2 + 0.5)   // 2.5
+
## Comparisons -``` -print(3 < 5) // 1 (true) +
print(3 < 5)     // 1 (true)
 print(3 == 3)    // 1
 print(3 != 4)    // 1
 
 // Be explicit when comparing ints vs floats if types matter
 print(1 == 1.0)              // may be true, but types differ
 print(cast(1.0, "number") == 1) // 1 (true) with explicit cast
-```
-
+
## Conversions and parsing -``` -n = to_number("123") // 123 (number) +
n = to_number("123")        // 123 (number)
 f = cast(n, "float")        // 123.0 (float)
 n2 = cast(3.9, "number")    // 3 (truncation semantics)
 print(to_string(f))          // "123"
-```
-
+
If parsing fails (e.g., to_number("abc")), expect a runtime error; guard accordingly. ## Clamping to fixed widths When interoperating with bytecode, C APIs, or binary formats, clamp integers to a specific bit width. -``` -// Unsigned clamp to N bits +
// Unsigned clamp to N bits
 u8  = uclamp(300, 8)   // 44
 u16 = uclamp(70000, 16)
 
 // Signed clamp to N bits
 s8  = sclamp(-130, 8)  // wraps into signed 8‑bit range
-```
-
+
Choose the bits according to the target field (8, 16, 32, 64). See your interop API docs for exact ranges. ## Bitwise operations (numbers) Bitwise operators apply to the integer number type. -``` -a = 0b0110 // if binary literals aren’t supported in your setup, use decimals: a = 6 +
a = 0b0110  // if binary literals aren’t supported in your setup, use decimals: a = 6
 b = 0b0011  // or b = 3
 
 print(a & b)  // 0b0010 -> 2
@@ -136,41 +119,34 @@ print(a ^ b)  // 0b0101 -> 5
 print(~a)     // bitwise NOT (two’s complement rules)
 print(a << 1) // 12
 print(a >> 1) // 3
-```
-
+
Note: Bitwise ops are defined for numbers, not floats. Cast floats to numbers first when needed. ## Common patterns Ensuring float math to avoid unintended truncation: -``` -avg = cast(sum, "float") / cast(count, "float") -``` - +
avg = cast(sum, "float") / cast(count, "float")
+
Safe division with guard against zero: -``` -num = 10 +
num = 10
 den = 0
 if den == 0 {
   print("division by zero")
 } else {
   print(num / den)
 }
-```
-
+
Parsing user input with fallback: -``` -raw = "not-a-number" +
raw = "not-a-number"
 val = 0
 // simplistic guard pattern; adapt to your error handling style
 if find(raw, "0") >= 0 || find(raw, "1") >= 0 {  // crude pre-check
   val = to_number(raw)
 }
-```
-
+
## Gotchas - Integer division vs float division: promote to float when you need fractional results. diff --git a/web/documentation/repl.md b/web/documentation/repl.md index e849255..04cd4fb 100644 --- a/web/documentation/repl.md +++ b/web/documentation/repl.md @@ -29,55 +29,41 @@ The REPL is optional at build time. It provides a fast feedback loop for experim - Build flag: -DFUN_WITH_REPL=ON - Typical CMake configuration example: -``` -cmake -S . -B build \ +
cmake -S . -B build \
   -DFUN_WITH_REPL=ON
 cmake --build build --target fun
-```
-
+
You can also set a default search path for the bundled stdlib using DEFAULT_LIB_DIR at configure time (used for completions and library loading): -``` -cmake -S . -B build -DFUN_WITH_REPL=ON -DDEFAULT_LIB_DIR="/usr/share/fun/lib" -``` - +
cmake -S . -B build -DFUN_WITH_REPL=ON -DDEFAULT_LIB_DIR="/usr/share/fun/lib"
+
## Launching the REPL - Directly run the main executable (ensure FUN_WITH_REPL=ON): -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun
+
- With the CMake “repl” convenience target (available only if built with FUN_WITH_REPL=ON): -``` -cmake --build build --target repl -``` - +
cmake --build build --target repl
+
On startup, you should see something like: -``` -Fun X.Y.Z REPL +
Fun X.Y.Z REPL
 Type :help for commands. Submit an empty line to run.
-```
-
+
Environment variable FUN_LIB_DIR can be used to point the REPL to the standard library directory for symbol completion and library loading. If not set, a compile-time DEFAULT_LIB_DIR (if provided) or "lib" is used. ## Running scripts and REPL-on-error - Run a script file normally: -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./demo.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun ./demo.fun
+
- Enable tracing, and drop into a REPL automatically when a runtime error occurs: -``` -FUN_LIB_DIR="$(pwd)/lib" ./build/fun --repl-on-error --trace ./demo.fun -``` - +
FUN_LIB_DIR="$(pwd)/lib" ./build/fun --repl-on-error --trace ./demo.fun
+
Inside REPL-on-error, you can inspect frames, locals, disassembly, set breakpoints, and continue or step. Use :help to see available commands. ## Prompts and input model diff --git a/web/documentation/rust.md b/web/documentation/rust.md index a308c39..76c29a8 100644 --- a/web/documentation/rust.md +++ b/web/documentation/rust.md @@ -77,8 +77,7 @@ Example: integer addition opcode implemented in Rust. In src/rust/src/lib.rs: -``` -#![no_std] +
#![no_std]
 
  #[repr(C)]
  pub struct Vm;
@@ -100,8 +99,7 @@ In src/rust/src/lib.rs:
 
  #[panic_handler]
  fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }
-```
-
+
What this does: - Pops two 64-bit integers from the VM stack. - Pushes back their sum. @@ -115,8 +113,7 @@ To make the VM call your Rust opcode, add a small C-side case that invokes the e String demo wiring (already present): src/vm/rust/hello.c -``` -case OP_RUST_HELLO: { +
case OP_RUST_HELLO: {
 #ifdef FUN_WITH_RUST
    const char *s = fun_rust_get_string();
    if (!s) s = "";
@@ -127,12 +124,10 @@ case OP_RUST_HELLO: {
 #endif
    break;
 }
-```
-
+
For a stack-based math opcode (like fun_op_radd), you would declare and call the Rust function similarly: -``` -#ifdef FUN_WITH_RUST +
#ifdef FUN_WITH_RUST
 extern int fun_op_radd(void* vm); // or use the proper VM type if available
 #endif
 
@@ -145,8 +140,7 @@ case OP_RADD: {
 #endif
    break;
 }
-```
-
+
Notes: - Follow the existing opcode conventions for your module (core, math, strings, etc.). diff --git a/web/documentation/stdlib.md b/web/documentation/stdlib.md index 2734e74..01117d7 100644 --- a/web/documentation/stdlib.md +++ b/web/documentation/stdlib.md @@ -80,11 +80,9 @@ The stdlib is written in Fun and organized by domain. Below is the current layou Note: Availability of some modules can depend on optional extensions selected at build time (see [build.md](./build/)). For instance, `regex/pcre2.fun` requires PCRE2 support; `ui/*` depends on chosen UI backends. ## Using modules -```fun -#include +
#include 
 
 let s = trim("  hello  ")
 print(s)
-```
-
+
For search paths and namespacing details, see [includes.md](./includes/) and [cli.md](./cli/) (FUN_LIB_DIR and DEFAULT_LIB_DIR). diff --git a/web/documentation/strings.md b/web/documentation/strings.md index c1d28e4..336a6bb 100644 --- a/web/documentation/strings.md +++ b/web/documentation/strings.md @@ -33,14 +33,12 @@ This guide covers string literals, common operations (length, concatenation, sub ## Literals and escaping -``` -s1 = "hello" +
s1 = "hello"
 s2 = "line1\nline2"   // newline
 s3 = "quote: \" and backslash: \\" // escaped quote and backslash
 
 print(s1)  // hello
-```
-
+
Notes: - Strings are immutable; operations return new strings rather than modifying in place. - Use to_string(x) when concatenating non-string values. @@ -49,66 +47,54 @@ Notes: Length and concatenation: -``` -name = "Ada" +
name = "Ada"
 greet = "Hello, " + name + "!"    // "Hello, Ada!"
 print(len(greet))                   // 12
-```
-
+
Substring (start, length) and search: -``` -s = "hello, world" +
s = "hello, world"
 print(substr(s, 7, 5))   // world
 idx = find(s, ",")      // 5, or -1 if not found
 if idx >= 0 { print("comma at index " + to_string(idx)) }
-```
-
+
Splitting into arrays: -``` -parts = split("a,b,c", ",") // ["a","b","c"] +
parts = split("a,b,c", ",")  // ["a","b","c"]
 for i = 0; i < len(parts); i = i + 1 {
   print(parts[i])
 }
-```
-
+
## Conversions and formatting -``` -n = 42 +
n = 42
 pi = 3.14
 msg = "n=" + to_string(n) + ", pi=" + to_string(pi)
 print(msg)
 
 // parsing (may error if the string is not numeric)
 n2 = to_number("123")    // 123
-```
-
+
If you need a specific type, you can use cast for advanced cases, e.g. cast("123", "number"). ## Common patterns - Guard on find results before slicing: -``` -email = "user@example.org" +
email = "user@example.org"
 at = find(email, "@")
 if at >= 0 {
   user = substr(email, 0, at)
   host = substr(email, at + 1, len(email) - at - 1)
   print(user + " on " + host)
 }
-```
-
+
- Building paths or messages: -``` -base = "/tmp" +
base = "/tmp"
 file = "log.txt"
 path = base + "/" + file
-```
-
+
## Gotchas - Strings are immutable: repeated concatenation in big loops can be costly; consider collecting pieces in an array and joining at the end if you have a helper for that in your setup. diff --git a/web/documentation/testing.md b/web/documentation/testing.md index 69641a6..8531e66 100644 --- a/web/documentation/testing.md +++ b/web/documentation/testing.md @@ -41,29 +41,21 @@ To list targets with CMake directly, consult your IDE or run the build system’ Debug profile example: -``` -cmake --build build --target test_opcodes && ./build/test_opcodes -``` - +
cmake --build build --target test_opcodes && ./build/test_opcodes
+
Release profile example: -``` -cmake --build build_release --target test_opcodes && ./build/test_opcodes -``` - +
cmake --build build_release --target test_opcodes && ./build/test_opcodes
+
If `fun_test` exists in your configuration: -``` -cmake --build build --target fun_test && ./build/fun_test -``` - +
cmake --build build --target fun_test && ./build/fun_test
+
You can also invoke CTest to run any tests registered with `add_test()`: -``` -cmake --build build --target test +
cmake --build build --target test
 ctest --test-dir build -j
-```
-
+
## Adding new tests - C/C++/VM-side tests: look for existing tests under `src` or `spec` and mirror the structure. Add a new source and register it in CMake with an executable or via `add_test()`. diff --git a/web/documentation/troubleshooting.md b/web/documentation/troubleshooting.md index 4fdea05..030b8f1 100644 --- a/web/documentation/troubleshooting.md +++ b/web/documentation/troubleshooting.md @@ -26,27 +26,21 @@ This page lists common issues when building and running Fun from a source checko Error example: -``` -Include error: cannot read '' -``` - +
Include error: cannot read ''
+
Fix: - When running from the repository without installing, set `FUN_LIB_DIR` to the local `./lib` directory so angle‑bracket includes resolve correctly. Linux/macOS/BSD: -``` -export FUN_LIB_DIR="$(pwd)/lib" +
export FUN_LIB_DIR="$(pwd)/lib"
 ./build/fun examples/include_lib.fun
-```
-
+
Windows (PowerShell): -``` -$env:FUN_LIB_DIR = "$PWD/lib" +
$env:FUN_LIB_DIR = "$PWD/lib"
 ./build/fun.exe .\examples\include_lib.fun
-```
-
+
If `FUN_LIB_DIR` is not set, the interpreter tries a compile‑time `DEFAULT_LIB_DIR`, and finally falls back to `./lib` relative to the current working directory. Be mindful of where you run the `fun` binary from. See includes.md for more details. @@ -59,12 +53,10 @@ Symptoms: Fix: - Build with `-DFUN_WITH_REPL=ON` and rebuild the `fun` target. Then launch without arguments: -``` -cmake -S . -B build -DFUN_WITH_REPL=ON +
cmake -S . -B build -DFUN_WITH_REPL=ON
 cmake --build build --target fun
 FUN_LIB_DIR="$(pwd)/lib" ./build/fun
-```
-
+
See repl.md for usage tips and features. ## Linker errors for optional libraries (JSON, PCRE2, CURL, SQLite, etc.) diff --git a/web/documentation/types.md b/web/documentation/types.md index b708b2b..2503d44 100644 --- a/web/documentation/types.md +++ b/web/documentation/types.md @@ -56,8 +56,7 @@ Helpers used throughout: Create arrays with square brackets and comma‑separated elements. -``` -// creation +
// creation
 a = [1, 2, 3]
 b = ["alpha", "beta"]
 c = []  // empty array
@@ -96,8 +95,7 @@ for pair in it.enumerate(["x", "y"]) {
   val = pair[1]
   print(idx + ":" + val)
 }
-```
-
+
Notes: - Indexing is bounds‑checked; invalid indices cause a runtime error that you can inspect with --trace or REPL‑on‑error. - Arrays are mutable; operations modify in place unless documented otherwise. @@ -106,8 +104,7 @@ Notes: Create maps with curly braces. Keys are typically strings; values can be any type. -``` -// creation +
// creation
 user = { "name": "Ada", "age": 37 }
 cfg  = {}
 
@@ -134,57 +131,48 @@ for i = 0; i < len(keys); i = i + 1 {
   k = keys[i]
   print(k + " = " + to_string(user[k]))
 }
-```
-
+
Notes: - Accessing a non‑existing key returns nil; write a guard before using it as another type. - Maps are mutable; assigning with map["k"] = v updates in place. ## Strings (brief) -``` -s = "hello, world" +
s = "hello, world"
 print(len(s))              // 12
 print(substr(s, 7, 5))     // world
 print(find(s, ","))       // 5 (index) or -1 if not found
 
 parts = split("a,b,c", ",")  // ["a","b","c"]
 print(join(parts, ";"))      // a;b;c
-```
-
+
## Numbers and floats (brief) -``` -n = 10 +
n = 10
 f = 3.14
 print(n + 2)               // 12
 print(f * 2)               // 6.28
 
 // clamp to widths when needed
 print(uclamp(300, 8))      // 44 (300 mod 256)
-```
-
+
## Booleans and nil -``` -ok = 1 // true +
ok = 1        // true
 no = 0        // false
 none = nil
 
 if ok && !no { print("yay") }
 if none == nil { print("is nil") }
-```
-
+
## Conversions and typing -``` -x = "42" +
x = "42"
 print(to_number(x) + 1)    // 43
 
 print(typeof([1,2,3]))     // "array"
 print(typeof({}))          // "map"
-```
-
+
## Common patterns - Accumulate values: diff --git a/web/documentation/website.md b/web/documentation/website.md index 8e4d768..5c95058 100644 --- a/web/documentation/website.md +++ b/web/documentation/website.md @@ -5,8 +5,8 @@ noToc: false noComments: false noDate: false title: Fun - Website Documentation (fun-lang.xyz) -subtitle: Documentation for the [fun-lang.xyz](https,//fun-lang.xyz) website in the `./web/` directory. -description: Documentation for the [fun-lang.xyz](https,//fun-lang.xyz) website in the `./web/` directory. +subtitle: Documentation for the fun-lang.xyz website in the `./web/` directory. +description: Documentation for the fun-lang.xyz website in the `./web/` directory. permalink: /documentation/website/ lang: en tags: @@ -93,9 +93,7 @@ To run the website locally for development: The website can be deployed using the Makefile: -```bash -cd web/ +
cd web/
 make release
-```
-
+
The `release` target builds the site, minifies the assets, and syncs the files to [fun-lang.xyz](https://fun-lang.xyz) via `rsync`. Ensure you have the necessary SSH permissions for the sync to succeed. diff --git a/web/index.md b/web/index.md index 8e99c29..6ce918a 100644 --- a/web/index.md +++ b/web/index.md @@ -37,7 +37,7 @@ permalink: /

{{ post.title }} 📌

+{% if post.date_updated %} - Edited: {{ post.date_updated | date: "%b %-d, %Y %H:%M:%S" }} ({{ post.date_updated | date: "%b %-d, %Y %H:%M:%S" | date: "%Z" }}){% endif %}{% if post.author %}, {{ post.author }}{% endif %}

{{ post.content | truncatewords: site.truncatewords_length }}

[Read post]

@@ -48,7 +48,7 @@ permalink: /

{{ post.title }}

+{% if post.date_updated %} - Edited: {{ post.date_updated | date: "%b %-d, %Y %H:%M:%S" }} ({{ post.date_updated | date: "%b %-d, %Y %H:%M:%S" | date: "%Z" }}){% endif %}{% if post.author %}, {{ post.author }}{% endif %}

{{ post.content | truncatewords: site.truncatewords_length }}

[Read post]