70 lines
4.1 KiB
Markdown
70 lines
4.1 KiB
Markdown
# Developing Decodal
|
|
|
|
Development notes live here rather than in the public manual. The manual describes released language behavior and public integration APIs; implementation plans and unresolved design work belong in issues or pull requests.
|
|
|
|
## Repository map
|
|
|
|
- `crates/decodal-core`: parser, evaluator, public Rust API, and tests.
|
|
- `crates/decodal-derive`: `Decodal` derive macros.
|
|
- `crates/decodal-language-service`: host-configurable semantic analysis and completion.
|
|
- `crates/decodal-language-tools`: source-preserving formatter and tooling.
|
|
- `crates/decodal-lsp`: LSP transport and document synchronization.
|
|
- `crates/decodal-wasm`: WebAssembly bindings.
|
|
- `packages/decodal-wasm`: generated npm and JSR runtime package.
|
|
- `packages/decodal-codemirror`: CodeMirror language support and formatter WebAssembly.
|
|
- `editors/lezer-decodal` and `editors/tree-sitter-decodal`: downstream editor grammars.
|
|
- `site/decodal-site`: documentation site and playground.
|
|
- `doc/manual/source`: English public manual consumed by the site.
|
|
- `doc/manual/source/jp`: Japanese translation of the public manual.
|
|
|
|
## Runtime architecture
|
|
|
|
The host owns I/O. `ImportLoader` turns an import specifier into DCDL source or a structured `Value`, and `HostEnvironment` installs the same loader and globals for production and editor tooling.
|
|
|
|
Evaluation proceeds through parse, lazy expression evaluation, and materialization. Object fields, module roots, imports, arguments, and defaults are represented by memoized thunks. A thunk re-entered while it is being evaluated produces a cycle diagnostic.
|
|
|
|
Runtime values distinguish concrete values from abstract ranges. Composition and `as` preserve that distinction; materialization selects defaults and rejects unresolved ranges or functions. `Data` is the output-only representation.
|
|
|
|
Diagnostics retain Decodal source spans. Structured host values use their stable import key and logical value path rather than synthetic source spans.
|
|
|
|
## Checks
|
|
|
|
Run the release validation commands documented in [`RELEASING.md`](../../RELEASING.md). For a focused change, run the tests for the affected crate or package first, then the full workspace and site checks before release.
|
|
|
|
The documentation site can be checked without regenerating committed WebAssembly artifacts:
|
|
|
|
```sh
|
|
npm --prefix site/decodal-site test
|
|
npm --prefix site/decodal-site run build
|
|
```
|
|
|
|
Use `npm --prefix site/decodal-site run build:wasm` when Rust bindings or formatter behavior changed.
|
|
|
|
## Documentation site delivery
|
|
|
|
The canonical site origin is `https://decodal.hareworks.net`, configured through Astro's `site` option. A normal site build generates the sitemap, robots policy, social metadata, structured data, 404 page, and source-backed Markdown endpoints. `/llms.txt` indexes the individual English and Japanese Markdown pages; `/llms-full.txt` and `/ja/llms-full.txt` provide complete manuals. These resources are built directly from `doc/manual/source` and do not use Cloudflare's HTML-to-Markdown conversion.
|
|
|
|
Deploy the already prepared site with:
|
|
|
|
```sh
|
|
npm --prefix site/decodal-site run deploy
|
|
```
|
|
|
|
Cloudflare Pages `_redirects` handles legacy paths within the site, but not hostname redirects. In the Cloudflare account, configure a Bulk Redirect from `https://decodal-site.pages.dev/` to `https://decodal.hareworks.net/` with status `301`, subpath matching, path-suffix preservation, and query-string preservation enabled. This prevents the Pages project hostname from becoming a second public origin.
|
|
|
|
## Syntax changes
|
|
|
|
When syntax changes:
|
|
|
|
1. Update the public EBNF in `doc/manual/source/language/grammar.md` and the relevant language page.
|
|
2. Update the Rust lexer/parser and tests.
|
|
3. Update the Lezer and Tree-sitter grammars and regenerate their committed outputs.
|
|
4. Update formatter, playground, and language-service tests as applicable.
|
|
5. Run the validation commands in `RELEASING.md`.
|
|
|
|
The Rust parser is authoritative for evaluation. Lezer and Tree-sitter are downstream editor integrations and are not runtime or formatter dependencies.
|
|
|
|
## Releases
|
|
|
|
Package versions, validation commands, publish order, and registry commands are maintained only in [`RELEASING.md`](../../RELEASING.md).
|