Release 1.0.0-beta.21 JSON document scalar parsing foundation

This commit is contained in:
sanjin 2026-05-23 01:40:34 +02:00
parent c1231fdb5f
commit 87e627045e
23 changed files with 1063 additions and 73 deletions

View File

@ -0,0 +1,72 @@
# 1.0.0-beta.21 JSON Document Scalar Parsing Foundation
## Scope
`1.0.0-beta.21` is a standard-library and compiler-gate slice. It adds
source-authored `std.json` helpers for scalar JSON documents while keeping
source-language syntax, runtime C, compiler-known runtime names, and ABI/layout
policy unchanged.
The release adds:
- `parse_string_document_result ((document string)) -> (result string i32)`
- `parse_bool_document_result ((document string)) -> (result bool i32)`
- `parse_i32_document_result ((document string)) -> (result i32 i32)`
- `parse_u32_document_result ((document string)) -> (result u32 i32)`
- `parse_i64_document_result ((document string)) -> (result i64 i32)`
- `parse_u64_document_result ((document string)) -> (result u64 i32)`
- `parse_f64_document_result ((document string)) -> (result f64 i32)`
- `parse_null_document_result ((document string)) -> (result bool i32)`
## Contract
Each helper trims ASCII whitespace around the whole input document with
`std.string.trim_ascii`, then delegates to the already released exact
value-token parser for that scalar family.
Leading and trailing ASCII whitespace around one scalar document is accepted.
Trailing non-whitespace remains an ordinary parse failure and returns `err 1`
through the underlying exact parser.
## Non-Scope
This scope does not add:
- compiler-known `std.json.*_document_result` runtime names
- private `__glagol_json_*document*` runtime symbols
- runtime C helper implementations
- source-language syntax
- object or array parsing
- recursive `JsonValue`
- tokenizer/parser objects
- maps, sets, executable generics, or generic collections
- streaming parsers or encoders
- Unicode escape decoding beyond the existing string-token helper
- embedded NUL policy
- stable JSON APIs
- stable ABI/layout
- stable standard-library compatibility
- performance claims
## Acceptance Criteria
- `lib/std/json.slo` exports all eight document scalar helpers.
- Explicit `std.json` import examples exercise trimmed whitespace success,
no-whitespace success, and trailing non-whitespace failure.
- Local `std-layout-local-json` examples mirror the public helper surface with
an explicit local `string` dependency for `trim_ascii`.
- Focused compiler coverage verifies the helpers are source-authored and that
direct compiler-known runtime calls for the new names remain unsupported.
- `scripts/release-gate.sh` runs the focused beta21 test.
- Generated standard-library API documentation includes the new signatures.
## Gates
```bash
cargo fmt --check
cargo test --test standard_json_document_scalar_parsing_beta21
cargo test --test standard_json_source_facade_alpha
cargo test --test promotion_gate
cargo test
./scripts/release-gate.sh
```

View File

@ -0,0 +1,25 @@
# 1.0.0-beta.21 Glagol Implementation Notes
Scope: JSON Document Scalar Parsing Foundation.
This Glagol-side slice prepares compiler/test/release-gate coverage for the
source-authored `std.json` document scalar helpers:
- `parse_string_document_result`
- `parse_bool_document_result`
- `parse_i32_document_result`
- `parse_u32_document_result`
- `parse_i64_document_result`
- `parse_u64_document_result`
- `parse_f64_document_result`
- `parse_null_document_result`
The focused beta21 test uses an explicit `std.json` import, checks/formats/tests
the imported helpers, requires the helpers to exist in `lib/std/json.slo`, and
asserts that no `std.json.parse_*_document_result` compiler-known calls or
private `__glagol_json_*document*` runtime symbols are introduced.
The JSON source-facade and promotion-gate inventories are updated to match the
Slovo-side source/export/example work, which adds three JSON document scalar
fixture tests and raises local and explicit `std.json` fixture output from 9 to
12 tests.

View File

@ -0,0 +1,52 @@
# 1.0.0-beta.21 Release Review
Scope: JSON Document Scalar Parsing Foundation.
## Findings
No blocking findings.
The uncommitted beta21 candidate matches the release contract:
- `lib/std/json.slo` exports all eight source-authored
`parse_*_document_result` helpers.
- Each document helper trims the whole input with `trim_ascii`, then delegates
to the existing exact scalar value-token parser for the matching family.
- Direct compiler-known `std.json.parse_*_document_result` calls are not
introduced, and no private `__glagol_json_*document*` runtime symbol is
introduced.
- The explicit `std.json` example imports repo-root `std.json` and covers
trimmed success, plain success, trailing non-whitespace failure, scalar
token parsing, fields, arrays, objects, and 12 tests.
- The local JSON example imports local `json`, the local `json` fixture imports
local `string (trim_ascii)`, and it mirrors the same 12-test coverage.
- Compiler coverage includes the focused beta21 test, JSON facade inventory,
promotion-gate alignment, release-gate wiring, package version bump, and the
generated standard-library API catalog signatures.
- Release docs describe `1.0.0-beta.21` as released, and the source/docs scan
did not find local/private publication text.
## Verification
Commands run:
```bash
git diff --check
git diff --cached --check
bash -n scripts/release-gate.sh
cargo fmt --check --manifest-path compiler/Cargo.toml
cargo test --test standard_json_document_scalar_parsing_beta21
cargo test --test standard_json_source_facade_alpha
cargo test --test promotion_gate -- promotion_gate_artifacts_are_aligned
```
Results:
- `standard_json_document_scalar_parsing_beta21`: 2 passed.
- `standard_json_source_facade_alpha`: 2 passed.
- `promotion_gate_artifacts_are_aligned`: 1 passed.
- Formatting, shell syntax, and diff whitespace checks passed.
- Targeted stale-release/private-text scans over source/docs paths passed.
Not run by design for this review: full `cargo test`, ignored smoke tests, and
the full release gate.

View File

@ -6,7 +6,7 @@ This repository is the canonical public monorepo for the language design,
standard library source, compiler, runtime, examples, benchmarks, and technical standard library source, compiler, runtime, examples, benchmarks, and technical
documents. documents.
Current release: `1.0.0-beta.20`. Current release: `1.0.0-beta.21`.
## Repository Layout ## Repository Layout
@ -24,7 +24,7 @@ scripts/ local release and document tooling
## Beta Scope ## Beta Scope
`1.0.0-beta.20` keeps the `1.0.0-beta` language baseline, includes the `1.0.0-beta.21` keeps the `1.0.0-beta` language baseline, includes the
`1.0.0-beta.1` tooling/install hardening slice, the `1.0.0-beta.2` `1.0.0-beta.1` tooling/install hardening slice, the `1.0.0-beta.2`
runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library
stabilization bundle, the `1.0.0-beta.4` language-usability diagnostics stabilization bundle, the `1.0.0-beta.4` language-usability diagnostics
@ -41,8 +41,9 @@ slice, the `1.0.0-beta.13` diagnostic catalog and schema policy slice, the
ledger, the `1.0.0-beta.16` string scanning and token boundary foundation, ledger, the `1.0.0-beta.16` string scanning and token boundary foundation,
the `1.0.0-beta.17` JSON primitive scalar parsing foundation, the the `1.0.0-beta.17` JSON primitive scalar parsing foundation, the
`1.0.0-beta.18` JSON string token parsing foundation, the `1.0.0-beta.18` JSON string token parsing foundation, the
`1.0.0-beta.19` test discovery and user-project conformance foundation, and `1.0.0-beta.19` test discovery and user-project conformance foundation, the
the `1.0.0-beta.20` string search and ASCII trim foundation. `1.0.0-beta.20` string search and ASCII trim foundation, and the
`1.0.0-beta.21` JSON document scalar parsing foundation.
The language baseline supports practical local command-line, file, and The language baseline supports practical local command-line, file, and
loopback-network programs with: loopback-network programs with:
@ -57,7 +58,8 @@ loopback-network programs with:
`SLOVO_STD_PATH` `SLOVO_STD_PATH`
- beta-scoped loopback TCP handles through `std.net` - beta-scoped loopback TCP handles through `std.net`
- JSON string quoting, compact JSON text construction, primitive scalar token - JSON string quoting, compact JSON text construction, primitive scalar token
parsing, and ASCII JSON string-token parsing through `std.json` parsing, ASCII JSON string-token parsing, and scalar JSON document parsing
through `std.json`
- byte-oriented string search and ASCII edge trimming through `std.string` - byte-oriented string search and ASCII edge trimming through `std.string`
- hosted native builds through LLVM IR, Clang, and `runtime/runtime.c` - hosted native builds through LLVM IR, Clang, and `runtime/runtime.c`
@ -121,18 +123,19 @@ concrete numeric primitives, and exact `null` only. Numeric and boolean parse
helpers consume one isolated JSON primitive token: no leading/trailing helpers consume one isolated JSON primitive token: no leading/trailing
whitespace, no leading `+`, no leading-zero integer form except `0`, and no whitespace, no leading `+`, no leading-zero integer form except `0`, and no
non-finite f64 values. This is not full JSON parsing: object/array parsing, non-finite f64 values. This is not full JSON parsing: object/array parsing,
tokenizers, recursive `JsonValue`, whitespace-tolerant document parsing, tokenizers, recursive `JsonValue`, document parsing beyond the beta21 scalar
schema validation, streaming, Unicode escape handling, stable ABI/layout, and document helpers, schema validation, streaming, Unicode escape handling,
a stable stdlib/API freeze remain deferred. stable ABI/layout, and a stable stdlib/API freeze remain deferred.
The `1.0.0-beta.18` JSON string token parsing foundation adds The `1.0.0-beta.18` JSON string token parsing foundation adds
`std.json.parse_string_value_result` as a thin source facade over the matching `std.json.parse_string_value_result` as a thin source facade over the matching
promoted runtime name. It consumes one already-isolated ASCII JSON string token promoted runtime name. It consumes one already-isolated ASCII JSON string token
with exact quotes and no leading/trailing whitespace, decodes the simple JSON with exact quotes and no leading/trailing whitespace, decodes the simple JSON
escapes `\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, and `\t`, and returns escapes `\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, and `\t`, and returns
`err 1` for ordinary parse failure. Full JSON document parsing, object/array `err 1` for ordinary parse failure. Complete JSON document parsing beyond the
parsing, tokenizer APIs, Unicode escape decoding/normalization, embedded NUL beta21 scalar document helpers, object/array parsing, tokenizer APIs, Unicode
policy, stable ABI/layout, and a stable stdlib/API freeze remain deferred. escape decoding/normalization, embedded NUL policy, stable ABI/layout, and a
stable stdlib/API freeze remain deferred.
The `1.0.0-beta.19` test discovery and user-project conformance foundation The `1.0.0-beta.19` test discovery and user-project conformance foundation
adds `glagol test --list <file|project|workspace>` plus legacy adds `glagol test --list <file|project|workspace>` plus legacy
@ -149,6 +152,17 @@ helpers over the existing byte string primitives. Search is byte-oriented,
empty needles match at the first index and at `(len value)` for last search, empty needles match at the first index and at `(len value)` for last search,
and ASCII trimming removes only bytes `9`, `10`, `11`, `12`, `13`, and `32`. and ASCII trimming removes only bytes `9`, `10`, `11`, `12`, `13`, and `32`.
The `1.0.0-beta.21` JSON document scalar parsing foundation adds
source-authored `std.json.parse_*_document_result` helpers for string, bool,
`i32`, `u32`, `i64`, `u64`, `f64`, and exact `null` scalar JSON documents.
Each helper trims ASCII whitespace around the whole document with
`std.string.trim_ascii`, then delegates to the already released exact JSON
value-token parser for that scalar family. This scope does not add new
compiler-known runtime names, object/array parsing, recursive `JsonValue`,
tokenizer objects, maps/sets, streaming, Unicode escape decoding beyond the
existing string-token behavior, embedded NUL policy, stable ABI/layout, or a
stable stdlib/API freeze.
Still deferred before stable: executable generics, generic aliases, maps/sets, Still deferred before stable: executable generics, generic aliases, maps/sets,
broad package registry semantics, stable Markdown schema, stable stdlib/API broad package registry semantics, stable Markdown schema, stable stdlib/API
compatibility freeze, DNS/TLS/async networking, LSP/watch guarantees, SARIF compatibility freeze, DNS/TLS/async networking, LSP/watch guarantees, SARIF
@ -435,6 +449,24 @@ This scope adds no compiler-known runtime names. It does not claim Unicode
scalar, grapheme, case-folding, locale, regex, tokenizer, mutable string, scalar, grapheme, case-folding, locale, regex, tokenizer, mutable string,
language slice/view, stable ABI/layout, or stable stdlib/API semantics. language slice/view, stable ABI/layout, or stable stdlib/API semantics.
## 1.0.0-beta.21 JSON Document Scalar Parsing Foundation
The `1.0.0-beta.21` scope extends `std.json` with source-authored
whole-document scalar helpers:
`parse_string_document_result`, `parse_bool_document_result`,
`parse_i32_document_result`, `parse_u32_document_result`,
`parse_i64_document_result`, `parse_u64_document_result`,
`parse_f64_document_result`, and `parse_null_document_result`.
The helpers accept leading and trailing ASCII whitespace around a single
scalar document by composing with `std.string.trim_ascii`; trailing
non-whitespace still fails through the existing exact value-token parsers.
This scope does not add object/array parsing, recursive JSON values, parser
objects, maps/sets, streaming, Unicode escape decoding beyond the existing
string-token behavior, embedded NUL policy, new compiler-known runtime names,
stable ABI/layout, or stable stdlib/API semantics.
## 1.0.0-beta.15 Reserved Generic Collection Boundary Hardening And Collection Ledger ## 1.0.0-beta.15 Reserved Generic Collection Boundary Hardening And Collection Ledger
The `1.0.0-beta.15` release documents the current concrete collection and The `1.0.0-beta.15` release documents the current concrete collection and

2
compiler/Cargo.lock generated
View File

@ -4,4 +4,4 @@ version = 3
[[package]] [[package]]
name = "glagol" name = "glagol"
version = "1.0.0-beta.20" version = "1.0.0-beta.21"

View File

@ -1,6 +1,6 @@
[package] [package]
name = "glagol" name = "glagol"
version = "1.0.0-beta.20" version = "1.0.0-beta.21"
edition = "2021" edition = "2021"
description = "Glagol, the first compiler for the Slovo language" description = "Glagol, the first compiler for the Slovo language"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"

View File

@ -1229,6 +1229,14 @@ const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[
"parse_u64_value_result", "parse_u64_value_result",
"parse_f64_value_result", "parse_f64_value_result",
"parse_null_value_result", "parse_null_value_result",
"parse_string_document_result",
"parse_bool_document_result",
"parse_i32_document_result",
"parse_u32_document_result",
"parse_i64_document_result",
"parse_u64_document_result",
"parse_f64_document_result",
"parse_null_document_result",
"field_string", "field_string",
"field_bool", "field_bool",
"field_i32", "field_i32",
@ -1265,6 +1273,7 @@ const STANDARD_JSON_RUNTIME_NAMES: &[&str] = &[
]; ];
const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[
"(import std.string (trim_ascii))",
"std.json.quote_string", "std.json.quote_string",
"std.string.concat", "std.string.concat",
"std.num.i32_to_string", "std.num.i32_to_string",
@ -1281,6 +1290,17 @@ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[
"std.json.parse_f64_value_result", "std.json.parse_f64_value_result",
]; ];
const STANDARD_JSON_DOCUMENT_SCALAR_BETA21: &[&str] = &[
"parse_string_document_result",
"parse_bool_document_result",
"parse_i32_document_result",
"parse_u32_document_result",
"parse_i64_document_result",
"parse_u64_document_result",
"parse_f64_document_result",
"parse_null_document_result",
];
const STANDARD_PROCESS_SOURCE_FACADE_ALPHA: &[&str] = &[ const STANDARD_PROCESS_SOURCE_FACADE_ALPHA: &[&str] = &[
"argc", "argc",
"arg", "arg",
@ -4458,6 +4478,7 @@ fn assert_slovo_std_source_layout_alpha(repo: &Path, std_dir: &Path) {
); );
for source in [&slovo_json, &glagol_json] { for source in [&slovo_json, &glagol_json] {
assert_deferred_json_surface_absent(source, "standard json facade"); assert_deferred_json_surface_absent(source, "standard json facade");
assert_json_document_scalar_helpers_are_source_authored(source, "standard json facade");
} }
for helper in STANDARD_JSON_SOURCE_FACADE_ALPHA { for helper in STANDARD_JSON_SOURCE_FACADE_ALPHA {
assert!( assert!(
@ -7316,10 +7337,13 @@ fn assert_project_std_import_json_tooling_matches_fixture(project: &Path) {
"test \"explicit std json primitive scalar parse failure facade\" ... ok\n", "test \"explicit std json primitive scalar parse failure facade\" ... ok\n",
"test \"explicit std json string token parse success facade\" ... ok\n", "test \"explicit std json string token parse success facade\" ... ok\n",
"test \"explicit std json string token parse failure facade\" ... ok\n", "test \"explicit std json string token parse failure facade\" ... ok\n",
"test \"explicit std json document parse trimmed success facade\" ... ok\n",
"test \"explicit std json document parse plain success facade\" ... ok\n",
"test \"explicit std json document parse trailing failure facade\" ... ok\n",
"test \"explicit std json fields facade\" ... ok\n", "test \"explicit std json fields facade\" ... ok\n",
"test \"explicit std json arrays objects facade\" ... ok\n", "test \"explicit std json arrays objects facade\" ... ok\n",
"test \"explicit std json facade all\" ... ok\n", "test \"explicit std json facade all\" ... ok\n",
"9 test(s) passed\n", "12 test(s) passed\n",
), ),
); );
} }
@ -9527,10 +9551,13 @@ fn assert_project_std_layout_local_json_tooling_matches_fixture(project: &Path)
"test \"explicit local json primitive scalar parse failure facade\" ... ok\n", "test \"explicit local json primitive scalar parse failure facade\" ... ok\n",
"test \"explicit local json string token parse success facade\" ... ok\n", "test \"explicit local json string token parse success facade\" ... ok\n",
"test \"explicit local json string token parse failure facade\" ... ok\n", "test \"explicit local json string token parse failure facade\" ... ok\n",
"test \"explicit local json document parse trimmed success facade\" ... ok\n",
"test \"explicit local json document parse plain success facade\" ... ok\n",
"test \"explicit local json document parse trailing failure facade\" ... ok\n",
"test \"explicit local json fields facade\" ... ok\n", "test \"explicit local json fields facade\" ... ok\n",
"test \"explicit local json arrays objects facade\" ... ok\n", "test \"explicit local json arrays objects facade\" ... ok\n",
"test \"explicit local json facade all\" ... ok\n", "test \"explicit local json facade all\" ... ok\n",
"9 test(s) passed\n", "12 test(s) passed\n",
), ),
"std layout local json project test", "std layout local json project test",
); );
@ -10724,6 +10751,34 @@ fn assert_deferred_json_surface_absent(source: &str, context: &str) {
} }
} }
fn assert_json_document_scalar_helpers_are_source_authored(source: &str, context: &str) {
for helper in STANDARD_JSON_DOCUMENT_SCALAR_BETA21 {
assert!(
!source.contains(&format!("std.json.{}", helper)),
"{} must keep `{}` source-authored, not compiler-known",
context,
helper
);
}
for private_prefix in [
"__glagol_json_parse_string_document",
"__glagol_json_parse_bool_document",
"__glagol_json_parse_i32_document",
"__glagol_json_parse_u32_document",
"__glagol_json_parse_i64_document",
"__glagol_json_parse_u64_document",
"__glagol_json_parse_f64_document",
"__glagol_json_parse_null_document",
] {
assert!(
!source.contains(private_prefix),
"{} must not introduce private JSON document runtime symbol `{}`",
context,
private_prefix
);
}
}
fn repo_root() -> PathBuf { fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")) Path::new(env!("CARGO_MANIFEST_DIR"))
.parent() .parent()

View File

@ -0,0 +1,313 @@
use std::{
env,
ffi::OsStr,
fs,
path::{Path, PathBuf},
process::{Command, Output},
sync::atomic::{AtomicUsize, Ordering},
};
static NEXT_TEMP_ID: AtomicUsize = AtomicUsize::new(0);
const EXPECTED_TEST_OUTPUT: &str = concat!(
"test \"explicit std json document scalar string\" ... ok\n",
"test \"explicit std json document scalar bool\" ... ok\n",
"test \"explicit std json document scalar integer\" ... ok\n",
"test \"explicit std json document scalar float null\" ... ok\n",
"test \"explicit std json document scalar failures\" ... ok\n",
"test \"explicit std json document scalar all\" ... ok\n",
"6 test(s) passed\n",
);
const STANDARD_JSON_DOCUMENT_SCALAR_BETA21: &[&str] = &[
"parse_string_document_result",
"parse_bool_document_result",
"parse_i32_document_result",
"parse_u32_document_result",
"parse_i64_document_result",
"parse_u64_document_result",
"parse_f64_document_result",
"parse_null_document_result",
];
#[test]
fn explicit_std_json_document_scalar_helpers_check_and_test() {
let project = write_project(
"std-json-document-scalar-beta21",
r#"
(module main)
(import std.json (parse_string_document_result parse_bool_document_result parse_i32_document_result parse_u32_document_result parse_i64_document_result parse_u64_document_result parse_f64_document_result parse_null_document_result))
(fn imported_json_document_string_ok () -> bool
(if (= (std.result.unwrap_ok (parse_string_document_result " \"slovo\" ")) "slovo")
(= (std.result.unwrap_ok (parse_string_document_result "\n\t\"slo\\\"vo\"\t")) "slo\"vo")
false))
(fn imported_json_document_bool_ok () -> bool
(if (std.result.unwrap_ok (parse_bool_document_result " true "))
(= (std.result.unwrap_ok (parse_bool_document_result "\nfalse\t")) false)
false))
(fn imported_json_document_integer_ok () -> bool
(if (= (std.result.unwrap_ok (parse_i32_document_result " -7 ")) -7)
(if (= (std.result.unwrap_ok (parse_u32_document_result "\n7\t")) 7u32)
(if (= (std.result.unwrap_ok (parse_i64_document_result " -8 ")) -8i64)
(= (std.result.unwrap_ok (parse_u64_document_result "9 ")) 9u64)
false)
false)
false))
(fn imported_json_document_float_null_ok () -> bool
(if (= (std.result.unwrap_ok (parse_f64_document_result " 1e2 ")) 100.0)
(std.result.unwrap_ok (parse_null_document_result "\nnull\t"))
false))
(fn imported_json_document_failures_ok () -> bool
(if (= (std.result.unwrap_err (parse_string_document_result "\"slovo\" x")) 1)
(if (= (std.result.unwrap_err (parse_bool_document_result " TRUE ")) 1)
(if (= (std.result.unwrap_err (parse_i32_document_result " 01 ")) 1)
(if (= (std.result.unwrap_err (parse_u32_document_result " -1 ")) 1)
(if (= (std.result.unwrap_err (parse_i64_document_result " 8i64 ")) 1)
(if (= (std.result.unwrap_err (parse_u64_document_result " ")) 1)
(if (= (std.result.unwrap_err (parse_f64_document_result " 01.0 ")) 1)
(= (std.result.unwrap_err (parse_null_document_result " NULL ")) 1)
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_document_scalar_all_ok () -> bool
(if (imported_json_document_string_ok)
(if (imported_json_document_bool_ok)
(if (imported_json_document_integer_ok)
(if (imported_json_document_float_null_ok)
(imported_json_document_failures_ok)
false)
false)
false)
false))
(fn main () -> i32
(if (imported_json_document_scalar_all_ok)
42
1))
(test "explicit std json document scalar string"
(imported_json_document_string_ok))
(test "explicit std json document scalar bool"
(imported_json_document_bool_ok))
(test "explicit std json document scalar integer"
(imported_json_document_integer_ok))
(test "explicit std json document scalar float null"
(imported_json_document_float_null_ok))
(test "explicit std json document scalar failures"
(imported_json_document_failures_ok))
(test "explicit std json document scalar all"
(= (main) 42))
"#,
);
let source = read(&project.join("src/main.slo"));
let std_json = read(&std_json_path());
assert!(
!project.join("src/json.slo").exists(),
"beta21 fixture must exercise repo-root std.json, not a local module copy"
);
assert!(
source.starts_with("(module main)\n\n(import std.json ("),
"beta21 fixture must use an explicit std.json import"
);
assert_json_document_scalar_helpers_are_source_authored(&std_json);
let fmt = run_glagol([
OsStr::new("fmt"),
OsStr::new("--check"),
project.as_os_str(),
]);
assert_success("std json document scalar fmt --check", &fmt);
let check = run_glagol([OsStr::new("check"), project.as_os_str()]);
assert_success_stdout(check, "", "std json document scalar check");
let test = run_glagol([OsStr::new("test"), project.as_os_str()]);
assert_success_stdout(test, EXPECTED_TEST_OUTPUT, "std json document scalar test");
}
#[test]
fn json_document_scalar_helpers_are_not_compiler_known_runtime_calls() {
let std_json = read(&std_json_path());
assert_json_document_scalar_helpers_are_source_authored(&std_json);
for helper in STANDARD_JSON_DOCUMENT_SCALAR_BETA21 {
let fixture = write_fixture(
helper,
&format!(
"(module main)\n\n(fn main () -> i32\n (std.result.unwrap_err (std.json.{} \"invalid\")))\n",
helper
),
);
let output = run_glagol([fixture.as_os_str()]);
assert_failure_stderr_contains(
&format!("direct std.json.{} runtime call", helper),
&output,
&format!(
"standard library call `std.json.{}` is not supported",
helper
),
);
}
}
fn assert_json_document_scalar_helpers_are_source_authored(std_json: &str) {
assert!(
std_json.starts_with("(module json (export "),
"lib/std/json.slo must stay a source-authored module export"
);
for helper in STANDARD_JSON_DOCUMENT_SCALAR_BETA21 {
assert!(
std_json.contains(&format!("(fn {} ", helper)),
"lib/std/json.slo is missing source facade `{}`",
helper
);
assert!(
!std_json.contains(&format!("std.json.{}", helper)),
"std.json.{} must remain source-authored, not a compiler-known runtime call",
helper
);
}
for private_prefix in [
"__glagol_json_parse_string_document",
"__glagol_json_parse_bool_document",
"__glagol_json_parse_i32_document",
"__glagol_json_parse_u32_document",
"__glagol_json_parse_i64_document",
"__glagol_json_parse_u64_document",
"__glagol_json_parse_f64_document",
"__glagol_json_parse_null_document",
] {
assert!(
!std_json.contains(private_prefix),
"lib/std/json.slo must not introduce private JSON document runtime symbol `{}`",
private_prefix
);
}
}
fn run_glagol<I, S>(args: I) -> Output
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
Command::new(env!("CARGO_BIN_EXE_glagol"))
.args(args)
.current_dir(Path::new(env!("CARGO_MANIFEST_DIR")))
.output()
.expect("run glagol")
}
fn write_project(name: &str, source: &str) -> PathBuf {
let root = temp_root(name);
let src = root.join("src");
fs::create_dir_all(&src).unwrap_or_else(|err| panic!("create `{}`: {}", src.display(), err));
fs::write(
root.join("slovo.toml"),
format!(
"[project]\nname = \"{}\"\nsource_root = \"src\"\nentry = \"main\"\n",
name
),
)
.unwrap_or_else(|err| panic!("write project manifest: {}", err));
fs::write(src.join("main.slo"), source.trim_start())
.unwrap_or_else(|err| panic!("write project main.slo: {}", err));
root
}
fn write_fixture(name: &str, source: &str) -> PathBuf {
let mut path = env::temp_dir();
path.push(format!(
"glagol-standard-json-document-scalar-beta21-{}-{}-{}.slo",
name,
std::process::id(),
NEXT_TEMP_ID.fetch_add(1, Ordering::Relaxed)
));
fs::write(&path, source.trim_start())
.unwrap_or_else(|err| panic!("write `{}`: {}", path.display(), err));
path
}
fn temp_root(name: &str) -> PathBuf {
let root = env::temp_dir().join(format!(
"glagol-standard-json-document-scalar-beta21-{}-{}-{}",
name,
std::process::id(),
NEXT_TEMP_ID.fetch_add(1, Ordering::Relaxed)
));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(&root).unwrap_or_else(|err| panic!("create `{}`: {}", root.display(), err));
root
}
fn std_json_path() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../lib/std/json.slo")
}
fn read(path: &Path) -> String {
fs::read_to_string(path).unwrap_or_else(|err| panic!("read `{}`: {}", path.display(), err))
}
fn assert_success(context: &str, output: &Output) {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
output.status.success(),
"{} failed\nstatus: {:?}\nstdout:\n{}\nstderr:\n{}",
context,
output.status.code(),
stdout,
stderr
);
assert!(stderr.is_empty(), "{} wrote stderr:\n{}", context, stderr);
}
fn assert_success_stdout(output: Output, expected: &str, context: &str) {
assert_success(context, &output);
let stdout = String::from_utf8_lossy(&output.stdout);
assert_eq!(stdout, expected, "{}", context);
}
fn assert_failure_stderr_contains(context: &str, output: &Output, needle: &str) {
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!output.status.success(),
"{} unexpectedly passed\nstdout:\n{}\nstderr:\n{}",
context,
stdout,
stderr
);
assert!(
stdout.is_empty(),
"{} rejected compile wrote stdout:\n{}",
context,
stdout
);
assert!(
stderr.contains(needle),
"{} stderr did not contain `{}`:\n{}",
context,
needle,
stderr
);
}

View File

@ -12,10 +12,13 @@ const EXPECTED_LOCAL_TEST_OUTPUT: &str = concat!(
"test \"explicit local json primitive scalar parse failure facade\" ... ok\n", "test \"explicit local json primitive scalar parse failure facade\" ... ok\n",
"test \"explicit local json string token parse success facade\" ... ok\n", "test \"explicit local json string token parse success facade\" ... ok\n",
"test \"explicit local json string token parse failure facade\" ... ok\n", "test \"explicit local json string token parse failure facade\" ... ok\n",
"test \"explicit local json document parse trimmed success facade\" ... ok\n",
"test \"explicit local json document parse plain success facade\" ... ok\n",
"test \"explicit local json document parse trailing failure facade\" ... ok\n",
"test \"explicit local json fields facade\" ... ok\n", "test \"explicit local json fields facade\" ... ok\n",
"test \"explicit local json arrays objects facade\" ... ok\n", "test \"explicit local json arrays objects facade\" ... ok\n",
"test \"explicit local json facade all\" ... ok\n", "test \"explicit local json facade all\" ... ok\n",
"9 test(s) passed\n", "12 test(s) passed\n",
); );
const EXPECTED_STD_IMPORT_TEST_OUTPUT: &str = concat!( const EXPECTED_STD_IMPORT_TEST_OUTPUT: &str = concat!(
@ -25,10 +28,13 @@ const EXPECTED_STD_IMPORT_TEST_OUTPUT: &str = concat!(
"test \"explicit std json primitive scalar parse failure facade\" ... ok\n", "test \"explicit std json primitive scalar parse failure facade\" ... ok\n",
"test \"explicit std json string token parse success facade\" ... ok\n", "test \"explicit std json string token parse success facade\" ... ok\n",
"test \"explicit std json string token parse failure facade\" ... ok\n", "test \"explicit std json string token parse failure facade\" ... ok\n",
"test \"explicit std json document parse trimmed success facade\" ... ok\n",
"test \"explicit std json document parse plain success facade\" ... ok\n",
"test \"explicit std json document parse trailing failure facade\" ... ok\n",
"test \"explicit std json fields facade\" ... ok\n", "test \"explicit std json fields facade\" ... ok\n",
"test \"explicit std json arrays objects facade\" ... ok\n", "test \"explicit std json arrays objects facade\" ... ok\n",
"test \"explicit std json facade all\" ... ok\n", "test \"explicit std json facade all\" ... ok\n",
"9 test(s) passed\n", "12 test(s) passed\n",
); );
const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[ const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[
@ -48,6 +54,14 @@ const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[
"parse_u64_value_result", "parse_u64_value_result",
"parse_f64_value_result", "parse_f64_value_result",
"parse_null_value_result", "parse_null_value_result",
"parse_string_document_result",
"parse_bool_document_result",
"parse_i32_document_result",
"parse_u32_document_result",
"parse_i64_document_result",
"parse_u64_document_result",
"parse_f64_document_result",
"parse_null_document_result",
"field_string", "field_string",
"field_bool", "field_bool",
"field_i32", "field_i32",
@ -84,6 +98,7 @@ const STANDARD_JSON_RUNTIME_NAMES: &[&str] = &[
]; ];
const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[
"(import std.string (trim_ascii))",
"std.json.quote_string", "std.json.quote_string",
"std.string.concat", "std.string.concat",
"std.num.i32_to_string", "std.num.i32_to_string",
@ -100,6 +115,17 @@ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[
"std.json.parse_f64_value_result", "std.json.parse_f64_value_result",
]; ];
const STANDARD_JSON_DOCUMENT_SCALAR_BETA21: &[&str] = &[
"parse_string_document_result",
"parse_bool_document_result",
"parse_i32_document_result",
"parse_u32_document_result",
"parse_i64_document_result",
"parse_u64_document_result",
"parse_f64_document_result",
"parse_null_document_result",
];
#[test] #[test]
fn standard_json_source_facade_project_checks_formats_and_tests() { fn standard_json_source_facade_project_checks_formats_and_tests() {
let project = let project =
@ -199,6 +225,7 @@ fn assert_json_source_shape(json: &str, main: &str, context: &str) {
} }
assert_std_only_contains(json, STANDARD_JSON_ALLOWED_STD_NAMES, context); assert_std_only_contains(json, STANDARD_JSON_ALLOWED_STD_NAMES, context);
assert_deferred_json_surface_absent(json, main, context); assert_deferred_json_surface_absent(json, main, context);
assert_json_document_scalar_helpers_are_source_authored(json, context);
for helper in STANDARD_JSON_SOURCE_FACADE_ALPHA { for helper in STANDARD_JSON_SOURCE_FACADE_ALPHA {
assert!( assert!(
@ -216,6 +243,34 @@ fn assert_json_source_shape(json: &str, main: &str, context: &str) {
} }
} }
fn assert_json_document_scalar_helpers_are_source_authored(json: &str, context: &str) {
for helper in STANDARD_JSON_DOCUMENT_SCALAR_BETA21 {
assert!(
!json.contains(&format!("std.json.{}", helper)),
"{} must keep `{}` source-authored, not compiler-known",
context,
helper
);
}
for private_prefix in [
"__glagol_json_parse_string_document",
"__glagol_json_parse_bool_document",
"__glagol_json_parse_i32_document",
"__glagol_json_parse_u32_document",
"__glagol_json_parse_i64_document",
"__glagol_json_parse_u64_document",
"__glagol_json_parse_f64_document",
"__glagol_json_parse_null_document",
] {
assert!(
!json.contains(private_prefix),
"{} must not introduce private JSON document runtime symbol `{}`",
context,
private_prefix
);
}
}
fn assert_deferred_json_surface_absent(json: &str, main: &str, context: &str) { fn assert_deferred_json_surface_absent(json: &str, main: &str, context: &str) {
for deferred in [ for deferred in [
"parse_object", "parse_object",

View File

@ -231,6 +231,15 @@ object/array parsing, tokenizer objects, Unicode escape decoding or
normalization, embedded NUL policy, streaming, schema validation, and stable normalization, embedded NUL policy, streaming, schema validation, and stable
ABI/API guarantees remain deferred. ABI/API guarantees remain deferred.
Released in `1.0.0-beta.21`: `lib/std/json.slo` adds source-authored scalar
document parse facades for string, bool, `i32`, `u32`, `i64`, `u64`, `f64`,
and exact `null`. Each helper trims ASCII whitespace around the whole document
with `std.string.trim_ascii`, then delegates to the already released exact
value-token parser. This intentionally remains scalar document parsing only:
object/array parsing, recursive JSON values, parser/tokenizer objects,
maps/sets, streaming, new compiler-known runtime names, broader Unicode escape
policy, embedded NUL policy, and stable ABI/API guarantees remain deferred.
Why seventh: networking and CLI tools need data interchange, but a complete JSON Why seventh: networking and CLI tools need data interchange, but a complete JSON
library depends on collection work. library depends on collection work.

View File

@ -12,6 +12,40 @@ integration/readiness release, not the first real beta.
No active unreleased compiler scope is documented here yet. No active unreleased compiler scope is documented here yet.
## 1.0.0-beta.21
Release label: `1.0.0-beta.21`
Release date: 2026-05-23
Release state: JSON document scalar parsing foundation
### Summary
The beta.21 compiler/tooling slice adds focused coverage for source-authored
`std.json` document-scalar helpers without adding compiler-known runtime names:
- Bump the `glagol` compiler package version to `1.0.0-beta.21`.
- Add focused `standard_json_document_scalar_parsing_beta21` coverage for
explicit `std.json` imports of `parse_string_document_result`,
`parse_bool_document_result`, `parse_i32_document_result`,
`parse_u32_document_result`, `parse_i64_document_result`,
`parse_u64_document_result`, `parse_f64_document_result`, and
`parse_null_document_result`.
- Gate the helpers as source-authored public facades over existing JSON token
parsers and source-level document trimming/composition.
- Require direct `std.json.parse_*_document_result` runtime calls and private
`__glagol_json_*document*` runtime symbols to remain unsupported.
- Add the focused beta21 test to `scripts/release-gate.sh`.
### Explicit Deferrals
This release does not implement object parsing, array parsing, recursive JSON
values, tokenizers, Unicode escape decoding, streaming, schema validation,
stable parser APIs, new compiler-known `std.*` runtime names, runtime C
changes, source-language syntax, stable ABI/layout, or a stable
standard-library compatibility contract.
## 1.0.0-beta.20 ## 1.0.0-beta.20
Release label: `1.0.0-beta.20` Release label: `1.0.0-beta.20`

View File

@ -9,10 +9,9 @@ Compiler rule: make the tree visible. The pipeline should remain:
.slo source -> tokens -> S-expression tree -> AST -> typed AST -> LLVM IR text -> hosted Clang/runtime executable step .slo source -> tokens -> S-expression tree -> AST -> typed AST -> LLVM IR text -> hosted Clang/runtime executable step
``` ```
Long-horizon compiler planning lives in Long-horizon compiler planning lives in `.llm/ROADMAP_TO_STABLE.md`. It
`.llm/GENERAL_PURPOSE_LANGUAGE_ROADMAP.md`. It mirrors Slovo's experimental mirrors Slovo's release train beyond the first real general-purpose beta
release train from the historical `v2.0.0-beta.1` tag toward and beyond the toolchain.
first real general-purpose beta toolchain.
Release maturity policy lives in `.llm/RELEASE_MATURITY_POLICY.md`. Historical Release maturity policy lives in `.llm/RELEASE_MATURITY_POLICY.md`. Historical
`exp-*` releases remain experimental maturity. `1.0.0-beta` is the first real `exp-*` releases remain experimental maturity. `1.0.0-beta` is the first real
@ -22,8 +21,8 @@ general-purpose beta release.
A Glagol feature is done only when it has parser/lowerer support, checker behavior, diagnostics for invalid forms, backend behavior or explicit unsupported diagnostics, and tests. A Glagol feature is done only when it has parser/lowerer support, checker behavior, diagnostics for invalid forms, backend behavior or explicit unsupported diagnostics, and tests.
Current stage: `1.0.0-beta.20`, released on 2026-05-23 as a string search Current stage: `1.0.0-beta.21`, released on 2026-05-23 as a JSON document
and ASCII trim foundation. It keeps the scalar parsing foundation. It keeps the
`1.0.0-beta` language/compiler support baseline and includes the `1.0.0-beta` language/compiler support baseline and includes the
`1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2` runtime/resource `1.0.0-beta.1` tooling hardening release, the `1.0.0-beta.2` runtime/resource
foundation release, the `1.0.0-beta.3` standard-library stabilization release, foundation release, the `1.0.0-beta.3` standard-library stabilization release,
@ -105,6 +104,17 @@ beta16-or-earlier string primitives and existing option/result shapes, and
verifies that direct compiler-known runtime calls for the new helper names verifies that direct compiler-known runtime calls for the new helper names
remain unsupported. remain unsupported.
The beta.21 compiler/tooling slice bumps the package version and gates
source-authored `std.json` document scalar facades for
`parse_string_document_result`, `parse_bool_document_result`,
`parse_i32_document_result`, `parse_u32_document_result`,
`parse_i64_document_result`, `parse_u64_document_result`,
`parse_f64_document_result`, and `parse_null_document_result` through explicit
`std.json` imports. It keeps those helpers source-authored over the existing
JSON token parser family and existing source-level composition, and verifies
that direct compiler-known runtime calls and private `__glagol_json_*document*`
symbols for the new helper names remain unsupported.
Generic vectors, generic collections, maps, sets, generic stdlib dispatch, Generic vectors, generic collections, maps, sets, generic stdlib dispatch,
runtime collection changes, collection unification, stable human diagnostic runtime collection changes, collection unification, stable human diagnostic
text, stable artifact-manifest or Markdown schema freezes, LSP/watch text, stable artifact-manifest or Markdown schema freezes, LSP/watch

View File

@ -8,7 +8,7 @@ Historical `exp-*` releases listed here are experimental maturity milestones.
The pushed tag `v2.0.0-beta.1` is historical. It is now documented as an The pushed tag `v2.0.0-beta.1` is historical. It is now documented as an
experimental integration/readiness release, not as a beta maturity claim. experimental integration/readiness release, not as a beta maturity claim.
The current release is `1.0.0-beta.20`, published on 2026-05-23. It keeps the The current release is `1.0.0-beta.21`, published on 2026-05-23. It keeps the
`1.0.0-beta` language surface, includes the first post-beta tooling/install `1.0.0-beta` language surface, includes the first post-beta tooling/install
hardening bundle from `1.0.0-beta.1`, and adds the first runtime/resource hardening bundle from `1.0.0-beta.1`, and adds the first runtime/resource
foundation bundle from `1.0.0-beta.2` plus the first standard-library foundation bundle from `1.0.0-beta.2` plus the first standard-library
@ -30,12 +30,46 @@ boundary foundation from `1.0.0-beta.16`, and the JSON primitive scalar
parsing foundation from `1.0.0-beta.17`, plus the JSON string token parsing parsing foundation from `1.0.0-beta.17`, plus the JSON string token parsing
foundation from `1.0.0-beta.18`, the test discovery and user-project foundation from `1.0.0-beta.18`, the test discovery and user-project
conformance foundation from `1.0.0-beta.19`, and the string search and ASCII conformance foundation from `1.0.0-beta.19`, and the string search and ASCII
trim foundation from `1.0.0-beta.20`. trim foundation from `1.0.0-beta.20`, plus the JSON document scalar parsing
foundation from `1.0.0-beta.21`.
## Unreleased ## Unreleased
No active unreleased language scope is documented here yet. No active unreleased language scope is documented here yet.
## 1.0.0-beta.21
Release label: `1.0.0-beta.21`
Release name: JSON Document Scalar Parsing Foundation
Release date: 2026-05-23
Status: released beta standard-library JSON document scalar parsing foundation
on the `1.0.0-beta` language baseline.
The source facade adds these source-authored `std.json` helpers:
- `parse_string_document_result ((document string)) -> (result string i32)`
- `parse_bool_document_result ((document string)) -> (result bool i32)`
- `parse_i32_document_result ((document string)) -> (result i32 i32)`
- `parse_u32_document_result ((document string)) -> (result u32 i32)`
- `parse_i64_document_result ((document string)) -> (result i64 i32)`
- `parse_u64_document_result ((document string)) -> (result u64 i32)`
- `parse_f64_document_result ((document string)) -> (result f64 i32)`
- `parse_null_document_result ((document string)) -> (result bool i32)`
Each helper trims ASCII whitespace around the whole document with
`std.string.trim_ascii`, then delegates to the already released exact
value-token parser for that scalar family. Leading and trailing ASCII
whitespace around one scalar document is accepted; trailing non-whitespace
still returns `err 1` through the underlying exact parser.
This release adds no compiler-known runtime names, parser objects, object/array
parsing, recursive `JsonValue`, maps/sets, streaming, Unicode escape decoding
beyond the existing string-token behavior, embedded NUL policy, stable
ABI/layout guarantees, or stable stdlib/API freeze.
## 1.0.0-beta.20 ## 1.0.0-beta.20
Release label: `1.0.0-beta.20` Release label: `1.0.0-beta.20`

View File

@ -5,13 +5,11 @@ compiler implementation inside the same monorepo.
Guiding rule: the manifest wins. A feature is not accepted until it has surface syntax, typed-core meaning, lowering behavior, formatter behavior, diagnostics, and tests. Guiding rule: the manifest wins. A feature is not accepted until it has surface syntax, typed-core meaning, lowering behavior, formatter behavior, diagnostics, and tests.
Long-horizon planning lives in Long-horizon planning lives in `.llm/ROADMAP_TO_STABLE.md`. It defines the
`.llm/GENERAL_PURPOSE_LANGUAGE_ROADMAP.md`. It defines the experimental release train beyond the first real general-purpose beta Slovo contract.
release train from the historical `v2.0.0-beta.1` tag toward and beyond the
first real general-purpose beta Slovo contract.
Current stage: `1.0.0-beta.20`, released on 2026-05-23 as a post-beta string Current stage: `1.0.0-beta.21`, released on 2026-05-23 as a post-beta JSON
search and ASCII trim foundation. It keeps the document scalar parsing foundation. It keeps the
`1.0.0-beta` language `1.0.0-beta` language
contract and includes the `1.0.0-beta.1` tooling hardening release, the contract and includes the `1.0.0-beta.1` tooling hardening release, the
`1.0.0-beta.2` runtime/resource foundation release, the `1.0.0-beta.3` `1.0.0-beta.2` runtime/resource foundation release, the `1.0.0-beta.3`
@ -28,7 +26,8 @@ collection boundary hardening and collection ledger, and `1.0.0-beta.16`
string scanning and token boundary helpers, `1.0.0-beta.17` JSON primitive string scanning and token boundary helpers, `1.0.0-beta.17` JSON primitive
scalar token parsing, `1.0.0-beta.18` JSON string token parsing, scalar token parsing, `1.0.0-beta.18` JSON string token parsing,
`1.0.0-beta.19` test discovery and user-project conformance tooling, and `1.0.0-beta.19` test discovery and user-project conformance tooling, and
`1.0.0-beta.20` string search and ASCII trim helpers. `1.0.0-beta.20` string search and ASCII trim helpers, plus
`1.0.0-beta.21` JSON document scalar parsing helpers.
`1.0.0-beta.16` adds `std.string` source facades and examples for `1.0.0-beta.16` adds `std.string` source facades and examples for
`byte_at_result`, `slice_result`, `starts_with`, and `ends_with`. These helpers `byte_at_result`, `slice_result`, `starts_with`, and `ends_with`. These helpers
@ -40,11 +39,12 @@ semantics; full JSON parsing; object/array parsing; tokenizer objects;
language slice/view syntax; mutable strings; stable ABI/layout; performance language slice/view syntax; mutable strings; stable ABI/layout; performance
claims; or a stable stdlib/API freeze. claims; or a stable stdlib/API freeze.
The current released stage adds primitive scalar JSON token parse facades for The current released JSON stage adds primitive scalar JSON token parse facades
booleans, concrete numeric primitives, exact `null`, and one narrow ASCII JSON for booleans, concrete numeric primitives, exact `null`, one narrow ASCII JSON
string-token helper. Full JSON document parsing, object/array parsing, string-token helper, and scalar JSON document helpers that accept leading and
recursive JSON values, tokenizers, whitespace-tolerant document parsing, schema trailing ASCII whitespace. Object/array parsing, recursive JSON values,
validation, streaming, Unicode escape decoding/normalization, embedded NUL tokenizers, schema validation, streaming, Unicode escape
decoding/normalization beyond the existing string-token helper, embedded NUL
policy, stable ABI/layout, and stable stdlib/API freeze remain deferred. policy, stable ABI/layout, and stable stdlib/API freeze remain deferred.
Full JSON parsing, object/array parsing, recursive JSON values, Full JSON parsing, object/array parsing, recursive JSON values,
@ -85,6 +85,16 @@ Unicode/grapheme semantics, case folding, regexes, tokenizer APIs, language
slice/view syntax, mutable strings, stable ABI/layout guarantees, or stable slice/view syntax, mutable strings, stable ABI/layout guarantees, or stable
stdlib/API freeze. stdlib/API freeze.
`1.0.0-beta.21` adds source-authored
`std.json.parse_*_document_result` helpers for string, bool, `i32`, `u32`,
`i64`, `u64`, `f64`, and exact `null` documents by trimming ASCII whitespace
around the whole document with `std.string.trim_ascii`, then delegating to the
existing exact value-token parser for each scalar family. The scope keeps
object/array parsing, recursive JSON values, tokenizer objects, maps/sets,
streaming, new compiler-known runtime names, Unicode escape decoding beyond
the existing string-token helper, embedded NUL policy, stable ABI/layout, and
stable stdlib/API freeze deferred.
The final experimental precursor scope is `exp-125`, defined in The final experimental precursor scope is `exp-125`, defined in
`.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its `.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its
unsigned direct-value flow, parse/format runtime lanes, and matching staged unsigned direct-value flow, parse/format runtime lanes, and matching staged

View File

@ -11,7 +11,8 @@ boundary hardening and collection ledger, `1.0.0-beta.16` string scanning
and token boundary foundation, `1.0.0-beta.17` JSON primitive scalar parsing and token boundary foundation, `1.0.0-beta.17` JSON primitive scalar parsing
foundation, `1.0.0-beta.18` JSON string token parsing foundation, foundation, `1.0.0-beta.18` JSON string token parsing foundation,
`1.0.0-beta.19` test discovery and user-project conformance tooling, and `1.0.0-beta.19` test discovery and user-project conformance tooling, and
`1.0.0-beta.20` string search and ASCII trim foundation. The `1.0.0-beta.20` string search and ASCII trim foundation, and
`1.0.0-beta.21` JSON document scalar parsing foundation. The
language contract language contract
integrates integrates
promoted language slices through `exp-125` and the historical publication promoted language slices through `exp-125` and the historical publication
@ -205,20 +206,20 @@ Current v1 release surface and explicit experimental targets:
`std.json.parse_i64_value_result`, `std.json.parse_u64_value_result`, `std.json.parse_i64_value_result`, `std.json.parse_u64_value_result`,
`std.json.parse_f64_value_result`, and `std.json.parse_null_value_result` `std.json.parse_f64_value_result`, and `std.json.parse_null_value_result`
consume one already-isolated primitive scalar token and return concrete consume one already-isolated primitive scalar token and return concrete
`(result ... i32)` values; full JSON document parsing, string/object/array `(result ... i32)` values; JSON document parsing beyond the beta21 scalar
parsing, tokenizers, recursive `JsonValue`, Unicode escape handling, stable helpers, string/object/array parsing, tokenizers, recursive `JsonValue`,
ABI/layout, performance claims, and stable stdlib/API freeze remain out of Unicode escape handling, stable ABI/layout, performance claims, and stable
scope stdlib/API freeze remain out of scope
- `1.0.0-beta.18` JSON string token parsing target: - `1.0.0-beta.18` JSON string token parsing target:
`std.json.parse_string_value_result : (string) -> (result string i32)` `std.json.parse_string_value_result : (string) -> (result string i32)`
consumes one already-isolated ASCII JSON string token with exact quotes and consumes one already-isolated ASCII JSON string token with exact quotes and
no leading/trailing whitespace, decodes simple JSON escapes, returns no leading/trailing whitespace, decodes simple JSON escapes, returns
`err 1` for ordinary parse failure, and rejects raw control bytes, bad `err 1` for ordinary parse failure, and rejects raw control bytes, bad
escapes, unterminated/trailing bytes, raw non-ASCII, and all `\uXXXX` escapes escapes, unterminated/trailing bytes, raw non-ASCII, and all `\uXXXX` escapes
for this slice; full JSON document parsing, object/array parsing, tokenizer for this slice; JSON document parsing beyond the beta21 scalar helpers,
APIs, recursive `JsonValue`, Unicode escape decoding/normalization, embedded object/array parsing, tokenizer APIs, recursive `JsonValue`, Unicode escape
NUL policy, stable ABI/layout, performance claims, and stable stdlib/API decoding/normalization, embedded NUL policy, stable ABI/layout, performance
freeze remain out of scope claims, and stable stdlib/API freeze remain out of scope
- `1.0.0-beta.19` test discovery and user-project conformance target: - `1.0.0-beta.19` test discovery and user-project conformance target:
`glagol test --list <file|project|workspace>` and legacy `glagol test --list <file|project|workspace>` and legacy
`glagol --run-tests --list <file>` list checked/discovered tests without `glagol --run-tests --list <file>` list checked/discovered tests without
@ -240,6 +241,21 @@ Current v1 release surface and explicit experimental targets:
runtime names, Unicode/grapheme semantics, case folding, locale-sensitive runtime names, Unicode/grapheme semantics, case folding, locale-sensitive
matching, regex, tokenizer APIs, language slice/view syntax, mutable matching, regex, tokenizer APIs, language slice/view syntax, mutable
strings, stable ABI/layout, performance claims, or stable stdlib/API freeze strings, stable ABI/layout, performance claims, or stable stdlib/API freeze
- `1.0.0-beta.21` JSON document scalar parsing:
source-authored `std.json.parse_string_document_result`,
`std.json.parse_bool_document_result`,
`std.json.parse_i32_document_result`,
`std.json.parse_u32_document_result`,
`std.json.parse_i64_document_result`,
`std.json.parse_u64_document_result`,
`std.json.parse_f64_document_result`, and
`std.json.parse_null_document_result` trim ASCII whitespace around the whole
document with `std.string.trim_ascii`, then delegate to the existing exact
value-token parsers for one scalar JSON document. This target does not add
compiler-known runtime names, object/array parsing, recursive `JsonValue`,
parser/tokenizer objects, maps/sets, streaming, Unicode escape decoding
beyond the existing string-token behavior, embedded NUL policy,
ABI/layout guarantees, performance claims, or stable stdlib/API freeze
- `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two - `exp-1` owned runtime strings: compiler-known `std.string.concat` accepts two
`string` values and returns an immutable runtime-owned `string`; existing `string` values and returns an immutable runtime-owned `string`; existing
string equality, length, printing, locals, parameters, returns, and calls work string equality, length, printing, locals, parameters, returns, and calls work
@ -1266,6 +1282,10 @@ std.json.parse_string_value_result: (string) -> (result string i32)
std.json.parse_bool_value_result: (string) -> (result bool i32) std.json.parse_bool_value_result: (string) -> (result bool i32)
std.json.parse_i32_value_result/parse_u32_value_result/parse_i64_value_result/parse_u64_value_result/parse_f64_value_result std.json.parse_i32_value_result/parse_u32_value_result/parse_i64_value_result/parse_u64_value_result/parse_f64_value_result
std.json.parse_null_value_result: (string) -> (result bool i32) std.json.parse_null_value_result: (string) -> (result bool i32)
std.json.parse_string_document_result: (string) -> (result string i32)
std.json.parse_bool_document_result: (string) -> (result bool i32)
std.json.parse_i32_document_result/parse_u32_document_result/parse_i64_document_result/parse_u64_document_result/parse_f64_document_result
std.json.parse_null_document_result: (string) -> (result bool i32)
std.json.field_string/field_bool/field_i32/field_u32/field_i64/field_u64/field_f64/field_null std.json.field_string/field_bool/field_i32/field_u32/field_i64/field_u64/field_f64/field_null
std.json.array0/array1/array2/array3 std.json.array0/array1/array2/array3
std.json.object0/object1/object2/object3 std.json.object0/object1/object2/object3
@ -1293,13 +1313,20 @@ whitespace. It decodes the simple JSON escapes `\"`, `\\`, `\/`, `\b`, `\f`,
unterminated or trailing bytes, raw non-ASCII, and all `\uXXXX` escapes for unterminated or trailing bytes, raw non-ASCII, and all `\uXXXX` escapes for
this slice. this slice.
The `1.0.0-beta.21` JSON foundation adds source-authored
`parse_*_document_result` helpers for string, bool, concrete numeric
primitives, and exact `null`. Each helper accepts leading and trailing ASCII
whitespace around one scalar JSON document by composing with
`std.string.trim_ascii`, then delegates to the matching exact value-token
parser. Trailing non-whitespace still fails through the exact parser.
This is not a complete JSON or serialization contract. JSON parsing beyond the This is not a complete JSON or serialization contract. JSON parsing beyond the
single ASCII string-token helper, object/array parsing, recursive JSON values, scalar document helpers, object/array parsing, recursive JSON values, maps/sets,
maps/sets, generic collections, tokenizer objects, streaming decoders or generic collections, tokenizer objects, streaming decoders or encoders, schema
encoders, schema validation, Unicode escape decoding or validation, Unicode escape decoding or normalization beyond the existing
normalization, embedded NUL policy, stable text encoding policy beyond the string-token behavior, embedded NUL policy, stable text encoding policy beyond
current null-terminated runtime string ABI, stable runtime helper symbols, and the current null-terminated runtime string ABI, stable runtime helper symbols,
stable standard-library API guarantees remain deferred. and stable standard-library API guarantees remain deferred.
### 4.4.6 Post-Beta Concrete Type Alias Foundation ### 4.4.6 Post-Beta Concrete Type Alias Foundation

View File

@ -6,7 +6,7 @@ Do not edit this file by hand.
## Stability Tiers ## Stability Tiers
- `beta-supported`: exported from `lib/std` and covered by source-search, promotion, or facade gates in the current beta line. - `beta-supported`: exported from `lib/std` and covered by source-search, promotion, or facade gates in the current beta line.
- `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.20`; future releases may mark new helpers this way before they graduate. - `experimental`: not used for exported `lib/std` helpers in `1.0.0-beta.21`; future releases may mark new helpers this way before they graduate.
- `internal`: helper names that are not exported from their module; they are intentionally omitted from this catalog. - `internal`: helper names that are not exported from their module; they are intentionally omitted from this catalog.
The catalog is a beta API discovery aid, not a stable `1.0.0` standard-library freeze. The catalog is a beta API discovery aid, not a stable `1.0.0` standard-library freeze.
@ -16,7 +16,7 @@ Only exported `(fn ...)` helpers are listed; `(type ...)` aliases and non-export
## Summary ## Summary
- Modules: 19 - Modules: 19
- Exported helper signatures: 596 - Exported helper signatures: 604
- Exported type aliases omitted: 0 - Exported type aliases omitted: 0
- Default tier: `beta-supported` - Default tier: `beta-supported`
@ -193,7 +193,7 @@ Only exported `(fn ...)` helpers are listed; `(type ...)` aliases and non-export
- Path: `lib/std/json.slo` - Path: `lib/std/json.slo`
- Tier: `beta-supported` - Tier: `beta-supported`
- Exported helper signatures: 32 - Exported helper signatures: 40
- `quote_string ((value string)) -> string` - `quote_string ((value string)) -> string`
- `null_value () -> string` - `null_value () -> string`
@ -211,6 +211,14 @@ Only exported `(fn ...)` helpers are listed; `(type ...)` aliases and non-export
- `parse_u64_value_result ((token string)) -> (result u64 i32)` - `parse_u64_value_result ((token string)) -> (result u64 i32)`
- `parse_f64_value_result ((token string)) -> (result f64 i32)` - `parse_f64_value_result ((token string)) -> (result f64 i32)`
- `parse_null_value_result ((token string)) -> (result bool i32)` - `parse_null_value_result ((token string)) -> (result bool i32)`
- `parse_string_document_result ((document string)) -> (result string i32)`
- `parse_bool_document_result ((document string)) -> (result bool i32)`
- `parse_i32_document_result ((document string)) -> (result i32 i32)`
- `parse_u32_document_result ((document string)) -> (result u32 i32)`
- `parse_i64_document_result ((document string)) -> (result i64 i32)`
- `parse_u64_document_result ((document string)) -> (result u64 i32)`
- `parse_f64_document_result ((document string)) -> (result f64 i32)`
- `parse_null_document_result ((document string)) -> (result bool i32)`
- `field_string ((name string) (value string)) -> string` - `field_string ((name string) (value string)) -> string`
- `field_bool ((name string) (value bool)) -> string` - `field_bool ((name string) (value bool)) -> string`
- `field_i32 ((name string) (value i32)) -> string` - `field_i32 ((name string) (value i32)) -> string`

View File

@ -1,6 +1,6 @@
(module main) (module main)
(import std.json (quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3)) (import std.json (quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result parse_string_document_result parse_bool_document_result parse_i32_document_result parse_u32_document_result parse_i64_document_result parse_u64_document_result parse_f64_document_result parse_null_document_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3))
(type JsonText string) (type JsonText string)
@ -92,6 +92,57 @@
false) false)
false)) false))
(fn imported_json_parse_document_trimmed_success () -> bool
(if (= (unwrap_ok (parse_string_document_result " \t\n\"slovo\" \n\t")) "slovo")
(if (unwrap_ok (parse_bool_document_result "\n true \t"))
(if (= (unwrap_ok (parse_i32_document_result " -7 ")) -7)
(if (= (unwrap_ok (parse_u32_document_result " 7 ")) 7u32)
(if (= (unwrap_ok (parse_i64_document_result " 8 ")) 8i64)
(if (= (unwrap_ok (parse_u64_document_result " 9 ")) 9u64)
(if (= (unwrap_ok (parse_f64_document_result " 1e2 ")) 100.0)
(unwrap_ok (parse_null_document_result " null "))
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_parse_document_plain_success () -> bool
(if (= (unwrap_ok (parse_string_document_result "\"plain\"")) "plain")
(if (= (unwrap_ok (parse_bool_document_result "false")) false)
(if (= (unwrap_ok (parse_i32_document_result "-8")) -8)
(if (= (unwrap_ok (parse_u32_document_result "8")) 8u32)
(if (= (unwrap_ok (parse_i64_document_result "9")) 9i64)
(if (= (unwrap_ok (parse_u64_document_result "10")) 10u64)
(if (= (unwrap_ok (parse_f64_document_result "1.5")) 1.5)
(unwrap_ok (parse_null_document_result "null"))
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_parse_document_trailing_failure () -> bool
(if (= (unwrap_err (parse_string_document_result " \t\"slovo\"x \n")) 1)
(if (= (unwrap_err (parse_bool_document_result " truex ")) 1)
(if (= (unwrap_err (parse_i32_document_result " -7x ")) 1)
(if (= (unwrap_err (parse_u32_document_result " 7x ")) 1)
(if (= (unwrap_err (parse_i64_document_result " 8x ")) 1)
(if (= (unwrap_err (parse_u64_document_result " 9x ")) 1)
(if (= (unwrap_err (parse_f64_document_result " 1.5x ")) 1)
(= (unwrap_err (parse_null_document_result " nullx ")) 1)
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_fields () -> bool (fn imported_json_fields () -> bool
(if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"") (if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"")
(if (= (field_bool "ok" true) "\"ok\":true") (if (= (field_bool "ok" true) "\"ok\":true")
@ -139,6 +190,9 @@
(if (imported_json_parse_scalar_failure) (if (imported_json_parse_scalar_failure)
(if (imported_json_parse_string_success) (if (imported_json_parse_string_success)
(if (imported_json_parse_string_failure) (if (imported_json_parse_string_failure)
(if (imported_json_parse_document_trimmed_success)
(if (imported_json_parse_document_plain_success)
(if (imported_json_parse_document_trailing_failure)
(if (imported_json_fields) (if (imported_json_fields)
(imported_json_arrays_objects) (imported_json_arrays_objects)
false) false)
@ -147,6 +201,9 @@
false) false)
false) false)
false) false)
false)
false)
false)
false)) false))
(fn main () -> i32 (fn main () -> i32
@ -172,6 +229,15 @@
(test "explicit std json string token parse failure facade" (test "explicit std json string token parse failure facade"
(imported_json_parse_string_failure)) (imported_json_parse_string_failure))
(test "explicit std json document parse trimmed success facade"
(imported_json_parse_document_trimmed_success))
(test "explicit std json document parse plain success facade"
(imported_json_parse_document_plain_success))
(test "explicit std json document parse trailing failure facade"
(imported_json_parse_document_trailing_failure))
(test "explicit std json fields facade" (test "explicit std json fields facade"
(imported_json_fields)) (imported_json_fields))

View File

@ -1,4 +1,6 @@
(module json (export quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3)) (module json (export quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result parse_string_document_result parse_bool_document_result parse_i32_document_result parse_u32_document_result parse_i64_document_result parse_u64_document_result parse_f64_document_result parse_null_document_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3))
(import string (trim_ascii))
(type JsonText string) (type JsonText string)
@ -56,6 +58,30 @@
(ok bool i32 true) (ok bool i32 true)
(err bool i32 1))) (err bool i32 1)))
(fn parse_string_document_result ((document string)) -> (result string i32)
(parse_string_value_result (trim_ascii document)))
(fn parse_bool_document_result ((document string)) -> (result bool i32)
(parse_bool_value_result (trim_ascii document)))
(fn parse_i32_document_result ((document string)) -> (result i32 i32)
(parse_i32_value_result (trim_ascii document)))
(fn parse_u32_document_result ((document string)) -> (result u32 i32)
(parse_u32_value_result (trim_ascii document)))
(fn parse_i64_document_result ((document string)) -> (result i64 i32)
(parse_i64_value_result (trim_ascii document)))
(fn parse_u64_document_result ((document string)) -> (result u64 i32)
(parse_u64_value_result (trim_ascii document)))
(fn parse_f64_document_result ((document string)) -> (result f64 i32)
(parse_f64_value_result (trim_ascii document)))
(fn parse_null_document_result ((document string)) -> (result bool i32)
(parse_null_value_result (trim_ascii document)))
(fn field_fragment ((name string) (encoded_value JsonText)) -> JsonField (fn field_fragment ((name string) (encoded_value JsonText)) -> JsonField
(std.string.concat (std.string.concat (quote_string name) ":") encoded_value)) (std.string.concat (std.string.concat (quote_string name) ":") encoded_value))

View File

@ -1,6 +1,6 @@
(module main) (module main)
(import json (quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3)) (import json (quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result parse_string_document_result parse_bool_document_result parse_i32_document_result parse_u32_document_result parse_i64_document_result parse_u64_document_result parse_f64_document_result parse_null_document_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3))
(type JsonText string) (type JsonText string)
@ -92,6 +92,57 @@
false) false)
false)) false))
(fn imported_json_parse_document_trimmed_success () -> bool
(if (= (unwrap_ok (parse_string_document_result " \t\n\"slovo\" \n\t")) "slovo")
(if (unwrap_ok (parse_bool_document_result "\n true \t"))
(if (= (unwrap_ok (parse_i32_document_result " -7 ")) -7)
(if (= (unwrap_ok (parse_u32_document_result " 7 ")) 7u32)
(if (= (unwrap_ok (parse_i64_document_result " 8 ")) 8i64)
(if (= (unwrap_ok (parse_u64_document_result " 9 ")) 9u64)
(if (= (unwrap_ok (parse_f64_document_result " 1e2 ")) 100.0)
(unwrap_ok (parse_null_document_result " null "))
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_parse_document_plain_success () -> bool
(if (= (unwrap_ok (parse_string_document_result "\"plain\"")) "plain")
(if (= (unwrap_ok (parse_bool_document_result "false")) false)
(if (= (unwrap_ok (parse_i32_document_result "-8")) -8)
(if (= (unwrap_ok (parse_u32_document_result "8")) 8u32)
(if (= (unwrap_ok (parse_i64_document_result "9")) 9i64)
(if (= (unwrap_ok (parse_u64_document_result "10")) 10u64)
(if (= (unwrap_ok (parse_f64_document_result "1.5")) 1.5)
(unwrap_ok (parse_null_document_result "null"))
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_parse_document_trailing_failure () -> bool
(if (= (unwrap_err (parse_string_document_result " \t\"slovo\"x \n")) 1)
(if (= (unwrap_err (parse_bool_document_result " truex ")) 1)
(if (= (unwrap_err (parse_i32_document_result " -7x ")) 1)
(if (= (unwrap_err (parse_u32_document_result " 7x ")) 1)
(if (= (unwrap_err (parse_i64_document_result " 8x ")) 1)
(if (= (unwrap_err (parse_u64_document_result " 9x ")) 1)
(if (= (unwrap_err (parse_f64_document_result " 1.5x ")) 1)
(= (unwrap_err (parse_null_document_result " nullx ")) 1)
false)
false)
false)
false)
false)
false)
false))
(fn imported_json_fields () -> bool (fn imported_json_fields () -> bool
(if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"") (if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"")
(if (= (field_bool "ok" true) "\"ok\":true") (if (= (field_bool "ok" true) "\"ok\":true")
@ -139,6 +190,9 @@
(if (imported_json_parse_scalar_failure) (if (imported_json_parse_scalar_failure)
(if (imported_json_parse_string_success) (if (imported_json_parse_string_success)
(if (imported_json_parse_string_failure) (if (imported_json_parse_string_failure)
(if (imported_json_parse_document_trimmed_success)
(if (imported_json_parse_document_plain_success)
(if (imported_json_parse_document_trailing_failure)
(if (imported_json_fields) (if (imported_json_fields)
(imported_json_arrays_objects) (imported_json_arrays_objects)
false) false)
@ -147,6 +201,9 @@
false) false)
false) false)
false) false)
false)
false)
false)
false)) false))
(fn main () -> i32 (fn main () -> i32
@ -172,6 +229,15 @@
(test "explicit local json string token parse failure facade" (test "explicit local json string token parse failure facade"
(imported_json_parse_string_failure)) (imported_json_parse_string_failure))
(test "explicit local json document parse trimmed success facade"
(imported_json_parse_document_trimmed_success))
(test "explicit local json document parse plain success facade"
(imported_json_parse_document_plain_success))
(test "explicit local json document parse trailing failure facade"
(imported_json_parse_document_trailing_failure))
(test "explicit local json fields facade" (test "explicit local json fields facade"
(imported_json_fields)) (imported_json_fields))

View File

@ -0,0 +1,55 @@
(module string (export trim_ascii))
(fn len ((value string)) -> i32
(std.string.len value))
(fn byte_at_result ((value string) (index i32)) -> (result i32 i32)
(std.string.byte_at_result value index))
(fn slice_result ((value string) (start i32) (count i32)) -> (result string i32)
(std.string.slice_result value start count))
(fn is_ascii_trim_byte ((value i32)) -> bool
(if (= value 9)
true
(if (= value 10)
true
(if (= value 11)
true
(if (= value 12)
true
(if (= value 13)
true
(= value 32)))))))
(fn byte_is_ascii_trim ((value string) (position i32)) -> bool
(match (byte_at_result value position)
((ok byte)
(is_ascii_trim_byte byte))
((err code)
false)))
(fn trim_ascii_start ((value string)) -> string
(let value_len i32 (len value))
(var start i32 0)
(while (and (< start value_len) (byte_is_ascii_trim value start))
(set start (+ start 1)))
(match (slice_result value start (- value_len start))
((ok text)
text)
((err code)
value)))
(fn trim_ascii_end ((value string)) -> string
(let value_len i32 (len value))
(var end i32 value_len)
(while (and (> end 0) (byte_is_ascii_trim value (- end 1)))
(set end (- end 1)))
(match (slice_result value 0 end)
((ok text)
text)
((err code)
value)))
(fn trim_ascii ((value string)) -> string
(trim_ascii_end (trim_ascii_start value)))

View File

@ -42,7 +42,9 @@ compiler-known runtime calls; `1.0.0-beta.7` serialization work releases
`1.0.0-beta.17` JSON foundation adds primitive scalar token parse facades for `1.0.0-beta.17` JSON foundation adds primitive scalar token parse facades for
booleans, concrete numeric primitives, and exact `null`; the Slovo-facing booleans, concrete numeric primitives, and exact `null`; the Slovo-facing
`1.0.0-beta.18` JSON foundation adds one ASCII string-token parse `1.0.0-beta.18` JSON foundation adds one ASCII string-token parse
facade; the facade; the `1.0.0-beta.21` JSON foundation adds source-authored
whole-document scalar parse facades over `std.string.trim_ascii` and the
existing exact value-token parsers; the
`1.0.0-beta.8` concrete type alias target keeps that same helper surface while `1.0.0-beta.8` concrete type alias target keeps that same helper surface while
using local `JsonText` and `JsonField` aliases as transparent names for using local `JsonText` and `JsonField` aliases as transparent names for
`string` JSON fragments. `string` JSON fragments.
@ -111,10 +113,15 @@ and the current `std.num.*_to_string` helpers. The Slovo-facing
facades over promoted `std.json` bool/numeric runtime helpers and an exact facades over promoted `std.json` bool/numeric runtime helpers and an exact
source-only `null` token helper. The `1.0.0-beta.18` JSON foundation source-only `null` token helper. The `1.0.0-beta.18` JSON foundation
adds `parse_string_value_result` for one already-isolated ASCII JSON string adds `parse_string_value_result` for one already-isolated ASCII JSON string
token over the matching promoted runtime helper. Full JSON document parsing, token over the matching promoted runtime helper. The
object/array parsing, recursive JSON values, maps/sets, streaming decoders or `1.0.0-beta.21` JSON foundation adds source-authored
encoders, schema validation, Unicode escape decoding/normalization, embedded `parse_*_document_result` helpers for string, bool, concrete numeric
NUL policy, and stable text encoding policy remain deferred; primitives, and exact `null` by trimming ASCII whitespace around the whole
document and delegating to those exact value-token parsers. Object/array
parsing, recursive JSON values, maps/sets, streaming decoders or encoders,
schema validation, Unicode escape decoding/normalization beyond the existing
string-token behavior, embedded NUL policy, and stable text encoding policy
remain deferred;
`1.0.0-beta.8` targets top-level concrete type aliases in source facades and `1.0.0-beta.8` targets top-level concrete type aliases in source facades and
uses `JsonText` / `JsonField` only as local transparent aliases inside uses `JsonText` / `JsonField` only as local transparent aliases inside
`std/json.slo` and matching local JSON fixtures. These aliases are not exported `std/json.slo` and matching local JSON fixtures. These aliases are not exported
@ -330,11 +337,18 @@ array, and small object text from existing string and number helpers.
`1.0.0-beta.17` adds primitive scalar token parse facades for `bool`, `i32`, `1.0.0-beta.17` adds primitive scalar token parse facades for `bool`, `i32`,
`u32`, `i64`, `u64`, `f64`, and exact `null` only. The `u32`, `i64`, `u64`, `f64`, and exact `null` only. The
`1.0.0-beta.18` source facade adds `parse_string_value_result` for one exact `1.0.0-beta.18` source facade adds `parse_string_value_result` for one exact
ASCII JSON string token with simple escape decoding. It is not a full JSON ASCII JSON string token with simple escape decoding. The
parser and does not define object/array parsing, recursive JSON values, `1.0.0-beta.21` source facade adds `parse_string_document_result`,
maps/sets, streaming decoders or encoders, schema validation, Unicode escape `parse_bool_document_result`, `parse_i32_document_result`,
decoding/normalization, embedded NUL policy, or stable text encoding policy `parse_u32_document_result`, `parse_i64_document_result`,
beyond the current runtime string ABI. `parse_u64_document_result`, `parse_f64_document_result`, and
`parse_null_document_result`; each trims ASCII whitespace around the whole
document with `std.string.trim_ascii`, then delegates to the matching exact
value-token parser. It is not a full JSON parser and does not define
object/array parsing, recursive JSON values, maps/sets, streaming decoders or
encoders, schema validation, Unicode escape decoding/normalization beyond the
existing string-token behavior, embedded NUL policy, or stable text encoding
policy beyond the current runtime string ABI.
`std/process.slo` includes the exp-52 narrow source wrappers over already `std/process.slo` includes the exp-52 narrow source wrappers over already
released process argument runtime calls and a source-authored `has_arg` released process argument runtime calls and a source-authored `has_arg`
predicate. exp-61 adds `arg_or` and `arg_or_empty` as ordinary source predicate. exp-61 adds `arg_or` and `arg_or_empty` as ordinary source

View File

@ -1,4 +1,6 @@
(module json (export quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3)) (module json (export quote_string null_value bool_value i32_value u32_value i64_value u64_value f64_value parse_string_value_result parse_bool_value_result parse_i32_value_result parse_u32_value_result parse_i64_value_result parse_u64_value_result parse_f64_value_result parse_null_value_result parse_string_document_result parse_bool_document_result parse_i32_document_result parse_u32_document_result parse_i64_document_result parse_u64_document_result parse_f64_document_result parse_null_document_result field_string field_bool field_i32 field_u32 field_i64 field_u64 field_f64 field_null array0 array1 array2 array3 object0 object1 object2 object3))
(import std.string (trim_ascii))
(type JsonText string) (type JsonText string)
@ -56,6 +58,30 @@
(ok bool i32 true) (ok bool i32 true)
(err bool i32 1))) (err bool i32 1)))
(fn parse_string_document_result ((document string)) -> (result string i32)
(parse_string_value_result (trim_ascii document)))
(fn parse_bool_document_result ((document string)) -> (result bool i32)
(parse_bool_value_result (trim_ascii document)))
(fn parse_i32_document_result ((document string)) -> (result i32 i32)
(parse_i32_value_result (trim_ascii document)))
(fn parse_u32_document_result ((document string)) -> (result u32 i32)
(parse_u32_value_result (trim_ascii document)))
(fn parse_i64_document_result ((document string)) -> (result i64 i32)
(parse_i64_value_result (trim_ascii document)))
(fn parse_u64_document_result ((document string)) -> (result u64 i32)
(parse_u64_value_result (trim_ascii document)))
(fn parse_f64_document_result ((document string)) -> (result f64 i32)
(parse_f64_value_result (trim_ascii document)))
(fn parse_null_document_result ((document string)) -> (result bool i32)
(parse_null_value_result (trim_ascii document)))
(fn field_fragment ((name string) (encoded_value JsonText)) -> JsonField (fn field_fragment ((name string) (encoded_value JsonText)) -> JsonField
(std.string.concat (std.string.concat (quote_string name) ":") encoded_value)) (std.string.concat (std.string.concat (quote_string name) ":") encoded_value))

View File

@ -71,6 +71,7 @@ cargo test --test standard_json_scalar_parsing_beta17
cargo test --test standard_json_string_parsing_beta18 cargo test --test standard_json_string_parsing_beta18
cargo test --test test_discovery_beta19 cargo test --test test_discovery_beta19
cargo test --test standard_string_search_trim_beta20 cargo test --test standard_string_search_trim_beta20
cargo test --test standard_json_document_scalar_parsing_beta21
# Full cargo test includes unignored integration gates such as dx_v1_7, # Full cargo test includes unignored integration gates such as dx_v1_7,
# beta_v2_0_0_beta_1, and beta_1_0_0. # beta_v2_0_0_beta_1, and beta_1_0_0.
cargo test cargo test