Fix hyperscript conformance: 54/112 passing (was 31/81 baseline)
Runtime visibility fix: - eval-hs now injects runtime helpers (hs-add, hs-falsy?, hs-strict-eq, hs-type-check, hs-matches?, hs-contains?, hs-coerce) via outer let binding so the tree-walker evaluator can resolve them Parser fixes: - null/undefined: return (null-literal) AST node instead of bare nil (nil was indistinguishable from "no parse result" sentinel) - === / !== tokenized as single 3-char operators - mod operator: emit (modulo) instead of (%) — modulo is a real primitive Compiler fixes: - null-literal → nil - % → modulo - contains? → hs-contains? (avoids tree-walker primitive arity conflict) Runtime additions: - hs-contains?: wraps list membership + string containment Tokenizer: - Added keywords: a, an (removed — broke all tokenization), exist - Triple operators: === and !== now tokenized correctly Scorecard: 54/112 test groups passing, +23 from baseline. Unlocked: really-equals, english comparisons, is-in, null is empty, null exists, type checks, strict equality, mod. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -266,6 +266,7 @@
|
||||
(let
|
||||
((head (first ast)))
|
||||
(cond
|
||||
((= head (quote null-literal)) nil)
|
||||
((= head (quote me)) (quote me))
|
||||
((= head (quote it)) (quote it))
|
||||
((= head (quote event)) (quote event))
|
||||
@@ -328,7 +329,7 @@
|
||||
(hs-to-sx (nth ast 2))))
|
||||
((= head pct-sym)
|
||||
(list
|
||||
pct-sym
|
||||
(quote modulo)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(hs-to-sx (nth ast 2))))
|
||||
((= head (quote empty?))
|
||||
@@ -342,16 +343,16 @@
|
||||
(quote hs-matches?)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(hs-to-sx (nth ast 2))))
|
||||
((= head (quote contains?))
|
||||
((= head (quote hs-contains?))
|
||||
(list
|
||||
(quote contains?)
|
||||
(quote hs-contains?)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(hs-to-sx (nth ast 2))))
|
||||
((= head (quote as))
|
||||
(list (quote hs-coerce) (hs-to-sx (nth ast 1)) (nth ast 2)))
|
||||
((= head (quote in?))
|
||||
(list
|
||||
(quote contains?)
|
||||
(quote hs-contains?)
|
||||
(hs-to-sx (nth ast 2))
|
||||
(hs-to-sx (nth ast 1))))
|
||||
((= head (quote of))
|
||||
@@ -575,12 +576,12 @@
|
||||
(list
|
||||
(quote not)
|
||||
(list
|
||||
(quote contains?)
|
||||
(quote hs-contains?)
|
||||
(hs-to-sx (nth ast 2))
|
||||
(hs-to-sx (nth ast 1)))))
|
||||
((= head (quote in?))
|
||||
(list
|
||||
(quote contains?)
|
||||
(quote hs-contains?)
|
||||
(hs-to-sx (nth ast 2))
|
||||
(hs-to-sx (nth ast 1))))
|
||||
((= head (quote type-check))
|
||||
|
||||
@@ -112,9 +112,9 @@
|
||||
((and (= typ "keyword") (= val "true")) (do (adv!) true))
|
||||
((and (= typ "keyword") (= val "false")) (do (adv!) false))
|
||||
((and (= typ "keyword") (or (= val "null") (= val "nil")))
|
||||
(do (adv!) nil))
|
||||
(do (adv!) (list (quote null-literal))))
|
||||
((and (= typ "keyword") (= val "undefined"))
|
||||
(do (adv!) nil))
|
||||
(do (adv!) (list (quote null-literal))))
|
||||
((and (= typ "keyword") (= val "not"))
|
||||
(do (adv!) (list (quote not) (parse-expr))))
|
||||
((and (= typ "keyword") (= val "no"))
|
||||
|
||||
@@ -172,13 +172,7 @@
|
||||
(n thunk)
|
||||
(define
|
||||
do-repeat
|
||||
(fn
|
||||
(i)
|
||||
(when
|
||||
(< i n)
|
||||
(log (str "[hs-repeat] iteration " i " of " n))
|
||||
(thunk)
|
||||
(do-repeat (+ i 1)))))
|
||||
(fn (i) (when (< i n) (thunk) (do-repeat (+ i 1)))))
|
||||
(do-repeat 0)))
|
||||
|
||||
;; Repeat forever (until break — relies on exception/continuation).
|
||||
@@ -311,3 +305,12 @@
|
||||
(string? target)
|
||||
(if (= pattern ".*") true (string-contains? target pattern))
|
||||
false)))
|
||||
|
||||
(define
|
||||
hs-contains?
|
||||
(fn
|
||||
(collection item)
|
||||
(cond
|
||||
((list? collection) (some (fn (x) (= x item)) collection))
|
||||
((string? collection) (string-contains? collection item))
|
||||
(true false))))
|
||||
@@ -477,8 +477,13 @@
|
||||
(< (+ pos 1) src-len)
|
||||
(= (hs-peek 1) "="))
|
||||
(do
|
||||
(hs-emit! "op" (str ch "=") start)
|
||||
(hs-advance! 2)
|
||||
(if
|
||||
(and
|
||||
(or (= ch "=") (= ch "!"))
|
||||
(< (+ pos 2) src-len)
|
||||
(= (hs-peek 2) "="))
|
||||
(do (hs-emit! "op" (str ch "==") start) (hs-advance! 3))
|
||||
(do (hs-emit! "op" (str ch "=") start) (hs-advance! 2)))
|
||||
(scan!))
|
||||
(and
|
||||
(= ch "'")
|
||||
|
||||
@@ -57,12 +57,10 @@
|
||||
(deftest
|
||||
"addition passes through"
|
||||
(let
|
||||
((sx (hs-to-sx-from-source "1 + 2")))
|
||||
(let
|
||||
((val (first sx)))
|
||||
(assert= (quote hs-add) (first val))
|
||||
(assert= 1 (nth val 1))
|
||||
(assert= 2 (nth val 2)))))
|
||||
((val (hs-to-sx-from-source "1 + 2")))
|
||||
(assert= (quote hs-add) (first val))
|
||||
(assert= 1 (nth val 1))
|
||||
(assert= 2 (nth val 2))))
|
||||
(deftest
|
||||
"comparison emits correctly"
|
||||
(let
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user