1 ;;; -*- Mode: Lisp; Package: Maxima; Syntax: Common-Lisp; Base: 10 -*- ;;;;
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;; The data in this file contains enhancements. ;;;;;
5 ;;; Copyright (c) 1984,1987 by William Schelter,University of Texas ;;;;;
6 ;;; All rights reserved ;;;;;
7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9 ;;; Please do not modify this file. See GJC ;;;
10 ;;; (c) Copyright 1980 Massachusetts Institute of Technology ;;;
11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15 ;;; TRANSLATION PROPERTIES FOR MACSYMA OPERATORS AND FUNCTIONS.
17 ;;; This file is for list and array manipulation optimizations.
19 (macsyma-module trans2
)
21 (def%tr $random
(form)
22 (destructuring-bind (mode . arg
) (translate (cadr form
))
23 (cons (or (find mode
'($fixnum $float
) :test
#'eq
) '$number
)
27 (setq form
(cdr form
))
28 (let ((mode (cond ((atom (car form
))
29 (function-mode (car form
)))
31 (setq form
(tr-args form
))
32 (let ((op (car form
)))
33 (call-and-simp mode
'mcall
`(,op .
,(cdr form
))))))
35 ;;; Meaning of the mode properties: most names are historical.
36 ;;; (GETL X '(ARRAY-MODE)) means it is an array callable by the
37 ;;; old maclisp style. This is unfortunately still useful to
38 ;;; avoid indirection through the property list to get to the
41 (defvar $translate_fast_arrays nil
)
42 ;;When $translate_fast_arrays and $use_fast_arrays are true
43 ;;there should only be two types of arrays and they should be stored on
44 ;;the value cell of the symbol. These should be the equivalent of the
45 ;;zetalisp art-q and the si:equal-hash-table. Note that maxima lists
46 ;;and maxima $matrices are also allowed for setting. Note also that
47 ;;because of some hokey things like mqapply etc, if you want
48 ;;fast referenceing use a[i], or b[i]:..., ie use variables,
49 ;;since if you try something complicated it may not translate as
51 ;;Idea of these is for the lispm to store the array in the value cell
52 ;;to use equal-hash-tables, and to clean up the local variable
53 ;;in translated code for an array.
54 ;;txx(i,j):=block([hl],hl[i]:j,hl[i]); should leave hl unbound, after creating
55 ;;a hash table for hl, There should be a resource of these.
57 (defun tr-maset (ar val inds
)
58 ;; Top-level forms need to define the variable first.
59 (if *macexpr-top-level-form-p
*
60 `(nil progn
(defvar ,ar
',ar
) (maset ,val
,ar
,@ inds
))
61 `(nil maset
,val
,ar
,@ inds
)))
63 (defun maset1 (val ar
&rest inds
)
65 ((and (typep ar
'cl
:array
)
66 (= (length inds
) (cl:array-rank ar
)))
67 (setf (apply #'aref ar inds
) val
))
68 ((typep ar
'cl
:hash-table
)
69 (setf (gethash (if (cdr inds
) (copy-list inds
) (car inds
))
73 (error "MASET1: first argument must not be a symbol; found: ~A" ar
))
74 ((and (= (length inds
) 1)
75 (or ($listp ar
) ($matrixp ar
)))
76 (setf (nth (car inds
) ar
) val
))
79 (setf (nth (second inds
) (nth (car inds
) ar
)) val
))
80 (t (error "MASET1: invalid array reference: ~A" ar
))))
83 ;;apply is too expensive for a simple array reference. The time
84 ;;is increased by a factor of 6. Note we use the locf form to get at
85 ;;the local variable of the function calling maset in order to be able
86 ;;to store a hash-table there in the case that the variable was not an
89 ;;COULD USE THE FOLLOWING TO handle fast_arrays:true.
90 ;;(defun set-up-hash-table (&optional val key &aux tab)
91 ;; (setq tab (make-hash-table :test 'equal)) ;alike?
92 ;; (setf (gethash key tab) val) tab)
94 ;;(defun maset-help1 ( val ar &rest inds &aux )
95 ;; "returns t if it set and nil if what went in could not be set but is a variable that
96 ;; should be set to hash array"
97 ;; (cond ((hash-table-p ar)
98 ;; (setf (gethash (car inds) ar) val))
101 ;; (setf (nth (car inds) ar) val) t)
102 ;; (($matrixp ar) (setf (nth (second inds) (nth (car inds) ar)) val) t)
103 ;; (t (error "not valid place ~A to put an array" ar))))
106 ;;;;doesn't prevent multiple evaluation of inds val and ar.. but doesn't use locf
107 ;;(defmacro maset (val ar &rest inds )
109 ;; ((arrayp ar) (setf (aref ar ,@ inds) ,val))
110 ;; ((maset-help1 ,val ,ar ,@ inds) ,val)
111 ;; (t (setf ,ar (set-up-hash-table ,val (car ,ind))),val)))
113 ;;(defmacro maref ( ar &rest inds)
114 ;; `(cond ((arrayp ,ar) (aref ,ar ,@ inds))
115 ;; ((hash-table-p ,ar) (gethash ,ar (car ,inds)))
116 ;; ((symbolp ,ar)`((,ar ,@ (copy-list ,inds))))))
118 ;;in maref in transl now
120 (defun tr-maref (ar inds
)
121 `(nil maref
, ar
,@ (copy-list inds
)))
123 (defun maref1 (ar &rest inds
)
125 ((and (typep ar
'cl
:array
)
126 (= (length inds
) (cl:array-rank ar
)))
127 (apply #'aref ar inds
))
128 ((typep ar
'cl
:hash-table
)
129 (gethash (if (cdr inds
) inds
(car inds
)) ar
))
131 (cond ((mget ar
'hashar
)
132 (harrfind `((,ar array
) ,@(copy-list inds
))))
134 `((,ar array
) ,@(copy-list inds
)))))
135 ((and (= (length inds
) 1)
136 (or ($listp ar
) ($matrixp ar
)))
137 (nth (first inds
) ar
))
138 ((and ($matrixp ar
) (= (length inds
) 2))
139 (nth (second inds
) (nth (first inds
) ar
)))
141 (merror (intl:gettext
"Wrong number of array indices: ~M") (cons '(mlist) inds
)))))
144 (defun tr-arraycall (form &aux all-inds
)
146 ($translate_fast_arrays
(setq all-inds
(mapcar 'dtranslate
(cdr form
)))
147 ;;not apply changed 'tr-maref
148 (funcall 'tr-maref
(cdr (translate (caar form
))) all-inds
))
150 (translate `((marrayref)
151 ,(if $tr_array_as_ref
(caar form
)
152 `((mquote) ,(caar form
)))
157 (defun tr-arraysetq (array-ref value
)
158 ;; actually an array SETF, but it comes from A[X]:FOO
159 ;; which is ((MSETQ) ... ...)
161 ($translate_fast_arrays
162 (funcall 'tr-maset
(caar array-ref
) (dtranslate value
)
163 (mapcar 'dtranslate
(copy-list (cdr array-ref
)))))
165 ;; oops. Hey, I switch around order of evaluation
166 ;; here. no need to either man. gee.
167 (translate `((marrayset) ,value
168 ,(if $tr_array_as_ref
(caar array-ref
)
169 `((mquote) ,(caar array-ref
)))
170 ,@(cdr array-ref
))))))
173 (def%tr marrayref
(form)
174 (setq form
(cdr form
))
175 (let ((mode (cond ((atom (car form
))
176 (get (car form
) 'array-mode
)))))
177 (cond ((null mode
) (setq mode
'$any
)))
178 (setq form
(tr-args form
))
179 (let ((op (car form
)))
180 `(,mode .
(,(if (and (= (length form
) 2)
184 ,op .
,(cdr form
))))))
186 (def%tr marrayset
(form)
187 (setq form
(cdr form
))
188 (let ((mode (cond ((atom (cadr form
))
189 (get (cadr form
) 'array-mode
)))))
190 (when (null mode
) (setq mode
'$any
))
191 (setq form
(tr-args form
))
192 (destructuring-let (((val aarray . inds
) form
))
193 `(,mode .
(,(if (and (= (length inds
) 1)
197 ,val
,aarray .
,inds
)))))
200 (if (null (cdr form
)) ;;; []
202 `($any .
(list '(mlist) .
,(tr-args (cdr form
))))))
204 (def%tr $first
(form)
205 (setq form
(translate (cadr form
)))
206 (call-and-simp '$any
(if (eq '$list
(car form
))