HS: split type-check (predicate) from type-assert (:) — +5 comparisonOperator
Last commit's `hs-type-check` rewrite collapsed predicate and assertion into one runtime fn that always raised on mismatch. That fixed `: Type` but broke `is a Type` / `is not a Type` (which need a bool): null is a String expected true, got nil (raised) null is not a String expected false, got true (default boolean) Restored the split. Parser now emits `(type-assert ...)` for `:` and keeps `(type-check ...)` for `is a` / `is not a`. Runtime adds: - `hs-type-check` — predicate, never raises (nil passes) - `hs-type-check-strict` — predicate, false on nil - `hs-type-assert` — value or raises - `hs-type-assert-strict` — value or raises (also raises on nil) Compiler maps `type-assert` / `type-assert-strict` to the new runtime fns. comparisonOperator 74/83 → 79/83 (+5: `is a/an`, `is not a/an` four tests plus a fifth that depended on them). typecheck stays 2/5 (no regression). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1703,6 +1703,16 @@
|
||||
(quote hs-type-check-strict)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote type-assert))
|
||||
(list
|
||||
(quote hs-type-assert)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote type-assert-strict))
|
||||
(list
|
||||
(quote hs-type-assert-strict)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote strict-eq))
|
||||
(list
|
||||
(quote hs-strict-eq)
|
||||
|
||||
@@ -678,8 +678,8 @@
|
||||
(when strict (adv!))
|
||||
(if
|
||||
strict
|
||||
(list (quote type-check-strict) left type-name)
|
||||
(list (quote type-check) left type-name)))))))
|
||||
(list (quote type-assert-strict) left type-name)
|
||||
(list (quote type-assert) left type-name)))))))
|
||||
((and (= typ "keyword") (= val "of"))
|
||||
(do
|
||||
(adv!)
|
||||
|
||||
@@ -769,28 +769,48 @@
|
||||
(dom-set-style target prop (str to-val))
|
||||
(when duration (hs-settle target))))
|
||||
|
||||
(define
|
||||
hs-type-check
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
value
|
||||
(let
|
||||
((matches (cond ((= type-name "Number") (number? value)) ((= type-name "String") (string? value)) ((= type-name "Boolean") (or (= value true) (= value false))) ((= type-name "Array") (list? value)) ((= type-name "Object") (dict? value)) ((= type-name "Element") (= (host-typeof value) "element")) ((= type-name "Node") (or (= (host-typeof value) "element") (= (host-typeof value) "text"))) (true (= (host-typeof value) (downcase type-name))))))
|
||||
(if
|
||||
matches
|
||||
value
|
||||
(raise (str "Typecheck failed! expected " type-name)))))))
|
||||
(begin
|
||||
(define
|
||||
hs-type-check
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
true
|
||||
(cond
|
||||
((= type-name "Number") (number? value))
|
||||
((= type-name "String") (string? value))
|
||||
((= type-name "Boolean") (or (= value true) (= value false)))
|
||||
((= type-name "Array") (list? value))
|
||||
((= type-name "Object") (dict? value))
|
||||
((= type-name "Element") (= (host-typeof value) "element"))
|
||||
((= type-name "Node")
|
||||
(or
|
||||
(= (host-typeof value) "element")
|
||||
(= (host-typeof value) "text")))
|
||||
(true (= (host-typeof value) (downcase type-name)))))))
|
||||
(define
|
||||
hs-type-assert
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(hs-type-check value type-name)
|
||||
value
|
||||
(raise (str "Typecheck failed! expected " type-name)))))
|
||||
(define
|
||||
hs-type-assert-strict
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
(raise (str "Typecheck failed! expected " type-name " but got nil"))
|
||||
(hs-type-assert value type-name)))))
|
||||
|
||||
(define
|
||||
hs-type-check-strict
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
(raise (str "Typecheck failed! expected " type-name " but got nil"))
|
||||
(hs-type-check value type-name))))
|
||||
(if (nil? value) false (hs-type-check value type-name))))
|
||||
|
||||
(define
|
||||
hs-strict-eq
|
||||
|
||||
@@ -1703,6 +1703,16 @@
|
||||
(quote hs-type-check-strict)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote type-assert))
|
||||
(list
|
||||
(quote hs-type-assert)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote type-assert-strict))
|
||||
(list
|
||||
(quote hs-type-assert-strict)
|
||||
(hs-to-sx (nth ast 1))
|
||||
(nth ast 2)))
|
||||
((= head (quote strict-eq))
|
||||
(list
|
||||
(quote hs-strict-eq)
|
||||
|
||||
@@ -678,8 +678,8 @@
|
||||
(when strict (adv!))
|
||||
(if
|
||||
strict
|
||||
(list (quote type-check-strict) left type-name)
|
||||
(list (quote type-check) left type-name)))))))
|
||||
(list (quote type-assert-strict) left type-name)
|
||||
(list (quote type-assert) left type-name)))))))
|
||||
((and (= typ "keyword") (= val "of"))
|
||||
(do
|
||||
(adv!)
|
||||
|
||||
@@ -769,28 +769,48 @@
|
||||
(dom-set-style target prop (str to-val))
|
||||
(when duration (hs-settle target))))
|
||||
|
||||
(define
|
||||
hs-type-check
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
value
|
||||
(let
|
||||
((matches (cond ((= type-name "Number") (number? value)) ((= type-name "String") (string? value)) ((= type-name "Boolean") (or (= value true) (= value false))) ((= type-name "Array") (list? value)) ((= type-name "Object") (dict? value)) ((= type-name "Element") (= (host-typeof value) "element")) ((= type-name "Node") (or (= (host-typeof value) "element") (= (host-typeof value) "text"))) (true (= (host-typeof value) (downcase type-name))))))
|
||||
(if
|
||||
matches
|
||||
value
|
||||
(raise (str "Typecheck failed! expected " type-name)))))))
|
||||
(begin
|
||||
(define
|
||||
hs-type-check
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
true
|
||||
(cond
|
||||
((= type-name "Number") (number? value))
|
||||
((= type-name "String") (string? value))
|
||||
((= type-name "Boolean") (or (= value true) (= value false)))
|
||||
((= type-name "Array") (list? value))
|
||||
((= type-name "Object") (dict? value))
|
||||
((= type-name "Element") (= (host-typeof value) "element"))
|
||||
((= type-name "Node")
|
||||
(or
|
||||
(= (host-typeof value) "element")
|
||||
(= (host-typeof value) "text")))
|
||||
(true (= (host-typeof value) (downcase type-name)))))))
|
||||
(define
|
||||
hs-type-assert
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(hs-type-check value type-name)
|
||||
value
|
||||
(raise (str "Typecheck failed! expected " type-name)))))
|
||||
(define
|
||||
hs-type-assert-strict
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
(raise (str "Typecheck failed! expected " type-name " but got nil"))
|
||||
(hs-type-assert value type-name)))))
|
||||
|
||||
(define
|
||||
hs-type-check-strict
|
||||
(fn
|
||||
(value type-name)
|
||||
(if
|
||||
(nil? value)
|
||||
(raise (str "Typecheck failed! expected " type-name " but got nil"))
|
||||
(hs-type-check value type-name))))
|
||||
(if (nil? value) false (hs-type-check value type-name))))
|
||||
|
||||
(define
|
||||
hs-strict-eq
|
||||
|
||||
Reference in New Issue
Block a user