This repository has been archived by the owner on Nov 8, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathread-package.lisp
75 lines (67 loc) · 2.74 KB
/
read-package.lisp
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; File - read-package.lisp
;; Description - Read-time package hacks
;; Author - Tim Bradshaw (tfb at lostwithiel)
;; Created On - Fri Jul 6 12:13:59 2001
;; Last Modified On - Tue Apr 30 14:23:26 2002
;; Last Modified By - Tim Bradshaw (tfb at lostwithiel)
;; Update Count - 13
;; Status - Unknown
;;
;; $Id: //depot/www-tfeb-org/before-2013-prune/www-tfeb-org/html/programs/lisp/read-package.lisp#1 $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; Symbolics-style read-time packages.
;;;
;;; read-package.lisp is copyright 2001 by me, Tim Bradshaw, and may
;;; be used for any purpose whatsoever by anyone. It has no warranty
;;; whatsoever. I would appreciate acknowledgement if you use it in
;;; anger, and I would also very much appreciate any feedback or bug
;;; fixes.
;;; In genera you could give package prefixes to entire forms:
;;; cl-user:(cons 1 2)
;;; meant `read in package CL-USER.
;;;
;;; This can't easily be implemented in standard CL, but something
;;; similar can. This file implements a dispatching macro char, @,
;;; which forces the following form to be read in the package named:
;;; #@cl-user (cons 1 2) does about the same thing as above.
;;;
;;; The principal hack here is that CL gives no hook into the reader
;;; before it interns things, so you can't say `give me a token', but
;;; have to accept something like a symbol. Hence the hack of using a
;;; secret package in which things get interned & then uninterned (to
;;; avoid leaks).
;;;
(eval-when (:compile-toplevel :load-toplevel :execute)
(when (not (find-package ':org.tfeb.hax))
(make-package ':org.tfeb.hax)))
(in-package :org.tfeb.hax)
(defvar *read-package-package*
(make-package "READ-PACKAGE-PACKAGE" :use '()))
(when (get-dispatch-macro-character #\# #\@)
(error "Someone is already using #@"))
(set-dispatch-macro-character
#\# #\@
#'(lambda (stream char infix)
(declare (ignore char infix))
(let* ((*package* *read-package-package*)
(tok (read stream t nil t))
(string (typecase tok
(symbol
(if (eq (symbol-package tok) *read-package-package*)
(unintern tok)
(warn
"Dubious syntax for read-package: symbol in package ~A"
(package-name (symbol-package tok))))
(symbol-name tok))
(string
(warn "Dubious syntax for read-package: string read")
tok)
(t
(error "read-package: got a ~A, expecting a symbol"
(type-of tok)))))
(package (find-package string)))
(unless package
(error "No package with name ~A for read-package" string))
(let ((*package* package))
(read stream t nil t)))))