;;; -*- Mode:LISP; Package:SYSTEM-INTERNALS; Lowercase:T; Base:8; Readtable:CL -*- ;;; this file contains macro definitions for zetalisp special forms ;;; for use with the common-lisp MACRO-FUNCTION function. ;;; Note that many special forms have been punted as they are either ;;; too obscure or kludgey or too implementation-dependant to make ;;; any sense to a common-lisp program in any case. ;;;; list of all fexprs in the source as of 23-Apr-84 09:12:05 ;;; ; perviously defined, or commonlisp special form ;;; * defined in this file ;;; ~ puntable ;;; ? ? ;;;------------------------------------------------------------------------------------------ ;;; ? catch ;;; ? multiple-value-call ;;; ? the ;;;VOTRAX.LISP.1 ;;; ~ (defun speak-words ("e &rest list-of-words) ;;;GRIND.LISP.143 ;;; ~ (defun grindef ("e &rest fcns) ;;;HACKS.LISP.190 ;;; ~ (defun skipa ("e var form) ;;; ~ (defun skipe ("e var form) ;;; ~ (defun skipn ("e var form) ;;;CADRLP.LISP.148 ;;; ~ (defun defmic ("e name opcode arglist lisp-function-p &optional no-qintcmp ;;;COLDUT.LISP.91 ;;; ~ (defun defmic ("e name opcode arglist lisp-function-p &optional no-qintcmp) ;;;COMPAT.LISP.32 ;;; ~ (defun include ("e &rest ignore)) ;;;EVAL.LISP.43 ;;; ~ (defun *catch-for-eval (tag "e &rest body) ;;; ; (defun setq ("e &rest symbols-and-values) ;;; ~ (defun variable-boundp ("e variable) ;;; ~ (defun variable-location ("e variable) ;;; ~ (defun variable-makunbound ("e variable) ;;; * (defun multiple-value ("e var-list exp) ;;; * (defun nth-value (value-number "e exp) ;;; * (defun multiple-value-list ("e exp) ;;; ; (defun multiple-value-prog1 ("e value-form &rest forms) ;;; * (defun multiple-value-bind ("e var-list exp &rest body) ;;; * (defun dont-optimize ("e &rest body) ;;; ; (defun progn ("e &rest body) ;;; * (defun comment ("e &rest ignore) ;;; * (defun with-stack-list ("e variable-and-elements &rest body) ;;; * (defun with-stack-list* ("e variable-and-elements &rest body) ;;; * (defun and ("e &rest expressions) ;;; * (defun or ("e &rest expressions) ;;; * (defun cond ("e &rest clauses) ;;; ; (defun let ("e varlist &rest body) ;;; ; (defun let* ("e varlist &rest body) ;;; ; (defun flet ("e function-list &rest body) ;;; ; (defun macrolet ("e macro-list &rest body) ;;; ; (defun labels ("e function-list &rest body) ;;; ; (defun progv (vars vals "e &rest body) ;;;(defun progw (vars-and-vals "e &rest body) ;;;(defun let-if (cond "e var-list "e &rest body) ;;; ; (defun unwind-protect ("e body-form &rest cleanup-forms) ;;; ; (defun *throw (tag "e value-expression) ;;; ; (defun block ("e name &rest body) ;;; ; (defun return-from ("e blockname &rest vals) ;;; * (defun return ("e &rest vals) ;;; ; (defun tagbody ("e &rest body) ;;; ; (defun go ("e tag &aux tem) ;;; * (defun prog ("e &rest prog-arguments) ;;; * (defun prog* ("e &rest prog-arguments) ;;; * (defun do ("e &rest x) ;;; * (defun do-named ("e name &rest x) ;;; * (defun do* ("e &rest x) ;;; * (defun do*-named ("e name &rest x) ;;; ; (defun function ("e function) ;;; ; (defun quote ("e x) x) ;;; ~ (defun functional-alist ("e x) ;just like quote interpreted. however, the compiler ;;;LTOP.LISP.464 ;;;(defun break (&optional "e format-string &eval &rest args ;;;QCFILE.LISP.307 ;;;(defun patch-source-file ("e si:patch-source-file-namestring &rest body) ;;;(defun special (&rest "e symbols) ;;;(defun unspecial (&rest "e symbols) ;;; ~ (defun defmic ("e name opcode arglist lisp-function-p &optional (no-qintcmp nil) ;;;QCOPT.LISP.99 ;;; ~ (defun *lexpr ("e &rest l) ;;; ~ (defun *expr ("e &rest l) ;;; ~ (defun *fexpr ("e &rest l) ;;;QFCTNS.LISP.734 ;;; * (defun deff ("e function-spec &eval definition) ;;; * (defun def ("e function-spec &rest defining-forms) ;;; * (defun defun ("e &rest arg) ;;; * (defun macro ("e function-spec &rest def) ;;; * (defun deff-macro ("e function &eval definition) ;;;(defun defsubst ("e symbol &rest def) ;;; ~ (defun signp ("e test &eval num) ;;; ~ (defun array ("e x type &eval &rest dimlist) ;;; ; (defun declare ("e &rest declarations) ;;; ; (defun eval-when ("e times &rest forms &aux val) ;;;QMISC.LISP.605 ;;; ~ (defun status ("e status-function &optional (item nil item-p)) ;;; ~ (defun sstatus ("e status-function item ;;; ; (defun compiler-let ("e bindlist &rest body) ;;; ~ (defun lexpr-funcall-with-mapping-table (function "e table &eval &rest args) ;;; ~ (defun funcall-with-mapping-table (function "e table &eval &rest args) ;;;QRAND.LISP.374 ;;;(defun special (&rest "e symbols) ;;;(defun unspecial (&rest "e symbols) ;;; * (defun defprop ("e symbol value property) ;;;(defun defvar-1 ("e symbol &optional (value ':unbound) documentation) ;;;(defun defconst-1 ("e symbol &eval value &optional documentation) ;;;CLASS.LISP.88 ;;; ~ (defun defclass-1 ("e class-symbol superclass-symbol instance-pattern) ;;; ~ (defun defclass-bootstrap ("e nm c-s method-tail variables) ;;;FLAVOR.LISP.258 ;;; ~ (defun with-self-accessible ("e flavor-name &rest body) ;;;LOGIN.LISP.80 ;;; ~ (defun login-setq ("e &rest l) ;undoing setq ;;;LOOP.LISP.795 ;;; ~ (defun loop-featurep ("e f) ;;; ~ (defun loop-nofeaturep ("e f) ;;; ~ (defun loop-set-feature ("e f) ;;; ~ (defun loop-set-nofeature ("e f) ;;;QTRACE.LISP.149 ;;; ? (defun trace ("e &rest specs) ;;; ? (defun untrace ("e &rest fns) ;;;SELEV.LISP.21 ;;;(defun matchcarcdr ("e arg car cdr) ;;;USYMLD.LISP.186 ;;; ~ (defun ua-defmic ("e name opcode arglist lisp-function-p &optional (no-qintcmp nil)) ;;;COMTAB.LISP.307 ;;; ~ (defun set-comtab-return-undo (&rest "e form &aux undo) ;;; ADVISE crap (defmacro (advise-let alternate-macro-definition) (&rest expressions) `(LET ,@expressions)) (defmacro (advise-multiple-value-list alternate-macro-definition) (&rest expressions) `(MULTIPLE-VALUE-LIST ,@expressions)) (defmacro (advise-prog alternate-macro-definition) (&rest expressions) `(PROG ,@expressions)) (defmacro (advise-progn alternate-macro-definition) (&rest expressions) `(PROGN ,@expressions)) (defmacro (advise-return-list alternate-macro-definition) (&rest expressions) `(RETURN-LIST ,@expressions)) (defmacro (advise-setq alternate-macro-definition) (&rest expressions) `(SETQ ,@expressions)) ;;; AND ;;;(and a b c d) => (if a (if b (if c d))) (defmacro (and alternate-macro-definition) (&rest expressions) (case (length expressions) (0 t) (1 (car expressions)) (t (do* ((foo (cdr (reverse expressions)) (cdr foo)) (result `(,(car (last expressions))))) ((null foo) (car result)) (setq result `((if ,(car foo) . ,result))))))) ;;; COMMENT (defmacro (comment alternate-macro-definition) (&rest ignore) `(QUOTE IGNORE)) ;;; COND ;;;(cond (a b c) (d) (e f)) => (if a (progn b c) (let (d) (if d (if e f))) ;;; This is inadequate, fix it. (defmacro (cond alternate-macro-definition) (&rest clauses) (do ((foo (reverse clauses) (cdr foo)) (result nil) loser) ((null foo) (if loser `(let (,loser) . ,result) (car result))) (if (> (length (car foo)) 1) (setq result `((if ,(caar foo) (progn . ,(cdar foo)) . ,result))) (progn (or loser (setq loser (make-symbol "LOSER" t))) (setq result `((if (setq ,loser ,(caar foo)) ,loser . ,result))))))) ;;; DEF ;;; This is a crock for the editor. (defmacro (def alternate-macro-definition) (function-spec &rest defining-forms) `(PROGN ,@defining-forms ',function-spec)) ;;; DEFF (defmacro (deff alternate-macro-definition) (function-spec definition) `(PROGN (FSET-CAREFULLY (QUOTE ,function-spec) ,definition) (QUOTE ,function-spec))) ;;; DEFF-MACRO (defmacro (deff-macro alternate-macro-definition) (function definition) `(PROGN (FDEFINE ',function ,definition t) ',function)) ;;; DEFPROP (defmacro (defprop alternate-macro-definition) (symbol value property) `(progn (putprop ',symbol ',value ',property) ',symbol)) ;;; DEFUN ;;; This is inadequate, fix it. (defmacro (defun alternate-macro-definition) (name &rest body) `(PROGN (FDEFINE ',name (PROCESS-DEFUN-BODY ',name ',body) T) ',name)) ;;; DO, DO*, DO-NAMED, DO*-NAMED (defun separate-do-bindings (binding-list receiver) (labels ((scan-bindings (tail binding-names initial-values iteration-clauses) (if (null tail) (funcall receiver (reverse binding-names) (reverse initial-values) (reverse iteration-clauses)) (let ((this-clause (first tail))) (if (symbolp this-clause) (scan-bindings (rest tail) (cons this-clause binding-names) (cons 'nil initial-values) (cons this-clause iteration-clauses)) (let ((this-binding (first this-clause)) (init-and-step (rest this-clause))) (if (null init-and-step) (scan-bindings (rest tail) (cons this-binding binding-names) (cons 'nil initial-values) (cons this-binding iteration-clauses)) (let ((init (first init-and-step)) (step (rest init-and-step))) (if (null step) (scan-bindings (rest tail) (cons this-binding binding-names) (cons init initial-values) (cons this-binding iteration-clauses)) (scan-bindings (rest tail) (cons this-binding binding-names) (cons init initial-values) (cons (first step) iteration-clauses))))))))))) (scan-bindings binding-list '() '() '()))) (defun expand-do-macro (let-type setq-type) #'(lambda (do-form ignore) (separate-do-bindings (second do-form) #'(lambda (binding-names initial-values iteration-clauses) (let* ((loop-tag (gensym)) (test-form (third do-form)) (test (first test-form)) (result (if (null (rest test-form)) '(PROGN NIL) `(PROGN ,@(rest test-form)))) (body (rest (rest (rest do-form))))) (labels ((interleave (x y) (cond ((null x) y) ((null y) x) (t (cons (car x) (interleave y (cdr x))))))) `(BLOCK NIL (,let-type ,(mapcar #'list binding-names initial-values) (TAGBODY ,loop-tag (WHEN ,test (RETURN-FROM NIL ,result)) (PROGN ,@body) (,setq-type ,@(interleave binding-names iteration-clauses)) (GO ,loop-tag)))))))))) (deff do-expander (expand-do-macro 'let 'psetq)) (deff do*-expander (expand-do-macro 'let* 'setq)) (defprop do (macro . do-expander) alternate-macro-definition) (defprop do* (macro . do*-expander) alternate-macro-definition) (defmacro (do-named alternate-macro-definition) (name vars test-and-result &body body) `(BLOCK ,name (DO ,vars ,test-and-result ,@body))) (defmacro (do*-named alternate-macro-definition) (name vars test-and-result &body body) `(BLOCK ,name (DO* ,vars ,test-and-result ,@body))) ;;; DONT-OPTIMIZE (defmacro (dont-optimize alternate-macro-definition) (&body body) `(PROGN ,@body)) ;;; ENCAPSULATION-LET (defmacro (encapsulation-let alternate-macro-definition) (&body body) `(LET ,@body)) ;;; FUNCALL-WITH-MAPPING-TABLE (defmacro (funcall-with-mapping-table alternate-macro-definition) (function table &rest args) (declare (ignore table)) `(APPLY ,function (LIST ,@(copylist args)))) ;;; FUNCALL-WITH-MAPPING-TABLE-INTERNAL (defmacro (funcall-with-mapping-table-internal alternate-macro-definition) (function table &rest args) (declare (ignore table)) `(APPLY ,function (LIST ,@(copylist args)))) ;;; ZL:IF ;;; This needs fixing. (defmacro (zl:if alternate-macro-definition) (test then &rest elses) `(cli:if ,test ,then (progn ,@elses))) ;;; LET-IF (gak) (defmacro (let-if alternate-macro-definition) (condition binding-list &rest body) (let ((thunk (gensym))) (labels ((split-bindings (bindings variables values) (if (null bindings) `(LET ((,thunk ,@body)) (IF ,condition (PROGV ,variables ,values (FUNCALL ,thunk)) (FUNCALL ,thunk))) (let ((this-binding (first bindings))) (split-bindings (rest bindings) (cons (if (listp this-binding) (first this-binding) this-binding) variables) (cons (if (and (listp this-binding) (cdr this-binding)) (second this-binding) 'nil) values)))))) (split-bindings binding-list '() '())))) ;;; LEXPR-FUNCALL-WITH-MAPPING-TABLE (defmacro (lexpr-funcall-with-mapping-table alternate-macro-definition) (function table &rest args) (declare (ignore table)) `(APPLY (FUNCTION LEXPR-FUNCALL) ,function (LIST ,@(copylist args)))) ;;; LEXPR-FUNCALL-WITH-MAPPING-TABLE-INTERNAL (defmacro (lexpr-funcall-with-mapping-table-internal alternate-macro-definition) (function table &rest args) (declare (ignore table)) `(APPLY (FUNCTION LEXPR-FUNCALL) ,function (LIST ,@(copylist args)))) ;;; MACRO (defmacro (macro alternate-macro-definition) (function-spec &rest def) (unless (symbolp function-spec) (setq function-spec (standardize-function-spec function-spec))) `(PROGN (FDEFINE (QUOTE ,function-spec) (CONS (QUOTE MACRO) (QUOTE (LAMBDA ,(car def) ,@(cdr def)))) T) (QUOTE ,function-spec))) ;;; MULTIPLE-VALUE (defmacro (multiple-value alternate-macro-definition) (vars exp) `(MULTIPLE-VALUE-SETQ ,vars ,exp)) ;;; MULTIPLE-VALUE-BIND (defmacro (multiple-value-bind alternate-macro-definition) (vars exp &body body) `(MULTIPLE-VALUE-CALL #'(LAMBDA ,vars ,@body) ,exp)) ;;; MULTIPLE-VALUE-LIST (defmacro (multiple-value-list alternate-macro-definition) (exp) `(MULTIPLE-VALUE-CALL #'LIST ,exp)) ;;; MULTIPLE-VALUE-SETQ (defmacro (multiple-value-setq alternate-macro-definition) (vars form) (labels ((pair-up (vars bindings setqs) (if (null vars) `(MULTIPLE-VALUE-CALL #'(LAMBDA ,(cons '&OPTIONAL (reverse bindings)) ,@(reverse setqs) ,(first (reverse bindings))) ,form) (let ((temp (gensym))) (pair-up (rest vars) (cons temp bindings) (cons `(SETQ ,(first vars) ,temp) setqs)))))) (pair-up vars nil nil))) ;;; NTH-VALUE (defmacro (nth-value alternate-macro-definition) (value-number exp) `(NTH ,value-number (MULTIPLE-VALUE-LIST ,exp))) ;;; OR ;;; (or a c b d) => (cond (a) (b) (c) (t d)) ;;; This is inadequate, fix it. (defmacro (or alternate-macro-definition) (&rest expressions) (case (length expressions) (0 nil) (1 (car expressions)) (t (do ((x expressions (cdr x)) (result (list 'COND) (cons (list (car x)) result))) ((null (cdr x)) (push (list t (car x)) result) (nreverse result)))))) ;;; PROG, PROG* ;;; Bletch. (defun make-prog-macroexpander (prog-type let-type) #'(lambda (prog-form macroenvironment) (when (not (>= (length prog-form) 2)) (ferror nil "Too few arguments to ~S in ~S." prog-type prog-form)) (let ((binding-list (second prog-form)) (body (rest (rest prog-form)))) ;; Macroexpand body to get declarations. (let ((macroexpanded-body (mapcar #'(lambda (form) (macroexpand form macroenvironment)) body))) ;; Scan out declarations. (do ((forms macroexpanded-body (rest forms)) (decls '() (cons (first forms) decls))) ((or (not (consp (first forms))) (not (eq (car (first forms)) 'LISP::DECLARE))) `(BLOCK NIL (,let-type ,binding-list ,@(reverse decls) (TAGBODY ,@forms))))))))) (deff prog-macro-expander (make-prog-macroexpander 'PROG 'LET)) (deff prog*-macro-expander (make-prog-macroexpander 'PROG* 'LET*)) (defprop prog (macro . prog-macro-expander) alternate-macro-definition) (defprop prog* (macro . prog*-macro-expander) alternate-macro-definition) ;;; RETURN (defmacro (return alternate-macro-definition) (&rest values) `(RETURN-FROM NIL ,@values)) ;;; RETURN-LIST ;;; Crock, this is an old interpreter function that the ;;; advice system uses randomly. (defmacro (return-list alternate-macro-definition) (l) `(RETURN-FROM NIL (VALUES-LIST ,l))) ;;; WITH-STACK-LIST, WITH-STACK-LIST* (defmacro (with-stack-list alternate-macro-definition) ((var . elts) &body body) `(LET ((,var (LIST ,@elts))) ,@body)) (defmacro (with-stack-list* alternate-macro-definition) ((var . elts) &body body) `(LET ((,var (LIST* ,@elts))) ,@body)) (defmacro (prog1 alternate-macro-definition) (first &body forms) (let ((result (gensym))) `(let ((,result ,first)) ,@forms ,result))) (defmacro (prog2 alternate-macro-definition) (first second &body forms) `(progn ,first (prog1 ,second ,@forms)))