;;; -*- Mode:LISP; Package:(FSI :USE LISP) ; Base:10; Readtable:CL -*- ;;;; Useful subroutines which should live outside this file. (DEFUN MAKE-SYMBOL-FROM-CONCATENATED-NAMES (&OPTIONAL (PKG *PACKAGE*) &REST FROBS) (INTERN (APPLY #'CONCATENATE 'STRING (MAP 'LIST #'STRING-UPCASE FROBS)) PKG)) ;;;; Immediate instances. (DEFMACRO DEFINSTANCE-IMMEDIATE (NAME &BODY INSTANCE-VARIABLES) (LET ((INSTANCE-VARIABLE-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-INSTANCE-VARIABLES")) (METHOD-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-WHICH-OPERATIONS"))) (SET METHOD-LIST-NAME NIL) (SET INSTANCE-VARIABLE-LIST-NAME INSTANCE-VARIABLES) `(PROGN 'COMPILE (SETQ ,INSTANCE-VARIABLE-LIST-NAME ',INSTANCE-VARIABLES) (SETQ ,METHOD-LIST-NAME NIL) (SETF (GET ',NAME 'SI:FLAVOR) T) ;This makes M-. work (DEFVAR ,NAME)))) (DEFMACRO DECLARE-INSTANCE-IMMEDIATE-INSTANCE-VARIABLES ((NAME) &BODY BODY) (LET ((INSTANCE-VARIABLE-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-INSTANCE-VARIABLES"))) `(LOCAL-DECLARE ((SPECIAL . ,(SYMBOL-VALUE INSTANCE-VARIABLE-LIST-NAME))) . ,BODY))) (EVAL-WHEN (COMPILE LOAD) (SETF (GET 'DECLARE-INSTANCE-IMMEDIATE-INSTANCE-VARIABLES 'SI:MAY-SURROUND-DEFUN) T)) (DEFMACRO DEFMETHOD-IMMEDIATE ((NAME MESSAGE) ARGLIST &BODY BODY) (LET ((METHOD-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-WHICH-OPERATIONS")) (METHOD-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME #\- MESSAGE "-METHOD"))) (WHEN (MEMBER MESSAGE (SYMBOL-VALUE METHOD-LIST-NAME)) (PUSH MESSAGE (SYMBOL-VALUE METHOD-LIST-NAME))) `(DECLARE-INSTANCE-IMMEDIATE-INSTANCE-VARIABLES (,NAME) (DEFUN ,METHOD-NAME (IGNORE . ,ARGLIST) . ,BODY)))) (DEFMACRO MAKE-INSTANCE-IMMEDIATE (NAME INIT-PLIST-GENERATOR) (LET ((INSTANCE-VARIABLE-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-INSTANCE-VARIABLES")) (METHOD-LIST-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-WHICH-OPERATIONS")) (SEND-IF-HANDLES-METHOD-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-SEND-IF-HANDLES")) (OPERATION-HANDLED-P-METHOD-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-OPERATION-HANDLED-P")) (GET-HANDLER-FOR-METHOD-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME "-GET-HANDLER-FOR")) (METHOD-LIST 'SI:UNCLAIMED-MESSAGE)) (DOLIST (MESSAGE (SYMBOL-VALUE METHOD-LIST-NAME)) (LET ((METHOD-NAME (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL NAME #\- MESSAGE "-METHOD"))) (PUSH (CONS MESSAGE METHOD-NAME) METHOD-LIST))) (PUSH (CONS ':WHICH-OPERATIONS METHOD-LIST-NAME) METHOD-LIST) (PUSH (CONS ':SEND-IF-HANDLES SEND-IF-HANDLES-METHOD-NAME) METHOD-LIST) (PUSH (CONS ':OPERATION-HANDLED-P OPERATION-HANDLED-P-METHOD-NAME) METHOD-LIST) (PUSH (CONS ':GET-HANDLER-FOR GET-HANDLER-FOR-METHOD-NAME) METHOD-LIST) `(PROGN 'COMPILE (DEFUN ,SEND-IF-HANDLES-METHOD-NAME (IGNORE OPERATION &REST ARGS) (IF (MEMBER OPERATION (,METHOD-LIST-NAME NIL)) (LEXPR-SEND SELF OPERATION ARGS))) (DEFUN ,OPERATION-HANDLED-P-METHOD-NAME (IGNORE OPERATION) (MEMBER OPERATION (,METHOD-LIST-NAME NIL))) (DEFUN ,GET-HANDLER-FOR-METHOD-NAME (IGNORE OPERATION) (IF (MEMBER OPERATION (,METHOD-LIST-NAME NIL)) (MAKE-SYMBOL-FROM-CONCATENATED-NAMES NIL ',NAME "-" OPERATION) ',(PKG-NAME PACKAGE))) (DEFUN ,METHOD-LIST-NAME (IGNORE) ',(SYMBOL-VALUE METHOD-LIST-NAME)) (SETQ ,NAME (FAKE-UP-INSTANCE ',NAME ',(SYMBOL-VALUE INSTANCE-VARIABLE-LIST-NAME) ',METHOD-LIST ',INIT-PLIST-GENERATOR)))))