HS parser: is/is-not ignoring case, eq-ignore-case runtime — 423→425

- Parse `is X ignoring case` → (eq-ignore-case left right)
- Parse `is not X ignoring case` → (not (eq-ignore-case left right))
- Compiler: eq-ignore-case → hs-eq-ignore-case
- Runtime: hs-eq-ignore-case using downcase/str

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 09:38:12 +00:00
parent eaf3c88a36
commit c05d8788c7
5 changed files with 50 additions and 17 deletions

View File

@@ -1078,6 +1078,11 @@
(quote hs-strict-eq) (quote hs-strict-eq)
(hs-to-sx (nth ast 1)) (hs-to-sx (nth ast 1))
(hs-to-sx (nth ast 2)))) (hs-to-sx (nth ast 2))))
((= head (quote eq-ignore-case))
(list
(quote hs-eq-ignore-case)
(hs-to-sx (nth ast 1))
(hs-to-sx (nth ast 2))))
((= head (quote some)) ((= head (quote some))
(list (list
(quote some) (quote some)

View File

@@ -410,7 +410,14 @@
(true (true
(let (let
((right (parse-expr))) ((right (parse-expr)))
(list (quote not) (list (quote =) left right)))))) (if
(match-kw "ignoring")
(do
(match-kw "case")
(list
(quote not)
(list (quote eq-ignore-case) left right)))
(list (quote not) (list (quote =) left right)))))))
((match-kw "empty") (list (quote empty?) left)) ((match-kw "empty") (list (quote empty?) left))
((match-kw "less") ((match-kw "less")
(do (do
@@ -474,7 +481,12 @@
(do (adv!) (list (quote prop-is) left prop-name))) (do (adv!) (list (quote prop-is) left prop-name)))
(let (let
((right (parse-expr))) ((right (parse-expr)))
(list (quote =) left right))))))) (if
(match-kw "ignoring")
(do
(match-kw "case")
(list (quote eq-ignore-case) left right))
(list (quote =) left right))))))))
((and (= typ "keyword") (= val "am")) ((and (= typ "keyword") (= val "am"))
(do (do
(adv!) (adv!)

View File

@@ -388,6 +388,10 @@
(fn (a b) (and (= (type-of a) (type-of b)) (= a b)))) (fn (a b) (and (= (type-of a) (type-of b)) (= a b))))
;; ── Sandbox/test runtime additions ────────────────────────────── ;; ── Sandbox/test runtime additions ──────────────────────────────
;; Property access — dot notation and .length ;; Property access — dot notation and .length
(define
hs-eq-ignore-case
(fn (a b) (= (downcase (str a)) (downcase (str b)))))
;; DOM query stub — sandbox returns empty list
(define (define
hs-falsy? hs-falsy?
(fn (fn
@@ -399,7 +403,7 @@
((and (list? v) (= (len v) 0)) true) ((and (list? v) (= (len v) 0)) true)
((= v 0) true) ((= v 0) true)
(true false)))) (true false))))
;; DOM query stub — sandbox returns empty list ;; Method dispatch — obj.method(args)
(define (define
hs-matches? hs-matches?
(fn (fn
@@ -408,7 +412,9 @@
(string? target) (string? target)
(if (= pattern ".*") true (string-contains? target pattern)) (if (= pattern ".*") true (string-contains? target pattern))
false))) false)))
;; Method dispatch — obj.method(args)
;; ── 0.9.90 features ─────────────────────────────────────────────
;; beep! — debug logging, returns value unchanged
(define (define
hs-contains? hs-contains?
(fn (fn
@@ -428,11 +434,9 @@
true true
(hs-contains? (rest collection) item))))) (hs-contains? (rest collection) item)))))
(true false)))) (true false))))
;; ── 0.9.90 features ─────────────────────────────────────────────
;; beep! — debug logging, returns value unchanged
(define precedes? (fn (a b) (< (str a) (str b))))
;; Property-based is — check obj.key truthiness ;; Property-based is — check obj.key truthiness
(define precedes? (fn (a b) (< (str a) (str b))))
;; Array slicing (inclusive both ends)
(define (define
hs-empty? hs-empty?
(fn (fn
@@ -443,7 +447,7 @@
((list? v) (= (len v) 0)) ((list? v) (= (len v) 0))
((dict? v) (= (len (keys v)) 0)) ((dict? v) (= (len (keys v)) 0))
(true false)))) (true false))))
;; Array slicing (inclusive both ends) ;; Collection: sorted by
(define (define
hs-empty-target! hs-empty-target!
(fn (fn
@@ -464,11 +468,11 @@
(dom-set-prop target "value" "")))) (dom-set-prop target "value" ""))))
((= tag "FORM") (dom-set-inner-html target "")) ((= tag "FORM") (dom-set-inner-html target ""))
(true (dom-set-inner-html target "")))))))) (true (dom-set-inner-html target ""))))))))
;; Collection: sorted by
(define hs-first (fn (lst) (first lst)))
;; Collection: sorted by descending ;; Collection: sorted by descending
(define hs-last (fn (lst) (last lst))) (define hs-first (fn (lst) (first lst)))
;; Collection: split by ;; Collection: split by
(define hs-last (fn (lst) (last lst)))
;; Collection: joined by
(define (define
hs-template hs-template
(fn (fn
@@ -554,7 +558,7 @@
(set! i (+ i 1)) (set! i (+ i 1))
(tpl-loop))))))) (tpl-loop)))))))
(do (tpl-loop) result)))) (do (tpl-loop) result))))
;; Collection: joined by
(define (define
hs-make-object hs-make-object
(fn (fn

View File

@@ -410,7 +410,14 @@
(true (true
(let (let
((right (parse-expr))) ((right (parse-expr)))
(list (quote not) (list (quote =) left right)))))) (if
(match-kw "ignoring")
(do
(match-kw "case")
(list
(quote not)
(list (quote eq-ignore-case) left right)))
(list (quote not) (list (quote =) left right)))))))
((match-kw "empty") (list (quote empty?) left)) ((match-kw "empty") (list (quote empty?) left))
((match-kw "less") ((match-kw "less")
(do (do
@@ -474,7 +481,12 @@
(do (adv!) (list (quote prop-is) left prop-name))) (do (adv!) (list (quote prop-is) left prop-name)))
(let (let
((right (parse-expr))) ((right (parse-expr)))
(list (quote =) left right))))))) (if
(match-kw "ignoring")
(do
(match-kw "case")
(list (quote eq-ignore-case) left right))
(list (quote =) left right))))))))
((and (= typ "keyword") (= val "am")) ((and (= typ "keyword") (= val "am"))
(do (do
(adv!) (adv!)

File diff suppressed because one or more lines are too long