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

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-12T10:26:23Z";
var SX_VERSION = "2026-03-12T18:28:35Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -3739,6 +3739,189 @@ callExpr.push(dictGet(kwargs, k)); } }
})();
})()); };
// _count-leading-dots
var _countLeadingDots = function(s) { return (isSxTruthy(isEmpty(s)) ? 0 : (isSxTruthy(startsWith(s, ".")) ? (1 + _countLeadingDots(slice(s, 1))) : 0)); };
// _strip-trailing-close
var _stripTrailingClose = function(s) { return (isSxTruthy(endsWith(s, ")")) ? _stripTrailingClose(slice(s, 0, (len(s) - 1))) : s); };
// _index-of-safe
var _indexOfSafe = function(s, needle) { return (function() {
var idx = indexOf_(s, needle);
return (isSxTruthy(sxOr(isNil(idx), (idx < 0))) ? NIL : idx);
})(); };
// _last-index-of
var _lastIndexOf = function(s, needle) { return (function() {
var idx = _indexOfSafe(s, needle);
return (isSxTruthy(isNil(idx)) ? NIL : (function() {
var restIdx = _lastIndexOf(slice(s, (idx + 1)), needle);
return (isSxTruthy(isNil(restIdx)) ? idx : ((idx + 1) + restIdx));
})());
})(); };
// _pop-sx-url-level
var _popSxUrlLevel = function(url) { return (function() {
var stripped = _stripTrailingClose(url);
var closeCount = (len(url) - len(_stripTrailingClose(url)));
return (isSxTruthy((closeCount <= 1)) ? "/" : (function() {
var lastDp = _lastIndexOf(stripped, ".(");
return (isSxTruthy(isNil(lastDp)) ? "/" : (String(slice(stripped, 0, lastDp)) + String(slice(url, (len(url) - (closeCount - 1))))));
})());
})(); };
// _pop-sx-url-levels
var _popSxUrlLevels = function(url, n) { return (isSxTruthy((n <= 0)) ? url : _popSxUrlLevels(_popSxUrlLevel(url), (n - 1))); };
// _split-pos-kw
var _splitPosKw = function(tokens, i, pos, kw) { return (isSxTruthy((i >= len(tokens))) ? {"positional": join(".", pos), "keywords": kw} : (function() {
var tok = nth(tokens, i);
return (isSxTruthy(startsWith(tok, ":")) ? (function() {
var val = (isSxTruthy(((i + 1) < len(tokens))) ? nth(tokens, (i + 1)) : "");
return _splitPosKw(tokens, (i + 2), pos, append(kw, [[tok, val]]));
})() : _splitPosKw(tokens, (i + 1), append(pos, [tok]), kw));
})()); };
// _parse-relative-body
var _parseRelativeBody = function(body) { return (isSxTruthy(isEmpty(body)) ? {"positional": "", "keywords": []} : _splitPosKw(split(body, "."), 0, [], [])); };
// _extract-innermost
var _extractInnermost = function(url) { return (function() {
var stripped = _stripTrailingClose(url);
var suffix = slice(url, len(_stripTrailingClose(url)));
return (function() {
var lastDp = _lastIndexOf(stripped, ".(");
return (isSxTruthy(isNil(lastDp)) ? {"before": "/(", "content": slice(stripped, 2), "suffix": suffix} : {"before": slice(stripped, 0, (lastDp + 2)), "content": slice(stripped, (lastDp + 2)), "suffix": suffix});
})();
})(); };
// _find-kw-in-tokens
var _findKwInTokens = function(tokens, i, kw) { return (isSxTruthy((i >= len(tokens))) ? NIL : (isSxTruthy((isSxTruthy((nth(tokens, i) == kw)) && ((i + 1) < len(tokens)))) ? nth(tokens, (i + 1)) : _findKwInTokens(tokens, (i + 1), kw))); };
// _find-keyword-value
var _findKeywordValue = function(content, kw) { return _findKwInTokens(split(content, "."), 0, kw); };
// _replace-kw-in-tokens
var _replaceKwInTokens = function(tokens, i, kw, value) { return (isSxTruthy((i >= len(tokens))) ? [] : (isSxTruthy((isSxTruthy((nth(tokens, i) == kw)) && ((i + 1) < len(tokens)))) ? append([kw, value], _replaceKwInTokens(tokens, (i + 2), kw, value)) : cons(nth(tokens, i), _replaceKwInTokens(tokens, (i + 1), kw, value)))); };
// _set-keyword-in-content
var _setKeywordInContent = function(content, kw, value) { return (function() {
var current = _findKeywordValue(content, kw);
return (isSxTruthy(isNil(current)) ? (String(content) + String(".") + String(kw) + String(".") + String(value)) : join(".", _replaceKwInTokens(split(content, "."), 0, kw, value)));
})(); };
// _is-delta-value?
var _isDeltaValue_p = function(s) { return (isSxTruthy(!isSxTruthy(isEmpty(s))) && isSxTruthy((len(s) > 1)) && sxOr(startsWith(s, "+"), startsWith(s, "-"))); };
// _apply-delta
var _applyDelta = function(currentStr, deltaStr) { return (function() {
var cur = parseInt_(currentStr, NIL);
var delta = parseInt_(deltaStr, NIL);
return (isSxTruthy(sxOr(isNil(cur), isNil(delta))) ? deltaStr : (String((cur + delta))));
})(); };
// _apply-kw-pairs
var _applyKwPairs = function(content, kwPairs) { return (isSxTruthy(isEmpty(kwPairs)) ? content : (function() {
var pair = first(kwPairs);
var kw = first(pair);
var rawVal = nth(pair, 1);
return (function() {
var actualVal = (isSxTruthy(_isDeltaValue_p(rawVal)) ? (function() {
var current = _findKeywordValue(content, kw);
return (isSxTruthy(isNil(current)) ? rawVal : _applyDelta(current, rawVal));
})() : rawVal);
return _applyKwPairs(_setKeywordInContent(content, kw, actualVal), rest(kwPairs));
})();
})()); };
// _apply-keywords-to-url
var _applyKeywordsToUrl = function(url, kwPairs) { return (isSxTruthy(isEmpty(kwPairs)) ? url : (function() {
var parts = _extractInnermost(url);
return (function() {
var newContent = _applyKwPairs(get(parts, "content"), kwPairs);
return (String(get(parts, "before")) + String(newContent) + String(get(parts, "suffix")));
})();
})()); };
// _normalize-relative
var _normalizeRelative = function(url) { return (isSxTruthy(startsWith(url, "(")) ? url : (String("(") + String(url) + String(")"))); };
// resolve-relative-url
var resolveRelativeUrl = function(current, relative) { return (function() {
var canonical = _normalizeRelative(relative);
return (function() {
var relInner = slice(canonical, 1, (len(canonical) - 1));
return (function() {
var dots = _countLeadingDots(relInner);
var body = slice(relInner, _countLeadingDots(relInner));
return (isSxTruthy((dots == 0)) ? current : (function() {
var parsed = _parseRelativeBody(body);
var posBody = get(parsed, "positional");
var kwPairs = get(parsed, "keywords");
return (function() {
var afterNav = (isSxTruthy((dots == 1)) ? (isSxTruthy(isEmpty(posBody)) ? current : (function() {
var stripped = _stripTrailingClose(current);
var suffix = slice(current, len(_stripTrailingClose(current)));
return (String(stripped) + String(".") + String(posBody) + String(suffix));
})()) : (function() {
var base = _popSxUrlLevels(current, (dots - 1));
return (isSxTruthy(isEmpty(posBody)) ? base : (isSxTruthy((base == "/")) ? (String("/(") + String(posBody) + String(")")) : (function() {
var stripped = _stripTrailingClose(base);
var suffix = slice(base, len(_stripTrailingClose(base)));
return (String(stripped) + String(".(") + String(posBody) + String(")") + String(suffix));
})()));
})());
return _applyKeywordsToUrl(afterNav, kwPairs);
})();
})());
})();
})();
})(); };
// relative-sx-url?
var relativeSxUrl_p = function(url) { return sxOr((isSxTruthy(startsWith(url, "(")) && !isSxTruthy(startsWith(url, "/("))), startsWith(url, ".")); };
// _url-special-forms
var _urlSpecialForms = function() { return ["!source", "!inspect", "!diff", "!search", "!raw", "!json"]; };
// url-special-form?
var urlSpecialForm_p = function(name) { return (isSxTruthy(startsWith(name, "!")) && contains(_urlSpecialForms(), name)); };
// parse-sx-url
var parseSxUrl = function(url) { return (isSxTruthy((url == "/")) ? {"type": "home", "raw": url} : (isSxTruthy(relativeSxUrl_p(url)) ? {"type": "relative", "raw": url} : (isSxTruthy((isSxTruthy(startsWith(url, "/(!")) && endsWith(url, ")"))) ? (function() {
var inner = slice(url, 2, (len(url) - 1));
return (function() {
var dotPos = _indexOfSafe(inner, ".");
var parenPos = _indexOfSafe(inner, "(");
return (function() {
var endPos = (isSxTruthy((isSxTruthy(isNil(dotPos)) && isNil(parenPos))) ? len(inner) : (isSxTruthy(isNil(dotPos)) ? parenPos : (isSxTruthy(isNil(parenPos)) ? dotPos : min(dotPos, parenPos))));
return (function() {
var formName = slice(inner, 0, endPos);
var restPart = slice(inner, endPos);
return (function() {
var innerExpr = (isSxTruthy(startsWith(restPart, ".")) ? slice(restPart, 1) : restPart);
return {"type": "special-form", "form": formName, "inner": innerExpr, "raw": url};
})();
})();
})();
})();
})() : (isSxTruthy((isSxTruthy(startsWith(url, "/(~")) && endsWith(url, ")"))) ? (function() {
var name = slice(url, 2, (len(url) - 1));
return {"type": "direct-component", "name": name, "raw": url};
})() : (isSxTruthy((isSxTruthy(startsWith(url, "/(")) && endsWith(url, ")"))) ? {"type": "absolute", "raw": url} : {"type": "path", "raw": url}))))); };
// url-special-form-name
var urlSpecialFormName = function(url) { return (function() {
var parsed = parseSxUrl(url);
return (isSxTruthy((get(parsed, "type") == "special-form")) ? get(parsed, "form") : NIL);
})(); };
// url-special-form-inner
var urlSpecialFormInner = function(url) { return (function() {
var parsed = parseSxUrl(url);
return (isSxTruthy((get(parsed, "type") == "special-form")) ? get(parsed, "inner") : NIL);
})(); };
// === Transpiled from signals (reactive signal runtime) ===