Skip to content

Commit 416796b

Browse files
ganehagclaude
andcommitted
Overhaul README: features, stdlib table, examples, quick start
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 86588ab commit 416796b

1 file changed

Lines changed: 123 additions & 53 deletions

File tree

README.md

Lines changed: 123 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,164 @@
11
# Gengo (言語)
22

3-
gengo is a small embeddable scripting language/runtime implemented in Zig.
3+
A small embeddable scripting language implemented in Zig. Single-pass Pratt compiler → bytecode VM. Runs natively or as a WASI module.
4+
5+
**[Try it in the browser →](https://gengoscript.github.io/gengo/)**
46

57
Project status: early-stage and intentionally evolving.
68

7-
## Language Example
9+
## Language at a Glance
810

911
```gengo
1012
std := import("std")
1113
12-
type User struct {
13-
id int,
14-
name string,
15-
bio ?string
14+
type Shape interface {
15+
area() float
16+
}
17+
18+
type Rect struct { w float, h float }
19+
20+
func (r Rect) area() float {
21+
return r.w * r.h
1622
}
1723
18-
func greet(u User) {
19-
// Multiline escaped string:
20-
// open with ", continue with " at same column, close on last line with ".
21-
msg := "Hello,
22-
"this is gengo
23-
"User:"
24-
std.io.println(msg + " " + u.name)
24+
func printArea(s Shape) {
25+
std.io.printf("area: %f\n", s.area())
2526
}
2627
27-
u := User{ id: 7, name: "user", bio: "こんにちは" }
28-
greet(u)
28+
printArea(Rect{w: 4.0, h: 3.0})
2929
```
3030

31-
Raw multiline strings use `'` with the same continuation/termination shape and keep backslashes literally.
31+
```gengo
32+
std := import("std")
3233
33-
Additional current syntax/features:
34-
- `const` immutable bindings; `:=` is first-class mutable declaration syntax
35-
- explicit typed declarations: `x int = 10`, `const x int = 10`
36-
- mandatory typed params: `func sum(...xs int) int { ... }`
37-
- `std.io.printf("%s %d", "x", 1)`
38-
- nominal/range types:
39-
- `type Month int range 1..12`
40-
- `type UserId string`
41-
- enums with qualified members:
42-
- `type Status enum { pending, approved, denied }`
43-
- `Status.pending`
34+
// Named types with range constraints
35+
type Celsius float range -273.15..1000.0
4436
45-
## Toolchain
37+
// Multi-return with trap binding — panics on error, caught by defer/recover
38+
func parseTemp(s string) {
39+
defer func() {
40+
err := std.core.recover()
41+
if err != null { std.io.println("bad input:", err) }
42+
}()
4643
47-
- Zig: `0.16.0` (matches CI)
48-
- wasmtime: recent preview1-compatible release
44+
n, trap := std.conv.to_float(s)
45+
std.io.printf("%.1f °C\n", float(Celsius(n)))
46+
}
47+
48+
parseTemp("98.6")
49+
parseTemp("not a number")
50+
```
51+
52+
## Features
53+
54+
**Types**
55+
- Structs with typed fields, nullable (`?T`), union (`A|B`), and method receivers
56+
- Interfaces with structural satisfaction checking
57+
- Enums with qualified member access (`Status.pending`)
58+
- Named scalar types: `type UserId string`, `type Month int range 1..12`
59+
- First-class `error` values; `any` as the empty interface
60+
61+
**Functions**
62+
- Typed parameters (mandatory); `any` to opt out
63+
- Variadic: `func sum(...xs int) int`
64+
- Multi-return: `return value, err`
65+
- Named return variables: `func f() (result float, err ?error)`
66+
- Closures with upvalue capture
67+
68+
**Error Handling**
69+
- `defer` — runs on function exit in LIFO order
70+
- `std.core.recover()` — intercepts panics from inside a defer
71+
- `assert condition` / `assert condition, "message"` — panic if false
72+
- `x, trap := f()` — panic if the bound slot is non-null, pass through if null
73+
74+
**Control Flow**
75+
- `if / else if / else` with optional init statement
76+
- `for cond`, `for init; cond; post`, `for v in seq`, `for i, v in seq`
77+
- `switch expr { case v { } default { } }`
78+
- `break`, `continue`, `return`
79+
80+
**Declarations**
81+
- `x := expr` — inferred mutable
82+
- `x Type = expr` — explicit typed mutable
83+
- `const x Type = expr` — immutable
84+
- `_` discard in destructure: `val, _ := f()`
85+
86+
## Standard Library
87+
88+
| Namespace | Functions |
89+
|---|---|
90+
| `std.io` | `println`, `printf` |
91+
| `std.core` | `len`, `bytelen`, `append`, `contains`, `remove`, `has`, `delete`, `keys`, `values`, `error`, `is_error`, `recover`, `gc`, `gc_live_objects`, `gc_stats` |
92+
| `std.string` | `split`, `join`, `trim`, `upper`, `lower`, `starts_with`, `ends_with`, `index_of` |
93+
| `std.math` | `abs`, `sqrt`, `floor`, `ceil`, `round`, `sin`, `cos`, `tan`, `log`, `log2`, `log10`, `pow`, `min`, `max`, `pi`, `e`, `inf` |
94+
| `std.conv` | `to_int`, `to_float`, `to_bool`, `to_string` |
4995

5096
## Quick Start
5197

52-
Build the WASI runtime:
98+
**Native CLI** (recommended for development):
99+
100+
```bash
101+
zig build -Dpreset=dev cli
102+
./zig-out/bin/gengo script.gengo
103+
```
104+
105+
**WASI runtime** (for browser/sandboxed embedding):
53106

54107
```bash
55108
zig build -Dpreset=dev wasi
109+
wasmtime --dir . ./zig-out/lib/gengo-test.wasm -- script.gengo
56110
```
57111

58-
Run a script:
112+
**Conformance tests:**
59113

60114
```bash
61-
wasmtime --dir . ./gengo-test.wasm -- examples/simple_math.gengo
115+
zig build -Dpreset=dev test
62116
```
63117

64-
Run conformance tests:
118+
**Benchmarks:**
65119

66120
```bash
67-
WASMTIME_BIN=/path/to/wasmtime zig build -Dpreset=dev test
121+
zig build -Dpreset=dev bench
68122
```
69123

70-
## Repo Layout
124+
## Build Presets
71125

72-
- `lang/`: lexer, compiler, bytecode, VM logic
73-
- `runtime/`: runtime services, host ABI, memory
74-
- `examples/`: spec, fail-cases, benchmarks, parity cases
75-
- `docs/`: language and runtime docs
76-
- `tests/`: harness scripts used by `make test` / `make bench`
126+
| Preset | Use |
127+
|---|---|
128+
| `dev` | Default — generous limits, debug-friendly |
129+
| `tiny` | Minimal heap and stack for constrained embedding |
130+
| `stress` | Tight limits to catch edge cases in tests |
77131

78-
## Notes
132+
Pass with `-Dpreset=<name>` to any build step.
79133

80-
- File extension is `.gengo`.
81-
- `import("std")` is the supported builtin namespace.
82-
- Language behavior may change as the project evolves.
83-
- Runtime defaults are small by design (see `docs/language.md` limits section).
84-
- Managed heap allocations are class-based; a single managed block is currently capped at `32 KiB`.
85-
- Embedding API guide: `docs/embedding.md` (`runtime/api.zig`).
134+
## Toolchain
86135

87-
## Browser Playground
136+
- Zig `0.16.0`
137+
- wasmtime (any recent preview1-compatible release) — only needed for WASM target
88138

89-
A GitHub Pages playground is included under `playground/`.
139+
## Repo Layout
90140

91-
- It runs the WASI `gengo-test.wasm` in-browser.
92-
- It mounts your script as an in-memory file (`script.gengo`) and executes it.
141+
```
142+
src/
143+
lang/ lexer, compiler, bytecode, VM
144+
runtime/ heap, GC, host ABI, embedding API
145+
examples/
146+
spec/ conformance pass-cases (+ .out expected output)
147+
spec/fail/ conformance fail-cases (+ .err expected error)
148+
bench/ benchmark scripts
149+
docs/ language reference, embedding guide, changelog
150+
playground/ browser playground (GitHub Pages)
151+
```
152+
153+
## Embedding
154+
155+
Gengo is designed to be embedded in Zig hosts. See `docs/embedding.md` and `src/runtime/api.zig`.
156+
157+
Runtime limits (heap, stack, call depth, etc.) are configured via preset files in `src/runtime/`.
158+
159+
## Notes
93160

94-
After pushing to `main`, the Pages workflow publishes the site.
161+
- File extension: `.gengo`
162+
- Only `import("std")` is currently supported; file imports are planned
163+
- A single managed heap block is capped at 32 KiB regardless of total heap size
164+
- Language surface is still evolving; breaking changes are expected

0 commit comments

Comments
 (0)