From 5411db37294873dd3b1a0cc64c95c336e2d71cfb Mon Sep 17 00:00:00 2001 From: Yogthos Date: Sat, 27 Jun 2026 10:46:52 -0400 Subject: [PATCH] Track :refer-clojure :exclude so syntax-quote qualifies an excluded name to the current ns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A name a namespace excludes from clojure.core (:refer-clojure :exclude) is not clojure.core/name even before the ns defines its own — syntax-quote must qualify it to the current ns, like Clojure. refer-clojure was a no-op, so a syntax-quoted excluded name (core.logic.fd's `==`, referenced by a constraint's -rator before fd defines ==) resolved to clojure.core/==. jolt-refer-clojure now records the :exclude set per ns; hc-sq-symbol consults it before falling back to clojure.core. Fixes core.logic's fd constraint -rator names. Runtime only, no re-mint. --- host/chez/host-contract.ss | 4 ++++ host/chez/ns.ss | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/host/chez/host-contract.ss b/host/chez/host-contract.ss index fbbf083..d747902 100644 --- a/host/chez/host-contract.ss +++ b/host/chez/host-contract.ss @@ -326,6 +326,10 @@ ;; Referred names live in a separate table, so this only hits a real ;; local intern, matching how the analyzer resolves the bare symbol. ((var-cell-lookup (chez-actx-cns ctx) nm) (jolt-symbol (chez-actx-cns ctx) nm)) + ;; a name the compile ns excluded from clojure.core (:refer-clojure + ;; :exclude) is not clojure.core/nm even before the ns defines its own — + ;; qualify to the compile ns, like Clojure (core.logic.fd's `==`). + ((chez-core-excluded? (chez-actx-cns ctx) nm) (jolt-symbol (chez-actx-cns ctx) nm)) ((var-cell-lookup "clojure.core" nm) (jolt-symbol "clojure.core" nm)) ;; a name referred into the compile ns (:require :refer / :use :only) ;; qualifies to its SOURCE ns, not the compile ns — so a macro that diff --git a/host/chez/ns.ss b/host/chez/ns.ss index 9d39013..cad5286 100644 --- a/host/chez/ns.ss +++ b/host/chez/ns.ss @@ -281,7 +281,29 @@ (chez-register-refer! cns (var-cell-name c) target))) (hashtable-values var-table)) jolt-nil)) -(define (jolt-refer-clojure . _) jolt-nil) +;; (:refer-clojure :exclude [names…]) — clojure.core always resolves on Chez, so +;; the only thing to track is the EXCLUDE set: an excluded name is not +;; clojure.core/name, so syntax-quote qualifies it to the current ns instead (a ns +;; that excludes and defines its own, e.g. core.logic.fd's ==). +(define ns-core-exclude-table (make-hashtable equal-hash equal?)) ; cns -> (name -> #t) +(define (chez-register-core-exclude! cns name) + (let ((h (or (hashtable-ref ns-core-exclude-table cns #f) + (let ((h (make-hashtable string-hash string=?))) + (hashtable-set! ns-core-exclude-table cns h) h)))) + (hashtable-set! h name #t))) +(define (chez-core-excluded? cns name) + (let ((h (hashtable-ref ns-core-exclude-table cns #f))) + (and h (hashtable-ref h name #f) #t))) +(define (jolt-refer-clojure . args) + (let ((cns (chez-current-ns))) + (let loop ((a args)) + (when (and (pair? a) (pair? (cdr a))) + (when (and (keyword? (car a)) (string=? (keyword-t-name (car a)) "exclude")) + (for-each (lambda (n) (when (symbol-t? n) + (chez-register-core-exclude! cns (symbol-t-name n)))) + (seq->list (cadr a)))) + (loop (cddr a))))) + jolt-nil) ;; alter-meta! / reset-meta!: update a var's metadata (var-meta-table, rt.ss). (define (jolt-alter-meta! ref f . args)