home *** CD-ROM | disk | FTP | other *** search
- ;; -*- package: NotInROM -*-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; NotInROM-u.Lisp
- ;;
- ;; Copyright ⌐ 1992 Northwestern University Institute for the Learning Sciences
- ;; All Rights Reserved
- ;;
- ;; author: Michael S. Engber
- ;;
- ;; Provides a syntax for defining and calling "Not in ROM" ToolBox Routines
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Modification History
- ;;
- ;; 02/11/92 bill EXPORT goes after IN-PACKAGE, PROVIDE at end of file.
- ;;
-
- (defpackage :NotInROM
- (:use :common-lisp :common-lisp-user :ccl))
-
- (in-package :NotInROM)
-
- (export '(require-trap-NotInROM deftrap-NotInROM deftrap-alt-name))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;; for Not in ROM traps requiring a fn defn
- (defmacro deftrap-NotInROM (symbol result-type (&rest typed-arglist) &body body)
- (declare (ignore result-type))
- (let* ((trap-sym (ensure-trap-sym symbol))
- (fn-sym (gen-NIR-fn-sym trap-sym))
- (macro-sym (gen-NIR-macro-sym trap-sym))
- (arglist (mapcar #'first typed-arglist))
- (type-spec-list (mapcar #'second typed-arglist)))
-
- `(eval-when (:compile-toplevel :load-toplevel :execute)
- (setf (get ',trap-sym :NotInROM-fn-sym) ',fn-sym)
- (setf (get ',trap-sym :NotInROM-macro-sym) ',macro-sym)
-
- (defmacro ,macro-sym ,arglist
- (NIR-arglist-check ',fn-sym ',arglist ',type-spec-list)
- `(,',fn-sym ,,@arglist))
-
- (defun ,fn-sym ,arglist ,@body))))
-
-
- ;; for Not in ROM traps simply requiring a renaming
- (defmacro deftrap-alt-name (alt-trap-symbol asm-trap-symbol)
- (let ((alt-trap-sym (ensure-trap-sym alt-trap-symbol))
- (asm-trap-sym (ensure-trap-sym asm-trap-symbol)))
- `(eval-when (:compile-toplevel :load-toplevel :execute)
- (setf (get ',alt-trap-sym :NotInROM-macro-sym) ',asm-trap-sym))))
-
-
- ;;analogous to require-trap
- (defmacro require-trap-NotInROM (trap-symbol &rest arglist)
- (if (trap-prefixp trap-symbol)
- `(require-trap ,trap-symbol ,@arglist)
- `(,trap-symbol ,@arglist)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
- ;;takes a potential trap symbol, makes sure it in the right package and begins with an _
- (defun ensure-trap-sym (symbol)
- (if (trap-prefixp symbol)
- (if (eq (symbol-package symbol) ccl::*traps-package*)
- symbol
- (intern (symbol-name symbol) :traps))
- (error "trap symbol ~s does not start with an _" symbol)))
-
- ;;generates a symbol for the Not in ROM fn
- (defun gen-NIR-fn-sym (symbol)
- (intern (concatenate 'string "NIR" (symbol-name symbol)) :traps))
-
- ;;generates a symbol for the macro to do compile time arg checking for the Not in ROM fn
- (defun gen-NIR-macro-sym (symbol)
- (intern (concatenate 'string "TCHECK-NIR" (symbol-name symbol)) :traps))
-
- ;;checks if a symbol starts with an _
- (defun trap-prefixp (symbol)
- (char= #\_ (char (symbol-name symbol) 0)))
-
- ;;compile time type checking
- (defun NIR-arglist-check (fn-symbol arglist type-spec-list)
- (flet ((arg-check (arg type-spec)
- (when (constantp arg)
- (unless (funcall (ccl::mactype-ct-type-check (ccl::find-arg-mactype type-spec))
- (typecase arg (symbol (symbol-value arg)) (t arg)))
- (error "~s value ~s is not of expected type: ~s" fn-symbol arg type-spec)))))
- (declare (dynamic-extent #'arg-check))
- (mapc #'arg-check arglist type-spec-list)))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;stream for reading symbols adding an underscore prefix
-
- (defclass 1char-prefix-stream (input-stream)
- ((prefix-char :accessor prefix-char
- :initform nil)
- (suffix-stream :accessor suffix-stream)))
-
- (defmethod stream-tyi ((s 1char-prefix-stream))
- (if (and (prefix-char s) (not (stream-eofp (suffix-stream s))))
- (prog1 (prefix-char s) (setf (prefix-char s) nil))
- (stream-tyi (suffix-stream s))))
-
- (defmethod stream-untyi ((s 1char-prefix-stream) char)
- (setf (prefix-char s) char))
-
- (defvar *prefix-stream* (make-instance '1char-prefix-stream))
-
- ;;reads in the next symbol from the stream into the traps package, prepending an _
- (defun read-trap-sym (stream)
- (let ((prefix-stream (or *prefix-stream* (make-instance '1char-prefix-stream)))
- (*prefix-stream* nil))
- (setf (suffix-stream prefix-stream) stream)
- (unread-char #\_ prefix-stream)
- (let ((*package* ccl::*traps-package*))
- (read prefix-stream t nil t))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;#~ dispatching macro char
-
- ;;This is my chance to map a symbol to something else, like a Not In ROM macro or fn.
- ;; It would be nice to auto-load any necessary defns at this point too.
- ;; But that's not currently implemented.
- (defun NotInROM-lookup (symbol)
- (or (get symbol :NotInROM-macro-sym) (get symbol :NotInROM-fn-sym) symbol))
-
-
- (defun NotInROM-dispatch (s macro-char int)
- (declare (ignore macro-char))
-
- (when (and int (not *read-suppress*))
- (error "Reader dispatch macro character #\~ doesn't take an argument."))
-
- (let* ((symbol (NotInROM-lookup (read-trap-sym s))))
- (unless *read-suppress*
- (when (eq symbol 'traps::_)
- (error "illegal form following #~~ : ~s" (read s t nil t)))
-
- ;;if it turns out to be a regular trap symbol we must load it
- (when (trap-prefixp symbol) (ccl::load-trap symbol)))
-
- symbol))
-
- (set-dispatch-macro-character #\# #\~ #'NotInROM-dispatch)
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- #|
-
- ;;This cryptic fn tests if a trap is in the index. If so, it returns
- ;;the trap's name, else nil. It uses undocumented ccl fns so it may break
- ;;someday.
-
- ;; originally I thought I'd need this fn, but I haven't so far
- (defun trap-indexed-p (trap-symbol)
- (ccl::find-interface-entry trap-symbol
- ccl::*traps-index-file*
- 'ccl::*traps-index-stream*
- nil nil nil nil nil))
-
-
- |#
-
- (provide :NotInROM-u)
-