HS parser: fix number+comparison keyword collision, eval-hs uses hs-compile
Parser: skip unit suffix when next ident is a comparison keyword (starts, ends, contains, matches, is, does, in, precedes, follows). Fixes "123 starts with '12'" returning "123starts" instead of true. eval-hs: use hs-compile directly instead of hs-to-sx-from-source with "return " prefix, which was causing the parser to consume the comparison as a string suffix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
sx/sx/specs-explorer/spec-effect-badge.sx
Normal file
15
sx/sx/specs-explorer/spec-effect-badge.sx
Normal file
@@ -0,0 +1,15 @@
|
||||
(defcomp
|
||||
(&key effect)
|
||||
(span
|
||||
:class (str
|
||||
"text-xs px-1.5 py-0.5 rounded "
|
||||
(case
|
||||
effect
|
||||
"mutation"
|
||||
"bg-amber-100 text-amber-700"
|
||||
"io"
|
||||
"bg-orange-100 text-orange-700"
|
||||
"render"
|
||||
"bg-sky-100 text-sky-700"
|
||||
:else "bg-stone-100 text-stone-500"))
|
||||
effect))
|
||||
24
sx/sx/specs-explorer/spec-explorer-content.sx
Normal file
24
sx/sx/specs-explorer/spec-explorer-content.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
(defcomp
|
||||
(&key data)
|
||||
:affinity :server
|
||||
(let-match
|
||||
{:stats stats :desc desc :title title :filename filename :platform-interface platform-interface :sections sections}
|
||||
data
|
||||
(~docs/page
|
||||
:title (str title " — Explorer")
|
||||
(~specs-explorer/spec-explorer-header
|
||||
:filename filename
|
||||
:title title
|
||||
:desc desc
|
||||
:slug (replace filename ".sx" ""))
|
||||
(~specs-explorer/spec-explorer-stats :stats stats)
|
||||
(map
|
||||
(fn
|
||||
(section)
|
||||
(~specs-explorer/spec-explorer-section
|
||||
:section section
|
||||
:filename filename))
|
||||
sections)
|
||||
(when
|
||||
(not (empty? platform-interface))
|
||||
(~specs-explorer/spec-platform-interface :items platform-interface)))))
|
||||
55
sx/sx/specs-explorer/spec-explorer-define-detail.sx
Normal file
55
sx/sx/specs-explorer/spec-explorer-define-detail.sx
Normal file
@@ -0,0 +1,55 @@
|
||||
(defcomp
|
||||
(&key d filename)
|
||||
:affinity :server
|
||||
(div
|
||||
(~tw :tokens "max-w-3xl mx-auto")
|
||||
(div
|
||||
(~tw :tokens "mb-4")
|
||||
(a
|
||||
(~tw :tokens "text-sm text-violet-600 hover:text-violet-800")
|
||||
:href (str
|
||||
"/sx/(language.(spec.(explore."
|
||||
(replace filename ".sx" "")
|
||||
")))")
|
||||
:sx-get (str
|
||||
"/sx/(language.(spec.(explore."
|
||||
(replace filename ".sx" "")
|
||||
")))")
|
||||
:sx-target "#sx-content"
|
||||
:sx-select "#sx-content"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-push-url "true"
|
||||
(str "← Back to " (replace filename ".sx" ""))))
|
||||
(let-match
|
||||
{:kind kind :effects effects :params params :source source :name name}
|
||||
d
|
||||
(div
|
||||
(~tw :tokens "rounded border border-violet-200 bg-violet-50/30 p-4")
|
||||
(div
|
||||
(~tw :tokens "flex items-center gap-2 flex-wrap mb-3")
|
||||
(span
|
||||
(~tw :tokens "font-mono text-lg font-semibold text-stone-800")
|
||||
name)
|
||||
(span (~tw :tokens "text-xs text-stone-400") kind)
|
||||
(if
|
||||
(empty? effects)
|
||||
(span
|
||||
(~tw
|
||||
:tokens "text-xs px-1.5 py-0.5 rounded bg-green-100 text-green-700")
|
||||
"pure")
|
||||
(map
|
||||
(fn (eff) (~specs-explorer/spec-effect-badge :effect eff))
|
||||
effects)))
|
||||
(when
|
||||
(not (empty? params))
|
||||
(~specs-explorer/spec-param-list :params params))
|
||||
(details
|
||||
:open "true"
|
||||
(summary
|
||||
(~tw
|
||||
:tokens "px-3 py-1.5 bg-stone-50 text-xs font-medium text-stone-600 cursor-pointer select-none mt-3 rounded")
|
||||
"SX Source")
|
||||
(pre
|
||||
(~tw
|
||||
:tokens "text-xs p-3 overflow-x-auto bg-white rounded mt-1 border border-stone-200")
|
||||
(code (~tw :tokens "language-sx") source)))))))
|
||||
24
sx/sx/specs-explorer/spec-explorer-define.sx
Normal file
24
sx/sx/specs-explorer/spec-explorer-define.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
(defcomp
|
||||
(&key d filename)
|
||||
(let-match
|
||||
{:kind kind :name name}
|
||||
d
|
||||
(div
|
||||
(~tw
|
||||
:tokens "flex items-center gap-2 py-1.5 px-2 rounded hover:bg-stone-50 cursor-pointer group")
|
||||
:id (str "fn-" name)
|
||||
:sx-get (str
|
||||
"/sx/(language.(spec.(explore."
|
||||
(replace filename ".sx" "")
|
||||
"."
|
||||
name
|
||||
")))")
|
||||
:sx-target "#sx-content"
|
||||
:sx-select "#sx-content"
|
||||
:sx-swap "innerHTML"
|
||||
:sx-push-url "true"
|
||||
(span
|
||||
(~tw
|
||||
:tokens "font-mono text-sm font-medium text-stone-800 group-hover:text-violet-700")
|
||||
name)
|
||||
(span (~tw :tokens "text-xs text-stone-400") kind))))
|
||||
19
sx/sx/specs-explorer/spec-explorer-header.sx
Normal file
19
sx/sx/specs-explorer/spec-explorer-header.sx
Normal file
@@ -0,0 +1,19 @@
|
||||
(defcomp
|
||||
(&key filename title desc slug)
|
||||
(div
|
||||
(~tw :tokens "mb-6")
|
||||
(div
|
||||
(~tw :tokens "flex items-center justify-between")
|
||||
(div
|
||||
(h1 (~tw :tokens "text-2xl font-bold text-stone-800") title)
|
||||
(p (~tw :tokens "text-sm text-stone-500 mt-1") desc))
|
||||
(a
|
||||
:href (str "/sx/(language.(spec." slug "))")
|
||||
:sx-get (str "/sx/(language.(spec." slug "))")
|
||||
:sx-target "#sx-content"
|
||||
:sx-select "#sx-content"
|
||||
:sx-swap "outerHTML"
|
||||
:sx-push-url "true"
|
||||
(~tw :tokens "text-sm text-violet-600 hover:text-violet-800 font-medium")
|
||||
"View Source"))
|
||||
(p (~tw :tokens "text-xs text-stone-400 font-mono mt-2") filename)))
|
||||
20
sx/sx/specs-explorer/spec-explorer-section.sx
Normal file
20
sx/sx/specs-explorer/spec-explorer-section.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
(defcomp
|
||||
(&key section filename)
|
||||
(let-match
|
||||
{:defines defines :title title :comment comment}
|
||||
section
|
||||
(div
|
||||
(~tw :tokens "mb-6")
|
||||
(h2
|
||||
(~tw
|
||||
:tokens "text-base font-semibold text-stone-600 mb-2 border-b border-stone-200 pb-1")
|
||||
:id (replace (lower title) " " "-")
|
||||
title)
|
||||
(when comment (p (~tw :tokens "text-sm text-stone-500 mb-2") comment))
|
||||
(div
|
||||
(~tw :tokens "space-y-0.5")
|
||||
(map
|
||||
(fn
|
||||
(d)
|
||||
(~specs-explorer/spec-explorer-define :d d :filename filename))
|
||||
defines)))))
|
||||
39
sx/sx/specs-explorer/spec-explorer-stats.sx
Normal file
39
sx/sx/specs-explorer/spec-explorer-stats.sx
Normal file
@@ -0,0 +1,39 @@
|
||||
(defcomp
|
||||
(&key stats)
|
||||
(let-match
|
||||
{:lines lines :io-count io-count :render-count render-count :pure-count pure-count :mutation-count mutation-count :test-total test-total :total-defines total-defines}
|
||||
stats
|
||||
(div
|
||||
(~tw :tokens "flex flex-wrap gap-2 mb-6 text-xs")
|
||||
(span
|
||||
(~tw
|
||||
:tokens "bg-stone-100 text-stone-600 px-2 py-0.5 rounded font-medium")
|
||||
(str total-defines " defines"))
|
||||
(when
|
||||
(> pure-count 0)
|
||||
(span
|
||||
(~tw :tokens "bg-green-100 text-green-700 px-2 py-0.5 rounded")
|
||||
(str pure-count " pure")))
|
||||
(when
|
||||
(> mutation-count 0)
|
||||
(span
|
||||
(~tw :tokens "bg-amber-100 text-amber-700 px-2 py-0.5 rounded")
|
||||
(str mutation-count " mutation")))
|
||||
(when
|
||||
(> io-count 0)
|
||||
(span
|
||||
(~tw :tokens "bg-orange-100 text-orange-700 px-2 py-0.5 rounded")
|
||||
(str io-count " io")))
|
||||
(when
|
||||
(> render-count 0)
|
||||
(span
|
||||
(~tw :tokens "bg-sky-100 text-sky-700 px-2 py-0.5 rounded")
|
||||
(str render-count " render")))
|
||||
(when
|
||||
(> test-total 0)
|
||||
(span
|
||||
(~tw :tokens "bg-violet-100 text-violet-700 px-2 py-0.5 rounded")
|
||||
(str test-total " tests")))
|
||||
(span
|
||||
(~tw :tokens "bg-stone-100 text-stone-500 px-2 py-0.5 rounded")
|
||||
(str lines " lines")))))
|
||||
24
sx/sx/specs-explorer/spec-param-list.sx
Normal file
24
sx/sx/specs-explorer/spec-param-list.sx
Normal file
@@ -0,0 +1,24 @@
|
||||
(defcomp
|
||||
(&key params)
|
||||
(div
|
||||
(~tw :tokens "mt-1 flex flex-wrap gap-1")
|
||||
(map
|
||||
(fn
|
||||
(p)
|
||||
(let-match
|
||||
{:type typ :name name}
|
||||
p
|
||||
(if
|
||||
(or (= name "&rest") (= name "&key"))
|
||||
(span (~tw :tokens "text-xs font-mono text-violet-500") name)
|
||||
(span
|
||||
(~tw
|
||||
:tokens "text-xs font-mono px-1 py-0.5 rounded bg-stone-50 border border-stone-200")
|
||||
(if
|
||||
typ
|
||||
(<>
|
||||
(span (~tw :tokens "text-stone-700") name)
|
||||
(span (~tw :tokens "text-stone-400") " : ")
|
||||
(span (~tw :tokens "text-violet-600") typ))
|
||||
(span (~tw :tokens "text-stone-700") name))))))
|
||||
params)))
|
||||
46
sx/sx/specs-explorer/spec-platform-interface.sx
Normal file
46
sx/sx/specs-explorer/spec-platform-interface.sx
Normal file
@@ -0,0 +1,46 @@
|
||||
(defcomp
|
||||
(&key items)
|
||||
(div
|
||||
(~tw :tokens "mt-8")
|
||||
(h2
|
||||
(~tw
|
||||
:tokens "text-lg font-semibold text-stone-700 border-b border-stone-200 pb-1 mb-3")
|
||||
"Platform Interface")
|
||||
(p
|
||||
(~tw :tokens "text-sm text-stone-500 mb-3")
|
||||
"Functions the host platform must provide.")
|
||||
(div
|
||||
(~tw :tokens "overflow-x-auto rounded border border-stone-200")
|
||||
(table
|
||||
(~tw :tokens "w-full text-left text-sm")
|
||||
(thead
|
||||
(tr
|
||||
(~tw :tokens "border-b border-stone-200 bg-stone-50")
|
||||
(th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Name")
|
||||
(th (~tw :tokens "px-3 py-2 font-medium text-stone-600") "Params")
|
||||
(th
|
||||
(~tw :tokens "px-3 py-2 font-medium text-stone-600")
|
||||
"Returns")
|
||||
(th
|
||||
(~tw :tokens "px-3 py-2 font-medium text-stone-600")
|
||||
"Description")))
|
||||
(tbody
|
||||
(map
|
||||
(fn
|
||||
(item)
|
||||
(let-match
|
||||
{:doc doc :params params :returns returns :name name}
|
||||
item
|
||||
(tr
|
||||
(~tw :tokens "border-b border-stone-100")
|
||||
(td
|
||||
(~tw :tokens "px-3 py-2 font-mono text-sm text-violet-700")
|
||||
name)
|
||||
(td
|
||||
(~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
|
||||
params)
|
||||
(td
|
||||
(~tw :tokens "px-3 py-2 font-mono text-xs text-stone-500")
|
||||
returns)
|
||||
(td (~tw :tokens "px-3 py-2 text-stone-600") doc))))
|
||||
items))))))
|
||||
15
sx/sx/specs-explorer/spec-ring-bridge.sx
Normal file
15
sx/sx/specs-explorer/spec-ring-bridge.sx
Normal file
@@ -0,0 +1,15 @@
|
||||
(defcomp
|
||||
(&key refs)
|
||||
(div
|
||||
(~tw :tokens "mt-2")
|
||||
(span (~tw :tokens "text-xs font-medium text-stone-500") "References")
|
||||
(div
|
||||
(~tw :tokens "flex flex-wrap gap-1 mt-1")
|
||||
(map
|
||||
(fn
|
||||
(ref)
|
||||
(a
|
||||
:href (str "#fn-" ref)
|
||||
(~tw :tokens "text-xs px-1.5 py-0.5 rounded bg-stone-100 text-stone-600 font-mono hover:bg-stone-200")
|
||||
ref))
|
||||
refs))))
|
||||
20
sx/sx/specs-explorer/spec-ring-runtime.sx
Normal file
20
sx/sx/specs-explorer/spec-ring-runtime.sx
Normal file
@@ -0,0 +1,20 @@
|
||||
(defcomp
|
||||
(&key tests test-count)
|
||||
(div
|
||||
(~tw :tokens "mt-2")
|
||||
(div
|
||||
(~tw :tokens "flex items-center gap-1")
|
||||
(span (~tw :tokens "text-xs font-medium text-stone-500") "Tests")
|
||||
(span
|
||||
(~tw :tokens "text-xs px-1.5 py-0.5 rounded bg-violet-100 text-violet-700")
|
||||
(str test-count)))
|
||||
(ul
|
||||
(~tw :tokens "mt-1 text-xs text-stone-500 list-none")
|
||||
(map
|
||||
(fn
|
||||
(t)
|
||||
(li
|
||||
(~tw :tokens "flex items-center gap-1")
|
||||
(span (~tw :tokens "text-green-500 text-xs") "●")
|
||||
(get t "name")))
|
||||
tests))))
|
||||
40
sx/sx/specs-explorer/spec-ring-translations.sx
Normal file
40
sx/sx/specs-explorer/spec-ring-translations.sx
Normal file
@@ -0,0 +1,40 @@
|
||||
(defcomp
|
||||
(&key source python javascript z3)
|
||||
(when
|
||||
(not (= source ""))
|
||||
(div
|
||||
(~tw :tokens "mt-3 border border-stone-200 rounded-lg overflow-hidden")
|
||||
(details
|
||||
(summary
|
||||
(~tw :tokens "px-3 py-1.5 bg-stone-50 text-xs font-medium text-stone-600 cursor-pointer select-none")
|
||||
"SX Source")
|
||||
(pre
|
||||
(~tw :tokens "text-xs p-3 overflow-x-auto bg-white")
|
||||
(code (~tw :tokens "language-sx") source)))
|
||||
(when
|
||||
python
|
||||
(details
|
||||
(summary
|
||||
(~tw :tokens "px-3 py-1.5 bg-stone-50 text-xs font-medium text-stone-600 cursor-pointer border-t border-stone-200")
|
||||
"Python")
|
||||
(pre
|
||||
(~tw :tokens "text-xs p-3 overflow-x-auto bg-white")
|
||||
(code (highlight python "python")))))
|
||||
(when
|
||||
javascript
|
||||
(details
|
||||
(summary
|
||||
(~tw :tokens "px-3 py-1.5 bg-stone-50 text-xs font-medium text-stone-600 cursor-pointer border-t border-stone-200")
|
||||
"JavaScript")
|
||||
(pre
|
||||
(~tw :tokens "text-xs p-3 overflow-x-auto bg-white")
|
||||
(code (highlight javascript "javascript")))))
|
||||
(when
|
||||
z3
|
||||
(details
|
||||
(summary
|
||||
(~tw :tokens "px-3 py-1.5 bg-stone-50 text-xs font-medium text-stone-600 cursor-pointer border-t border-stone-200")
|
||||
"Z3 / SMT-LIB")
|
||||
(pre
|
||||
(~tw :tokens "text-xs p-3 overflow-x-auto bg-white")
|
||||
(code (highlight z3 "lisp"))))))))
|
||||
Reference in New Issue
Block a user