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