From 87e627045e0b0240f8fd5afefa0344800e6de35a Mon Sep 17 00:00:00 2001 From: sanjin Date: Sat, 23 May 2026 01:40:34 +0200 Subject: [PATCH] Release 1.0.0-beta.21 JSON document scalar parsing foundation --- ...JSON_DOCUMENT_SCALAR_PARSING_FOUNDATION.md | 72 ++++ .llm/reviews/BETA_21_IMPLEMENTATION_NOTES.md | 25 ++ .llm/reviews/BETA_21_RELEASE_REVIEW.md | 52 +++ README.md | 54 ++- compiler/Cargo.lock | 2 +- compiler/Cargo.toml | 2 +- compiler/tests/promotion_gate.rs | 59 +++- ...ard_json_document_scalar_parsing_beta21.rs | 313 ++++++++++++++++++ .../standard_json_source_facade_alpha.rs | 59 +++- docs/POST_BETA_ROADMAP.md | 9 + docs/compiler/RELEASE_NOTES.md | 34 ++ docs/compiler/ROADMAP.md | 22 +- docs/language/RELEASE_NOTES.md | 38 ++- docs/language/ROADMAP.md | 34 +- docs/language/SPEC-v1.md | 57 +++- docs/language/STDLIB_API.md | 14 +- .../projects/std-import-json/src/main.slo | 72 +++- .../std-layout-local-json/src/json.slo | 28 +- .../std-layout-local-json/src/main.slo | 72 +++- .../std-layout-local-json/src/string.slo | 55 +++ lib/std/README.md | 34 +- lib/std/json.slo | 28 +- scripts/release-gate.sh | 1 + 23 files changed, 1063 insertions(+), 73 deletions(-) create mode 100644 .llm/BETA_21_JSON_DOCUMENT_SCALAR_PARSING_FOUNDATION.md create mode 100644 .llm/reviews/BETA_21_IMPLEMENTATION_NOTES.md create mode 100644 .llm/reviews/BETA_21_RELEASE_REVIEW.md create mode 100644 compiler/tests/standard_json_document_scalar_parsing_beta21.rs create mode 100644 examples/projects/std-layout-local-json/src/string.slo diff --git a/.llm/BETA_21_JSON_DOCUMENT_SCALAR_PARSING_FOUNDATION.md b/.llm/BETA_21_JSON_DOCUMENT_SCALAR_PARSING_FOUNDATION.md new file mode 100644 index 0000000..686070a --- /dev/null +++ b/.llm/BETA_21_JSON_DOCUMENT_SCALAR_PARSING_FOUNDATION.md @@ -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 +``` diff --git a/.llm/reviews/BETA_21_IMPLEMENTATION_NOTES.md b/.llm/reviews/BETA_21_IMPLEMENTATION_NOTES.md new file mode 100644 index 0000000..6f559ae --- /dev/null +++ b/.llm/reviews/BETA_21_IMPLEMENTATION_NOTES.md @@ -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. diff --git a/.llm/reviews/BETA_21_RELEASE_REVIEW.md b/.llm/reviews/BETA_21_RELEASE_REVIEW.md new file mode 100644 index 0000000..d08aff5 --- /dev/null +++ b/.llm/reviews/BETA_21_RELEASE_REVIEW.md @@ -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. diff --git a/README.md b/README.md index 0057c2e..b18a6a6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This repository is the canonical public monorepo for the language design, standard library source, compiler, runtime, examples, benchmarks, and technical documents. -Current release: `1.0.0-beta.20`. +Current release: `1.0.0-beta.21`. ## Repository Layout @@ -24,7 +24,7 @@ scripts/ local release and document tooling ## 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` runtime/resource foundation bundle, the `1.0.0-beta.3` standard-library 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, 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.19` test discovery and user-project conformance foundation, and -the `1.0.0-beta.20` string search and ASCII trim foundation. +`1.0.0-beta.19` test discovery and user-project conformance foundation, the +`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 loopback-network programs with: @@ -57,7 +58,8 @@ loopback-network programs with: `SLOVO_STD_PATH` - beta-scoped loopback TCP handles through `std.net` - 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` - 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 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, -tokenizers, recursive `JsonValue`, whitespace-tolerant document parsing, -schema validation, streaming, Unicode escape handling, stable ABI/layout, and -a stable stdlib/API freeze remain deferred. +tokenizers, recursive `JsonValue`, document parsing beyond the beta21 scalar +document helpers, schema validation, streaming, Unicode escape handling, +stable ABI/layout, and a stable stdlib/API freeze remain deferred. 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 promoted runtime name. It consumes one already-isolated ASCII JSON string token with exact quotes and no leading/trailing whitespace, decodes the simple JSON escapes `\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, and `\t`, and returns -`err 1` for ordinary parse failure. Full JSON document parsing, object/array -parsing, tokenizer APIs, Unicode escape decoding/normalization, embedded NUL -policy, stable ABI/layout, and a stable stdlib/API freeze remain deferred. +`err 1` for ordinary parse failure. Complete JSON document parsing beyond the +beta21 scalar document helpers, object/array parsing, tokenizer APIs, Unicode +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 adds `glagol test --list ` 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, 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, broad package registry semantics, stable Markdown schema, stable stdlib/API 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, 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 The `1.0.0-beta.15` release documents the current concrete collection and diff --git a/compiler/Cargo.lock b/compiler/Cargo.lock index dd2151b..5aee6aa 100644 --- a/compiler/Cargo.lock +++ b/compiler/Cargo.lock @@ -4,4 +4,4 @@ version = 3 [[package]] name = "glagol" -version = "1.0.0-beta.20" +version = "1.0.0-beta.21" diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index 926a79b..c54d36f 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "glagol" -version = "1.0.0-beta.20" +version = "1.0.0-beta.21" edition = "2021" description = "Glagol, the first compiler for the Slovo language" license = "MIT OR Apache-2.0" diff --git a/compiler/tests/promotion_gate.rs b/compiler/tests/promotion_gate.rs index a4a3caf..42da8ec 100644 --- a/compiler/tests/promotion_gate.rs +++ b/compiler/tests/promotion_gate.rs @@ -1229,6 +1229,14 @@ const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[ "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", @@ -1265,6 +1273,7 @@ const STANDARD_JSON_RUNTIME_NAMES: &[&str] = &[ ]; const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ + "(import std.string (trim_ascii))", "std.json.quote_string", "std.string.concat", "std.num.i32_to_string", @@ -1281,6 +1290,17 @@ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ "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] = &[ "argc", "arg", @@ -4458,6 +4478,7 @@ fn assert_slovo_std_source_layout_alpha(repo: &Path, std_dir: &Path) { ); for source in [&slovo_json, &glagol_json] { 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 { 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 string token parse success 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 arrays objects facade\" ... 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 string token parse success 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 arrays objects facade\" ... 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", ); @@ -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 { Path::new(env!("CARGO_MANIFEST_DIR")) .parent() diff --git a/compiler/tests/standard_json_document_scalar_parsing_beta21.rs b/compiler/tests/standard_json_document_scalar_parsing_beta21.rs new file mode 100644 index 0000000..e89de43 --- /dev/null +++ b/compiler/tests/standard_json_document_scalar_parsing_beta21.rs @@ -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(args: I) -> Output +where + I: IntoIterator, + S: AsRef, +{ + 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 + ); +} diff --git a/compiler/tests/standard_json_source_facade_alpha.rs b/compiler/tests/standard_json_source_facade_alpha.rs index 480aa2b..a4caf3a 100644 --- a/compiler/tests/standard_json_source_facade_alpha.rs +++ b/compiler/tests/standard_json_source_facade_alpha.rs @@ -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 string token parse success 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 arrays objects facade\" ... 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!( @@ -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 string token parse success 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 arrays objects facade\" ... 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] = &[ @@ -48,6 +54,14 @@ const STANDARD_JSON_SOURCE_FACADE_ALPHA: &[&str] = &[ "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", @@ -84,6 +98,7 @@ const STANDARD_JSON_RUNTIME_NAMES: &[&str] = &[ ]; const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ + "(import std.string (trim_ascii))", "std.json.quote_string", "std.string.concat", "std.num.i32_to_string", @@ -100,6 +115,17 @@ const STANDARD_JSON_ALLOWED_STD_NAMES: &[&str] = &[ "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] fn standard_json_source_facade_project_checks_formats_and_tests() { 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_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 { 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) { for deferred in [ "parse_object", diff --git a/docs/POST_BETA_ROADMAP.md b/docs/POST_BETA_ROADMAP.md index 8608262..4bf5a41 100644 --- a/docs/POST_BETA_ROADMAP.md +++ b/docs/POST_BETA_ROADMAP.md @@ -231,6 +231,15 @@ object/array parsing, tokenizer objects, Unicode escape decoding or normalization, embedded NUL policy, streaming, schema validation, and stable 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 library depends on collection work. diff --git a/docs/compiler/RELEASE_NOTES.md b/docs/compiler/RELEASE_NOTES.md index 9fa8b4f..8813789 100644 --- a/docs/compiler/RELEASE_NOTES.md +++ b/docs/compiler/RELEASE_NOTES.md @@ -12,6 +12,40 @@ integration/readiness release, not the first real beta. 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 Release label: `1.0.0-beta.20` diff --git a/docs/compiler/ROADMAP.md b/docs/compiler/ROADMAP.md index 2eb5a70..63a9b06 100644 --- a/docs/compiler/ROADMAP.md +++ b/docs/compiler/ROADMAP.md @@ -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 ``` -Long-horizon compiler planning lives in -`.llm/GENERAL_PURPOSE_LANGUAGE_ROADMAP.md`. It mirrors Slovo's experimental -release train from the historical `v2.0.0-beta.1` tag toward and beyond the -first real general-purpose beta toolchain. +Long-horizon compiler planning lives in `.llm/ROADMAP_TO_STABLE.md`. It +mirrors Slovo's release train beyond the first real general-purpose beta +toolchain. Release maturity policy lives in `.llm/RELEASE_MATURITY_POLICY.md`. Historical `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. -Current stage: `1.0.0-beta.20`, released on 2026-05-23 as a string search -and ASCII trim foundation. It keeps the +Current stage: `1.0.0-beta.21`, released on 2026-05-23 as a JSON document +scalar parsing foundation. It keeps 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 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 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, runtime collection changes, collection unification, stable human diagnostic text, stable artifact-manifest or Markdown schema freezes, LSP/watch diff --git a/docs/language/RELEASE_NOTES.md b/docs/language/RELEASE_NOTES.md index 12b333c..3bc7a91 100644 --- a/docs/language/RELEASE_NOTES.md +++ b/docs/language/RELEASE_NOTES.md @@ -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 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 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 @@ -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 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 -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 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 Release label: `1.0.0-beta.20` diff --git a/docs/language/ROADMAP.md b/docs/language/ROADMAP.md index 41b0b26..30cf418 100644 --- a/docs/language/ROADMAP.md +++ b/docs/language/ROADMAP.md @@ -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. -Long-horizon planning lives in -`.llm/GENERAL_PURPOSE_LANGUAGE_ROADMAP.md`. It defines the experimental -release train from the historical `v2.0.0-beta.1` tag toward and beyond the -first real general-purpose beta Slovo contract. +Long-horizon planning lives in `.llm/ROADMAP_TO_STABLE.md`. It defines the +release train 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 -search and ASCII trim foundation. It keeps the +Current stage: `1.0.0-beta.21`, released on 2026-05-23 as a post-beta JSON +document scalar parsing foundation. It keeps the `1.0.0-beta` language 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` @@ -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 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.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 `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 claims; or a stable stdlib/API freeze. -The current released stage adds primitive scalar JSON token parse facades for -booleans, concrete numeric primitives, exact `null`, and one narrow ASCII JSON -string-token helper. Full JSON document parsing, object/array parsing, -recursive JSON values, tokenizers, whitespace-tolerant document parsing, schema -validation, streaming, Unicode escape decoding/normalization, embedded NUL +The current released JSON stage adds primitive scalar JSON token parse facades +for booleans, concrete numeric primitives, exact `null`, one narrow ASCII JSON +string-token helper, and scalar JSON document helpers that accept leading and +trailing ASCII whitespace. Object/array parsing, recursive JSON values, +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. 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 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 `.llm/EXP_125_UNSIGNED_U32_U64_NUMERIC_AND_STDLIB_BREADTH_ALPHA.md`. Its unsigned direct-value flow, parse/format runtime lanes, and matching staged diff --git a/docs/language/SPEC-v1.md b/docs/language/SPEC-v1.md index e0acf6d..3486c5a 100644 --- a/docs/language/SPEC-v1.md +++ b/docs/language/SPEC-v1.md @@ -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 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.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 integrates 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_f64_value_result`, and `std.json.parse_null_value_result` consume one already-isolated primitive scalar token and return concrete - `(result ... i32)` values; full JSON document parsing, string/object/array - parsing, tokenizers, recursive `JsonValue`, Unicode escape handling, stable - ABI/layout, performance claims, and stable stdlib/API freeze remain out of - scope + `(result ... i32)` values; JSON document parsing beyond the beta21 scalar + helpers, string/object/array parsing, tokenizers, recursive `JsonValue`, + Unicode escape handling, stable ABI/layout, performance claims, and stable + stdlib/API freeze remain out of scope - `1.0.0-beta.18` JSON string token parsing target: `std.json.parse_string_value_result : (string) -> (result string i32)` consumes one already-isolated ASCII JSON string token with exact quotes and no leading/trailing whitespace, decodes simple JSON escapes, returns `err 1` for ordinary parse failure, and rejects raw control bytes, bad escapes, unterminated/trailing bytes, raw non-ASCII, and all `\uXXXX` escapes - for this slice; full JSON document parsing, object/array parsing, tokenizer - APIs, recursive `JsonValue`, Unicode escape decoding/normalization, embedded - NUL policy, stable ABI/layout, performance claims, and stable stdlib/API - freeze remain out of scope + for this slice; JSON document parsing beyond the beta21 scalar helpers, + object/array parsing, tokenizer APIs, recursive `JsonValue`, Unicode escape + decoding/normalization, embedded NUL policy, stable ABI/layout, performance + claims, and stable stdlib/API freeze remain out of scope - `1.0.0-beta.19` test discovery and user-project conformance target: `glagol test --list ` and legacy `glagol --run-tests --list ` 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 matching, regex, tokenizer APIs, language slice/view syntax, mutable 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 `string` values and returns an immutable runtime-owned `string`; existing 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_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_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.array0/array1/array2/array3 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 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 -single ASCII string-token helper, object/array parsing, recursive JSON values, -maps/sets, generic collections, tokenizer objects, streaming decoders or -encoders, schema validation, Unicode escape decoding or -normalization, embedded NUL policy, stable text encoding policy beyond the -current null-terminated runtime string ABI, stable runtime helper symbols, and -stable standard-library API guarantees remain deferred. +scalar document helpers, object/array parsing, recursive JSON values, maps/sets, +generic collections, tokenizer objects, streaming decoders or encoders, schema +validation, Unicode escape decoding or normalization beyond the existing +string-token behavior, embedded NUL policy, stable text encoding policy beyond +the current null-terminated runtime string ABI, stable runtime helper symbols, +and stable standard-library API guarantees remain deferred. ### 4.4.6 Post-Beta Concrete Type Alias Foundation diff --git a/docs/language/STDLIB_API.md b/docs/language/STDLIB_API.md index 1521b38..55c68f5 100644 --- a/docs/language/STDLIB_API.md +++ b/docs/language/STDLIB_API.md @@ -6,7 +6,7 @@ Do not edit this file by hand. ## Stability Tiers - `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. 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 - Modules: 19 -- Exported helper signatures: 596 +- Exported helper signatures: 604 - Exported type aliases omitted: 0 - Default tier: `beta-supported` @@ -193,7 +193,7 @@ Only exported `(fn ...)` helpers are listed; `(type ...)` aliases and non-export - Path: `lib/std/json.slo` - Tier: `beta-supported` -- Exported helper signatures: 32 +- Exported helper signatures: 40 - `quote_string ((value string)) -> 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_f64_value_result ((token string)) -> (result f64 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_bool ((name string) (value bool)) -> string` - `field_i32 ((name string) (value i32)) -> string` diff --git a/examples/projects/std-import-json/src/main.slo b/examples/projects/std-import-json/src/main.slo index a5f9880..b783757 100644 --- a/examples/projects/std-import-json/src/main.slo +++ b/examples/projects/std-import-json/src/main.slo @@ -1,6 +1,6 @@ (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) @@ -92,6 +92,57 @@ 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 (if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"") (if (= (field_bool "ok" true) "\"ok\":true") @@ -139,8 +190,14 @@ (if (imported_json_parse_scalar_failure) (if (imported_json_parse_string_success) (if (imported_json_parse_string_failure) - (if (imported_json_fields) - (imported_json_arrays_objects) + (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) + (imported_json_arrays_objects) + false) + false) + false) false) false) false) @@ -172,6 +229,15 @@ (test "explicit std json string token parse failure facade" (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" (imported_json_fields)) diff --git a/examples/projects/std-layout-local-json/src/json.slo b/examples/projects/std-layout-local-json/src/json.slo index 2c64baa..b7825c8 100644 --- a/examples/projects/std-layout-local-json/src/json.slo +++ b/examples/projects/std-layout-local-json/src/json.slo @@ -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) @@ -56,6 +58,30 @@ (ok bool i32 true) (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 (std.string.concat (std.string.concat (quote_string name) ":") encoded_value)) diff --git a/examples/projects/std-layout-local-json/src/main.slo b/examples/projects/std-layout-local-json/src/main.slo index 2caa205..09f30dc 100644 --- a/examples/projects/std-layout-local-json/src/main.slo +++ b/examples/projects/std-layout-local-json/src/main.slo @@ -1,6 +1,6 @@ (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) @@ -92,6 +92,57 @@ 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 (if (= (field_string "name" "slo\"vo") "\"name\":\"slo\\\"vo\"") (if (= (field_bool "ok" true) "\"ok\":true") @@ -139,8 +190,14 @@ (if (imported_json_parse_scalar_failure) (if (imported_json_parse_string_success) (if (imported_json_parse_string_failure) - (if (imported_json_fields) - (imported_json_arrays_objects) + (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) + (imported_json_arrays_objects) + false) + false) + false) false) false) false) @@ -172,6 +229,15 @@ (test "explicit local json string token parse failure facade" (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" (imported_json_fields)) diff --git a/examples/projects/std-layout-local-json/src/string.slo b/examples/projects/std-layout-local-json/src/string.slo new file mode 100644 index 0000000..056c937 --- /dev/null +++ b/examples/projects/std-layout-local-json/src/string.slo @@ -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))) diff --git a/lib/std/README.md b/lib/std/README.md index eaa6d26..eca9a86 100644 --- a/lib/std/README.md +++ b/lib/std/README.md @@ -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 booleans, concrete numeric primitives, and exact `null`; the Slovo-facing `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 using local `JsonText` and `JsonField` aliases as transparent names for `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 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 -token over the matching promoted runtime helper. Full JSON document parsing, -object/array parsing, recursive JSON values, maps/sets, streaming decoders or -encoders, schema validation, Unicode escape decoding/normalization, embedded -NUL policy, and stable text encoding policy remain deferred; +token over the matching promoted runtime helper. The +`1.0.0-beta.21` JSON foundation adds source-authored +`parse_*_document_result` helpers for string, bool, concrete numeric +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 uses `JsonText` / `JsonField` only as local transparent aliases inside `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`, `u32`, `i64`, `u64`, `f64`, and exact `null` only. The `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 -parser and does not define object/array parsing, recursive JSON values, -maps/sets, streaming decoders or encoders, schema validation, Unicode escape -decoding/normalization, embedded NUL policy, or stable text encoding policy -beyond the current runtime string ABI. +ASCII JSON string token with simple escape decoding. The +`1.0.0-beta.21` source facade adds `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`; 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 released process argument runtime calls and a source-authored `has_arg` predicate. exp-61 adds `arg_or` and `arg_or_empty` as ordinary source diff --git a/lib/std/json.slo b/lib/std/json.slo index 2c64baa..2b14ff3 100644 --- a/lib/std/json.slo +++ b/lib/std/json.slo @@ -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) @@ -56,6 +58,30 @@ (ok bool i32 true) (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 (std.string.concat (std.string.concat (quote_string name) ":") encoded_value)) diff --git a/scripts/release-gate.sh b/scripts/release-gate.sh index 41007b0..596188f 100755 --- a/scripts/release-gate.sh +++ b/scripts/release-gate.sh @@ -71,6 +71,7 @@ cargo test --test standard_json_scalar_parsing_beta17 cargo test --test standard_json_string_parsing_beta18 cargo test --test test_discovery_beta19 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, # beta_v2_0_0_beta_1, and beta_1_0_0. cargo test