;;; -*- Mode:LISP; Package:ZWEI; Base:8; Readtable:T -*- ;;; Zwei compiler commands, see ZWEI;COMA for comments ;;; ** (c) Copyright 1980 Massachusetts Institute of Technology ** (DEFCOM COM-EVALUATE-MINI-BUFFER "Evaluate a form from the mini-buffer." (KM) (EVALUATE-MINI-BUFFER)) (DEFUN EVALUATE-MINI-BUFFER (&OPTIONAL INITIAL-CONTENTS INITIAL-CHAR-POS &AUX INTERVAL) "Read an expression with a mini buffer, and evaluate it. INITIAL-CONTENTS is a string to initialize the contents from, and INITIAL-CHAR-POS is where to put the cursor, as a number of characters from the beginning." (MULTIPLE-VALUE (NIL NIL INTERVAL) (EDIT-IN-MINI-BUFFER *MINI-BUFFER-MULTI-LINE-COMTAB* INITIAL-CONTENTS INITIAL-CHAR-POS '("Forms to evaluate (end with End)"))) (LET ((FORM-STRING (STRING-INTERVAL INTERVAL))) (DO ((I 0) (FORM) (*READTABLE* *READTABLE*) (*READ-BASE* *PRINT-BASE*) (*PRINT-BASE* *PRINT-BASE*) (EOF '(()))) (NIL) (CONDITION-CASE (ERROR) (MULTIPLE-VALUE (FORM I) (CLI:READ-FROM-STRING FORM-STRING NIL EOF :START I)) (SYS:READ-ERROR (BARF (SEND ERROR :REPORT-STRING)) (RETURN NIL))) (WHEN (EQ FORM EOF) (RETURN NIL)) (DO ((VALS (LET ((*STANDARD-INPUT* SI:SYN-TERMINAL-IO)) (MULTIPLE-VALUE-LIST (SI:EVAL-ABORT-TRIVIAL-ERRORS FORM))) (CDR VALS)) (FLAG T NIL)) ((NULL VALS)) (UNLESS FLAG (SEND *QUERY-IO* :FRESH-LINE)) (FORMAT *QUERY-IO* "~:[, ~]~S" FLAG (CAR VALS))))) DIS-TEXT) ;DIS-TEXT in case user manually alters the buffer with Lisp code (DEFCOM COM-EVALUATE-INTO-BUFFER "Evaluate a form from the mini-buffer and insert the results into the buffer. If there are multiple values, each value is printed into the buffer, with a Return before each one. A numeric argument means output printed by the evaluation also goes in the buffer." (KM) (LET ((FORM (TYPEIN-LINE-MULTI-LINE-READ "Lisp form: (end with ~C)" #/END)) (STREAM (INTERVAL-STREAM-INTO-BP (POINT)))) (LET ((VALUES (MULTIPLE-VALUE-LIST (LET ((*STANDARD-OUTPUT* (IF *NUMERIC-ARG-P* STREAM *STANDARD-OUTPUT*))) (SI:EVAL-SPECIAL-OK FORM))))) (DOLIST (V VALUES) (TERPRI STREAM) (FUNCALL (OR PRIN1 #'PRIN1) V STREAM))) (MOVE-BP (POINT) (SEND STREAM :READ-BP))) DIS-TEXT) (DEFUN READ-OR-BARF (STREAM) (CONDITION-CASE (ERROR) (READ-PRESERVING-WHITESPACE STREAM) (SYS:READ-ERROR (BARF (STRING ERROR))))) (DEFCOM COM-EVALUATE-AND-REPLACE-INTO-BUFFER "Evaluate the next s-expression and replace the result into the buffer. The original expression is deleted and the value, printed out, replaces it." () (LET* ((POINT (POINT)) (MARK (MARK)) (STREAM (REST-OF-INTERVAL-STREAM POINT)) (FORM (READ-OR-BARF STREAM)) (VALUE (SI:EVAL-SPECIAL-OK FORM))) (MOVE-BP MARK (SEND STREAM :READ-BP)) (WITH-UNDO-SAVE ("replacement" POINT MARK T) (FUNCALL (OR PRIN1 'PRIN1) VALUE STREAM) (WITH-BP (END (SEND STREAM :READ-BP) :NORMAL) (DELETE-INTERVAL POINT MARK T) (MOVE-BP POINT END)))) DIS-TEXT) (DEFCOM COM-EVALUATE-AND-PRINT-INTO-BUFFER "Evaluate the next s-expression and print standard output into the buffer. The original expression is deleted and the output replaces it." () (LET* ((POINT (POINT)) (MARK (MARK)) (STREAM (REST-OF-INTERVAL-STREAM POINT)) (FORM (READ-OR-BARF STREAM)) ;(VALUE (SI:EVAL-SPECIAL-OK FORM)) ) (MOVE-BP MARK (SEND STREAM :READ-BP)) (WITH-UNDO-SAVE ("replacement" POINT MARK T) ;(FUNCALL (OR PRIN1 'PRIN1) VALUE STREAM) (LET ((*STANDARD-OUTPUT* STREAM)) (SI:EVAL-SPECIAL-OK FORM)) (WITH-BP (END (SEND STREAM :READ-BP) :NORMAL) (DELETE-INTERVAL POINT MARK T) (MOVE-BP POINT END)))) DIS-TEXT) (DEFCOM COM-MACRO-EXPAND-EXPRESSION "Print macroexpansion of next s-expression. The result is printed on the screen with GRIND-TOP-LEVEL." () (LET ((STREAM (REST-OF-INTERVAL-STREAM (POINT)))) (LET ((FORM (READ-OR-BARF STREAM))) (GRIND-TOP-LEVEL (MACROEXPAND FORM)))) DIS-NONE) (DEFCOM COM-MACRO-EXPAND-EXPRESSION-ALL "Print macroexpansion of next s-expression to all levels. The result is printed on the screen with GRIND-TOP-LEVEL." () (LET ((STREAM (REST-OF-INTERVAL-STREAM (POINT)))) (LET ((FORM (READ-OR-BARF STREAM))) (GRIND-TOP-LEVEL (COMPILER:MACROEXPAND-ALL FORM)))) DIS-NONE) (DEFCOM COM-MACRO-EXPAND-EXPRESSION-INTO-BUFFER "Print macroexpansion of next s-expression at end of the current buffer. If there are multiple values, each value is printed into the buffer, with a Return before each one. A numeric argument means output printed by the evaluation also goes in the buffer." (KM) (LET ((STREAM (REST-OF-INTERVAL-STREAM (POINT)))) (LET ((FORM (READ-OR-BARF STREAM))) (GRIND-TOP-LEVEL (MACROEXPAND FORM) (send *standard-output* :size-in-characters) (interval-stream-into-bp (INTERVAL-LAST-BP *INTERVAL*))))) DIS-TEXT) (DEFCOM COM-MACRO-EXPAND-EXPRESSION-ALL-INTO-BUFFER "Print macroexpansion of next s-expression to all levels at end of current buffer." () (LET ((STREAM (REST-OF-INTERVAL-STREAM (POINT)))) (LET ((FORM (READ-OR-BARF STREAM))) (GRIND-TOP-LEVEL (COMPILER:MACROEXPAND-ALL FORM) (send *standard-output* :size-in-characters) (interval-stream-into-bp (INTERVAL-LAST-BP *INTERVAL*))))) DIS-TEXT) (DEFCOM COM-COMPILER-OPTIMIZE "Print compiler optimization of next s-expression. The result is printed on the screen with GRIND-TOP-LEVEL." () (LET ((STREAM (REST-OF-INTERVAL-STREAM (POINT)))) (LET ((FORM (READ-OR-BARF STREAM))) (GRIND-TOP-LEVEL (COMPILER:COMPILER-OPTIMIZE-EXTERNAL FORM)))) DIS-NONE) (DEFCOM COM-COMPILE-REGION "Compile the current region or defun. If there is a region, it is compiled. Otherwise, the current or next defun is compiled. In that case, DEFVARs reset the variable even if already bound." () (COMPILE-DEFUN-INTERNAL (or (get-buffer-compiler *interval*) T) "Compiling" "compiled.") DIS-NONE) (DEFCOM COM-CAREFUL-COMPILE-REGION "Compile the current region or defun, with optimizers and the peephole optimizer turnned off. Try this if you suspect a compiler bug. If there is a region, it is compiled. Otherwise, the current or next defun is compiled." () (COMPILE-DEFUN-INTERNAL (or (get-buffer-compiler *interval*) T) "Careful-compiling" "Careful-compiled." NIL ;USE-TYPEOUT NIL ;DEFVAR-HACK '(:MODE COMPILER:MACRO-COMPILE :CAREFUL-MODE T)) DIS-NONE) (DEFCOM COM-MICROCOMPILE-REGION "Microcompile the current region or defun. If there is a region, it is compiled. Otherwise, the current or next defun is compiled." () (COMPILE-DEFUN-INTERNAL (or (get-buffer-compiler *interval*) T) "Microcompiling" "microcompiled." NIL ;USE-TYPEOUT NIL ;DEFVAR-HACK '(:MODE COMPILER:MICRO-COMPILE)) DIS-NONE) (DEFCOM COM-CAREFUL-MICROCOMPILE-REGION "Microcompile the current region or defun, with optimizers turnned off. Try this if you suspect a microcompiler bug. If there is a region, it is compiled. Otherwise, the current or next defun is compiled." () (COMPILE-DEFUN-INTERNAL (or (get-buffer-compiler *interval*) T) "Careful-microcompiling" "Careful-microcompiled." NIL ;USE-TYPEOUT NIL ;DEFVAR-HACK '(:MODE COMPILER:MICRO-COMPILE :CAREFUL-MODE T)) DIS-NONE) (DEFCOM COM-EVALUATE-REGION "Evaluate the current region or defun. Result is typed out in the echo area. If there is a region, it is evaluated. Otherwise, the current or next defun is evaluated. In that case, DEFVARs reset the variable even if already bound." () (COMPILE-DEFUN-INTERNAL (GET-BUFFER-EVALUATOR *INTERVAL*) "Evaluating" "evaluated." :PROMPT) DIS-NONE) (DEFCOM COM-EVALUATE-REGION-VERBOSE "Evaluate the current region or defun. Result is typed out in the typeout window. If there is a region, it is evaluated. Otherwise, the current or next defun is evaluated. In that case, DEFVARs reset the variable even if already bound." () (COMPILE-DEFUN-INTERNAL (GET-BUFFER-EVALUATOR *INTERVAL*) "Evaluating" "evaluated." T) DIS-NONE) (DEFCOM COM-EVALUATE-REGION-HACK "Evaluate the current region or defun. DEFVARs reset the variable even if already bound. If there is a region, it is evaluated. Otherwise, the current or next defun is evaluated." () (COMPILE-DEFUN-INTERNAL (GET-BUFFER-EVALUATOR *INTERVAL*) "Evaluating" "evaluated." :PROMPT T) DIS-NONE) (DEFUN COMPILE-DEFUN-INTERNAL (COMPILE-P MODE-NAME ECHO-NAME &OPTIONAL USE-TYPEOUT DEFVAR-HACK (COMPILER-PROCESSING-MODE '(:MODE COMPILER:MACRO-COMPILE)) (*target-computer* 'compiler:lambda-interface) (*fasd-interface* 'compiler:lambda-fasd-interface) &AUX BP1 BP2 DEFUN-NAME) "Compile or evaluate a part of the current buffer. COMPILE-P is T to compile, NIL to eval, or else a function to evaluate and print a form. If there is a region, it is used; otherwise the current or following defun is used. USE-TYPEOUT is passed to COMPILE-PRINT-INTERVAL and controls where information is printed. DEFVAR-HACK says always re-set variables if DEFVARs are evaluated. Normally this is only done if there is no region. MODE-NAME is a string containing a capitalized present participle, such as /"Compiling/". ECHO-NAME is a string containing a lowecase past participle and period (/"compiled./")." (COND ((WINDOW-MARK-P *WINDOW*) (SETQ BP1 (MARK) BP2 (POINT)) (OR (BP-< BP1 BP2) (PSETQ BP1 BP2 BP2 BP1)) (SETQ DEFUN-NAME "Region")) ((SETQ BP1 (DEFUN-INTERVAL (BEG-LINE (POINT)) 1 NIL NIL)) (SETQ BP2 (INTERVAL-LAST-BP BP1) BP1 (INTERVAL-FIRST-BP BP1)) (SETQ DEFVAR-HACK T)) (T (BARF "Cannot find a defun near point."))) (COMPILE-PRINT-INTERVAL BP1 BP2 T COMPILE-P DEFUN-NAME MODE-NAME ECHO-NAME USE-TYPEOUT DEFVAR-HACK COMPILER-PROCESSING-MODE nil ;already-resectionized-flag *target-computer* *fasd-interface*)) (DEFCOM COM-EVALUATE-BUFFER "Evaluate the entire buffer." () (COMPILE-BUFFER (GET-BUFFER-EVALUATOR *INTERVAL*) "Evaluating" "evaluated.")) (DEFCOM COM-COMPILE-BUFFER "Compile the entire buffer." () (COMPILE-BUFFER (or (get-buffer-compiler *interval*) T) "Compiling" "compiled.")) (DEFCOM COM-MICROCOMPILE-BUFFER "Microcompile the entire buffer." () (COMPILE-BUFFER (or (get-buffer-compiler *interval*) T) "Microcompiling" "microcompiled." '(:MODE COMPILER:MICRO-COMPILE))) (DEFUN COMPILE-BUFFER (COMPILE-P MODE-NAME ECHO-NAME &OPTIONAL (COMPILER-PROCESSING-MODE '(:MODE COMPILER:MACRO-COMPILE)) (*target-computer* 'compiler:lambda-interface) (*fasd-interface* 'compiler:lambda-fasd-interface) &AUX BP1 BP2 NAME) "Compile or evaluate the current buffer. COMPILE-P is T to compile, NIL to eval, or else a function to evaluate and print a form. COMPILE-PROCESSING-MODE is a keyword list. The :MODE component should be either COMPILER:MACRO-COMPILE or COMPILER:MICRO-COMPILE. MODE-NAME is a string containing a capitalized present participle, such as /"Compiling/". ECHO-NAME is a string containing a lowecase past participle and period (/"compiled./")." (IF *NUMERIC-ARG-P* (SETQ BP1 (POINT) BP2 (INTERVAL-LAST-BP *INTERVAL*) NAME "Rest of buffer") (SETQ BP1 *INTERVAL* NAME "Buffer")) (COMPILE-PRINT-INTERVAL BP1 BP2 T COMPILE-P NAME MODE-NAME ECHO-NAME NIL ;USE-TYPEOUT NIL ;DEFVAR-HACK COMPILER-PROCESSING-MODE nil ;already-resectionized-flag *target-computer* *fasd-interface*) DIS-NONE) (DEFUN GET-BUFFER-EVALUATOR (BUFFER) "Return the evaluate-and-print function for BUFFER, or NIL (the default)." (SEND BUFFER :GET-ATTRIBUTE :EVALUATOR)) (defun get-buffer-compiler (buffer) "Return the compile-and-print function for BUFFER, or NIL (the default)." (send buffer :get-attribute :compiler)) ;; Copied from LAD: RELEASE-3.ZWEI; COMC.LISP#216 on 26-Mar-87 17:35:18 (DEFUN COMPILE-PRINT-INTERVAL (BP1 BP2 IN-ORDER-P COMPILE-P REGION-NAME MODE-NAME ECHO-NAME &OPTIONAL USE-TYPEOUT DEFVAR-HACK COMPILER-PROCESSING-MODE ALREADY-RESECTIONIZED-FLAG &optional (*target-computer* 'compiler:lambda-interface) (*fasd-interface* 'compiler:lambda-fasd-interface) &AUX FORMAT-FUNCTION SUCCESS) "Compile or evaluate the interval specified by BP1, BP2, IN-ORDER-P. COMPILE-P is T to compile, NIL to eval, or else a function to evaluate and print a form. REGION-NAME is a string to print as the name of this whole object, or NIL to mention each object's name. USE-TYPEOUT can be T, NIL, :TYPEOUT or :PROMPT. T prints form values and names of objects in typeout window. Otherwise, form values appear in the echo area, and :TYPEOUT prints names of objects in typeout window. :PROMPT prints names of objects in prompt line. NIL prints names of objects in the echo area. DEFVAR-HACK says always re-set variables if DEFVARs are evaluated. Normally this is only done if there is no region. COMPILE-PROCESSING-MODE is a keyword list selecting compiler options. For compatibility, a symbol such as COMPILER:MACRO-COMPILE or COMPILER:MICRO-COMPILE is converted to (:mode ) ALREADY-RESECTIONIZED-FLAG should be T to inhibit resectionization. MODE-NAME is a string containing a capitalized present participle, such as /"Compiling/". ECHO-NAME is a string containing a lowercase past participle and period (/"compiled./")." (cond ((null compiler-processing-mode) (setq compiler-processing-mode '(:mode compiler:macro-compile))) ((symbolp compiler-processing-mode) (setq compiler-processing-mode `(:mode ,compiler-processing-mode)))) (GET-INTERVAL BP1 BP2 IN-ORDER-P) (UNLESS ALREADY-RESECTIONIZED-FLAG (CHECK-INTERVAL-SECTIONS BP1 BP2 T)) (UNDO-SAVE-CURRENT-RANGE) (SETQ FORMAT-FUNCTION (CASE USE-TYPEOUT ((T :TYPEOUT) #'(LAMBDA (STRING &REST ARGS) (APPLY 'FORMAT T STRING ARGS))) (:PROMPT #'PROMPT-LINE-MORE) (OTHERWISE #'(LAMBDA (STRING &REST ARGS) (APPLY 'FORMAT *QUERY-IO* STRING ARGS))))) (IF REGION-NAME (FUNCALL FORMAT-FUNCTION "~&~A ~A" MODE-NAME REGION-NAME) (FUNCALL FORMAT-FUNCTION "~&~A ~S" MODE-NAME (function-name-from-bp BP1))) (UNWIND-PROTECT (PROGN (COMPILE-INTERVAL COMPILE-P (CASE USE-TYPEOUT ((T) T) (T *QUERY-IO*)) DEFVAR-HACK BP1 BP2 T COMPILER-PROCESSING-MODE *target-computer* *fasd-interface*) (SETQ SUCCESS T)) (OR SUCCESS (FUNCALL FORMAT-FUNCTION " -- aborted."))) (FUNCALL FORMAT-FUNCTION " -- ~A" ECHO-NAME) (UPDATE-INTERVAL-COMPILE-TICK BP1 BP2 T)) ;; Copied from LAD: RELEASE-3.ZWEI; COMC.LISP#216 on 26-Mar-87 17:35:19 (defun function-name-from-bp (bp) (let ((node (bp-node bp))) (if (typep node 'section-node) (section-node-name node) (funcall (get :lisp 'get-section-name) (car bp) bp)))) ;Careful! When you get around to changing this, leave ; COMPILE-P and COMPILE-PROCESSING-MODE as specials with the same meaning ; as now. Prolog uses them while expanding its macros. 3/17/85 (DEFUN COMPILE-INTERVAL (COMPILE-P PRINT-RESULTS-STREAM DEFVAR-HACK BP1 BP2 IN-ORDER-P COMPILE-PROCESSING-MODE &optional (*target-computer* 'compiler:lambda-interface) (*fasd-interface* 'compiler:lambda-fasd-interface) &AUX GENERIC-PATHNAME STREAM WHOLE-FILE ;T if processing the entire file. SI:FDEFINE-FILE-DEFINITIONS) "Compile or evaluate the interval specified by BP1, BP2, IN-ORDER-P. Does not print any sort of message saying what is being compiled, does not know about sectionization. COMPILE-P is T to compile, NIL to eval, or else a function to evaluate and print a form. PRINT-RESULTS-STREAM is a stream for printing the results of evaluation, or NIL not to print. DEFVAR-HACK says always re-set variables if DEFVARs are evaluated. Normally this is only done if there is no region. COMPILE-PROCESSING-MODE is a keyword list. The :MODE item should be either COMPILER:MACRO-COMPILE or COMPILER:MICRO-COMPILE. ALREADY-RESECTIONIZED-FLAG should be T to inhibit resectionization." (DECLARE (SPECIAL COMPILE-P PRINT-RESULTS-STREAM DEFVAR-HACK COMPILE-PROCESSING-MODE)) (SETQ GENERIC-PATHNAME (SEND *INTERVAL* :GENERIC-PATHNAME)) ;; Does not reparse the mode line; we should let the user decide whether to do that.! ;; Should not override the user's Set Package if he has done one. (GET-INTERVAL BP1 BP2 IN-ORDER-P) ;; Decide whether the entire file is being processed or just a part. ;; If the whole file, we want to notice if any function present in the file previously ;; is now missing. If just a part, anything we don't notice now we must assume ;; is elsewhere in the file. (SETQ WHOLE-FILE (AND (BP-= BP1 (INTERVAL-FIRST-BP *INTERVAL*)) (BP-= BP2 (INTERVAL-LAST-BP *INTERVAL*)))) (SETQ STREAM (INTERVAL-STREAM BP1 BP2 T)) ;; Arrange for first read-error's location to be saved in q-reg ".". (REMPROP (MAKE-REGISTER-NAME #/.) 'POINT) (LET ((SI:*ALL-FREE-INTERPRETER-VARIABLE-REFERENCES-SPECIAL* T)) (MULTIPLE-VALUE-BIND (VARS VALS) (SEND *INTERVAL* :ATTRIBUTE-BINDINGS) (PROGV VARS VALS (let ((compile-in-roots-prop (get *interval* :compile-in-roots))) (cond ((and (eq compile-p t) compile-in-roots-prop (not (cl:member (si:package-root-name *package*) compile-in-roots-prop :test 'string-equal))) (cond ((not (= 1 (length compile-in-roots-prop))) (fsignal "The current heirarchy ~S is not among those acceptable ~s." (si:package-root-name *package*) compile-in-roots-prop)) (t (format print-results-stream " Transferring to hierarchy ~s" (car compile-in-roots-prop)) (pkg-goto (si:pkg-name *package*) nil (pkg-find-package (car compile-in-roots-prop)))))))) (WHEN FS:THIS-IS-A-PATCH-FILE ;; If compiling out of the editor buffer of a patch file, ;; make sure the file itself is marked ;; so that Meta-. will behave right. (PUTPROP GENERIC-PATHNAME T :PATCH-FILE)) ;; Bind off this flag -- our stream is not generating font changes ;; so READ should not try to remove any. (LET ((SI:READ-DISCARD-FONT-CHANGES NIL)) (FLET ((DO-IT () (COMPILER:COMPILE-STREAM STREAM GENERIC-PATHNAME NIL ;FASD-FLAG (IF (AND COMPILE-P (NOT (EQ COMPILE-P T))) ;if using user supplied evaluator, avoid any possible macro-expanding, etc ; in COMPILE-DRIVER. 'SIMPLE-COMPILE-INTERVAL-PROCESS-FN 'COMPILE-INTERVAL-PROCESS-FN) T ;QC-FILE-LOAD-FLAG NIL ;QC-FILE-IN-CORE-FLAG *PACKAGE* NIL ;FILE-LOCAL-DECLARATIONS NIL ;Unused WHOLE-FILE *target-computer* *fasd-interface*))) (IF COMPILE-P (COMPILER:LOCKING-RESOURCES-NO-QFASL (DO-IT)) (DO-IT))))))) (OR (NULL GENERIC-PATHNAME) (SI:RECORD-FILE-DEFINITIONS GENERIC-PATHNAME SI:FDEFINE-FILE-DEFINITIONS WHOLE-FILE))) (DEFUN COMPILE-INTERVAL-PROCESS-FN (FORM) (COMPILER:COMPILE-DRIVER FORM 'COMPILE-INTERVAL-PROCESS-BASIC-FORM 'COMPILE-INTERVAL-PREPROCESS-FN)) ;;;COMPILE-DRIVER does all sorts of macro-expand stuff these days, regardless of process-fn ;;; and OVERRIDE-FN, so we bypass it if this buffer doesnt contain LISP anyway. (DEFUN SIMPLE-COMPILE-INTERVAL-PROCESS-FN (FORM) (COMPILE-INTERVAL-PROCESS-BASIC-FORM FORM 'RANDOM)) ;;; Record the name of what we are compiling, if this form makes it clear. ;;; Turn DEFVAR into SETQ if appropriate. ;;; If we are "evaluating", look for EVAL rather than COMPILE and LOAD in any EVAL-WHEN. ;;; Do not affect the processing of anything but EVAL-WHENs. (DEFUN COMPILE-INTERVAL-PREPROCESS-FN (FORM) (DECLARE (SPECIAL COMPILE-P DEFVAR-HACK)) ;; If appropriate, turn a DEFVAR into a SETQ. (WHEN (AND DEFVAR-HACK (CONSP FORM) (> (LENGTH FORM) 2) (MEMQ (CAR FORM) '(DEFVAR DEFVAR-RESETTABLE)) (NEQ (CADDR FORM) ':UNBOUND)) (UNLESS (SYMBOLP (CADR FORM)) (FERROR NIL "~S not a recognized form" FORM)) (PUTPROP (CADR FORM) T 'SPECIAL) ;Declare it (WHEN (> (LENGTH FORM) 3) ;in case there is a documentation string. (SETF (DOCUMENTATION (SECOND FORM) 'VARIABLE) (SI:EVAL1 (FOURTH FORM))) (SETQ FORM (NBUTLAST FORM))) ;remove documentation so that ;hack into SETQ works properly. (SETF (CAR FORM) 'SETQ)) ;then always SETQ (WHEN (AND (NOT COMPILE-P) (EQ (CAR-SAFE FORM) 'EVAL-WHEN)) (WHEN (MEMQ 'EVAL (CADR FORM)) (MAPC #'COMPILE-INTERVAL-PROCESS-FN (CDDR FORM))) T)) ;;; We get here when COMPILER:COMPILE-DRIVER finds something it doesn't handle specially. (DEFUN COMPILE-INTERVAL-PROCESS-BASIC-FORM (FORM TYPE) (DECLARE (SPECIAL COMPILE-P PRINT-RESULTS-STREAM)) ;; Really eval or compile the thing. (COND ((EQ COMPILE-P T) (COMPILE-BUFFER-FORM FORM TYPE)) (COMPILE-P (FUNCALL COMPILE-P FORM)) (T (EVAL-PRINT FORM PRINT-RESULTS-STREAM)))) (DEFUN EVAL-PRINT (OBJECT PRINT-RESULTS-STREAM) (LET ((LIST (MULTIPLE-VALUE-LIST (SYS:EVAL1 OBJECT)))) (DOLIST (VAL LIST) (IF PRINT-RESULTS-STREAM (LET-IF (EQ PRINT-RESULTS-STREAM *QUERY-IO*) ((*PRINT-LENGTH* 5) (*PRINT-LEVEL* 2)) (FORMAT PRINT-RESULTS-STREAM "~&~S" VAL)))) (VALUES (CAR LIST) OBJECT))) ;;; Functional to be passed to COMPILE-DRIVER. (DEFUN COMPILE-BUFFER-FORM (FORM TYPE) (DECLARE (SPECIAL COMPILE-PROCESSING-MODE)) (IF (MEMQ TYPE '(DECLARE RANDOM SPECIAL proclaim)) (EVAL FORM) (let-if (get-from-alternating-list compile-processing-mode :CAREFUL-MODE) ((compiler:peep-enable nil) (compiler:*inhibit-optimizers* t)) (COMPILER:COMPILE-1 (CADR FORM) (APPEND (CASE (CAR FORM) (DEFSUBST '(NAMED-SUBST)) (MACRO '(MACRO NAMED-LAMBDA)) (DEFUN '(NAMED-LAMBDA))) (CDR (SI:PROCESS-DEFUN-BODY (CADR FORM) (CDDR FORM)))) (IF (MEMQ (CAR FORM) '(MACRO DEFSUBST)) 'COMPILER:MACRO-COMPILE (GET-FROM-ALTERNATING-LIST COMPILE-PROCESSING-MODE :MODE)))))) ;;;; Correspondences (DEFSIGNAL DEFINITION-NOT-UNIQUE FERROR (FUNCTION-SPEC) "Signaled by FUNCTION-CORRESPONDENCE when ZWEI can't tell which text definition to make the correspondence with.") (DEFUN FUNCTION-CORRESPONDENCE (FUNCTION-SPEC) "Given a function spec, make a correspondence from its definition to its text. The function spec better have an interpreted definition. If there is not a unique definition section for the function spec, an error is signaled with condition name ZWEI:DEFINITION-NOT-UNIQUE. The command M-X Make Correspondence can be used to tell ZWEI which definition to prefer." (MULTIPLE-VALUE-BIND (BP BUFFER) (DEFINITION-TEXT-LOCATION-1 FUNCTION-SPEC) (IF BP (FUNCTION-CORRESPONDENCE-1 FUNCTION-SPEC BP BUFFER) (FERROR 'DEFINITION-NOT-UNIQUE "There is more than one definition of ~S." FUNCTION-SPEC)))) (DEFCOM COM-MAKE-CORRESPONDENCE "Make a correspondence table for this function. The correspondence table maps between links in the list structure of the function and positions in the text in the buffer." () (CONDITION-CASE (ERROR) (FUNCTION-CORRESPONDENCE-1 (SECTION-NODE-NAME (LINE-NODE (BP-LINE (POINT)))) (POINT) *INTERVAL*) (DEFINITION-NOT-SEXP (BARF ERROR))) DIS-NONE) (DEFUN FUNCTION-CORRESPONDENCE-1 (FUNCTION BP BUFFER) (LET* ((LINE (CAR BP)) (INT (DEFUN-INTERVAL (CREATE-BP LINE 0) 1 NIL NIL)) (DEFINITION (FDEFINITION (SI:UNENCAPSULATE-FUNCTION-SPEC FUNCTION))) NEWSEXP TEM (CORRESPONDENCE (SI:FUNCTION-SPEC-GET FUNCTION 'ZMACS-CORRESPONDENCE))) (COND ((OR (ATOM DEFINITION) (AND (EQ (CAR DEFINITION) 'MACRO) (ATOM (CDR DEFINITION)))) (FERROR 'DEFINITION-NOT-SEXP "The definition of ~S is not an s-expression." FUNCTION))) (SI:FUNCTION-SPEC-PUTPROP FUNCTION (CONS BUFFER (SECTION-NODE-DEFUN-LINE (LINE-NODE (BP-LINE (INTERVAL-FIRST-BP INT))))) 'ZMACS-CHOSEN-DEFINITION) (COND ((OR (NULL CORRESPONDENCE) (NEQ (CAR CORRESPONDENCE) DEFINITION) (> (INTERVAL-REAL-TICK INT) (CADDR CORRESPONDENCE))) ;; Read in the text. Get a new sexp for the function, ;; together with a correspondence between it and the text. (MULTIPLE-VALUE (NEWSEXP CORRESPONDENCE) (ESTABLISH-CORRESPONDENCE DEFINITION BUFFER INT)) (SETQ TEM (MEMQ NEWSEXP CORRESPONDENCE)) (AND TEM (RPLACA TEM DEFINITION)) (SETQ NEWSEXP (CDDR NEWSEXP)) ;Flush DEFUN or DEFMETHOD, and fn name. (SETQ DEFINITION (SI:LAMBDA-EXP-ARGS-AND-BODY DEFINITION)) ;; Now the new sexp should look like the definition. ;; Move the correspondence to the definition. (TRANSFER-CORRESPONDENCE FUNCTION CORRESPONDENCE NEWSEXP DEFINITION) (SI:FUNCTION-SPEC-PUTPROP FUNCTION CORRESPONDENCE 'ZMACS-CORRESPONDENCE))) CORRESPONDENCE)) (DEFUN ESTABLISH-CORRESPONDENCE (DEFINITION BUFFER BP1 &OPTIONAL BP2 IN-ORDER-P) (GET-INTERVAL BP1 BP2 IN-ORDER-P) (LET ((STREAM (INTERVAL-STREAM BP1 BP2 T)) (SI:XR-CORRESPONDENCE-FLAG T) SI:XR-CORRESPONDENCE) (VALUES (READ STREAM) `(,DEFINITION ,BUFFER ,(NODE-TICK BUFFER) ,BP1 ,BP2 . ,SI:XR-CORRESPONDENCE)))) (DEFUN INTERVAL-REAL-TICK (BP1 &OPTIONAL BP2 IN-ORDER-P) "Return the latest tick at which any line in an interval was modified. Pass either an interval or a pair of BPs." (GET-INTERVAL BP1 BP2 IN-ORDER-P) (DO ((LINE (BP-LINE BP1) (LINE-NEXT LINE)) (FIRST-LINE (BP-LINE BP1)) (MAX-TICK 0) (LIMIT (BP-LINE BP2))) (NIL) (SETQ MAX-TICK (MAX MAX-TICK (LINE-TICK LINE) (OR (AND (NEQ LINE FIRST-LINE) (GET (LOCF (LINE-PLIST LINE)) 'PRECEDING-LINES-DELETED-TICK)) 0))) (IF (EQ LINE LIMIT) (RETURN MAX-TICK)))) ;;; Given a correspondence from the sexp TEMPDEF, matches up TEMPDEF ;;; and REALDEF and clobbers the correspondence to be from REALDEF instead. ;;; FUNCTION is just for error messages. ;;; We throw to TRANSFER-CORRESPONDENCE-LOSSAGE if the two sexps don't match. (DEFUN TRANSFER-CORRESPONDENCE (FUNCTION CORRESPONDENCE TEMPDEF REALDEF) (LET ((TEM (MEMQ TEMPDEF CORRESPONDENCE))) (AND TEM (RPLACA TEM REALDEF))) ;; In the real definition, some displacing macros may have gone off. (AND (EQ (CAR REALDEF) 'SI:DISPLACED) (SETQ REALDEF (CADR REALDEF))) (OR (= (LENGTH TEMPDEF) (LENGTH REALDEF)) (*THROW 'TRANSFER-CORRESPONDENCE-LOSSAGE NIL)) (DO ((TD TEMPDEF (CDR TD)) (RD REALDEF (CDR RD))) ((NULL TD)) (AND (COND ((ATOM (CAR TD)) (NOT (EQUAL (CAR TD) (CAR RD)))) (T (ATOM (CAR RD)))) (*THROW 'TRANSFER-CORRESPONDENCE-LOSSAGE NIL)) (OR (ATOM (CAR TD)) (TRANSFER-CORRESPONDENCE FUNCTION CORRESPONDENCE (CAR TD) (CAR RD))))) ;;;; These functions know about zmacs buffers and sections. (DEFUN UPDATE-INTERVAL-COMPILE-TICK (BP1 &OPTIONAL BP2 IN-ORDER-P) "Update the tick-of-last-compilation for all sections in an interval. Pass either an interval or a pair of BPs." (TICK) (GET-INTERVAL BP1 BP2 IN-ORDER-P) (DO ((NODE (BP-NODE BP1) (NODE-NEXT NODE)) (FIRST T NIL) TEM) ((OR (NULL NODE) (NOT (OR FIRST (BP-< (INTERVAL-FIRST-BP NODE) BP2))))) (WHEN (OR (NOT FIRST) ;; If compiled or evaluated only part of the text in a node, ;; don't set its compile tick. ;; Now that there is only one form per section, ;; we can be confident that if the compiled code ;; started at the beginning of the form, ;; it must have reached the end, ;; unless either the compilation bombed out from unmatched parens ;; or the section contains unmatched parens. (EQ (BP-LINE BP1) (BP-LINE (INTERVAL-FIRST-BP NODE))) (AND (SETQ TEM (SEND NODE :SEND-IF-HANDLES :DEFUN-LINE)) (BP-< BP1 (CREATE-BP TEM 1)))) (SEND NODE :UPDATE-COMPILE-TICK)))) (DEFCOM COM-COMPILE-BUFFER-CHANGED-SECTIONS "Compile any sections in this buffer which have been edited. Only sections that contain definitions will be compiled. A numeric arg means ask about each section individually." () (SI:FILE-OPERATION-WITH-WARNINGS ((AND (BUFFER-FILE-ID *INTERVAL*) (SEND (SEND *INTERVAL* :GENERIC-PATHNAME) :GENERIC-PATHNAME)) :COMPILE NIL) (COMPILER:COMPILER-WARNINGS-CONTEXT-BIND (COMPILE-BUFFER-CHANGED-FUNCTIONS *INTERVAL* *NUMERIC-ARG-P*))) (FORMAT T "~&Done.~%") DIS-NONE) (DEFMACRO DO-CHANGED-LISP-BUFFERS ((BUFFER BUFFER-LIST) &BODY BODY) "This is careful to not use random buffers." `(DOLIST (,BUFFER ,BUFFER-LIST) (WHEN (AND (EQ (IF (EQ ,BUFFER *INTERVAL*) *MAJOR-MODE* (BUFFER-SAVED-MAJOR-MODE ,BUFFER)) 'LISP-MODE) (NOT (GET ,BUFFER 'SPECIAL-PURPOSE)) ;; Don't consider buffers never modified. (> (NODE-TICK ,BUFFER) (BUFFER-FILE-READ-TICK BUFFER))) ,@BODY))) (DEFCOM COM-COMPILE-CHANGED-SECTIONS "Compile any sections which have been edited. Only sections that contain definitions will be compiled. A numeric arg means ask about each section individually." () (DO-CHANGED-LISP-BUFFERS (BUFFER *ZMACS-BUFFER-LIST*) (SI:FILE-OPERATION-WITH-WARNINGS ((AND (BUFFER-FILE-ID BUFFER) (SEND (SEND BUFFER :GENERIC-PATHNAME) :GENERIC-PATHNAME)) :COMPILE NIL) (COMPILER:COMPILER-WARNINGS-CONTEXT-BIND (COMPILE-BUFFER-CHANGED-FUNCTIONS BUFFER *NUMERIC-ARG-P*)))) (FORMAT T "~&Done.~%") DIS-NONE) (DEFCOM COM-TAGS-COMPILE-CHANGED-SECTIONS "Compile any sections in files in tag table which have been edited. Only sections that contain definitions will be compiled. A numeric arg means ask about each section individually." () (DO-CHANGED-LISP-BUFFERS (BUFFER (TAG-TABLE-BUFFERS NIL)) (SI:FILE-OPERATION-WITH-WARNINGS ((AND (BUFFER-FILE-ID BUFFER) (SEND (SEND BUFFER :GENERIC-PATHNAME) :GENERIC-PATHNAME)) :COMPILE NIL) (COMPILER:COMPILER-WARNINGS-CONTEXT-BIND (COMPILE-BUFFER-CHANGED-FUNCTIONS BUFFER *NUMERIC-ARG-P*)))) (FORMAT T "~&Done.~%") DIS-NONE) (DEFCOM COM-EVALUATE-BUFFER-CHANGED-SECTIONS "Evaluate any sections in this buffer which have been edited. Only sections that contain definitions will be evaluated. A numeric arg means ask about each section individually." () (COMPILE-BUFFER-CHANGED-FUNCTIONS *INTERVAL* *NUMERIC-ARG-P* NIL '("Evaluate" "Evaluating" "evaluated.")) (FORMAT T "~&Done.~%") DIS-NONE) (DEFCOM COM-EVALUATE-CHANGED-SECTIONS "Evaluate any sections which have been edited. Only sections that contain definitions will be evaluated. A numeric arg means ask about each section individually." () (DO-CHANGED-LISP-BUFFERS (BUFFER *ZMACS-BUFFER-LIST*) (COMPILE-BUFFER-CHANGED-FUNCTIONS BUFFER *NUMERIC-ARG-P* NIL '("Evaluate" "Evaluating" "evaluated."))) (FORMAT T "~&Done.~%") DIS-NONE) (DEFCOM COM-TAGS-EVALUATE-CHANGED-SECTIONS "Evaluate any sections in files in tag table which have been edited. Only sections that contain definitions will be evaluated. A numeric arg means ask about each section individually." () (DO-CHANGED-LISP-BUFFERS (BUFFER (TAG-TABLE-BUFFERS NIL)) (COMPILE-BUFFER-CHANGED-FUNCTIONS BUFFER *NUMERIC-ARG-P* NIL '("Evaluate" "Evaluating" "evaluated."))) (FORMAT T "~&Done.~%") DIS-NONE) (DEFUN COMPILE-BUFFER-CHANGED-FUNCTIONS (BUFFER ASK-P &OPTIONAL (COMPILE-P T) (NAMES '("Compile" "Compiling" "compiled.")) (*target-computer* 'compiler:lambda-interface) (*fasd-interface* 'compiler:lambda-fasd-interface) &AUX (*QUERY-IO* *STANDARD-OUTPUT*)) "Recompile or evaluate all changed sections in BUFFER (that contain definitions). COMPILE-P is T to compile, NIL to eval, or else a function to evaluate and print a form. ASK-P if non-NIL means query user for each section to be processed. NAMES has three elements, that are like (/"Compile/" /"Compiling/" /"compiled./")." (LET ((*INTERVAL* BUFFER)) (RESECTIONIZE-BUFFER *INTERVAL*) (DOLIST (SECTION (NODE-INFERIORS *INTERVAL*)) (IF (AND (TYPEP SECTION 'SECTION-NODE) (NOT (STRINGP (SECTION-NODE-NAME SECTION))) (NOT (BP-= (INTERVAL-FIRST-BP SECTION) (INTERVAL-LAST-BP SECTION))) (> (NODE-TICK SECTION) (SECTION-NODE-COMPILE-TICK SECTION)) (OR (NOT ASK-P) (FQUERY () "~A ~A? " (FIRST NAMES) (SECTION-NODE-NAME SECTION)))) (COMPILE-PRINT-INTERVAL SECTION NIL T COMPILE-P NIL ;region-name (SECOND NAMES) ;mode-name (THIRD NAMES) ;echo-name T ;use-typeout T ;defvar-hack NIL ;compiler-processing-mode T ;already-resectionized-flag *target-computer* *fasd-interface* )))))