(declare (usual-integrations))
\f
-(define (initialize-package!)
- (set! *keyword-intern-table* (make-string-hash-table))
- unspecific)
-(define *keyword-intern-table*)
+;; Keywords are really interned symbols with a funny name. We do it
+;; this way because we need to keep eq-ness when fasdumping and
+;; fasload them. The self-evaluating property of keywords is handled
+;; by in the syntaxer which simply doesn't recognize them as
+;; identifiers.
-(define-structure (keyword
- (constructor %make-keyword (name))
- (conc-name keyword/)
- (print-procedure (lambda (state object)
- (keyword-unparser state object))))
- ;; logically, the name is a string, but
- ;; we store it as a symbol so that the standard
- ;; symbol-quoting conventions work.
- (name #f read-only #t))
+(define-integrable keyword-prefix "#[keyword]")
-(define-guarantee keyword "Keyword object")
+(define (string->keyword string)
+ (guarantee-string string 'string->keyword)
+ (string->symbol (string-append keyword-prefix string)))
-(define (keyword-unparser state object)
- (let ((port (unparser-state/port state)))
- (case *parser-keyword-style*
- ((PREFIX)
- (write-char #\: port)
- (write (keyword/name object) port))
- ((SUFFIX)
- (write (keyword/name object) port)
- (write-char #\: port))
- (else
- (write-string "#[keyword " port)
- (write (keyword/name object) port)
- (write-string "]" port)))))
+(define (keyword? object)
+ (and (interned-symbol? object)
+ (string-prefix? keyword-prefix (symbol->string object))))
+
+(define-guarantee keyword "keyword")
(define (keyword->string keyword)
(guarantee-keyword keyword 'keyword->string)
- (symbol->string (keyword/name keyword)))
-
-(define (string->keyword string)
- (guarantee-string string 'string->keyword)
- (or (hash-table/get *keyword-intern-table* string #f)
- (let ((new-keyword (%make-keyword (string->symbol string))))
- (hash-table/put! *keyword-intern-table*
- (string-copy string)
- new-keyword)
- new-keyword)))
-
-(define (symbol->keyword symbol)
- (guarantee-symbol symbol 'symbol->keyword)
- (string->keyword (symbol->string symbol)))
\ No newline at end of file
+ (string-tail (symbol->string keyword) (string-length keyword-prefix)))
\ No newline at end of file
(unparse-symbol symbol)))))
(define (unparse-symbol symbol)
- (let ((s (symbol-name symbol)))
- (if (or (string-find-next-char-in-set
- s
- (if (environment-lookup *environment*
- '*PARSER-CANONICALIZE-SYMBOLS?*)
- canon-symbol-quoted
- non-canon-symbol-quoted))
- (fix:= (string-length s) 0)
- (and (char-set-member? char-set/number-leaders (string-ref s 0))
- (string->number s))
- (looks-like-keyword? s))
- (begin
- (*unparse-char #\|)
- (let ((end (string-length s)))
- (let loop ((start 0))
- (if (fix:< start end)
- (let ((i
- (substring-find-next-char-in-set
- s start end
- char-set/symbol-quotes)))
- (if i
- (begin
- (*unparse-substring s start i)
- (*unparse-char #\\)
- (*unparse-char (string-ref s i))
- (loop (fix:+ i 1)))
- (*unparse-substring s start end))))))
- (*unparse-char #\|))
- (*unparse-string s))))
+ (if (keyword? symbol)
+ (unparse-keyword-name (keyword->string symbol))
+ (unparse-symbol-name (symbol-name symbol))))
+
+(define (unparse-keyword-name s)
+ (case (environment-lookup *environment* '*PARSER-KEYWORD-STYLE*)
+ ((PREFIX)
+ (*unparse-char #\:)
+ (unparse-symbol-name s))
+ ((SUFFIX)
+ (unparse-symbol-name s)
+ (*unparse-char #\:))
+ (else
+ (*unparse-string "#[keyword ")
+ (unparse-symbol-name s)
+ (*unparse-char #\]))))
+
+(define (unparse-symbol-name s)
+ (if (or (string-find-next-char-in-set
+ s
+ (if (environment-lookup *environment*
+ '*PARSER-CANONICALIZE-SYMBOLS?*)
+ canon-symbol-quoted
+ non-canon-symbol-quoted))
+ (fix:= (string-length s) 0)
+ (and (char-set-member? char-set/number-leaders (string-ref s 0))
+ (string->number s))
+ (and (fix:> (string-length s) 1)
+ (looks-like-keyword? s)))
+ (begin
+ (*unparse-char #\|)
+ (let ((end (string-length s)))
+ (let loop ((start 0))
+ (if (fix:< start end)
+ (let ((i
+ (substring-find-next-char-in-set
+ s start end
+ char-set/symbol-quotes)))
+ (if i
+ (begin
+ (*unparse-substring s start i)
+ (*unparse-char #\\)
+ (*unparse-char (string-ref s i))
+ (loop (fix:+ i 1)))
+ (*unparse-substring s start end))))))
+ (*unparse-char #\|))
+ (*unparse-string s)))
(define (looks-like-keyword? string)
(case (environment-lookup *environment* '*PARSER-KEYWORD-STYLE*)