1
0
Fork 0
forked from fun/fun

Some more documentation fun. No code changes. (0.38.11)

This commit is contained in:
Johannes Findeisen 2026-02-11 17:34:24 +01:00
commit 41ebd59187
5 changed files with 215 additions and 156 deletions

View file

@ -11,6 +11,9 @@ This file serves as an index of the documents in this directory. Links are relat
- [opcodes.md](./opcodes.md) — VM opcodes overview grouped by domain with brief behavior/stack notes.
- [internals.md](./internals.md) — Implementation details: bytecode format, VM architecture, stacks/frames, parser, and dispatch.
- [rust.md](./rust.md) — Writing Rustbacked opcodes and wiring them into the C VM; build/setup notes.
- [examples.md](./examples.md) — How to run the examples and the interactive showcase script, with environment tips.
- [testing.md](./testing.md) — How to build and run tests/targets with CMake/CTest, and where to add new tests.
- [troubleshooting.md](./troubleshooting.md) — Common issues and quick fixes for build, includes, and REPL usage.
## Tips

62
docs/examples.md Normal file
View file

@ -0,0 +1,62 @@
# Running the Examples
This page shows how to run the example programs included with the repository and how to use the interactive showcase script.
All commands assume you are in the repository root.
## Prerequisites
- Build the interpreter (see handbook.md). Youll have `build_debug/fun` or `build_release/fun` (paths may vary by your setup/IDE).
- Set FUN_LIB_DIR to the repos lib directory when running without installation so `#include <...>` can find the standard library.
Example (Linux/macOS/BSD):
```
FUN_LIB_DIR="$(pwd)/lib" ./build_debug/fun examples/include_lib.fun
```
Windows (PowerShell):
```
$env:FUN_LIB_DIR = "$PWD/lib"
./build_release/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
```
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/aes256.fun
```
## Example categories
Browse the `examples/` tree for areas of interest:
- crypto — crypto demonstrations (e.g., AES)
- blocking / interactive — I/O or user-interactive patterns
- error / broken — negative tests and error showcases
- math — numeric operations
- sqlited / data — data access and HTTP/CGI-style samples (platform dependent)
## Creating your own examples
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 <io/console.fun>
```
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.).

59
docs/testing.md Normal file
View file

@ -0,0 +1,59 @@
# Building and Running Tests
This page explains how to build and run Funs tests using the existing CMake targets. It also points to where opcode and language tests typically live and how to add new ones.
## Test-related targets
Depending on your generator/profile, you may see the following targets in your IDE or via `cmake --build`:
- fun_test (executable) — main test runner/binary (where present)
- test_opcodes (executable) — opcode-focused tests/demos
- Continuous*/Experimental*/Nightly* — CTest dashboards (optional; mostly for CI)
- build / run / repl — convenience targets for local development
To list targets with CMake directly, consult your IDE or run the build systems metadata commands. In CLion, targets are shown in the Build tool window.
## Running tests from the command line
Debug profile example:
```
cmake --build build_debug --target test_opcodes && ./build_debug/test_opcodes
```
Release profile example:
```
cmake --build build_release --target test_opcodes && ./build_release/test_opcodes
``>
If `fun_test` exists in your configuration:
```
cmake --build build_debug --target fun_test && ./build_debug/fun_test
```
You can also invoke CTest to run any tests registered with `add_test()`:
```
cmake --build build_debug --target test
ctest --test-dir build_debug -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()`.
- Fun-level examples as tests: minimal scripts under `examples/` can act as smoke tests and are runnable via `./play.fun`. Consider adding a new example for new features and have CI invoke a subset.
Guidelines:
- Keep each test focused; prefer several small tests over one monolith.
- Avoid nondeterminism; set seeds where randomness is involved.
- Make tests independent of the working directory unless the behavior under test is precisely path resolution.
## Debugging failing tests
- Use `--trace` when running the interpreter to follow execution.
- Enable `--repl-on-error` to inspect state interactively on failure.
- Print intermediate values with `print()` and convert with `to_string()` when needed.
See repl.md and internals.md for deeper debugging tips.

91
docs/troubleshooting.md Normal file
View file

@ -0,0 +1,91 @@
# Troubleshooting Guide
This page lists common issues when building and running Fun from a source checkout and how to fix them quickly.
## Includes cannot be found
Error example:
```
Include error: cannot read '<io/console.fun>'
```
Fix:
- When running from the repository without installing, set `FUN_LIB_DIR` to the local `./lib` directory so anglebracket includes resolve correctly.
Linux/macOS/BSD:
```
export FUN_LIB_DIR="$(pwd)/lib"
./build_debug/fun examples/include_lib.fun
```
Windows (PowerShell):
```
$env:FUN_LIB_DIR = "$PWD/lib"
./build_release/fun.exe .\examples\include_lib.fun
```
If `FUN_LIB_DIR` is not set, the interpreter tries a compiletime `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.
## REPL does not start
Symptoms:
- Running the executable just exits, or `--repl-on-error` is not recognized.
Fix:
- Build with `-DFUN_WITH_REPL=ON` and rebuild the `fun` target. Then launch without arguments:
```
cmake -S . -B build_debug -DFUN_WITH_REPL=ON
cmake --build build_debug --target fun
FUN_LIB_DIR="$(pwd)/lib" ./build_debug/fun
```
See repl.md for usage tips and features.
## Linker errors for optional libraries (JSON, PCRE2, CURL, SQLite, etc.)
Symptoms:
- Build fails when enabling an optional feature.
Fix:
- Ensure the development packages for the chosen library are installed (headers + libs).
- Toggle features individually with `-DFUN_WITH_JSON=ON`, `-DFUN_WITH_PCRE2=ON`, etc., and verify your system provides them.
## Bytecode or opcode mismatch errors after refactors
Symptoms:
- Crashes or incorrect behavior after editing src/vm or src/bytecode.h.
Fix:
- Rebuild cleanly to ensure all amalgamated C units are recompiled.
- Verify opcode_names[] in src/vm.h matches enum ordering in src/bytecode.h.
- Re-run with `--trace` and (optionally) `--dump-bytecode` to inspect control flow.
## Paths differ when running from IDE vs. shell
Symptoms:
- Includes resolve in one environment but not the other; `./lib` fallback behaves differently.
Fix:
- Always set `FUN_LIB_DIR` explicitly in the run configuration of your IDE and in your shell session.
- Confirm the working directory of the launch configuration; relative includes use `$PWD`.
## Windows-specific quoting issues
Symptoms:
- Setting environment variables has no effect; include paths remain unresolved.
Fix:
- In CMD use: `set FUN_LIB_DIR=%CD%\lib && build-debug\fun.exe examples\include_lib.fun`
- In PowerShell use: `$env:FUN_LIB_DIR = "$PWD\lib"; .\build\fun.exe .\examples\include_lib.fun`
## Getting help
- Run the interpreter with `--help` to see supported flags.
- Explore docs/handbook.md and docs/repl.md.
- Check the examples under `examples/` and try `./play.fun` for an interactive tour.

156
play.fun
View file

@ -1,156 +0,0 @@
#!/usr/bin/env fun
/*
* Interactive demo runner for all examples in ./examples
* - Asks y/n before running each feature demo
* - Executes each example as a subprocess
*/
#include <strings.fun>
#include <io/console.fun>
#include <io/process.fun>
fun pick_fun_bin()
// Prefer an explicit FUN_BIN override; otherwise rely on PATH
b = env("FUN_BIN")
if b != ""
return b
return "fun"
fun run_example(bin, path)
// Ensure examples can locate stdlib when run from repo root.
// We execute via the shell so env assignment + redirection works.
cmd = join(["sh -c '\nFUN_LIB_DIR=./lib ", bin, " ", path, " 2>&1\n'"], "")
print("-- output begin --")
code = system(cmd)
print("-- output end --")
print(join(["exit code: ", to_string(code)], ""))
return code
fun main()
c = Console()
bin = pick_fun_bin()
print("=== Fun language feature showcase (interactive) ===")
print(join(["Using interpreter: ", bin], ""))
print("Tip: set FUN_BIN=/path/to/fun to override. Stdlib is passed via FUN_LIB_DIR=./lib\n")
// List of example scripts. Keep paths relative to repo root where this demo resides.
// If you add/remove examples, update this list.
files = [
"examples/arrays.fun",
"examples/arrays_advanced.fun",
"examples/arrays_iter.fun",
"examples/boolean_decl.fun",
"examples/booleans.fun",
"examples/builtins_conversions.fun",
"examples/builtins_extended.fun",
"examples/builtins_maps_and_more.fun",
"examples/byte_for_demo.fun",
"examples/byte_overflow_try_catch.fun",
"examples/cast_demo.fun",
"examples/class_constructor.fun",
"examples/classes_demo.fun",
"examples/crypto/crc32_example.fun",
"examples/crypto/crc32c_example.fun",
"examples/crypto/md5_demo.fun",
"examples/crypto/sha1_demo.fun",
"examples/crypto/sha256_demo.fun",
"examples/crypto/sha256_str_demo.fun",
"examples/crypto/sha384_example.fun",
"examples/crypto/sha512_demo.fun",
"examples/crypto/sha512_str_demo.fun",
"examples/datetime_basic.fun",
"examples/datetime_extended.fun",
"examples/datetime_timer.fun",
"examples/echo_example.fun",
"examples/error/debug_reporting.fun",
"examples/error/exit_example.fun",
"examples/error/repl_on_error.fun",
"examples/expressions_test.fun",
"examples/extra/curl_download.fun",
"examples/extra/curl_get_json.fun",
"examples/extra/curl_post.fun",
"examples/extra/ini_class_demo.fun",
"examples/extra/ini_complex.fun",
"examples/extra/ini_demo.fun",
"examples/extra/ini_subsections.fun",
"examples/extra/json_showcase.fun",
"examples/extra/libsql_example.fun",
"examples/extra/pcre2_opcodes.fun",
"examples/extra/pcre2_showcase.fun",
"examples/extra/pcsc_example.fun",
"examples/extra/sqlite_example.fun",
"examples/extra/tk_hello.fun",
"examples/extra/xml_access_catalog.fun",
"examples/extra/xml_access_employees.fun",
"examples/extra/xml_access_ns.fun",
"examples/extra/xml_class_example.fun",
"examples/extra/xml_minimal.fun",
"examples/fail.fun",
"examples/file_io.fun",
"examples/file_print_for_file_line_by_line.fun",
"examples/floats.fun",
"examples/for_range_test.fun",
"examples/functions_test.fun",
"examples/have_fun.fun",
"examples/have_fun_function.fun",
"examples/if_else_test.fun",
"examples/include_lib.fun",
"examples/include_local.fun",
"examples/include_local_util.fun",
"examples/include_namespace.fun",
"examples/inheritance_demo.fun",
"examples/interactive/input_example.fun",
"examples/loops_break_continue.fun",
"examples/namespaced_mod.fun",
"examples/nested_loops.fun",
"examples/objects_basic.fun",
"examples/objects_more.fun",
"examples/os_env.fun",
"examples/process_example.fun",
"examples/regex_demo.fun",
"examples/regex_procedural.fun",
"examples/short_circuit_test.fun",
"examples/signed_ints.fun",
"examples/stdlib_showcase.fun",
"examples/strings_test.fun",
"examples/tcp_http_get.fun",
"examples/tcp_http_get_class.fun",
"examples/thread_class_example.fun",
"examples/threads_demo.fun",
"examples/try_catch_finally.fun",
"examples/try_catch_with_error.fun",
"examples/type_safety.fun",
"examples/type_safety_fails.fun",
"examples/types_integers.fun",
"examples/types_overview.fun",
"examples/typeof.fun",
"examples/typeof_features.fun",
"examples/uint_types.fun",
"examples/unix_socket_echo.fun",
"examples/while_test.fun"
]
failures = []
for f in files
q = join(["Run ", f, "?"], "")
if c.ask_yes_no(q)
print(join(["=== Running: ", f, " ==="], ""))
code = run_example(bin, f)
if code != 0
failures.push(f)
print("")
else
print(join(["Skipped: ", f], ""))
if len(failures) == 0
print("All selected examples completed successfully.")
else
print("Some selected examples failed:")
for ff in failures
print(join([" - ", ff], ""))
main()