Skip to content

feat(solo/stdlib): json_parse / json_stringify (+ fix string-literal escapes)#53

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/solo-stdlib-json
May 18, 2026
Merged

feat(solo/stdlib): json_parse / json_stringify (+ fix string-literal escapes)#53
hyperpolymath merged 1 commit into
mainfrom
feat/solo-stdlib-json

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Second Phase-2 stdlib primitive (tracker #45), unblocked by Map (#46/#49).

What

  • json_parse(s) -> Value / json_stringify(v) -> String, backed by serde_json (promoted to a non-optional dep of my-lang; serde derive stays behind the serde feature).
  • Representation pairs with the Map builtins: object↔Record, array↔Array, integral number→Int else Float, string↔String, bool↔Bool, null↔Unit. Non-serializable values (functions/AI results, NaN/Inf floats) error cleanly.
  • Object keys serialize sorted (serde_json default BTreeMap) — same deterministic ordering as map_keys.

Prerequisite bug fixed (in scope — feature is unusable without it)

The lexer stored the raw slice between quotes and escape sequences were decoded nowhere. "a\"b" yielded the literal 4 chars a \ " b, and json_parse("{\"k\":1}") — issue #45's own repro — could not parse. parse_string_literal now decodes \" \\ \/ \n \t \r \0 and \uXXXX / \u{...}. Unknown escapes pass through leniently (backslash dropped, char kept) so no previously-valid program changes behavior except where it was already wrong.

Validation

  • examples/json.my runs and matches its documented output.
  • New regression tests: test_eval_json_roundtrip (sorted-key round-trip) and test_eval_string_escapes. Full suite 17 passed, 0 failed.
  • New code is rustfmt-clean and clippy-clean. Pre-existing fmt drift elsewhere in stdlib.rs left untouched (out of scope, consistent with PR feat(solo/stdlib): string-keyed Map/dict builtins #49).

Scope notes

vscode-extension/package-lock.json (pre-existing untracked) not included. Cargo.lock is gitignored in this repo.

Refs #45
Refs #47

🤖 Generated with Claude Code

Adds json_parse(s)->Value and json_stringify(v)->String, backed by
serde_json (promoted to a non-optional dependency of my-lang; serde
derive stays behind the `serde` feature). Mapping pairs with the Map
builtins (#46): object<->Record, array<->Array, integral number->Int
else Float, null<->Unit. Object keys serialize sorted (serde_json's
default BTreeMap), matching map_keys' deterministic ordering.

Also fixes a prerequisite latent bug: the lexer stored raw string-literal
slices and escape sequences were never decoded anywhere, so `"a\"b"`
yielded the four chars a \ " b and json_parse("{\"k\":1}") — issue #45's
own repro — was unparseable. parse_string_literal now decodes the
standard escapes (\" \\ \/ \n \t \r \0, \uXXXX / \u{...}); unknown
escapes pass through leniently so no previously-valid program breaks.

Adds examples/json.my and integration regression tests for both the JSON
round-trip (deterministic sorted keys) and string-escape decoding.

Rebased onto main after #49 (Map) landed; coexists with map_* builtins.

Refs #45
Refs #47

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hyperpolymath hyperpolymath force-pushed the feat/solo-stdlib-json branch from 9e12d7a to b6ef7b4 Compare May 18, 2026 09:56
@hyperpolymath hyperpolymath merged commit ffdd63a into main May 18, 2026
14 of 15 checks passed
@hyperpolymath hyperpolymath deleted the feat/solo-stdlib-json branch May 18, 2026 09:56
hyperpolymath added a commit that referenced this pull request May 18, 2026
time() only yields a Unix timestamp float; tooling that stamps generated
artifacts (changelogs, scaffolds) needs a calendar date. date_today()
returns the current UTC date as an ISO `YYYY-MM-DD` string.

Civil date derived from SystemTime epoch seconds via Howard Hinnant's
civil_from_days algorithm (public domain) — no date-crate dependency,
correct for all Gregorian dates. Verified: produces 2026-05-18 today.

Adds examples/date.my and an integration test asserting format/shape and
a sane range (exact value depends on the wall clock).

Rebased onto main after #49 (Map) and #53 (JSON) landed; coexists with
the map_* / json_* builtins.

Refs #45
Refs #48

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 18, 2026
time() only yields a Unix timestamp float; tooling that stamps generated
artifacts (changelogs, scaffolds) needs a calendar date. date_today()
returns the current UTC date as an ISO `YYYY-MM-DD` string.

Civil date derived from SystemTime epoch seconds via Howard Hinnant's
civil_from_days algorithm (public domain) — no date-crate dependency,
correct for all Gregorian dates. Verified: produces 2026-05-18 today.

Adds examples/date.my and an integration test asserting format/shape and
a sane range (exact value depends on the wall clock).

Rebased onto main after #49 (Map) and #53 (JSON) landed; coexists with
the map_* / json_* builtins.

Refs #45
Refs #48

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request May 18, 2026
#46/#47/#48 closed and merged via PR #49/#53/#54. The roadmap table
still showed them as Planned / In flight; sync to reality. IMPLEMENTATION.md
already lists them as builtins; this aligns the human-facing roadmap.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 35 issues detected

Severity Count
🔴 Critical 6
🟠 High 11
🟡 Medium 18

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Issue in quality.yml",
    "type": "missing_workflow",
    "file": "quality.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in security-policy.yml",
    "type": "missing_workflow",
    "file": "security-policy.yml",
    "action": "create",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "unwrap_or(0) with dangerous default (1 occurrences, CWE-754)",
    "type": "unwrap_dangerous_default",
    "file": "/home/runner/work/my-lang/my-lang/_exploratory/me-scaffolding/crates/parser/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "expect() in hot path (80 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/my-lang/my-lang/_exploratory/me-scaffolding/crates/parser/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (1 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/my-lang/my-lang/my-ssg/src/generator.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "expect() in hot path (5 occurrences, CWE-754)",
    "type": "expect_in_hot_path",
    "file": "/home/runner/work/my-lang/my-lang/crates/my-mir/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "medium"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (26 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/my-lang/my-lang/crates/my-fmt/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (1 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/my-lang/my-lang/crates/my-hir/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "unwrap() without prior check -- DoS via panic (3 occurrences, CWE-754)",
    "type": "unwrap_without_check",
    "file": "/home/runner/work/my-lang/my-lang/crates/my-llvm/src/lib.rs",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant