-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathns.rkt
75 lines (57 loc) · 1.69 KB
/
ns.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#lang racket/base
;; Abstract the global name space mechanism.
(require
;; "tools.rkt"
"ns-tx.rkt" ;; for reflection
racket/shared
racket/provide-syntax
racket/require-syntax
(for-template
racket/base)
(for-syntax
racket/base
syntax/stx
"ns-tx.rkt"
))
(provide
(all-defined-out))
;; Require / provide.
;; Implemented by the catch-all transformer. These are called #'ns-out
;; and #'ns-in because #'ns is already taken.
(define-provide-syntax ns-out ns-tx)
(define-require-syntax ns-in ns-tx)
;; Binding forms and references.
;; (ns namespace identifier) -> transforms variable reference
;; (ns namespace binding-form) -> transforms variable binding form
(define-syntax ns ns-tx)
;; Used for DTC
(define-syntax underscore underscore-tx)
;; Reflection
;; Run time access uses symbols.
(define (ns-name ns [name '||])
(syntax->datum
(ns-prefixed (datum->syntax #f ns)
(datum->syntax #f name))))
;; Unwrap the name, #f if not in ns.
(define (ns-name? ns)
(let* ((prefix (symbol->string (ns-name ns)))
(lp (string-length prefix)))
(lambda (sym)
(let* ((str (symbol->string sym))
(l (string-length str)))
(and (> l lp)
(string=? prefix (substring str 0 lp))
(string->symbol (substring str lp)))))))
;; Find all prefixed words in current namespace.
(define (ns-mapped-symbols ns)
(let ((basename (ns-name? ns)))
(foldl
(lambda (sym collect)
(let ((it (basename sym)))
(if it (cons it collect) collect)))
'()
(namespace-mapped-symbols))))
(define (make-ns-defined? sym)
(lambda (ns)
(namespace-variable-value
(ns-name ns sym) #t (lambda () #f))))