diff --git a/spec/v0.3.md b/spec/v0.3.md new file mode 100644 index 0000000..b91d582 --- /dev/null +++ b/spec/v0.3.md @@ -0,0 +1,484 @@ +# Fun Language Specification v0.3 + +This document describes Fun (Fun Uses Nothing) as of version 0.3. It supersedes v0.2 by formalizing classes/objects, inheritance, namespaced includes, richer collections and builtins, concurrency primitives, networking and OS integration, as reflected by the examples. + +--- + +## 1) Overview and Goals + +- Readable: strict, indentation-based syntax (2 spaces), no semicolons. +- Safe: explicit types, no implicit numeric coercions, bounds-checked operations, controlled side effects. +- Hackable: pragmatic stdlib, process I/O, sockets, threads. + +What’s new in v0.3 (high level): +- Classes and objects with methods, constructors, and inheritance (`extends`). +- Dot-call sugar for method calls, and explicit `this` in method definitions. +- Namespaced `#include ... as alias` for module imports. +- Maps (dictionaries) with literals and helpers. +- Control-flow additions: `break` and `continue`. +- Threads: `thread_spawn`, `thread_join` and `sleep`. +- Expanded system and network APIs (TCP/Unix sockets, serial, env, timers). +- Bitwise helpers (`band`, `bor`, `bxor`, `bnot`, `shl`). +- Exception syntax (`try/catch/finally`) is defined; runtime throwing/handling may be partial. + +--- + +## 2) Lexical Structure + +- Case-sensitive identifiers: letters, digits, `_`; must not start with a digit. +- Comments: + - Single-line: `// comment` + - Multi-line: `/* ... */` +- Whitespace and newlines: + - Indentation is exactly 2 spaces; tabs are forbidden. + - Newline terminates statements; no semicolons. + +Reserved keywords (cannot be redefined): +- `if`, `else`, `for`, `while`, `break`, `continue` +- `fun`, `return` +- `class`, `extends` +- `global`, `private` +- `true`, `false` +- `try`, `catch`, `finally` + +Notes: +- `#include` is a directive, not an expression; `as` is part of the include alias syntax (see Modules & Includes). + +--- + +## 3) Types + +Scalar types: +- `number`: 64-bit signed integer. +- `float`: 64-bit IEEE-754 floating point. +- `string` +- `boolean`: `true` / `false` (in conditionals `0` and `1` are accepted where noted). +- `byte`: 8-bit value (see conversions and overflow rules). + +Fixed-width integers (signed/unsigned): +- `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `int64`, `uint64` + +Aggregate types: +- `array` and typed arrays: `array` +- `map` (dictionary / associative array) +- `object` (instances of `class`) + +Examples: +```fun +number n = 42 +float pi = 3.14159 +string s = 'He said: "Fun!"' +boolean ok = true +byte b = 0x41 + +array nums = [1, 2, 3] +array mixed = [1, "two", true, [3, 4]] + +m = { "a": 1, "b": 2 } // map +``` + +Dynamic typing escape hatch (discouraged; use when interacting with unknown data): +```fun +dynamic string x = 42 // allowed by spec; runtime performs dynamic checks +x = "Now I'm a string" +``` + +--- + +## 4) Variables and Scope + +- `global` variables are visible program-wide. +- `private` variables are file-local (module private). +- Rebinding a global or shadowing a name is a compile-time error. + +```fun +global string message = "Hello" +private number count = 42 +number local = 23 +``` + +--- + +## 5) Operators and Builtins + +Arithmetic: `+`, `-`, `*`, `/`, `%` + +Comparison: `==`, `!=`, `>`, `<`, `>=`, `<=` + +Boolean: `&&`, `||`, `!` + +Assignment: `=` + +Bitwise helpers (functions): +- `band(a, b)`, `bor(a, b)`, `bxor(a, b)`, `bnot(a)`, `shl(a, n)` + +```fun +print(bxor(0x80000000, 0x00000001)) // 2147483649 +print(shl(0x80, 24)) // 2147483648 +``` + +Collection helpers (selected): +- Arrays: `push(arr, v)`, `join(arr, sep)`, `map(arr, f)`, `filter(arr, pred)`, `reduce(arr, init, f)` +- Maps: `has(m, key)`, `keys(m)`, `values(m)` + +Type/convert helpers (selected): +- `typeof(x) -> string` +- `to_string(x)` and numeric casts (see examples for `cast_demo.fun` and `conversions_showcase.fun`) + +--- + +## 6) Control Flow + +If/Else: +```fun +if (x != y) + print(x) +else if (a == b || h != i) + print(a + b) +else + if (k < 1 && l > 1) + print("Buh!") +``` + +While: +```fun +number i = 0 +while i < 10 + if i % 2 == 0 + i = i + 1 + continue + if i > 5 + break + i = i + 1 +``` + +For: +- Range iteration: `for i in range(start, end)` +- Array iteration: `for x in arr` +- Map iteration: `for k in keys(m)` then `m[k]` + +```fun +for i in range(0, 5) + print(i) + +for x in [1, 2, 3] + print(x) +``` + +Loop control: +- `break` exits the innermost loop. +- `continue` skips to next iteration of the current loop. + +Try/Catch/Finally (syntax defined; runtime throwing may be incomplete): +```fun +try + // protected section + risky() +catch err + print("caught error:") + print(err) +finally + print("cleanup") +``` + +--- + +## 7) Functions + +Built-in/runtime functions (selected): +- Basic: `print(x)`, `range(a, b)`, `sleep(ms)` +- Processes: `exec(cmd) -> string`, `system(cmd) -> number` +- Async processes: `nexec(cmd) -> pid/object`, `nsystem(cmd) -> number`, `nspawn(cmd) -> pid`, `wait(pid)`, `read(pid)`, `kill(pid)` +- Threads: `thread_spawn(fn, argOrArgs) -> thread_id`, `thread_join(thread_id) -> any` + +User-defined functions: +```fun +fun add(a, b) + return a + b + +fun divide(a, b) + if b == 0 + return 0, "division by zero" + return a / b, "" +``` + +Higher-order helper (example pattern): +```fun +fun call(f, arg) + return f(arg) +``` + +Multiple return values are supported syntactically; use tuple-like unpacking via arrays as needed in user code patterns. + +--- + +## 8) Classes and Objects + +Definition: +```fun +class Name(/* optional ctor params with types */) + // field defaults + field1 = 0 + field2 = "" + + // method: first parameter must be `this` + fun method(this, arg1, arg2) + // ... + return 0 +``` + +Constructors: +- Default constructor maps the class header parameters to fields of the same names. +- Optional explicit constructor hook: define `fun _construct(this, ...params...)` to customize initialization. It is invoked automatically on instantiation. + +Fields and methods: +- Fields are created/initialized with simple assignments in the class body. +- Methods are functions declared inside the class; the first parameter must be `this`. +- Private members: any field or method whose name starts with `_` is considered private to the class. Accessing them from outside should raise an access error. + +Instantiation and method calls: +```fun +p = Point(10, -2) +print(p.x) // field access via `.` or indexing +print(p["x"]) // map-like field access is supported + +// Dot-call sugar: p.method(a, b) is equivalent to method(p, a, b) +print(p.toString()) +``` + +Method references: +```fun +move_fn = p["move"] +move_fn(p, 3, 5) // call with explicit `this` +``` + +Inheritance: +```fun +class Parent(number start) + value = 0 + fun _construct(this, s) + this.value = s + + fun describe(this) + return "Parent(value=" + to_string(this.value) + ")" + +class Child(number start) extends Parent + bonus = 5 + fun _construct(this, s) + // runs after parent fields merged + this.value = this.value + this.bonus + fun describe(this) + return "Child(value=" + to_string(this.value) + ", bonus=" + to_string(this.bonus) + ")" +``` + +`typeof` on classes and instances: +- `typeof(Point) == "Class"` +- `typeof(p) == "Point(10, -2)"` (implementation-specific descriptive form) + +--- + +## 9) Modules and Includes + +Include sources: +- System/stdlib: angle brackets search the Fun library path (e.g., `FUN_LIB_DIR`). + ```fun + #include + ``` +- Local file: quoted, relative to the current working directory or file. + ```fun + #include "./utils/file.fun" + ``` +- Absolute path is supported. + +Namespaced includes: +- Use `as` to bind a module into a namespace alias. +```fun +#include as m +#include "examples/namespaced_mod.fun" as mod + +print(m.add(2, 3)) +g = mod.Greeter("Hi") +g.say("World") +``` + +Aliased access uses `alias.symbol` or `alias.ClassName`. + +Global/private at file scope control symbol exports from a module. + +--- + +## 10) Collections + +Arrays: +- Literals with `[ ... ]`; may be heterogeneous unless `array` is declared. +- Helpers: `push`, `join`, `map`, `filter`, `reduce`, iteration via `for x in arr`. + +Maps: +- Literal: `{ key: value, ... }` +- Indexing: `m["a"]`, assignment `m["c"] = 5` +- Introspection: `has(m, key)`, `keys(m)`, `values(m)` +- Iterate keys/values using arrays returned by `keys`/`values`. + +--- + +## 11) Concurrency (Threads) + +- `thread_spawn(fn, args)` starts `fn` in a new thread. `args` may be a single value or an array for multiple arguments. +- `thread_join(id)` waits for the thread and returns its result. +- `sleep(ms)` suspends current thread. + +Example: +```fun +fun square(n) + sleep(100) + return n * n + +ids = [] +for x in [1, 2, 3] + push(ids, thread_spawn(square, x)) + +results = [] +for id in ids + push(results, thread_join(id)) + +print(results) +``` + +--- + +## 12) System, Files, Environment, and Networking + +Processes: +- Blocking: `exec(cmd) -> string` (stdout), `system(cmd) -> number` (exit code) +- Non-blocking: `nexec`, `nspawn`, `nsystem`, with `wait(pid)`, `read(pid)`, `kill(pid)` helpers + +Environment and CLI: +- `env(NAME) -> string` to read env variables (see `os_env.fun`) +- `argv() -> array` from ``; also `FUN_ARGC`/`FUN_ARGS` environment interoperability in examples + +Files: +- Basic file I/O helpers exist in the stdlib; see `file_io.fun`, `file_print_for_file_line_by_line.fun` + +Time: +- Date/time and timers (see `datetime_basic.fun`, `datetime_extended.fun`, `datetime_timer.fun`) + +Random: +- `random` helpers (see `random_demo.fun`, `random_number_example.fun`) + +Regex: +- Regex operations via stdlib (see `regex_demo.fun`, `regex_procedural.fun`) + +Networking: +- TCP client helpers: `tcp_connect(host, port) -> fd`, `sock_send(fd, data)`, `sock_recv(fd, nbytes)`, `sock_close(fd)` +- Unix domain sockets (see `unix_socket_echo.fun`) + +Serial: +- Serial port helpers (see `serial_demo.fun`) + +Progress/UI: +- Helper functions to render CLI progress (see `progress.fun`, `progress_inline.fun`) + +Note: function names may live in stdlib modules; import accordingly (system-dependent availability). + +--- + +## 13) Error Handling and Type Safety + +- No implicit type coercion between numeric types; explicit casts or constructors are required. +- Overflow/underflow on fixed-width types is an error. +- Accessing undefined variables or re-defining globals is a compile-time error. +- Shadowing internal/runtime functions is forbidden. +- Exception syntax `try/catch/finally` is standardized in v0.3; throwing and catching at runtime may be partially implemented depending on the feature (see examples like `byte_overflow_try_catch.fun` and notes within). + +--- + +## 14) Examples (from the repository) + +Hello: +```fun +print("Hello, World!") +``` + +Namespaced includes: +```fun +#include as m +print(m.add(2, 3)) +``` + +Classes: +```fun +class Counter + value = 0 + fun inc(this) + this.value = this.value + 1 + return this.value + +c = Counter() +print(c.inc()) +``` + +Inheritance: +```fun +class Parent(number start) + value = 0 + fun _construct(this, s) + this.value = s + +class Child(number start) extends Parent + bonus = 5 + fun _construct(this, s) + this.value = this.value + this.bonus +``` + +Threads: +```fun +tid = thread_spawn(add3, [10, 20, 30]) +print(thread_join(tid)) // 60 +``` + +TCP GET: +```fun +fd = tcp_connect("example.org", 80) +req = "GET / HTTP/1.0\r\nHost: example.org\r\n\r\n" +sent = sock_send(fd, req) +print(sock_recv(fd, 8192)) +sock_close(fd) +``` + +--- + +## 15) Versioning and Compatibility + +- v0.3 keeps v0.2 syntax intact and adds new features. Where runtime support is evolving (exceptions, some stdlib facets), the syntax is stable and forward-compatible. +- Examples are authoritative for idioms and available helpers; consult `examples/` and `lib/` modules. + +--- + +## 16) Appendix: Notation and Conventions + +- Use backticks for code identifiers in prose (`fun`, `class`, `extends`, etc.). +- All code blocks are in `fun` pseudolanguage. +- Indentation is always 2 spaces; tabs will cause errors. + +--- + +## Changelog (from v0.2 to v0.3) + +- Added: `class`, methods with explicit `this`, default and custom constructors via `_construct`. +- Added: inheritance with `extends`. +- Added: private members by leading underscore naming convention. +- Added: dot-call sugar `obj.method(a, b)` ≡ `method(obj, a, b)`. +- Added: namespaced includes: `#include as alias`, `#include "path" as alias`. +- Added: `map` type with literals `{ key: value }` and helpers. +- Added: loop control `break`, `continue`. +- Added: threads (`thread_spawn`, `thread_join`), sleep. +- Added: socket helpers (TCP/Unix), serial devices, CLI argv, env helpers, timers. +- Added: bitwise helper functions: `band`, `bor`, `bxor`, `bnot`, `shl`. +- Added: exception syntax `try/catch/finally` (runtime handling is evolving). + +--- + +## How to use this file + +- Save this content as `./spec/v0.3.md` in the repository. +- Keep `examples/` in sync with this spec. When adding a new feature, provide an example and update the spec accordingly.