feat(std/xml): XML tree, reader and writer (step 1 of #78) #431

Merged
argus merged 3 commits from loop/429-std-xml into main 2026-10-23 14:51:35 +00:00
Collaborator

Closes #429

Task

Step 1 of #78: std/xml with a tree, a reader and a writer, as specified in #429.

What

  • New package std/xml: Xml (parse, write, indent), the tree XmlNode / XmlName / XmlAttribute / XmlDeclaration, and XmlError with line and column. XML 1.0 (fifth edition) with Namespaces in XML 1.0; names are resolved while reading, namespace declarations stay attributes so the writer writes back what the document declared. parse(write(parse(text))) == parse(text).
  • Syntax errors name line and column: unclosed and mismatched tags, a second root, a duplicate attribute, an undeclared prefix, an illegal character, a bare &, -- in a comment, plus the namespace constraints (reserved prefixes, no prefix undeclaring, unique expanded attribute names).
  • DOCTYPE: without an internal subset it is kept as a Doctype node; with one it is an XmlError at the [. Nothing external is ever fetched or opened, and only the five predefined entities and character references are read (no entity expansion).
  • Docs: docs/standard-library/xml.md (with a trb check example parsing an S3 ListBucketResult), listed in the standard library index; skills/ regenerated. ENCODING.md slice 8 is marked in progress with two entries in section 16 (the tree, the DOCTYPE rule). The CONCEPT.md sentence that gave document formats their own traits is reconciled with ENCODING.md: no format gets a trait of its own.

Conformance cases

The W3C XML Conformance Test Suite is not vendored: James Clark's part allows only unmodified redistribution, Sun's is "All Rights Reserved" and IBM's grants no redistribution. So std/xml/tests holds hand-written cases per production of XML 1.0 and Namespaces in XML 1.0 (conformance-cases.trb: 82 well-formed and 195 not well-formed documents, each naming its production or constraint), with the reasoning in tests/NOTICE.md, plus xml.test.trb for the tree, names, entities, errors with positions, DOCTYPE, writing and the round trip.

Test

Locally, with a nightly torb (no bootstrap, no gates): torb check std/xml (no problems), torb format --check std/xml (clean), torb test std/xml/tests (331 passed, 0 failed), torb doc --check --no-run std/xml (no problems), torb docs declarations docs, torb docs index docs --check and torb docs skill docs skills --check (all up to date). torb docs check docs reports only three problems that do not come from this change: no C compiler for the trb run blocks here, and two std/cli snippets the nightly cannot infer. Gates run in forge CI (tier A).

seed/ is not touched; the compiler does not import std/xml.

Closes #429 ## Task Step 1 of #78: `std/xml` with a tree, a reader and a writer, as specified in #429. ## What - New package `std/xml`: `Xml` (`parse`, `write`, `indent`), the tree `XmlNode` / `XmlName` / `XmlAttribute` / `XmlDeclaration`, and `XmlError` with line and column. XML 1.0 (fifth edition) with Namespaces in XML 1.0; names are resolved while reading, namespace declarations stay attributes so the writer writes back what the document declared. `parse(write(parse(text))) == parse(text)`. - Syntax errors name line and column: unclosed and mismatched tags, a second root, a duplicate attribute, an undeclared prefix, an illegal character, a bare `&`, `--` in a comment, plus the namespace constraints (reserved prefixes, no prefix undeclaring, unique expanded attribute names). - DOCTYPE: without an internal subset it is kept as a `Doctype` node; with one it is an `XmlError` at the `[`. Nothing external is ever fetched or opened, and only the five predefined entities and character references are read (no entity expansion). - Docs: `docs/standard-library/xml.md` (with a `trb check` example parsing an S3 `ListBucketResult`), listed in the standard library index; `skills/` regenerated. ENCODING.md slice 8 is marked in progress with two entries in section 16 (the tree, the DOCTYPE rule). The CONCEPT.md sentence that gave document formats their own traits is reconciled with ENCODING.md: no format gets a trait of its own. ## Conformance cases The W3C XML Conformance Test Suite is **not vendored**: James Clark's part allows only unmodified redistribution, Sun's is "All Rights Reserved" and IBM's grants no redistribution. So `std/xml/tests` holds hand-written cases per production of XML 1.0 and Namespaces in XML 1.0 (`conformance-cases.trb`: 82 well-formed and 195 not well-formed documents, each naming its production or constraint), with the reasoning in `tests/NOTICE.md`, plus `xml.test.trb` for the tree, names, entities, errors with positions, DOCTYPE, writing and the round trip. ## Test Locally, with a nightly `torb` (no bootstrap, no gates): `torb check std/xml` (no problems), `torb format --check std/xml` (clean), `torb test std/xml/tests` (331 passed, 0 failed), `torb doc --check --no-run std/xml` (no problems), `torb docs declarations docs`, `torb docs index docs --check` and `torb docs skill docs skills --check` (all up to date). `torb docs check docs` reports only three problems that do not come from this change: no C compiler for the `trb run` blocks here, and two `std/cli` snippets the nightly cannot infer. Gates run in forge CI (tier A). `seed/` is not touched; the compiler does not import `std/xml`.
Xml reads XML 1.0 (fifth edition) with namespaces into an XmlNode tree and writes it back; parse(write(parse(text))) equals parse(text). Syntax errors are an XmlError with line and column. A DOCTYPE without an internal subset is kept, one with a subset is refused, and nothing external is ever opened. Hand-written conformance cases per production stand in for the W3C suite, whose licences do not allow vendoring (tests/NOTICE.md).

Refs #429
docs(std/xml): add the std/xml page, mark ENCODING slice 8 in progress
Some checks failed
ci / commit messages (pull_request) Successful in 3s
ci / what the change touches (pull_request) Successful in 3s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Failing after 1m2s
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / gates (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tier B (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been cancelled
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / bootstrap (linux-x64) (pull_request) Has been cancelled
0f769a6f29
Reconciles the CONCEPT sentence on document formats with ENCODING: no format gets a trait of its own. Regenerates skills/.

Refs #429
docs(std/xml): register the notice and restamp CONCEPT for pdisc
All checks were successful
ci / commit messages (pull_request) Successful in 3s
ci / what the change touches (pull_request) Successful in 3s
ci / the VS Code extension (editors/vscode) (pull_request) Has been skipped
pdisc / pdisc (pull_request) Successful in 9s
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap (linux-x64) (pull_request) Successful in 2m9s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / tier A (linux-x64) (pull_request) Successful in 4m39s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m15s
ci / every host emits the same C (pull_request) Successful in 4m49s
ci / tier B (linux-x64) (pull_request) Successful in 12m40s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m53s
ci / gates (pull_request) Successful in 0s
f8aa89e765
Refs #429
argus approved these changes 2026-10-23 14:51:34 +00:00
argus left a comment

Checklist for f8aa89e (CI combined status success: tier A, tier B, gates, pdisc, bootstrap):

  • Tests: ok. 331 cases (82 well-formed, 195 not well-formed, each naming its production or constraint, plus tree/names/entities/errors/DOCTYPE/writing/round-trip tests) run in tier A.
  • Correctness: ok. Read parser, scanner, writer, node: line-break and attribute-value normalisation, character references (overflow guarded, Char production checked), namespace constraints (reserved prefixes, no undeclaring, unique expanded attribute names), depth limit, internal-subset DOCTYPE refused, no entity expansion; the writer refuses what the reader would refuse and declares missing namespaces.
  • Scope = task: ok. Matches every acceptance point of #429, including the CONCEPT.md/ENCODING.md reconciliation; seed/ untouched. Hand-written cases instead of the W3C suite is the fallback #429 names, and NOTICE.md records the licence reasoning.
  • Security: ok. No external fetch or open, no entity expansion, no secrets, no new dependencies.
  • Data / Release: n/a (new package, no stored format, no post-merge steps).
  • Docs: ok. docs/standard-library/xml.md, index entries, regenerated skills/, ENCODING.md slice 8; pdisc check green.

Non-blocking:

  • Xml.write: if a hand-built element carries an xmlns:p attribute and one of its names needs a different binding for p, declare adds a second xmlns:p and the output has a duplicate attribute (the seen check covers only the attributes, not the added declarations). Trees made by parse cannot hit this.
Checklist for f8aa89e (CI combined status success: tier A, tier B, gates, pdisc, bootstrap): - Tests: ok. 331 cases (82 well-formed, 195 not well-formed, each naming its production or constraint, plus tree/names/entities/errors/DOCTYPE/writing/round-trip tests) run in tier A. - Correctness: ok. Read parser, scanner, writer, node: line-break and attribute-value normalisation, character references (overflow guarded, `Char` production checked), namespace constraints (reserved prefixes, no undeclaring, unique expanded attribute names), depth limit, internal-subset DOCTYPE refused, no entity expansion; the writer refuses what the reader would refuse and declares missing namespaces. - Scope = task: ok. Matches every acceptance point of #429, including the CONCEPT.md/ENCODING.md reconciliation; `seed/` untouched. Hand-written cases instead of the W3C suite is the fallback #429 names, and NOTICE.md records the licence reasoning. - Security: ok. No external fetch or open, no entity expansion, no secrets, no new dependencies. - Data / Release: n/a (new package, no stored format, no post-merge steps). - Docs: ok. `docs/standard-library/xml.md`, index entries, regenerated `skills/`, ENCODING.md slice 8; pdisc check green. Non-blocking: - `Xml.write`: if a hand-built element carries an `xmlns:p` attribute and one of its names needs a *different* binding for `p`, `declare` adds a second `xmlns:p` and the output has a duplicate attribute (the `seen` check covers only the attributes, not the added declarations). Trees made by `parse` cannot hit this.
argus merged commit 21c16c3c99 into main 2026-10-23 14:51:35 +00:00
argus deleted branch loop/429-std-xml 2026-10-23 14:51:35 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!431
No description provided.