SX URL algebra: relative resolution, keyword ops, ! special forms

Extends router.sx with the full SX URL algebra — structural navigation
(.slug, .., ...), keyword set/delta (.:page.4, .:page.+1), bare-dot
shorthand, and ! special form parsing (!source, !inspect, !diff, !search,
!raw, !json). All pure SX spec, bootstrapped to both Python and JS.

Fixes: index-of -1/nil portability (_index-of-safe wrapper), variadic
(+ a b c) transpilation bug (use nested binary +). Includes 115 passing
tests covering all operations. Also: "The" strapline and essay title.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-12 18:31:21 +00:00
parent 7a1d1e9ea2
commit b23e81730c
8 changed files with 1554 additions and 26 deletions

View File

@@ -422,19 +422,52 @@ env["append!"] = _append_mut
def _load_router_from_bootstrap(env):
"""Load router functions from the bootstrapped sx_ref.py.
The hand-written evaluator can't run router.sx faithfully because
set! inside lambda closures doesn't propagate to outer scopes
(the evaluator uses dict copies, not cells). The bootstrapped code
compiles set! to cell-based mutation, so we import from there.
The hand-written evaluator can't run router.sx faithfully because:
1. set! inside lambda closures doesn't propagate to outer scopes
2. Deep recursive function chains exceed Python stack depth
The bootstrapped code compiles to native Python, avoiding both issues.
Build sx_ref.py with --spec-modules=router to include these functions.
"""
try:
from shared.sx.ref.sx_ref import (
# Original route matching
split_path_segments,
parse_route_pattern,
match_route_segments,
match_route,
find_matching_route,
make_route_segment,
# SX URL conversion
sx_url_to_path,
_fn_to_segment,
# Relative URL resolution
resolve_relative_url,
relative_sx_url_p,
_normalize_relative,
_count_leading_dots,
_strip_trailing_close,
_last_index_of,
_pop_sx_url_level,
_pop_sx_url_levels,
# Keyword operations
_extract_innermost,
_find_keyword_value,
_find_kw_in_tokens,
_set_keyword_in_content,
_replace_kw_in_tokens,
_is_delta_value_p,
_apply_delta,
_apply_kw_pairs,
_apply_keywords_to_url,
_parse_relative_body,
_split_pos_kw,
# URL special forms
parse_sx_url,
url_special_form_p,
url_special_form_name,
url_special_form_inner,
_url_special_forms,
)
env["split-path-segments"] = split_path_segments
env["parse-route-pattern"] = parse_route_pattern
@@ -442,8 +475,34 @@ def _load_router_from_bootstrap(env):
env["match-route"] = match_route
env["find-matching-route"] = find_matching_route
env["make-route-segment"] = make_route_segment
env["sx-url-to-path"] = sx_url_to_path
env["_fn-to-segment"] = _fn_to_segment
env["resolve-relative-url"] = resolve_relative_url
env["relative-sx-url?"] = relative_sx_url_p
env["_normalize-relative"] = _normalize_relative
env["_count-leading-dots"] = _count_leading_dots
env["_strip-trailing-close"] = _strip_trailing_close
env["_last-index-of"] = _last_index_of
env["_pop-sx-url-level"] = _pop_sx_url_level
env["_pop-sx-url-levels"] = _pop_sx_url_levels
env["_extract-innermost"] = _extract_innermost
env["_find-keyword-value"] = _find_keyword_value
env["_find-kw-in-tokens"] = _find_kw_in_tokens
env["_set-keyword-in-content"] = _set_keyword_in_content
env["_replace-kw-in-tokens"] = _replace_kw_in_tokens
env["_is-delta-value?"] = _is_delta_value_p
env["_apply-delta"] = _apply_delta
env["_apply-kw-pairs"] = _apply_kw_pairs
env["_apply-keywords-to-url"] = _apply_keywords_to_url
env["_parse-relative-body"] = _parse_relative_body
env["_split-pos-kw"] = _split_pos_kw
env["parse-sx-url"] = parse_sx_url
env["url-special-form?"] = url_special_form_p
env["url-special-form-name"] = url_special_form_name
env["url-special-form-inner"] = url_special_form_inner
env["_url-special-forms"] = _url_special_forms
except ImportError:
# Fallback: eval router.sx directly (may fail on set! scoping)
# Fallback: eval router.sx directly (may fail on set!/recursion)
eval_file("router.sx", env)