Files
hakorune/docs/private/roadmap/selfhosting/front_mvp.md

97 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Self-Hosting Front MVP — Ny → JSON v0
Status: drafting (Phase 15.9 entry)
## Purpose
- Deliver a Ny-written front-end that lowers Stage-3 Ny source into JSON v0 accepted by the existing MIR/VM/LLVM lines.
- Keep Core (`src/`) untouched; all implementation resides under `lang/src/compiler/`(旧 `apps/selfhost-compiler/` は互換ライン)。
- Fail fast: unsupported syntax must abort with a precise diagnostic, never fall back to Rust-side parser.
## Scope (Day 12)
- Expressions: integer literal, boolean literal, null, binary ops (`+ - * / %`, comparisons `== != < <= > >=`), logical `&& ||`, grouped `(...)`.
- Statements: `return`, `local`, `assignment`, `if/else`, `loop` (while-style), `break`, `continue`.
- Calls: direct function call (`foo()`), method call sugar (`obj.method()`), builtin boxes (Array/Map/String minimal) deferred to Day 34.
- Metadata: `meta.usings` populated from `ParserBox.extract_usings` (already implemented).
- JSON normalization: `JsonProgramBox` fixes key orderと既定値を整備Local/Const/If/Loop/Return/Call、空配列は常に`[]`、null配列は[]に正規化)。
## Interfaces
| box | responsibility |
| --- | --- |
| `ParserBox` | Tokenize/parse Ny source into Stage-1 AST JSON. Already handles Stage-2 constructs; ensure Stage-3 gating by `stage3_enable`. |
| `EmitterBox` | Convert Stage-1 AST JSON to JSON v0 Program. Delegates normalization/meta injection to `JsonProgramBox`. Must guarantee single-line output when `NYASH_JSON_ONLY=1`. |
| `MirEmitterBox` | Out of scope for Day 12 (stub remains). |
### Contracts
- `ParserBox.parse_program2(src)` returns a `Program` JSON string with `version/kind/body/meta` keys.
- `EmitterBox.emit_program(ast_json, usings_json)` injects metadata and *must* avoid altering the AST when `ast_json` already conforms to JSON v0.
- `Main.main(args)` (`lang/src/compiler/entry/compiler.hako`) orchestrates: read source → parse → emit → print.
## Deliverables
1. **Documentation**
- This file (living roadmap).
- Update `CURRENT_TASK_SELFHOST.md` with checklists and timeline (done).
- README snippet explaining how to run the front MVP via `hakorune` flags.
2. **Code**
- Extend `ParserBox` where gaps exist (Stage-3 gating, diagnostics).
- Add `lang/src/compiler/stage1/json_program_box.hako` — normalization box for Program/Stmt/Expr + `meta.usings` injection.
- Keep `EmitterBox` thin by delegating to `JsonProgramBox`.
3. **Tests**
- Quick smokes: `tools/smokes/v2/profiles/quick/selfhost/selfhost_min_const_ret_vm.sh` など。
- Normalization shape: `tools/smokes/v2/profiles/quick/selfhost/selfhost_json_normalize_shapes.sh`If/Loop/Call/Return, meta.usings 確認)。
- Edge normalization: `tools/smokes/v2/profiles/quick/selfhost/selfhost_json_normalize_edges.sh`Loop body null→[]、Call args null→[]、Null ノード維持)。
- Harness comparator: `tools/smokes/v2/run.sh --profile quick``selfhost_front_min_vm_llvm.sh`LLVM 環境があれば)
## Fail-Fast Checklist
- Parser errors include position info (gpos) and stop compilation.
- Unsupported statements/expressions raise `StageUnsupported` error (box-based), not silent drop.
- JSON builder ensures key order (`version`, `kind`, `body`, `meta`) for deterministic output.
## Box Layout Proposal (migrated)
```
lang/src/compiler/
├── parser/ # Stage-1/2/3 parser boxes
│ ├── parser_box.hako
│ ├── parser_expr_box.hako
│ └── parser_stmt_box.hako
├── emitter/ # emit helpers and normalization
│ ├── emitter_box.hako
│ └── json_program_box.hako
├── entry/
│ └── compiler.hako # entry (Ny→JSON v0)
└── docs/
└── front_mvp.md # this file
```
## Execution Examples
Emit-only (JSON header, pipeline v2):
```
NYASH_USE_NY_COMPILER=1 \
NYASH_NY_COMPILER_MIN_JSON=1 \
NYASH_NY_COMPILER_CHILD_ARGS="--pipeline-v2" \
NYASH_NY_COMPILER_EMIT_ONLY=1 \
NYASH_JSON_ONLY=1 \
./target/release/hakorune --backend vm apps/tests/selfhost_min/const_ret.hako
```
Expected output: `{"version":0,...}` single-line JSON.
Execute via VM (Result comparison):
```
NYASH_USE_NY_COMPILER=1 \
NYASH_NY_COMPILER_EMIT_ONLY=0 \
NYASH_SELFHOST_READ_TMP=1 \
./target/release/hakorune --backend vm apps/tests/selfhost_min/const_ret.hako
```
Expected output: `Result: 42`
## Timeline (rolling)
- **Day 1**: Docs + const/return + binop. Add selfhost_min_const_ret smoke.
- **Day 2**: if/else, loop sum smoke, branch diagnostics.
- **Day 3**: Calls/BoxCall minimal, DP integration reuse.
- **Day 4**: externcall string primitives, verify via `run_llvm_extended.sh`.
- **Day 5**: CLI polish + docs cleanup + bench harness alignment.
## Open Questions
- Should Stage-3 acceptance (`break`, `continue`, `throw`) be gated by CLI flag? (Currently via `--stage3`.)
- JSON v0 normalization: do we normalize binary op names (`+``Add`) or keep literal symbols? (Existing Stage-1 uses symbols; MIR builder already maps them.)
- How much of `ParserBox` should move into dedicated modules for maintainability? (Deferred; focus on MVP shipping.)