home *** CD-ROM | disk | FTP | other *** search
- ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; The data in this file contains enhancments. ;;;;;
- ;;; ;;;;;
- ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
- ;;; All rights reserved ;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
- (in-package "MAXIMA")
- (macsyma-module fcall)
-
- (TRANSL-MODULE FCALL)
-
- ;;; Bug-Fixes:
- ;;;
- ;;; 11/15/80 KMP Remove *TRIED-TO-AUTOLOAD* as a global and replaced
- ;;; MFUNCTION-CALL with a trampoline function that calls
- ;;; MFUNCTION-CALL-AUX with this info since MFUNCTION-CALL
- ;;; was being screwed by the non-local nature of this var
- ;;; when calls to itself got nested.
- ;;;
-
- ;;; This file is for macros, fsubrs, and subrs which are run time
- ;;; support for interpreted translated macsyma code.
-
- (defun _eval (x)
- #+NIL (si:internal-eval x)
- #-NIL (eval x))
-
- ;;; #+(OR NIL LMI) This poor man's closures stuff should go, and get replaced
- ;;; by the real thing!
-
- ;;; MFUNCTION-CALL is a macro in LIBMAX;TRANSQ
- ;;; This is an FSUBR for use in interpreted code.
- ;;; It should do quit a bit of checking for STATUS PUNT NIL lossage, etc.
- ;;; The macro will expand into code which will assume normal
- ;;; functional argument evaluation.
-
- (DEFMVAR $TR_WARN_BAD_FUNCTION_CALLS T
- "Warn when strange kinds of function calls are going on in
- translated code.")
-
- (DEFVAR *TR-RUNTIME-WARNED* NIL
- "This is an alist of warnings which have been given")
-
- (DEFMFUN $TR_WARNINGS_GET ()
- `((MLIST) ,@(MAPCAR #'(LAMBDA (U)
- `((MLIST) ,(CAR U) ,(CDR U)))
- *TR-RUNTIME-WARNED*)))
-
-
- (DEFUN MFUNCTION-CALL-WARN (F TYPE)
- (COND ((ASSQ F *TR-RUNTIME-WARNED*))
- (T
- (PUSH (CONS F TYPE) *TR-RUNTIME-WARNED*)
- (COND ($TR_WARN_BAD_FUNCTION_CALLS
- (LET ((TABL (CDR (ASSQ TYPE '((FEXPR . (FEXPR-WARNEDP
- "This may be due to lack of enough translation data *print-base* info."))
- (MACRO . (MACRO-WARNEDP
- "Macros should to be loaded when you are translating."))
- (UNDEFINED . (UNDEFINED-WARNP
- "The function was totaly undefined. Maybe you want to quote it."))
- (PUNT-NIL . (PUNT-NIL-WARNP
- "If you want the value of the function name, use APPLY"))
- (MFEXPR . (MFEXPR-WARNEDP
- "MFEXPRS should be loaded at translating time. Use of them in
- translated code (nay, any code!), is NOT recommened however.")))))))
- (COND ((NULL TABL))
- ((GET F (CAR TABL)))
- (T
- (PUTPROP F T (CAR TABL))
- (TERPRI)
- (PRINC "Warning: ")
- (MGRIND F NIL)
- (PRINC
- " has a function or macro call which has not been
- translated properly.")
- (COND ((CDR TABL)
- (TERPRI)
- (PRINC (CADR TABL))))))))))))
-
- (DEFUN MAPCAR-EVAL (X) (MAPCAR #'_EVAL X))
-
- ;(defmacro max-funcall (f &rest args)
- ; (cond ((fboundp f) `(,f ,@ args))
- ; (t`(max-funcall-aux ',f ',args (list ,@ args)))))
- ;
- ;(defun max-funcall-aux (fn arglis-syms vals &aux mfun args)
- ; (cond ((functionp fn)(apply fn vals))
- ; ((fboundp fn)(fsignal "can't funcall a macro or special form"))
- ; ((setq mfun (mget fn 'mexpr))
- ; (show mfun)
- ; (progv (setq args(cdr (second mfun))) vals
- ; (show args vals)
- ; (show (and (boundp (car args)) (symbol-value (car args))))
- ; (mlambda mfun vals fn t)))
- ; (t (fsignal "unknown function call"))))
- ;
- ;(defun foo (xx)
- ; (mfunction-call $ff xx))
-
- #+cl
- (defmacro MFUNCTION-CALL (f &rest ARGL)
- (cond ((fboundp f)
- `(,f ,@ argl))
- (t ;;loses if the argl could not be evaluated but macsyma "e functions
- ;;but the translator should be fixed so that if (mget f 'mfexprp) is t
- ;;then it doesn't translate as an mfunction-call.
- `(lispm-MFUNCTION-CALL-AUX ', f ',ARGL (list ,@ argl) NIL))))
- #-cl
- (DEFUN MFUNCTION-CALL FEXPR (F+ARGL)
- (MFUNCTION-CALL-AUX (CAR F+ARGL) (CDR F+ARGL) NIL))
-
- (DEFUN LISPM-MFUNCTION-CALL-AUX (F ARGL list-argl AUTOLOADED-ALREADY? &aux f-prop)
- (COND
- ((functionp F)
- (APPLY F list-argl))
- ((macro-function f) ;(SETQ F-PROP (GET F 'MACRO))
- (eval (cons f list-argl)))
- ((not (symbolp f)) (error "expected symbol or function"))
- ((setq f-prop (get f 'mfexpr*))
- ;;save a cons with (locf argl) not(cons nil argl)
- (funcall f-prop (locf argl)))
- ((SETQ F-PROP (MGET F 'MEXPR))
- (COND ((MGET F 'MFEXPRP)
- (MFUNCTION-CALL-WARN F 'MFEXPR)
- (MEVAL (CONS (LIST F) ARGL)))
- (T
- (mlambda f-prop list-argl f nil nil))))
- ((SETQ F-PROP (GET F 'AUTOLOAD))
- (COND (AUTOLOADED-ALREADY?
- (MERROR "~:@M, Function undefined after loading file:~A "
- F
- (NAMESTRING (GET F 'AUTOLOAD))))
-
- (T
- (funcall autoload (cons f F-PROP))
- (lispm-MFUNCTION-CALL-AUX F ARGL list-argl T))))
-
- ((BOUNDP F)
- (MFUNCTION-CALL-WARN F 'PUNT-NIL)
- (MAPPLY (_EVAL F) (MAPCAR-EVAL ARGL) F))
- (T
- (MFUNCTION-CALL-WARN F 'UNDEFINED)
- `((,F) ,@ list-argl))))
-
- #-cl
- (DEFUN MFUNCTION-CALL-AUX (F ARGL AUTOLOADED-ALREADY?)
- (LET ((F-PROP))
- (COND #+NIL
- ((FBOUNDP F)
- (APPLY F (MAPCAR-EVAL ARGL)))
- ((SETQ F-PROP (GETL F '(EXPR LEXPR)))
- (APPLY (CADR F-PROP) (MAPCAR-EVAL ARGL)))
- ((GETL F '(SUBR LSUBR))
- (APPLY F (MAPCAR-EVAL ARGL)))
- ((GETL F '(FEXPR FSUBR))
- (MFUNCTION-CALL-WARN F 'FEXPR)
- (APPLY F ARGL))
- ((SETQ F-PROP (GET F 'MACRO))
- (MFUNCTION-CALL-WARN F 'MACRO)
- (_EVAL (FUNCALL F-PROP (CONS F ARGL))))
- ((SETQ F-PROP (MGET F 'MEXPR))
- (COND ((MGET F 'MFEXPRP)
- (MFUNCTION-CALL-WARN F 'MFEXPR)
- (MEVAL (CONS (LIST F) ARGL)))
- (T
- (MAPPLY1 F-PROP (MAPCAR-EVAL ARGL) '|a translated fcall.| nil))))
- ((SETQ F-PROP (GET F 'AUTOLOAD))
- (COND (AUTOLOADED-ALREADY?
- (MERROR "~:@M, Function undefined after loading file:~A "
- F
- (NAMESTRING (GET F 'AUTOLOAD))))
-
- (T
- (funcall autoload (cons f F-PROP))
- (MFUNCTION-CALL-AUX F ARGL T))))
- ((BOUNDP F)
- (MFUNCTION-CALL-WARN F 'PUNT-NIL)
- (MAPPLY1 (_EVAL F) (MAPCAR-EVAL ARGL) F nil))
- (T
- (MFUNCTION-CALL-WARN F 'UNDEFINED)
- `((,F) ,@(MAPCAR-EVAL ARGL))))))
-
- ;;; I think that that just about covers it.
-
- ;;; This FEXPR may not work if it is not compiled.
- #-cl
- (defun TRD-MSYMEVAL fexpr ( L)
- (LET ((A-VAR? (CAR L)))
- (COND ((BOUNDP A-VAR?)
- (_EVAL A-VAR?)) ;;; ouch!
- (t
- ;; double ouch!
- (set A-VAR? (cond ((cdr l) (_EVAL (cadr l)))
- (t a-var?)))))))
- #+cl
- (defquote TRD-MSYMEVAL (&rest L)
- (LET ((A-VAR? (CAR L)))
- (COND ((BOUNDP A-VAR?)
- (_EVAL A-VAR?)) ;;; ouch!
- (t
- ;; double ouch!
- (set A-VAR? (cond ((cdr l) (_EVAL (cadr l)))
- (t a-var?)))))))
-
- (DEFUN EXPT$ (A B)
- (EXPT A B))
-
- ;;; These are the LAMBDA forms. They have macro properties that set
- ;;; up very different things in compiled code.
-
- ;;; (M-TLAMBDA ,@(CDR T-FORM))))
- ;;; (M-TLAMBDA& ,@(CDR T-FORM))))))
-
-
- (DEFUN MAKE-M-LAMBDA& (ARGL BODY)
- (DO ((L NIL)
- (LARGS ARGL (CDR LARGS))
- (J 1 (f1+ J)))
- ((NULL (CDR LARGS))
- `(LAMBDA *N*
- ((LAMBDA ,ARGL ,@BODY)
- ,@(NREVERSE L)
- (CONS '(MLIST) (LISTIFY (f- ,(f1- J) *N*))))))
- (PUSH `(ARG ,J) L)))
-
- #-cl
- (DEFUN M-TLAMBDA FEXPR (ARGS)
- (CONS 'LAMBDA ARGS))
-
- #+(and (not cl) lispm )
- (defquote M-TLAMBDA (&rest ARGS)
- (CONS 'LAMBDA ARGS))
-
- (DEFVAR *FCALL-MEMORY* NIL
- "This ALIST will never be very long. Considerably less hairy then
- a hashing scheme, perhaps faster in normal use. In either case
- there is the problem of garbage from red-defined functions.")
- #-cl
- (DEFUN M-TLAMBDA& FEXPR (ARGS)
- (LET ((FORM (ASSQ ARGS *FCALL-MEMORY*)))
- (COND (FORM (CDR FORM))
- (T
- (SETQ FORM (MAKE-M-LAMBDA& (CAR ARGS) (CDR ARGS)))
- (PUSH (CONS ARGS FORM) *FCALL-MEMORY*)
- FORM))))
-
- #+(and (not cl)lispm)
- (defquote M-TLAMBDA& (&rest ARGS)
- (LET ((FORM (ASSQ ARGS *FCALL-MEMORY*)))
- (COND (FORM (CDR FORM))
- (T
- (SETQ FORM (MAKE-M-LAMBDA& (CAR ARGS) (CDR ARGS)))
- (PUSH (CONS ARGS FORM) *FCALL-MEMORY*)
- FORM))))
-
- (DEFUN EVALQUOTE (EXP)
- (SETQ EXP (_EVAL EXP))
- (COND ((NUMBERP EXP) EXP)
- (T `(QUOTE ,EXP))))
- #-cl
- (DEFUN M-TLAMBDA&ENV FEXPR (ARGS)
- (LET (( ((REG-ARGL ENV-ARGL) . BODY) ARGS))
- `(LAMBDA ,REG-ARGL ((LAMBDA ,ENV-ARGL ,@BODY) ,@(MAPCAR 'EVALQUOTE
- ENV-ARGL)))))
-
- #+(and (not cl)lispm)
- (defquote M-TLAMBDA&ENV (&rest ARGS)
- (LET (( ((REG-ARGL ENV-ARGL) . BODY) ARGS))
- `(LAMBDA ,REG-ARGL ((LAMBDA ,ENV-ARGL ,@BODY) ,@(MAPCAR 'EVALQUOTE
- ENV-ARGL)))))
- #-cl
- (DEFUN M-TLAMBDA&ENV& FEXPR (ARGS)
- (LET (( ((REG-ARGL ENV-ARGL) . BODY) ARGS))
- (make-M-LAMBDA& REG-ARGL `(((LAMBDA ,ENV-ARGL ,@BODY)
- ,@(MAPCAR 'EVALQUOTE ENV-ARGL))))))
-
- #+(and (not cl) lispm ) ;;now defined by tranq.lisp The optimizer method taken out.
- (defquote M-TLAMBDA&ENV& (&rest ARGS)
- (LET (( ((REG-ARGL ENV-ARGL) . BODY) ARGS))
- (make-M-LAMBDA& REG-ARGL `(((LAMBDA ,ENV-ARGL ,@BODY)
- ,@(MAPCAR 'EVALQUOTE ENV-ARGL))))))
-
- ;;; (FUNGEN&ENV-for-meval <eval vars list> <late eval vars list> <EXP>)
- #-cl
- (DEFUN FUNGEN&ENV-FOR-MEVAL FEXPR (ARGS)
- (LET (((EVL LEVL . BODY) ARGS))
- ;;; all we want to do here is make sure that the EVL gets
- ;;; evaluated now so that we have some kind of compatibility
- ;;; with compiled code. we could just punt and pass the body.
- `(($APPLY) ((MQUOTE) ((LAMBDA) ((MLIST) ,@EVL) ,@BODY))
- ((MQUOTE SIMP) ((MLIST) ,@(MAPCAR-EVAL EVL))))))
-
- ;;; (FUNGEN&ENV-for-meval <eval vars list> <late eval vars list> <EXP>)
- ;;won't work in cl. fix later.
- #+cl
- (defquote FUNGEN&ENV-FOR-MEVAL (&rest ARGS)
- (LET (((EVL LEVL . BODY) ARGS))
- ;;; all we want to do here is make sure that the EVL gets
- ;;; evaluated now so that we have some kind of compatibility
- ;;; with compiled code. we could just punt and pass the body.
- `(($APPLY) ((MQUOTE) ((LAMBDA) ((MLIST) ,@EVL) ,@BODY))
- ((MQUOTE SIMP) ((MLIST) ,@(MAPCAR-EVAL EVL))))))
-
- ;;; (FUNGEN&ENV-FOR-MEVALSUMARG EVL VAR <translate-exp> <untranslated-exp>)
-
- ;;; The following code depends on the fact that the argument to an
- ;;; FEXPR is always EQ, for a given instance of FEXPR call. Lets say
- ;;; that the efficiency of the code depends on that fact. We cannot use
- ;;; displacing macros because of the $SAVE problem which I really don't
- ;;; feel like fooling around with since it is an IN-CORE function, and
- ;;; totaly cryptic code.
- #-cl
- (DEFUN FUNGEN&ENV-FOR-MEVALSUMARG FEXPR (ARGS)
- (LET ((RES (ASSQ ARGS *FCALL-MEMORY*)))
- (COND ((NULL RES)
- (LET (((EVL LEVL T-BODY M-BODY) ARGS))
- (SETQ RES (GENSYM))
- (PUTPROP RES
- (coerce
- `(LAMBDA (*IGNORED*)
- (PROG2 (MBIND ',EVL
- (GET ',RES 'SUMARG-ENV) NIL)
- (MEVALATOMS ',M-BODY)
- (MUNBIND ',EVL)))
- 'function)
- 'MEVALSUMARG-MACRO)
- ;; Obsolete and replaced by the following form --wj
- ;;; (PUTPROP RES
- ;;; `(LAMBDA ()
- ;;; (APPLY #'(LAMBDA ,EVL ,T-BODY)
- ;;; (GET ',RES 'SUMARG-ENV)))
- ;;; 'EXPR)
- (setf (symbol-function res)
- (coerce
- `(lambda ()
- (apply #'(lambda ,evl ,t-body)
- (get ',res 'sumarg-env)))
- 'function))
- (SETQ RES `(,ARGS ,RES ((,RES))))
- (PUSH RES *FCALL-MEMORY*))))
- (PUTPROP (CADR RES) (MAPCAR #'EVAL (CAR ARGS)) 'SUMARG-ENV)
- (CADDR RES)))
-
- ;;; (FUNGEN&ENV-FOR-MEVALSUMARG EVL VAR <translate-exp> <untranslated-exp>)
-
- ;;; The following code depends on the fact that the argument to an
- ;;; FEXPR is always EQ, for a given instance of FEXPR call. Lets say
- ;;; that the efficiency of the code depends on that fact. We cannot use
- ;;; displacing macros because of the $SAVE problem which I really don't
- ;;; feel like fooling around with since it is an IN-CORE function, and
- ;;; totaly cryptic code.
-
- #+cl
- (defquote FUNGEN&ENV-FOR-MEVALSUMARG (&rest ARGS)
- (LET ((RES (ASSQ ARGS *FCALL-MEMORY*)))
- (COND ((NULL RES)
- (LET (((EVL LEVL T-BODY M-BODY) ARGS))
- (SETQ RES (GENSYM))
- (PUTPROP RES
- (coerce
- `(LAMBDA (*IGNORED*)
- (PROG2 (MBIND ',EVL
- (GET ',RES 'SUMARG-ENV) NIL)
- (MEVALATOMS ',M-BODY)
- (MUNBIND ',EVL)))
- 'function)
- 'MEVALSUMARG-MACRO)
- ;; Obsolete and replaced by the following form --wj
- ;;; (PUTPROP RES
- ;;; `(LAMBDA ()
- ;;; (APPLY #'(LAMBDA ,EVL ,T-BODY)
- ;;; (GET ',RES 'SUMARG-ENV)))
- ;;; 'EXPR)
- (setf (symbol-function res)
- (coerce
- `(lambda ()
- (apply #'(lambda ,evl ,t-body)
- (get ',res 'sumarg-env)))
- 'function))
- (SETQ RES `(,ARGS ,RES ((,RES))))
- (PUSH RES *FCALL-MEMORY*))))
- (PUTPROP (CADR RES) (MAPCAR #'EVAL (CAR ARGS)) 'SUMARG-ENV)
- (CADDR RES)))
-
- #-cl
- (DEFUN M-TLAMBDA-I FEXPR (ARGS)
- `(LAMBDA ,@(CDDR ARGS)))
-
- #+cl
- (defquote M-TLAMBDA-I (&rest ARGS)
- `(LAMBDA ,@(CDDR ARGS)))
-
- #+MACLISP
- (DEFUN COMPILE-FORMS-TO-COMPILE-QUEUE FEXPR (FORM) FORM)
-
-