(defmacro %current-regular-pdl-pointer () `(let (.reg.pdl.pointer.tem.) (%push (compiler::%make-explicit-stack-list nil)) (setq .reg.pdl.pointer.tem. (%pop)) (%pop) (%make-pointer-offset dtp-locative .reg.pdl.pointer.tem. -3))) (defun eval-lambda (form fctn env) (let ((lambda-list (if (memq (car fctn) '(named-lambda named-subst)) (caddr fctn) (cadr fctn))) (num-args 0) args pdl-before-args ) ;; start of our manual list or list* (setq pdl-before-args (%current-regular-pdl-pointer)) (do ((ll lambda-list (cdr ll)) (quote-status '&eval) rest-flag) ((or (null ll) (memq (car ll) '(&aux &key))) (setq num-args (length (cdr form))) (%assure-pdl-room num-args)) (cond ((memq (car ll) '(&eval "e)) (setq quote-status (car ll))) ((eq (car ll) '&rest) (setq rest-flag t)) ((memq (car ll) lambda-list-keywords)) (rest-flag ;; Here if we encounter a rest arg. (if ( (length (cdr form)) (if (eq quote-status '"e) num-args ;; stack frames may be moby! 200.)) ;; If there aren't enough args supplied to actually ;; reach it, arrange to exit via the DO's end-test. (setq ll nil) ;; If the quoted rest arg is non-nil, ;; set NUM-ARGS to number of spread args, ;; and call with ADI. (%assure-pdl-room (1+ num-args)) (return))) (t (incf num-args)))) ;; Now push the args, evalling those that need it. (do ((ll lambda-list (cdr ll)) (argl (cdr form) (cdr argl)) (quote-status '&eval) (argnum 0 (1+ argnum)) tem) (()) (do () ((null ll)) (cond ((memq (car ll) '(&eval "e)) (setq quote-status (car ll))) ((memq (car ll) '(&rest &aux &key)) (setq ll nil)) ((memq (car ll) lambda-list-keywords)) (t (return))) (pop ll)) (cond ((= argnum num-args) ;; Done with spread args => push the rest arg. (setq tem (%current-regular-pdl-pointer)) (cond (argl ;; push on either the quoted rest or the extra parameters beyond the ;; stack-frame-size-limited number above (let ((tem1 (if (eq quote-status '&eval) (mapcar #'eval1 argl) argl))) (if (eq num-args 0) (setq args tem1) (%push tem1) ;; list*-ify to terminate the list of args (%p-dpb cdr-normal %%q-cdr-code tem) (%p-dpb cdr-error %%q-cdr-code (%pointer-plus tem 1))))) ((eq num-args 0) (setq args ())) (t ;; terminate the list of args (%p-dpb cdr-nil %%q-cdr-code tem))) (return)) ((eq quote-status '&eval) (%push (eval1 (car argl)))) (t (%push (car argl))))) (setq args (%make-pointer dtp-list (%pointer-plus pdl-before-args 1))) (if *applyhook* (let ((*evalhook* nil) (*applyhook* nil) (tem *applyhook*)) (funcall tem fctn args env)) (apply-lambda fctn args env))))