1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancments. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;;; 1001 TRANSLATE properties for everyone. ;;;
10 ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
11 ;;; Maintained by GJC ;;;
12 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
16 ;;; This file handles System FSUBR translation properties that were not handled in TRANSL.
18 (macsyma-module trans1
)
20 ;;;;;;;; THE FOLLOWING ARE MOSTLY FROM JPG MLISP ;;;;;;;;;;;;;;;;;;;;;
22 ;;; APPLY(F,[X]) is an idiom for funcall.
24 (defun quoted-symbolp (form)
26 (eq 'quote
(car form
))
27 (symbolp (cadr form
))))
30 (let* ((fun (dtranslate (cadr form
)))
31 (mode (cond ((symbolp fun
)
32 (function-mode-@ fun
))
34 (function-mode (cadr fun
)))
37 (cond (($listp
(caddr form
))
38 (let ((args (tr-args (cdr (caddr form
)))))
43 (let ((arg (dtranslate (caddr form
))))
44 (call-and-simp mode
'mapply-tr
48 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
49 (call-and-simp '$any
'map1
`((getopr ,fun
) .
,args
))))
51 (def%tr $maplist
(form)
52 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
53 `($any .
(maplist_tr ,fun
,@args
))))
55 (def%tr $fullmap
(form)
56 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
57 (call-and-simp '$any
'fmap1
`((getopr ,fun
) (list .
,args
) nil
))))
59 (def%tr $matrixmap
(form)
60 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
61 (call-and-simp '$any
`(lambda (fmaplvl)
62 (fmapl1 (getopr ,fun
) .
,args
))
65 (def%tr $fullmapl
(form)
66 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
67 (call-and-simp '$any
'fmapl1
`((getopr ,fun
) .
,args
))))
69 (def%tr $outermap
(form)
70 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
71 (call-and-simp '$any
(cond ((= (length args
) 1) 'fmapl1
)
73 `((getopr ,fun
) ,@args
))))
76 (def%tr $scanmap
(form)
77 (destructuring-let (((fun . args
) (tr-args (cdr form
))))
78 (call-and-simp '$any
'scanmap1
`((getopr ,fun
) ,@args
))))
81 `($any $put
',(cadr form
) ',(caddr form
) ',(cadddr form
)))
83 (def%tr $subvar
(form)
84 (translate (cons '(mqapply array
) (cdr form
))))
86 ;;; If the evaluation of the first argument does not depend on the
87 ;;; setting of the special variable PIECE, then it need not be
88 ;;; evaluated inside of PART1. If the PIECE feature is used, then
89 ;;; we must send down an expression to PART1 which when evaluated has
90 ;;; the proper environment for the compiled-away variable names in the
91 ;;; environment of the calling function.
92 ;;; It is possible to get unbelivebly strange results from the order of
93 ;;; evaluation of the arguments to $SUBSTPART, these crocks shall not
95 ;;; The PIECE feature is not as often used as say,
96 ;;; SUBSTPART("*",EXP,0) is.
98 (def%tr $substpart
(form)
99 (substpart-translation form t nil
'$inflag
'$substpart
))
101 (def%tr $substinpart
(form)
102 (substpart-translation form t nil t
'$substinpart
))
104 (defun for-eval-then-mquote-simp-argl (l)
105 ;; (MAPCAR #'(LAMBDA (U) ;;; consing not important here.
106 ;; `(LIST '(MQUOTE SIMP) ,U))
108 ;; JONL broke the fucking compiler. So I re-write this as=>
111 (if (null l
) (return (nreverse v
)))
112 (push `(list '(mquote simp
) ,(pop l
)) v
)
115 (defun substpart-translation (form flag1 flag2 flag3 fn
)
116 (let* ((subst-item (dtranslate (cadr form
)))
117 (freevars (free-lisp-vars subst-item
))
118 (argl (tr-args (cddr form
))))
119 (cond ((null (assoc '$piece freevars
:test
#'eq
))
120 ; this code is just to screw the people who
121 ; would use $PIECE non lexicaly. Not really, the
122 ; closure hacking is a lot slower at run time than
123 ; this easy case, so no sense screwing the people who
124 ; don't use $PIECE in foolish ways.
127 (list ,@(for-eval-then-mquote-simp-argl
128 (cons subst-item argl
)))
130 ,flag1
,flag2
,flag3
',fn
))))
132 (setq freevars
(tbound-free-vars freevars
))
133 (side-effect-free-check (cadr freevars
) (cadr form
))
135 (part1 (list (fungen&env-for-meval
136 ,(delete '$piece
(car freevars
) :test
#'equal
)
137 ($piece
) ,subst-item
)
138 ,@(for-eval-then-mquote-simp-argl argl
))
139 ,flag1
,flag2
,flag3
',fn
)))))))
141 ;;; This is could be done better on the LISPM
143 (def%tr $errcatch
(form)
144 (let ((form (translate `((mprogn) ,@(cdr form
))))
146 `($any .
((lambda (errcatch ,ret
)
147 (declare (special errcatch
))
148 ;; Very important to declare errcatch special
149 ;; here because merror uses it to figure out if
150 ;; someone is catching an error so it can be
151 ;; signaled in a way that we can catch.
152 (cond ((null (setq ,ret
153 (errset ,(cdr form
))))
154 (errlfun1 errcatch
)))
155 (cons '(mlist) ,ret
))
156 (cons bindlist loclist
) nil
))))
159 ;;; The MODE of a CATCH could either be the MODE of the last of the PROGN
160 ;;; or the mode of the THROW. The THROW may be hard to find, so this goes
161 ;;; on the assumption that the mode of the PROGN is enough to tell.
163 (def%tr $catch
(form)
164 (destructuring-let (((mode . body
) (translate `((mprogn) .
,(cdr form
)))))
165 `(,mode .
((lambda (mcatch)
167 (catch 'mcatch
,body
)
169 (cons bindlist loclist
)))))
171 (def%tr $throw
(form)
172 (destructuring-let (((mode . exp
) (translate (cadr form
))))
173 `(,mode .
((lambda (x)
175 (merror (intl:gettext
"throw: not within 'catch'; expression: ~M") x
))
179 ;;; Makelist is a very sorry FSUBR. All these FSUBRS are just to avoid
180 ;;; writing LAMBDA. But lots of users use MAKELIST now.
181 ;;; MAKELIST(EXP,X,0,N) with 4 args it is an iteration, with three it
182 ;;; is a mapping over a list (the third argument).
184 (def%tr $makelist
(form)
185 (setq form
(cdr form
))
187 ((= (length form
) 0) '($any .
'((mlist))))
191 `($any .
(list '(mlist) ,(cdr (tr-local-exp exp
))))))
194 (((exp n
) form
) (sum (tr-gensym)) (nn (tr-gensym)) (|
0|
(tr-gensym)))
195 (setq n
(dtranslate n
))
198 (setq ,nn
($float
,nn
))
200 (do ((,|
0|
1 (add 1 ,|
0|
)) (,sum nil
))
201 ((> ,|
0|
,nn
) (cons '(mlist) ,sum
))
203 (cons ,(cdr (tr-local-exp exp
)) ,sum
)))
205 (intl:gettext
"makelist: second argument must evaluate to a number; found: ~M") ,nn
)))
209 (((exp x n
) form
) (sum (tr-gensym)) (nn (tr-gensym)) (lil (tr-gensym)))
210 (setq n
(dtranslate n
))
214 (do ((,lil
(cdr ,nn
) (cdr ,lil
))
216 ((null ,lil
) (cons '(mlist) (nreverse ,sum
)))
220 (cons ,(cdr (tr-local-exp exp x
(value-mode x
))) ,sum
)))
222 (setq ,nn
($float
,nn
))
224 (do ((,x
1 (add 1 ,x
))
227 ,(cdr (tr-local-exp exp x
(value-mode x
)))
230 (cons '(mlist) (nreverse ,sum
)))
231 (declare (special ,x
)))
233 (intl:gettext
"makelist: third argument must be a number or a list; found: ~M") ,nn
)))))
237 (((exp x |
0| n
) form
) (|
00|
(tr-gensym)) (nn (tr-gensym))
238 (sum (tr-gensym)) (ii (tr-gensym)))
239 (setq |
0|
(dtranslate |
0|
) n
(dtranslate n
))
242 (setq ,nn
($float
(sub ,nn
,|
00|
)))
244 (do ((,x
,|
00|
(add 1 ,x
)) (,ii
0 (add 1 ,ii
))
247 ,(cdr (tr-local-exp exp x
(value-mode x
)))
249 ((> ,ii
,nn
) (cons '(mlist) (nreverse ,sum
)))
250 (declare (special ,x
)))
252 (intl:gettext
"makelist: the fourth argument minus the third one must evaluate to a number; found: ~M")
257 (((exp x |
0| n s
) form
) (|
00|
(tr-gensym)) (nn (tr-gensym))
258 (ss (tr-gensym)) (sum (tr-gensym)) (ii (tr-gensym)))
259 (setq |
0|
(dtranslate |
0|
) n
(dtranslate n
) s
(dtranslate s
))
261 ((lambda (,|
00|
,nn
,ss
)
262 (setq ,nn
($float
(div (sub ,nn
,|
00|
) ,ss
)))
264 (do ((,x
,|
00|
(add ,ss
,x
)) (,ii
0 (add 1 ,ii
))
267 ,(cdr (tr-local-exp exp x
(value-mode x
)))
269 ((> ,ii
,nn
) (cons '(mlist) (nreverse ,sum
)))
270 (declare (special ,x
)))
272 (intl:gettext
"makelist: the fourth argument minus the third one, divided by the fifth one must evaluate to a number; found: ~M")
276 (tr-format (intl:gettext
"makelist: maximum 5 arguments allowed; found: ~M.~%makelist: to create a list with sublists, use nested makelist commands.~%")
279 '($any .
'$
**error
**))))
282 `($any .
(mapply '$kill
',(cdr form
) nil
)))
284 ;;; Macsyma arrays are the biggest crock since STATUS PUNT NIL days.
285 ;;; The basic idea of ARRAY(<frob>,type,dims...) is that
287 ;;; (ASSoc (CADR X) '(($COMPLETE . T) ($INTEGER . FIXNUM) ($FIXNUM . FIXNUM)
288 ;;; ($FLOAT . FLONUM) ($FLONUM . FLONUM)))
289 ;;; then the dims are evaluated. But, if type is not one of those,
290 ;;; it "must" be a dim spec! Of course, I must make this "analysis"
291 ;;; at translate time, in order to preserve referential transparency
292 ;;; in compiled code.
294 (def%tr $array
(form)
295 (setq form
(cdr form
))
296 (let ((name (car form
))
297 (specp (assoc (cadr form
)
298 '(($complete . t
) ($integer . fixnum
) ($fixnum . fixnum
)
299 ($float . flonum
) ($flonum . flonum
)) :test
#'eq
)))
304 (list ',name
',(cadr form
) ,@(tr-args (cddr form
)))
309 (list ',name
,@(tr-args (cdr form
)))
313 ;;; it seems TRANSL has all sorts of code for hacking some kind of
314 ;;; $CRE mode. somehow there is no translate property for MRAT. who
315 ;;; knows. anyway here is something in the mean time before this
316 ;;; I have time to do up TRANSL correctly.
317 ;;;(DEFUN MRATEVAL (X)
318 ;;; ((LAMBDA (VARLIST)
319 ;;; (COND (EVP (MEVAL ($RATDISREP X)))
320 ;;; ((OR (AND $FLOAT $KEEPFLOAT) (NOT (ALIKE VARLIST (MAPCAR 'MEVAL VARLIST))))
321 ;;; (RATF (MEVAL ($RATDISREP X))))
324 ;;; EVP is a hack for $EV I think. The MEVAL down the varlist is to see if the
325 ;;; variables have any values, if not, then the result of (ratf (meval ($ratdisrep)))
326 ;;; will be alike to what you started with, so it is an efficiency hack! What a
328 ;;;(DEFPROP MRAT (LAMBDA (X) (MRATEVAL X)) MFEXPR*)
331 (let ((t-form (translate ($ratdisrep form
))))
332 (cond ((member (car t-form
) '($float $fixnum $number
) :test
#'eq
) t-form
)
333 (t `($any .
(ratf ,(cdr t-form
)))))))
336 ;;; The following special forms do not call the evaluator.
338 (def%tr $alias
(form)
339 `($any .
(meval ',form
)))
340 ;;most of these will lose in common since a local variable will not
341 ;;have its value accessible to the mfexpr*. They should
342 ;;be redone as macros with any necessary info passed along.
344 (def%tr $batch $alias
)
345 (def%tr $batchload $alias
)
346 (def%tr $closefile $alias
)
347 (def%tr $compfile $alias
)
348 (def%tr $demo $alias
)
349 (def%tr $dependencies $alias
)
350 (def%tr $describe $alias
)
351 (def%tr $dispfun $alias
)
352 (def%tr $disprule $alias
)
353 (def%tr $fundef $alias
)
354 (def%tr $gradef $alias
)
355 (def%tr $labels $alias
)
356 (def%tr $loadarrays $alias
)
357 (def%tr $loadfile $alias
)
358 (def%tr $numerval $alias
)
359 (def%tr $options $alias
)
360 (def%tr $ordergreat $alias
)
361 (def%tr $orderless $alias
)
362 (def%tr $printfile $alias
)
363 (def%tr $printprops $alias
)
364 (def%tr $product $alias
)
365 (def%tr %product $alias
)
366 (def%tr $properties $alias
)
367 (def%tr $propvars $alias
)
368 (def%tr $rearray $alias
)
369 (def%tr $remarray $alias
)
370 (def%tr $remfunction $alias
)
371 (def%tr $remove $alias
)
372 (def%tr $remvalue $alias
)
373 (def%tr $setup_autoload $alias
)
376 (def%tr $translate $alias
)
377 (def%tr $writefile $alias
)