|
1. Basic function call to determine what declarations are available
In cmucl:
* (pprint (sys::declaration-information 'declaration))
(SYSTEM::VARIABLE-REBINDING DYNAMIC-EXTENT SPECIAL IGNORABLE IGNORE NOTINLINE
INLINE FTYPE SYSTEM::DISCRIMINATED-TYPE TYPE DECLARATION OPTIMIZE)
*
In Allegro CL:
CL-USER(1): (pprint (sys::declaration-information 'declaration))
(:FASLMODE VALUES COMPILER::INSTANCE-VARIABLE :EXPLAIN
EXCL::DYNAMIC-EXTENT-ARGUMENTS :DISCARD-SOURCE-FILE-INFO
SYSTEM::VARIABLE-REBINDING DYNAMIC-EXTENT SPECIAL IGNORE-IF-UNUSED IGNORABLE
IGNORE NOTINLINE INLINE FTYPE SYSTEM::DISCRIMINATED-TYPE TYPE DECLARATION
OPTIMIZE)
CL-USER(2):
2. Some experiments on the optimize declaration:
In CMUCL:
* (setq e1 (sys::make-compilation-unit-environment))
Warning: Declaring E1 special.
#<Augmentable COMPILER environment {48589D55}>
* (setq e2 (sys::augment-environment e1 :declare '((optimize speed debug))))
Warning: Declaring E2 special.
#<Augmentable COMPILER environment 1 {4858B675}>
* (sys::declaration-information 'optimize)
((SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1) (DEBUG 2))
Note that the information is pushed, above, and does not modify the oiginal data here.
* (sys::declaration-information 'optimize e2)
((SPEED 3) (DEBUG 3) (SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1)
(DEBUG 2))
* (declaim (optimize (space 0) (safety 0)))
NIL
* (sys::declaration-information 'optimize)
((SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1) (DEBUG 2))
*
Note that the above did not make any difference, because Environments Access is currently implemented in CMUCL at level 1, and thus declaim does not invoke augment-environment (a level 2 acivity). Contrast with the Allegro CL example below.
* (sys::augment-environment nil :declare '((optimize (space 0) (safety 0))))
NIL
* (sys::declaration-information 'optimize)
((SPACE 0) (SAFETY 0) (SPEED 1) (COMPILATION-SPEED 1) (DEBUG 2))
note now that the values have actually changed, but...
* (sys::declaration-information 'optimize e2)
((SPEED 3) (DEBUG 3) (SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1)
(DEBUG 2))
*
Note also that the global change did not affect anything in this local environment.
Now in Allegro CL:
CL-USER(3): (setq e1 (sys::make-compilation-unit-environment))
#<Augmentable COMPILER environment @ #x40c25152>
CL-USER(4): (setq e2 (sys::augment-environment e1 :declare '((optimize speed debug))))
#<Augmentable COMPILER environment 1 @ #x40c25b22>
CL-USER(5): (sys::declaration-information 'optimize)
((SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1) (DEBUG 2))
CL-USER(6): (sys::declaration-information 'optimize e2)
((SPEED 3) (DEBUG 3) (SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1)
(DEBUG 2))
CL-USER(7): (declaim (optimize (space 0) (safety 0)))
T
CL-USER(8): (sys::declaration-information 'optimize)
((SPACE 0) (SAFETY 0) (SPEED 1) (COMPILATION-SPEED 1) (DEBUG 2))
Note above that the declaim took effect, and affected the global optimize namespace. If we had been in a compile-file, the shadow environment's optimize namespace would have been affected and not the global space.
CL-USER(9): (sys::declaration-information 'optimize e2)
((SPEED 3) (DEBUG 3) (SAFETY 1) (SPACE 1) (SPEED 1) (COMPILATION-SPEED 1)
(DEBUG 2))
CL-USER(10):
3. Peter Seibel complains in his book (Practical Common Lisp, p 441) that there is no way to call eval with an explicit environment, and he develops a workaround. Well, in Allegro CL, and this module, w can do just that:
CL-USER(2): (compile
(defun eval-in-env (form sys::*interpreter-environment*)
(excl::%eval form)))
EVAL-IN-ENV
NIL
NIL
CL-USER(3): (setq e1
(sys::augment-environment
(sys::make-augmentable-environment-boa :interpreter)
:variable 'x
:locative (list 10)))
#<Augmentable INTERPRETER environment 1 @ #x40c27322>
CL-USER(4): (describe 'x)
X is a NEW SYMBOL.
It is unbound.
It is INTERNAL in the COMMON-LISP-USER package.
CL-USER(5): (sys:variable-information 'x)
NIL
CL-USER(6): (sys:variable-information 'x e1)
:LEXICAL
(10)
NIL
T
CL-USER(7): (eval 'x)
Error: Attempt to take the value of the unbound variable `X'.
[condition type: UNBOUND-VARIABLE]
Restart actions (select using :continue):
0: Try evaluating X again.
1: Use :X instead.
2: Set the symbol-value of X and use its value.
3: Use a value without setting X.
4: Return to Top Level (an "abort" restart).
5: Abort entirely from this (lisp) process.
[1] CL-USER(8): :res
CL-USER(9): (eval-in-env 'x e1)
10
CL-USER(10): (eval-in-env '(setq x 1) e1)
1
CL-USER(11): (sys:variable-information 'x e1)
:LEXICAL
(1)
NIL
T
CL-USER(12):
4. During compilation, variable-information and function-information can tell us things about the names being processed. Note that this will only work on a level 4 Implementation (currently only Allegro CL). Note also that the values of variable and function information slots during compilation are implementation-dependent. (vifitest.cl is needed for this next example.)
CL-USER(1): (shell "cat vifitest.cl")
(in-package :user)
;; Avoid infinite recursion:
(eval-when (compile)
(without-package-locks
comp::(defmethod print-object ((x varrec) s)
(print-unreadable-object (x s :type t :identity nil)
(format s "~s~@[ ~:_Specialp: ~a~]~@[ ~:_~a~]"
(varrec-name x) (varrec-specialp x) (varrec-type x))))))
(defmacro with-vi-test ((var &optional all) &body body &environment e)
(format t "variable-information ~:[~;(all)~] of ~s is ~s~%"
all var (multiple-value-list (sys:variable-information var e all)))
`(progn ,@body))
(defmacro with-fi-test ((var &optional all spec) &body body &environment e)
(format t "function-information ~:[~;(all)~]~:[~; w/spec~] of ~s is ~s~%"
all spec var (multiple-value-list (sys:function-information var e all spec)))
`(progn ,@body))
(defconstant seven 7)
(defvar *framis*)
(defmacro not-twelve (x)
`(/= 12 ,x))
(define-symbol-macro not-eleven (1- seven))
(let ((x (multiple-value-list (get-universal-time))))
(declare (special frob))
(symbol-macrolet ((pie 22/7))
(flet ((epi (x) (1+ x)))
(macrolet ((poi (x)
`(sqrt ,x)))
(defun load-time ()
(with-vi-test (x)
(with-vi-test (frob)
(with-vi-test (*print-base*)
(with-vi-test (seven)
(with-vi-test (not-eleven)
(with-vi-test (pi)
(with-vi-test (pi t)
(with-vi-test (*framis*)
(let ((*framis* 10.0))
(with-vi-test (*framis*)
(with-vi-test (unknown)
(+ seven x)))))))))))))
(defun apple-pie (apple)
(with-vi-test (apple)
(with-vi-test (pie)
(with-fi-test (or)
(with-fi-test (or t)
(with-fi-test (or t t)
(with-fi-test (poi)
(with-fi-test (not-twelve)
(with-fi-test (car)
(with-fi-test (car t)
(with-fi-test (epi)
(print
(values pi
(* apple pie))))))))))))))))))
0
CL-USER(2): :cf vifitest
;;; Compiling file vifitest.cl
variable-information of X is (:LEXICAL (#<COMPILER::VARREC X UNKNOWN-TYPE>)
NIL :OUTER)
variable-information of FROB is (:SPECIAL
(#<COMPILER::VARREC FROB Specialp: DECLARE
UNKNOWN-TYPE>)
NIL :OUTER)
variable-information of *PRINT-BASE* is (:SPECIAL NIL NIL)
variable-information of SEVEN is (:CONSTANT 7 NIL)
variable-information of NOT-ELEVEN is (:SYMBOL-MACRO ((1- SEVEN)) NIL)
variable-information of PI is (:CONSTANT 3.141592653589793d0 NIL)
variable-information (all) of PI is (:CONSTANT 3.141592653589793d0
((TYPE
(DOUBLE-FLOAT
3.141592653589793d0
3.141592653589793d0))))
variable-information of *FRAMIS* is (:SPECIAL NIL NIL)
variable-information of *FRAMIS* is (:SPECIAL
(#<COMPILER::VARREC
*FRAMIS*
Specialp: T
UNKNOWN-TYPE>)
NIL :OUTER)
variable-information of UNKNOWN is (NIL)
variable-information of APPLE is (:LEXICAL
(#<COMPILER::VARREC APPLE UNKNOWN-TYPE>)
NIL :OUTER)
variable-information of PIE is (:SYMBOL-MACRO (22/7) NIL :OUTER)
function-information of OR is (:MACRO NIL NIL)
function-information (all) of OR is (:MACRO
(#<Function MACROEXPAND-1-TRANSFORM>) NIL)
function-information (all) w/spec of OR is (:SPECIAL-OPERATOR NIL NIL)
function-information of POI is (:MACRO
(#<Interpreted Function POI @ #x10679afa>)
NIL T)
function-information of NOT-TWELVE is (:MACRO NIL NIL)
function-information of CAR is (:FUNCTION NIL NIL)
function-information (all) of CAR is (:FUNCTION (#<Function CAR>) NIL)
function-information of EPI is (:FUNCTION (#:G45) NIL T)
;;; Writing fasl file vifitest.fasl
;;; Fasl write complete
CL-USER(3):
|