Added the Fun v0.3 specification. No code changes. (0.37.56)
This commit is contained in:
parent
d58bed053e
commit
c05b18b914
1 changed files with 484 additions and 0 deletions
484
spec/v0.3.md
Normal file
484
spec/v0.3.md
Normal file
|
|
@ -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<T>`
|
||||||
|
- `map<K, V>` (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<number> nums = [1, 2, 3]
|
||||||
|
array mixed = [1, "two", true, [3, 4]]
|
||||||
|
|
||||||
|
m = { "a": 1, "b": 2 } // map<string, number>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 <utils/math.fun>
|
||||||
|
```
|
||||||
|
- 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 <utils/math.fun> 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<T>` 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<string>` from `<cli.fun>`; 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 <utils/math.fun> 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 <path> 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.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue