;;; -*- Mode:LISP; Package:USER; Base:10; Readtable:CL -*- ;;; ;;; INTERPRETER-HOOKS.LISP ;;; ;;; Let the new interpreter slither into the old evaluator's wake. ;;; (defvar *use-old-evaluator* t) (defvar *inform-user* t) (defun inform-user (stream format-string &rest format-args) (when *inform-user* (apply #'format stream format-string format-args))) (defun make-hook-function (old-version new-version) #'(lambda (&rest args) (setq args (copylist args)) (if *use-old-evaluator* (apply old-version args) (apply new-version old-version args)))) (defun install-hook (old-function new-function) (fdefine old-function (make-hook-function (fsymeval old-function) new-function))) (defun eval-hook (old-version form &optional (nohook nil n-sup)) (declare (ignore old-version nohook)) (when n-sup (format t "~&Eval called with optional nohook.")) (k-lisp:eval form)) (defun eval1-hook (old-version form &optional (nohook nil n-sup)) (declare (ignore old-version nohook)) (inform-user t "~&Eval1 called") (if n-sup (inform-user t " with optional nohook.") (inform-user t ".")) (k-lisp:eval form)) (defun apply-lambda-hook (old-version fctn value-list &optional (environment nil env-sup)) (cond ((and (null environment) (consp fctn) (eq (car fctn) 'lambda)) (let ((closure (k-lisp:eval `(FUNCTION ,fctn)))) (apply closure value-list))) ((not *ki-allow-apply-lambda-bagbiting*) (ferror "Bagbiting in APPLY-LAMBDA")) ((and (null environment) (consp fctn) (eq (car fctn) 'named-lambda)) (inform-user *error-output* "~&>>WARNING: NAMED-LAMBDA is not valid in Common Lisp.") (let ((closure (k-lisp:eval `(FUNCTION (LAMBDA ,@(cddr fctn)))))) (apply closure value-list))) (t (let ((*use-old-evaluator* t)) (inform-user *error-output* "~&>>WARNING: Biting the bag with APPLY-LAMBDA.") (if env-sup (funcall old-version fctn value-list environment) (funcall old-version fctn value-list)))))) (defun evalhook-hook (old-version form *evalhook* *applyhook* &optional (env nil env-sup)) (declare (ignore old-version)) ; (format t "~&Called evalhook.") (if env-sup (k-lisp:evalhook form *evalhook* *applyhook* env) (k-lisp:evalhook form *evalhook* *applyhook*))) (defun applyhook-hook (old-version fn args *evalhook* *applyhook* &optional (env nil env-sup)) (declare (ignore old-version)) (if env-sup (k-lisp:applyhook fn args *evalhook* *applyhook* env) (k-lisp:applyhook fn args *evalhook* *applyhook*))) (defun eval-special-ok-hook (old-version form &optional (nohook nil n-sup)) (declare (ignore old-version nohook)) (when n-sup (format t "~&Eval-special-ok called with optional nohook.")) (interpreter::eval-special-ok form)) (defun fsymeval-in-environment-hook (old-version symbol env check-symbol-function) "This behaves incorrectly for lexical functions" (if (nframe-p env) (let ((lexical-binding (lookup-binding-in-environment symbol env :function))) (if (not lexical-binding) (if check-symbol-function (symbol-function symbol) NIL) (case (preprocessor-funmac-binding-type lexical-binding) (function (error "internal: lexical value of function not yet available")) (macro (preprocessor-funmac-binding-value lexical-binding))))) (funcall old-version symbol env check-symbol-function))) ;;; This variable prevents re-hooking. (defvar *hooks-installed*) (eval-when (load global:eval) (when (not (boundp '*hooks-installed*)) (install-hook 'si::eval 'eval-hook) (install-hook 'si::eval1 'eval1-hook) (install-hook 'si::apply-lambda 'apply-lambda-hook) (install-hook 'si::evalhook 'evalhook-hook) (install-hook 'si::applyhook 'applyhook-hook) (install-hook 'si::eval-special-ok 'eval-special-ok-hook) (install-hook 'si::fsymeval-in-environment 'fsymeval-in-environment-hook) (setq *hooks-installed* t) )) (eval-when (load global:eval) (when *bash-old-macros* (setf (macro-function 'global:defun) (macro-function 'k-lisp:defun)) (setf (macro-function 'global:defvar) (macro-function 'k-lisp:defvar)) (setf (macro-function 'si::defvar-1) (macro-function 'interpreter::defvar-1)) (setf (macro-function 'global:defparameter) (macro-function 'k-lisp:defparameter)) (setf (macro-function 'global:defconstant) (macro-function 'k-lisp:defconstant)) (setf (macro-function 'si::defconst-1) (macro-function 'interpreter::defconst-1)))) (defun new () (setq *use-old-evaluator* nil)) (defun old () (setq *use-old-evaluator* t))