Skip to content

Commit 1b4e317

Browse files
committed
Add interactive todo_demo example and document it in README, CHANGELOG, and skills.
The demo reads stdin commands for a Vec of structs with String; build output stays in target/ and is not committed.
1 parent 1c2cd5f commit 1b4e317

7 files changed

Lines changed: 421 additions & 5 deletions

File tree

.cursor/skills/ion-integration-tests/SKILL.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ End-to-end tests: Ion → C → gcc → run executable → assert exit code (or
1717

1818
The harness runs tests under `tests/` only. Files in `examples/` are documented demos; build and run them with `ion-build` and per-example manifests (see [README.md](../../../README.md#example-programs)). Regenerate committed `examples/*.c` snapshots with `ion-compiler` after codegen changes.
1919

20-
**Example output policy:** Top-level single-file examples commit one merged `.c` next to the `.ion`. `text_summary/` commits one `.c` plus `sample.txt`. Multi-file `data_lib/` keeps `.ion` only (see `examples/data_lib/README.md`).
20+
**Example output policy:** Top-level single-file examples commit one merged `.c` next to the `.ion`. `text_summary/` commits one `.c` plus `sample.txt`. `data_lib/` and `todo_demo/` keep `.ion` and `ion.toml` only (see each directory's `README.md`).
2121

2222
After compiler codegen changes, regenerate committed example `.c` files:
2323

@@ -27,7 +27,7 @@ for f in examples/*.ion; do ./target/release/ion-compiler "$f"; done
2727
./target/release/ion-compiler examples/text_summary/text_summary.ion
2828
```
2929

30-
Multi-file `examples/data_lib/` has no committed `.c`; see `examples/data_lib/README.md`.
30+
Multi-file `examples/data_lib/` has no committed `.c`; see `examples/data_lib/README.md`. `examples/todo_demo/` is the same; see `examples/todo_demo/README.md`.
3131

3232
To build examples, use `ion-build` (see README). Manual `gcc` + `runtime/ion_runtime.c` is for the test harness and advanced debugging only.
3333

.cursor/skills/writing-ion-code/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ Import with paths like `import "stdlib/io.ion" as io;`:
148148
| `fs.ion` | `read_to_string_result(path: String) -> ReadResult` (POSIX/MinGW) |
149149
| `result.ion` | generic `Result<T, E>` for library authors |
150150

151+
No stdlib stdin/line input. For POSIX `read` on fd 0, see [examples/todo_demo/](../../../examples/todo_demo/).
152+
151153
Built-ins: `Vec<T>`, `String`, `Box<T>`, `Option<T>`, `Result<T, E>` (define enums in-file or import). `String` literals assign to `String`; use `String::from("...")` when a owned copy is needed.
152154

153155
## Build and verify
@@ -162,7 +164,7 @@ cd examples # or example subdirectory with ion.toml
162164
echo $LASTEXITCODE
163165
```
164166

165-
Multi-file: `cd examples\data_lib` then `..\..\target\release\ion-build.exe build`. See [examples/data_lib/README.md](../../../examples/data_lib/README.md).
167+
Multi-file: `cd examples\data_lib` then `..\..\target\release\ion-build.exe build`. See [examples/data_lib/README.md](../../../examples/data_lib/README.md). Interactive stdin: [examples/todo_demo/README.md](../../../examples/todo_demo/README.md).
166168

167169
For codegen inspection or `tests/` integration harness work, use `ion-compiler` plus manual `gcc` (see `ion-lang` skill). On Windows add `-lws2_32` for channel/spawn when linking manually. Stop `ion-lsp` if rebuild fails with "Access is denied".
168170

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
- **Tooling**: GitHub Actions CI (Linux and Windows), pinned toolchain (1.96.0), `test_expectations.tsv` manifest, `--version`, line-numbered errors, Cursor agent skills. Split `tc` and `cgen` into submodules. `ion-build` driver and `ion.toml` manifests (`single`/`multi`, `out_dir`, `cflags`, `ldflags`, `stdlib_paths`, `emit_in_source`); per-example manifests and `build_hello`/`build_bad_main` harness smoke tests. Shared `discover_import_config` and stdlib search paths for `ion-compiler`, `ion-build`, and LSP. Integration harness precompiles `runtime/ion_runtime.c` once per run (`RUNTIME_OBJ`). `writing-ion-code` agent skill; `creating-ion-skills` examples index lists all eight project skills. Documented checked-in `examples/*.c` codegen snapshots in README and integration-test skill; regenerated example C output. Fixed `researching-pl-literature` skill `paper-seeds` reference formatting.
1111
- **Docs**: README, CONTRIBUTING, ION_SPEC, and agent skills aligned on project layout, `ion-build` workflow, `emit_in_source`, stdlib import order, LSP features and limitations, `src/build/` checklists, portable Git Bash paths for `test_runner.sh`, and rebuilding release binaries before harness or example C regen (stale `target/release/ion-compiler` note).
1212
- **Fixes**: match rvalue codegen, `Vec` struct drops, channel codegen, parser handling of `alias::call()`, scope-drop for moved-into-call bindings, HTTP server on Windows, integration harness on Windows. Cgen return-unwind: stop marking bindings dropped after inner-branch `return` (restores outer-path drops), dedupe `_`-prefixed unused silences, mark call arguments moved at emission to avoid double-free on unwind, and unify all function returns via `emit_function_return` (including diverging rvalue `match` arms). Cgen struct field move-out neutralizes owned fields after partial move, deferred to statement end when the move is a call argument; `Vec::push` passes address of struct lvalues; non-generic enums emit before structs; tuple IR uses resolved element types and `tuple_Vec_T` mangling with compound-zero `ret_val` for tuple returns (functions and fn literals). Integer indexing and `Vec<i32>` inference in the type checker. Match rvalue arms: reject diverging arms mixed with value arms; structural control-flow analysis for arm bodies (nested `if`/`else`, `loop` without `break`, `unsafe` blocks); reject mixed diverge and value-producing paths within one arm; cgen assigns through `if`/`else` value branches. `fmt::int_to_string` uses `String::push_byte` per digit instead of per-digit `push_str` branches; integration test asserts `0`, negatives, and `int::MIN`. `int::MIN`/`int::MAX` on integer primitives; `Vec::new()`/`with_capacity()` infer `T` from a `let` type annotation. Clippy fix in `portable_source_label`. `Vec::get`/`Vec::pop`: IR infers `Option<T>` from the vector argument; cgen dereferences `&mut Vec<T>` parameters, unpacks runtime `Option` via `ion_option_from_raw`, and uses a temp for struct-returning `Vec::push`/`Vec::set` call values. Grouped `match` switch arms: scope drops before the case `break` (GCC `-Wimplicit-fallthrough` under `-Werror`); guarded arms in a shared variant case break inside the guard `if` so fallback arms do not run.
13-
- **Examples**: `text_summary` (fixture file), `data_lib` (multi-module), `channel_worker` (flat single-file). Per-example `*.toml` manifests for `ion-build`. `http_server` accepts one client then exits (verifiable demo).
13+
- **Examples**: `text_summary` (fixture file), `data_lib` (multi-module), `channel_worker` (flat single-file), `todo_demo` (interactive stdin, `Vec` of structs with `String`). Per-example `*.toml` manifests for `ion-build`. `http_server` accepts one client then exits (verifiable demo).
1414
- **Multi-file fixes**: merge private struct types for cross-module type checking; per-module C symbol prefixes in multi-file codegen (`io_print_int`); walk-up `runtime/` discovery for nested build directories. Integration tests `test_multi_struct`, `test_multi_fmt_io`. Example policy: single-file examples commit `.c` snapshots; `data_lib` multi-file keeps `.ion` only.
1515

1616
## 2025-12

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ Committed `.c` snapshots are for review and `ion-compiler` regression; building
184184
cd text_summary
185185
..\..\target\release\ion-build.exe build
186186
.\target\text_summary.exe
187+
188+
# todo_demo (interactive stdin commands)
189+
cd todo_demo
190+
..\..\target\release\ion-build.exe build
191+
.\target\todo_demo.exe
187192
```
188193

189194
On Linux or macOS, use `./target/release/ion-build` and drop `.exe`. Windows channel/spawn builds add `-lws2_32` automatically.
@@ -199,9 +204,10 @@ On Linux or macOS, use `./target/release/ion-build` and drop `.exe`. Windows cha
199204
| [examples/minimal.ion](examples/minimal.ion) | (transpile-only with `ion-compiler`) | Smallest valid program |
200205
| [examples/channel_worker.ion](examples/channel_worker.ion) | [channel_worker.toml](examples/channel_worker.toml) | Channel worker |
201206
| [examples/text_summary/text_summary.ion](examples/text_summary/text_summary.ion) | [text_summary/ion.toml](examples/text_summary/ion.toml) | `fs` read, string iteration, counts |
207+
| [examples/todo_demo/todo_demo.ion](examples/todo_demo/todo_demo.ion) | [todo_demo/ion.toml](examples/todo_demo/ion.toml) | Interactive todo list: `Vec` of structs with `String`, stdin via FFI `read`; see [todo_demo/README.md](examples/todo_demo/README.md) |
202208
| [examples/data_lib/main.ion](examples/data_lib/main.ion) | [data_lib/ion.toml](examples/data_lib/ion.toml) | Multi-module library; see [data_lib/README.md](examples/data_lib/README.md) |
203209

204-
`examples/data_lib/` keeps only `.ion` sources; `ion-build` writes `.c`, `.h`, and the executable under `examples/data_lib/target/` (not committed).
210+
`examples/data_lib/` and `examples/todo_demo/` keep `.ion` sources and manifests only; `ion-build` writes under each project's `target/` (not committed).
205211

206212
## Project Structure
207213

examples/todo_demo/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# todo_demo
2+
3+
Interactive todo list: `Vec<Todo>`, struct + `String`, move-only rebuild updates, stdin commands.
4+
5+
## Build and run
6+
7+
From repo root (after `cargo build --release --bin ion-build`):
8+
9+
```powershell
10+
cd examples\todo_demo
11+
..\..\target\release\ion-build.exe build
12+
.\target\todo_demo.exe
13+
```
14+
15+
## Commands
16+
17+
At the `todo>` prompt:
18+
19+
| Command | Action |
20+
|---------|--------|
21+
| `help` | Show command list |
22+
| `list` | Print all todos |
23+
| `add <label>` | Add a todo (auto-numbered id) |
24+
| `done <id>` | Mark a todo done |
25+
| `remove <id>` | Delete a todo |
26+
| `quit` | Exit |
27+
28+
Example session:
29+
30+
```
31+
todo> add buy milk
32+
added
33+
todo> add walk the dog
34+
added
35+
todo> list
36+
1: buy milk
37+
2: walk the dog
38+
todo> done 1
39+
marked done
40+
todo> remove 2
41+
removed
42+
todo> list
43+
1: buy milk [done]
44+
todo> quit
45+
```
46+
47+
Build artifacts land in `examples/todo_demo/target/` (not committed).

examples/todo_demo/ion.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name = "todo_demo"
2+
main = "todo_demo.ion"
3+
output = "todo_demo"
4+
mode = "single"
5+
out_dir = "target"

0 commit comments

Comments
 (0)