1 ;;TODO : Potential smalloptimization - a+-0=a, a*/1=a
2 ;;TODO : Potential optimization, prevent blank v.ins({}) lines
3 (defparameter *maxima-function-dictionary-name
* "f")
4 (defparameter *maxima-variables-dictionary-name
* "v")
5 (defparameter *python-hierarchial-dict-name
* "Stack")
6 (defparameter *symbols-directly-convert
* '()
7 "List containing symbols to be converted as it is to Python symbols rather than maxima_vars[\"symbol\"]")
8 (defparameter *ins-method-name
* "ins")
9 (defparameter *assignment-method-name
* "assign")
11 (defvar *maxima-direct-ir-map
*
12 (let ((ht (make-hash-table)))
13 (setf (gethash 'mtimes ht
) '(op *))
14 (setf (gethash 'mplus ht
) '(op +))
15 (setf (gethash 'rat ht
) '(op /))
16 (setf (gethash 'mquotient ht
) '(op /))
17 (setf (gethash 'msetq ht
) '(op-no-bracket =))
18 (setf (gethash 'mlist ht
) '(struct-list))
19 (setf (gethash 'mand ht
) '(boolop (symbol "and")))
20 (setf (gethash 'mor ht
) '(boolop (symbol "or")))
21 (setf (gethash 'mnot ht
) '(funcall (symbol "not")))
22 (setf (gethash 'mminus ht
) '(unary-op -
))
23 (setf (gethash 'mgreaterp ht
) '(comp-op >))
24 (setf (gethash 'mequal ht
) '(comp-op ==))
25 (setf (gethash 'mnotequal ht
) '(comp-op !=))
26 (setf (gethash 'mlessp ht
) '(comp-op <))
27 (setf (gethash 'mgeqp ht
) '(comp-op >=))
28 (setf (gethash 'mleqp ht
) '(comp-op <=))
29 (setf (gethash '$floor ht
) '(funcall (symbol "math.floor")))
30 (setf (gethash '$fix ht
) '(funcall (symbol "math.floor")))
31 (setf (gethash '%fix ht
) '(funcall (symbol "math.floor")))
32 (setf (gethash '%sqrt ht
) '(funcall (symbol "math.sqrt")))
33 (setf (gethash 'mreturn ht
) '(funcall (symbol "return")))
34 (setf (gethash 'mabs ht
) '(funcall (symbol "abs")))
37 (defvar *maxima-special-ir-map
*
38 (let ((ht (make-hash-table)))
39 (setf (gethash 'mdefine ht
) 'func-def-to-ir
)
40 (setf (gethash '%array ht
) 'array-def-to-ir
)
41 (setf (gethash 'mprog ht
) 'mprog-to-ir
)
42 (setf (gethash 'mprogn ht
) 'mprogn-to-ir
)
43 (setf (gethash 'mcond ht
) 'mcond-to-ir
)
44 (setf (gethash 'lambda ht
) 'lambda-to-ir
)
45 (setf (gethash 'mdoin ht
) 'for-list-to-ir
)
46 (setf (gethash 'mdo ht
) 'for-loop-to-ir
)
47 (setf (gethash '%endcons ht
) 'endcons-to-ir
)
48 (setf (gethash '$endcons ht
) 'endcons-to-ir
)
49 (setf (gethash '$plot3d ht
) 'plot-to-ir
)
50 (setf (gethash '$plot2d ht
) 'plot-to-ir
)
51 (setf (gethash 'mexpt ht
) 'mexpt-to-ir
)
52 (setf (gethash 'mfactorial ht
) 'mfactorial-to-ir
)
55 (defvar *ir-forms-to-append
* '())
60 ; Check if form is mprogn
61 (defun mprogn-p (form)
62 (and (consp (clast form
))
63 (consp (car (clast form
)))
64 (eq (caar (clast form
)) 'mprogn
)))
66 (defun symbol-name-to-string (form)
67 (maybe-invert-string-case (symbol-name (stripdollar form
))))
69 (defun symbol-to-ir (form)
70 `(symbol ,(symbol-name-to-string form
)))
72 (defun symbol-to-dictionary-ir (form &optional
(dict-name nil
))
73 `(element-array (symbol
74 ,(cond (dict-name dict-name
)
75 (t *maxima-variables-dictionary-name
*)))
76 (string ,(symbol-name-to-string form
))))
78 (defun plot-to-ir (form)
80 (element-array ,*maxima-function-dictionary-name
*
82 ,(cond ((eql (list-length (cddr form
)) 1) "plot2d")
84 ,(maxima-to-ir (cadr form
))
86 (lambda (elm) (cond ((and (consp elm
)
88 (eq 'mlist
(caar elm
)))
89 `(struct-list (string ,(symbol-name-to-string (cadr elm
)))
90 ,@(mapcar #'maxima-to-ir
(cddr elm
))))
91 (t (maxima-to-ir elm
))))
94 (defun mfactorial-to-ir (form)
95 `(funcall (element-array (symbol ,*maxima-function-dictionary-name
*) (string "factorial")) ,@(mapcar #'maxima-to-ir
(cdr form
))))
97 (defun mexpt-to-ir (form)
98 `(funcall (element-array (symbol ,*maxima-function-dictionary-name
*) (string "pow")) ,@(mapcar #'maxima-to-ir
(cdr form
))))
100 (defun assignment-to-ir (form)
101 (cond ((consp (cadr form
)) `(op-no-bracket = ,@(mapcar #'maxima-to-ir
(cdr form
))))
102 (t `(funcall (symbol ,*assignment-method-name
*)
103 (string ,(symbol-name-to-string (cadr form
)))
104 ,(maxima-to-ir (caddr form
))
105 (symbol ,*maxima-variables-dictionary-name
*)))))
107 (defun symbol-to-asterisk-ir (form)
109 (concatenate 'string
"*"
110 (maybe-invert-string-case (symbol-name (stripdollar form
))))))
112 (defun endcons-to-ir (form)
113 (cond ((consp (clast form
))
114 (maxima-to-ir (append (clast form
) `(,(cadr form
)))))
116 `(struct-list (asterisk ,(maxima-to-ir (clast form
))) ,(maxima-to-ir (cadr form
))))))
118 (defun for-loop-to-ir (form)
119 (cond ((null (caddr (cdddr form
))) ; Condition Specified
120 `(body ,@(cond ((null (cadr form
)) '()) ; If variable not given
121 (t `((assign ,(maxima-to-ir (cadr form
)) ; If variable assigned by "for var:value"
122 ,(maxima-to-ir (caddr form
))))))
125 (consp (clast (butlast form
)))
126 (consp (car (clast (butlast form
))))
127 (eq 'mnot
(caar (clast (butlast form
)))))
128 (maxima-to-ir (cadr (clast (butlast form
)))))
130 `(funcall (symbol "not")
131 ,(maxima-to-ir (clast (butlast form
))))))
133 ,@(cond ((mprogn-p form
)
134 (mapcar 'maxima-to-ir
(cdr (clast form
))))
136 `(,(maxima-to-ir (clast form
)))))
137 ,@(cond ((null (cadddr form
)) '())
138 (t `((assign ,(maxima-to-ir (cadr form
))
139 (op + ,(maxima-to-ir (cadr form
)) ,(maxima-to-ir (cadddr form
)))))))))
140 ,@(cond ((null (cadr form
)) '()) ; If variable not given
141 (t `((del ,(maxima-to-ir (cadr form
))))))))
143 `(for-list ,(maxima-to-ir (cadr form
))
144 (funcall (symbol "range")
145 ,(maxima-to-ir (caddr form
))
146 ,(cond ((and (atom (caddr (cdddr form
)))
147 (not (symbolp (caddr (cdddr form
)))))
148 (maxima-to-ir (1+ (caddr (cdddr form
)))))
149 (t `(op + ,(maxima-to-ir (caddr (cdddr form
))) (num 1 0))))
150 ,@(cond ((eq (cadddr form
) 'nil
) '())
151 (t `(,(maxima-to-ir (cadddr form
))))))
153 ,@(cond ((mprogn-p form
)
154 (mapcar 'maxima-to-ir
(cdr (clast form
))))
156 `(,(maxima-to-ir (clast form
))))))))))
158 (defun for-list-to-ir (form)
159 `(for-list ,(maxima-to-ir (cadr form
))
160 ,(maxima-to-ir (caddr form
))
162 ,@(cond ((mprogn-p form
)
163 (mapcar 'maxima-to-ir
(cdr (clast form
))))
165 `(,(maxima-to-ir (clast form
))))))))
167 (defun func-call-arg-to-ir (form)
170 ((eq (caar form
) 'mlist
)
171 `(symbol ,(maybe-invert-string-case (symbol-name (stripdollar (cadr form
))))))))
172 (t (maxima-to-ir form
))))
174 (defun lambda-to-ir (form)
175 (let ((*symbols-directly-convert
* (append (mapcar
177 (cond ((consp x
) (cadr x
))
180 *symbols-directly-convert
*)))
181 (cond ((eql (list-length (cddr form
)) 1)
183 ,(let ((func-args (mapcar #'func-arg-to-ir
(cdadr form
))))
185 ; initialize dictionary holding variable bindings
187 (symbol ,*maxima-variables-dictionary-name
*)
188 (funcall (symbol ,*python-hierarchial-dict-name
*)
190 (symbol ,*maxima-variables-dictionary-name
*))))))
191 ,(maxima-to-ir (clast form
))))
193 (let ((func_name (gensym "$LAMBDA")) (func-args (mapcar #'func-arg-to-ir
(cdadr form
))))
194 (setf *ir-forms-to-append
*
195 (cons (func-def-to-ir
197 ((,func_name
) ,@(cdadr form
))
198 ((MPROGN) ,@(cddr form
))))
199 *ir-forms-to-append
*))
202 ; initialize dictionary holding variable bindings
204 (symbol ,*maxima-variables-dictionary-name
*)
205 (funcall (symbol ,*python-hierarchial-dict-name
*)
207 (symbol ,*maxima-variables-dictionary-name
*)))))
208 (funcall ,(symbol-to-ir func_name
)
209 ,@(mapcar #'func-call-arg-to-ir
(cdadr form
))
210 (funcall (symbol ,*python-hierarchial-dict-name
*)
212 (symbol ,*maxima-variables-dictionary-name
*)))))))))
214 (defun conditional-auxiliary (forms)
215 `(,(maxima-to-ir (car forms
))
216 ,(maxima-to-ir (cadr forms
))
217 ,(cond ((eq (caddr forms
) 't
) (maxima-to-ir (cadddr forms
)))
218 (t `(conditional ,@(conditional-auxiliary (cddr forms
)))))))
220 (defun conditional-to-ir (form)
221 ;; (conditional <condition> <res1> <else-res>)
222 `(conditional ,@(conditional-auxiliary (cdr form
))))
224 (defun if-to-ir (form &optional
(case-if nil
))
225 `(,@(cond (case-if '(body))
227 (,(cond (case-if 'cond-if
)
229 ,(maxima-to-ir (cadr form
)))
230 (body-indented ,(maxima-to-ir (caddr form
)))
231 ,@(cond ((eq (cadddr form
) 't
)
232 (cond ((or (eq (clast form
) 'nil
) (eq (clast form
) '$false
)) '())
233 ((and (consp (clast form
))
234 (consp (car (clast form
)))
235 (eq (caar (clast form
)) 'mcond
))
236 (if-to-ir (clast form
)))
238 (body-indented ,(maxima-to-ir (clast form
)))))))
239 (t (if-to-ir (cddr form
))))))
241 (defun mcond-to-ir (form &optional
(is_expr nil
))
242 (cond (is_expr (conditional-to-ir form
))
243 (t `(,@(if-to-ir form t
)))))
245 (defun mprog-variable-names-list (form)
246 (cond ((and (consp form
) (eq 'msetq
(caar form
))) (maxima-to-ir (cadr form
)))
247 (t (maxima-to-ir form
))))
249 (defun mprog-arg-list (form)
250 (cond ((and (consp form
) (eq 'msetq
(caar form
))) (maxima-to-ir (clast form
)))
251 (t `(symbol "None"))))
253 (defun mprog-assign-to-dict (form)
256 (cond ((consp x
) `((string ,(symbol-name-to-string (cadr x
)))
257 ,(maxima-to-ir (caddr x
))))
258 (t `((string ,(symbol-name-to-string x
))
262 (defun mlist-p (form)
265 (eq 'mlist
(caar form
))))
267 (defun first-list-mprog (form)
268 (find-if #'mlist-p
(cdr form
)))
270 (defun but-first-mlist (form)
271 (let ((pos (position-if #'mlist-p form
)))
274 if
(not (eq y pos
)) collect x
)))
276 (defun mprog-to-ir (form &key
(context nil
))
277 (cond ((not (null (cdr form
)))
278 (cond ((eq context
'function
)
280 (symbol ,*maxima-variables-dictionary-name
*)
281 (symbol ,*ins-method-name
*)
283 ,@(mprog-assign-to-dict (first-list-mprog form
))))
284 ,@(mapcar (lambda (elm) (cond ((and (consp elm
)
286 (eq (caar elm
) 'mcond
))
288 (t (maxima-to-ir elm
))))
289 (but-first-mlist (butlast (cdr form
))))
290 (funcall (symbol "return")
291 ,((lambda (elm) (cond ((and (consp elm
)
293 (eq (caar elm
) 'mcond
))
297 (eq (caar elm
) 'mreturn
))
298 (maxima-to-ir (cadr elm
)))
299 (t (maxima-to-ir elm
))))
302 (let ((func_name (symbol-to-ir (gensym "$BLOCK"))))
303 (setf *ir-forms-to-append
*
306 ((symbol ,*maxima-variables-dictionary-name
*))
309 (symbol ,*maxima-variables-dictionary-name
*)
310 (funcall (symbol ,*python-hierarchial-dict-name
*)
312 (symbol ,*maxima-variables-dictionary-name
*)))
314 (symbol ,*maxima-variables-dictionary-name
*)
315 (symbol ,*ins-method-name
*)
317 ,@(mprog-assign-to-dict (first-list-mprog form
))))
318 ,@(mapcar (lambda (elm) (cond ((and (consp elm
)
320 (eq (caar elm
) 'mcond
))
322 (t (maxima-to-ir elm
))))
323 (but-first-mlist (butlast (cdr form
))))
324 (funcall (symbol "return")
325 ,((lambda (elm) (cond ((and (consp elm
)
327 (eq (caar elm
) 'mcond
))
331 (eq (caar elm
) 'mreturn
))
332 (maxima-to-ir (cadr elm
)))
333 (t (maxima-to-ir elm
))))
335 *ir-forms-to-append
*))
336 `(funcall ,func_name
(funcall (symbol ,*python-hierarchial-dict-name
*)
338 (symbol ,*maxima-variables-dictionary-name
*)))))))))
340 (defun mprogn-to-ir (form &optional
(func-args '()))
341 (declare (ignore func-args
))
342 (let ((func_name (symbol-to-ir (gensym "$BLOCK"))))
343 (setf *ir-forms-to-append
*
346 ((symbol ,*maxima-variables-dictionary-name
*))
349 (symbol ,*maxima-variables-dictionary-name
*)
350 (funcall (symbol ,*python-hierarchial-dict-name
*)
352 (symbol ,*maxima-variables-dictionary-name
*)))
353 ,@(mapcar (lambda (elm) (cond ((and (consp elm
)
355 (eq (caar elm
) 'mcond
))
357 (t (maxima-to-ir elm
))))
358 (but-first-mlist (butlast (cdr form
))))
359 (funcall (symbol "return")
360 ,((lambda (elm) (cond ((and (consp elm
)
362 (eq (caar elm
) 'mcond
))
366 (eq (caar elm
) 'mreturn
))
367 (maxima-to-ir (cadr elm
)))
368 (t (maxima-to-ir elm
))))
370 *ir-forms-to-append
*))
371 `(funcall ,func_name
(symbol ,*maxima-variables-dictionary-name
*))))
373 ;;; Recursively generates IR for a multi-dimensional array and fills all cells with Null value
374 (defun array-gen-ir (dimensions)
375 (cond ((null dimensions
) '(symbol "None"))
376 (t `(op * (struct-list ,(array-gen-ir (cdr dimensions
))) ,(maxima-to-ir (car dimensions
))))))
378 ;;; Helper function for array-def-to-ir which generates the IR for array definition
379 (defun auxillary-array-to-ir (symbol dimensions
)
380 `(assign ,symbol
,(array-gen-ir dimensions
)))
382 ;;; Function to generate IR for array definition using different methods, by using the auxiliary function
383 (defun array-def-to-ir (form)
384 (cond ((consp (cadr form
))
385 (append '(body) (loop for symb in
(cdadr form
)
386 collect
(auxillary-array-to-ir (maxima-to-ir symb
) (cddr form
)))))
387 ((not (numberp (caddr form
)))
388 (auxillary-array-to-ir (maxima-to-ir (cadr form
)) (cdddr form
)))
390 (auxillary-array-to-ir (maxima-to-ir (cadr form
)) (cddr form
)))))
392 ;;; Function to convert reference to array elements to IR
393 ;;; TODO : However, for arrays that are undefined, it needs to be assigned to a hashed array(dictionary)
394 (defun array-ref-to-ir (symbol indices
)
395 (cond ((null indices
) (maxima-to-ir symbol
))
396 (t `(element-array ,(array-ref-to-ir symbol
(butlast indices
))
397 ,(cond ((and (atom (clast indices
))
398 (not (symbolp (clast indices
))))
399 (maxima-to-ir (1- (clast indices
))))
400 (t `(op + ,(maxima-to-ir (clast indices
)) -
1)))))))
402 ;;; Convert Function args to corresponding IR
403 ;;; Convert the optional list argument into corresponding *args form in python
404 (defun func-arg-to-ir (form)
407 ((eq (caar form
) 'mlist
)
408 `(symbol ,(concatenate 'string
"*" (symbol-name-to-string (cadr form
)))))))
409 (t (symbol-to-ir form
))))
411 ;;; Generates IR for function definition
412 (defun func-def-to-ir (form)
413 ;The name of function shouldn't be converted to dictionary element
414 (setf *symbols-directly-convert
* (cons (caaadr form
) *symbols-directly-convert
*))
418 ,(maxima-to-ir (caaadr form
))
419 ; Function argumenets, including variable mapping dictionary
420 ,(let ((func-args (mapcar #'func-arg-to-ir
(cdadr form
))))
422 ;; initialize dictionary holding variable bindings
424 (symbol ,*maxima-variables-dictionary-name
*)
425 (symbol ,*maxima-variables-dictionary-name
*)))))
428 (symbol ,*maxima-variables-dictionary-name
*)
429 (funcall (symbol ,*python-hierarchial-dict-name
*)
431 (symbol ,*maxima-variables-dictionary-name
*)))
432 ;; Map the variables in current context to the Stack
433 (obj-funcall (symbol ,*maxima-variables-dictionary-name
*)
434 (symbol ,*ins-method-name
*)
437 (lambda (x) (typecase x
438 (cons `((string ,(symbol-name-to-string (cadr x
))) (funcall (symbol "list") ,(symbol-to-ir (cadr x
)))))
439 (t `((string ,(symbol-name-to-string x
)) ,(symbol-to-ir x
)))))
441 ,@(cond ((and (consp (caddr form
))
442 (consp (caaddr form
))
443 (eq (car (caaddr form
)) 'mprog
))
444 `(,@(mprog-to-ir (caddr form
) :context
'function
)))
445 ((and (consp (caddr form
))
446 (consp (caaddr form
))
447 (eq (car (caaddr form
)) 'mprogn
))
448 (append (mapcar #'maxima-to-ir
(butlast (cdaddr form
)))
449 `((funcall (symbol "return") ,((lambda (elm) (cond ((and (consp elm
)
451 (eq (caar elm
) 'mcond
))
455 (eq (caar elm
) 'mreturn
))
456 (maxima-to-ir (cadr elm
)))
457 (t (maxima-to-ir elm
))))
458 (clast (cdaddr form
)))))))
460 `((funcall (symbol "return") ,((lambda (elm) (cond ((and (consp elm
)
462 (eq (caar elm
) 'mcond
))
466 (eq (caar elm
) 'mreturn
))
467 (maxima-to-ir (cadr elm
)))
468 (t (maxima-to-ir elm
))))
471 ,(symbol-to-dictionary-ir (caaadr form
) *maxima-function-dictionary-name
*)
472 ,(symbol-to-ir (caaadr form
)))))
474 ;;; Generates IR for atomic forms
475 (defun atom-to-ir (form)
477 ((eq form
'nil
) `(symbol "None"))
478 ((eq form
'$true
) `(symbol "True"))
479 ((stringp form
) `(string ,form
))
480 ((not (symbolp form
)) `(num ,form
0))
481 ((eq form
'$%i
) '(num 0 1)) ; iota complex number
482 ((eq form
'$%pi
) '(num (symbol "math.pi") 0)) ; Pi
483 ((eq form
'$%e
) '(num (symbol "math.e") 0)) ; Euler's Constant
484 ((eq form
'$inf
) '(num (symbol "math.inf") 0))
487 ((member form
*symbols-directly-convert
*) (symbol-to-ir form
))
488 (t (symbol-to-dictionary-ir form
))))))
490 ;;; Generates IR for non-atomic forms
491 (defun cons-to-ir (form)
494 (let ((type (gethash (caar form
) *maxima-direct-ir-map
*)))
496 ; If the form is present in *maxima-direct-ir-map*
501 ; If the form is to be transformed in a specific way
502 ((setf type
(gethash (caar form
) *maxima-special-ir-map
*))
504 ((member 'array
(car form
))
505 (array-ref-to-ir (caar form
) (cdr form
)))
509 ((member (caar form
) *symbols-directly-convert
*) (symbol-to-ir (caar form
)))
510 (t `(element-array ,*maxima-function-dictionary-name
* (string ,(symbol-name-to-string (caar form
)))))))
515 ;;; Generates IR for Maxima expression
516 (defun maxima-to-ir (form &optional
(is_stmt nil
))
518 ((ir (cond ((atom form
)
520 ((and (consp form
) (consp (car form
)))
523 (cons 'no-convert form
)))))
524 (cond (is_stmt (append '(body)
529 ;;; Driver function for the translator, calls the function
530 ;;; maxima-to-ir and then ir-to-python
531 (defun $pytranslate
(form &optional
(print-ir nil
))
532 (setq *ir-forms-to-append
* '())
533 (setf form
(nformat form
))
534 (cond (print-ir (ir-to-python (print (maxima-to-ir form t
))))
535 (t (ir-to-python (maxima-to-ir form t
)))))
537 (defvar *ir-python-direct-templates
*
538 (let ((ht (make-hash-table)))
539 (setf (gethash 'num ht
) 'num-to-python
)
540 (setf (gethash 'asterisk ht
) 'asterisk-to-python
)
541 (setf (gethash 'body ht
) 'body-to-python
)
542 (setf (gethash 'body-indented ht
) 'body-indented-to-python
)
543 (setf (gethash 'op ht
) 'op-to-python
)
544 (setf (gethash 'op-no-bracket ht
) 'op-no-bracket-to-python
)
545 (setf (gethash 'comp-op ht
) 'op-to-python
)
546 (setf (gethash 'boolop ht
) 'op-to-python
)
547 (setf (gethash 'op ht
) 'op-to-python
)
548 (setf (gethash 'del ht
) 'del-to-python
)
549 (setf (gethash 'unary-op ht
) 'unary-op-to-python
)
550 (setf (gethash 'symbol ht
) 'symbol-to-python
)
551 (setf (gethash 'assign ht
) 'assign-to-python
)
552 (setf (gethash 'string ht
) 'string-to-python
)
553 (setf (gethash 'funcall ht
) 'funcall-to-python
)
554 (setf (gethash 'struct-list ht
) 'struct-list-to-python
)
555 (setf (gethash 'func-def ht
) 'func-def-to-python
)
556 (setf (gethash 'element-array ht
) 'element-array-to-python
)
557 (setf (gethash 'conditional ht
) 'conditional-to-python
)
558 (setf (gethash 'cond-if ht
) 'cond-if-to-python
)
559 (setf (gethash 'cond-else ht
) 'cond-else-to-python
)
560 (setf (gethash 'cond-elif ht
) 'cond-elif-to-python
)
561 (setf (gethash 'lambda ht
) 'lambda-to-python
)
562 (setf (gethash 'for-list ht
) 'for-list-to-python
)
563 (setf (gethash 'while-loop ht
) 'while-loop-to-python
)
564 (setf (gethash 'obj-funcall ht
) 'obj-funcall-to-python
)
565 (setf (gethash 'dictionary ht
) 'dictionary-to-python
)
568 ;;; Generates Python source for given IR form
569 (defun ir-to-python (form &optional
570 (indentation-level 0)
575 (is_stmt ; To determine if the form needs to be indented
576 (format nil
"~v@{~A~:*~}" indentation-level
" "))
580 (let ((type (gethash (car form
) *ir-python-direct-templates
*)))
582 (type (funcall type form indentation-level
))
583 (t (format nil
"no-covert : (~a)" form
)))))
585 (format nil
"~a" form
)))))
587 ;;; Code below is for functions handling specefic IR forms and
588 ;;; generating the corresponding Python code.
590 (defun dictionary-to-python (form indentation-level
)
591 (format nil
"{~{~a~^, ~}}"
592 (mapcar (lambda (elm) (ir-to-python `(op-no-bracket #\
: ,(ir-to-python (car elm
))
593 ,(ir-to-python (cadr elm
)))
597 (defun obj-funcall-to-python (form indentation-level
)
598 (format nil
"~a.~a(~{~a~^, ~})"
599 (ir-to-python (cadr form
))
600 (ir-to-python (caddr form
))
602 (lambda (elm) (ir-to-python elm indentation-level
))
605 (defun while-loop-to-python (form indentation-level
)
606 (format nil
"while ~a:~&~a"
607 (ir-to-python (cadr form
) indentation-level
)
608 (ir-to-python (caddr form
) indentation-level
)))
610 (defun for-list-to-python (form indentation-level
)
611 (format nil
"for ~a in ~a:~&~a"
612 (ir-to-python (cadr form
) indentation-level
)
613 (ir-to-python (caddr form
) indentation-level
)
614 (ir-to-python (clast form
) indentation-level
)))
616 (defun lambda-to-python (form indentation-level
)
617 (format nil
"lambda ~{~a~^, ~}: ~a"
619 (lambda (elm) (ir-to-python elm indentation-level
))
621 (ir-to-python (clast form
) indentation-level
)))
623 (defun conditional-to-python (form indentation-level
)
624 (format nil
"(~a if ~a else ~a)"
625 (ir-to-python (caddr form
) indentation-level
)
626 (ir-to-python (cadr form
) indentation-level
)
627 (ir-to-python (cadddr form
) indentation-level
)))
629 (defun cond-if-to-python (form indentation-level
)
631 (ir-to-python (cadr form
) indentation-level
)))
633 (defun cond-else-to-python (form indentation-level
)
634 (declare (ignore form indentation-level
))
635 (format nil
"else:"))
637 (defun cond-elif-to-python (form indentation-level
)
638 (format nil
"elif ~a:"
639 (ir-to-python (cadr form
) indentation-level
)))
641 (defun element-array-to-python (form indentation-level
)
643 (ir-to-python (cadr form
) indentation-level
)
644 (ir-to-python (clast form
) indentation-level
)))
646 (defun func-def-to-python (form indentation-level
)
647 (format nil
"def ~a(~{~a~^, ~}):~&~a"
648 (ir-to-python (cadr form
))
650 (lambda (elm) (ir-to-python elm indentation-level
))
652 (ir-to-python (clast form
) indentation-level
)))
654 (defun struct-list-to-python (form indentation-level
)
655 (format nil
"[~{~a~^, ~}]"
657 (lambda (elm) (ir-to-python elm indentation-level
))
660 (defun unary-op-to-python (form indentation-level
)
663 (ir-to-python (caddr form
) indentation-level
)))
665 (defun del-to-python (form indentation-level
)
666 (declare (ignore indentation-level
))
668 (ir-to-python (cadr form
))))
670 (defun funcall-to-python (form indentation-level
)
671 (format nil
"~a(~{~a~^, ~})"
672 (ir-to-python (cadr form
))
674 (lambda (elm) (ir-to-python elm indentation-level
))
677 (defun string-to-python (form indentation-level
)
678 (declare (ignore indentation-level
))
684 (defun assign-to-python (form indentation-level
)
685 (declare (ignore indentation-level
))
686 (format nil
"~a = ~a"
687 (ir-to-python (cadr form
))
688 (ir-to-python (caddr form
))))
690 (defun asterisk-to-python (form indentation-level
)
691 (declare (ignore indentation-level
))
693 (ir-to-python (cadr form
))))
695 (defun symbol-to-python (form indentation-level
)
696 (declare (ignore indentation-level
))
699 (defun op-no-bracket-template (op)
700 (format nil
"~@?" "~~{~~#[~~;~~a~~:;~~a ~a ~~]~~}"
703 (defun op-no-bracket-to-python (form indentation-level
)
704 (format nil
(op-no-bracket-template (ir-to-python (cadr form
)))
706 (lambda (elm) (ir-to-python elm indentation-level
))
709 (defun op-template (op)
710 (format nil
"~@?" "(~~{~~#[~~;~~a~~:;~~a ~a ~~]~~})"
713 (defun op-to-python (form indentation-level
)
714 (format nil
(op-template (ir-to-python (cadr form
)))
716 (lambda (elm) (ir-to-python elm indentation-level
))
719 ;; "~{~&~a~}" but there was a problem regarding this with indentation:
720 ;; pytranslate('(while cond do (while cond do (while cond do expr))));
722 ;; while not(not(cond)):
724 ;; while not(not(cond)):
726 ;; while not(not(cond)):
728 ;; None = (None + None)
730 ;; None = (None + None)
732 ;; None = (None + None)
734 ;; The lines None=None arent properly indented
735 ;; Hence change to ~% for new line
736 (defun body-to-python (form indentation-level
)
737 (format nil
"~{~%~a~}"
739 (lambda (elm) (ir-to-python elm indentation-level t
))
742 (defun body-indented-to-python (form indentation-level
)
743 (format nil
"~{~&~a~}"
745 (lambda (elm) (ir-to-python elm
(1+ indentation-level
) t
))
748 (defun num-to-python (form indentation-level
)
749 (declare (ignore indentation-level
))
750 (cond ((eql 0 (clast form
)) (ir-to-python (cadr form
)))
753 ;;; Function to display the internal Maxima form
754 (defun $show_form
(form)
755 (print (nformat-check form
)))