File: f90.lisp

package info (click to toggle)
maxima-sage 5.45.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 113,788 kB
  • sloc: lisp: 440,833; fortran: 14,665; perl: 14,369; tcl: 10,997; sh: 4,475; makefile: 2,520; ansic: 447; python: 262; xml: 59; awk: 37; sed: 17
file content (133 lines) | stat: -rw-r--r-- 4,768 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
;;;; f90.lisp -- Application command line argument retrieval
;;;;                      and processing for Common Lisp.

;;;; Copyright (C) 2004 James F. Amundson

;;;; f90.lisp is free software; you can redistribute it
;;;; and/or modify it under the terms of the GNU General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 2, or (at your option) any later version.

;;;; f90.lisp is distributed in the hope that it will be
;;;; useful, but WITHOUT ANY WARRANTY; without even the implied
;;;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
;;;; See the GNU General Public License for more details.

;;;; You should have received a copy of the GNU General Public License
;;;; along with f90.lisp; see the file COPYING.  If not,
;;;; write to the Free Software Foundation, Inc., 59 Temple Place -
;;;; Suite 330, Boston, MA 02111-1307, USA.

;;;; Based on fortra.lisp. Copyright statements for fortra.lisp follow:
;;;;  Copyright (c) 1984,1987 by William Schelter,University of Texas
;;;;     All rights reserved
;;;;  (c) Copyright 1980 Massachusetts Institute of Technology

;;;; Output from f90 is "free form": no special attention to columns.
;;;; Lines longer than *F90-OUTPUT-LINE-LENGTH-MAX* are broken with
;;;; trailing ampersand (no additional spaces).

;;;; Commentary from the Texinfo for f90:
;;;; "The @code{f90} implementation was done as a quick hack.
;;;; It is not a necessarily a good example upon which to base
;;;; other language translations."

(in-package :maxima)

(macsyma-module f90)

(defmvar *f90-output-line-length-max* 65.)

(defvar $f90_output_line_length_max *f90-output-line-length-max*)

(progn
  (putprop '$f90_output_line_length_max '*f90-output-line-length-max* 'alias)
  (putprop '*f90-output-line-length-max* '$f90_output_line_length_max 'reversealias))

(defun f90-print (x
		  &aux
		  ;; This is a poor way of saying that array references
		  ;; are to be printed with parens instead of brackets.
		  (*lb* #\()
		  (*rb* #\)))
  ;; Restructure the expression for displaying.
  (setq x (fortscan x))
  ;; Linearize the expression using MSTRING.  Some global state must be
  ;; modified for MSTRING to generate using Fortran syntax.  This must be
  ;; undone so as not to modifiy the toplevel behavior of MSTRING.
  (unwind-protect
       (defprop mexpt msize-infix grind)
    (defprop mminus 100 lbp)

    (defprop msetq (#\:) strsym)
    (let ((*fortran-print* t)
	  (*read-default-float-format* 'single-float))
      ;; The above makes sure we an exponent marker for Fortran
      ;; numbers.
      (setq x (coerce (mstring x) 'string)))
    ;; Make sure this gets done before exiting this frame.
    (defprop mexpt msz-mexpt grind)
    (remprop 'mminus 'lbp))

  (if (>= (length x) *f90-output-line-length-max*)

    ;; Split this line and print it with trailing ampersand.
    ;; Previous scheme to break the lines nicely had some bugs;
    ;; it's simpler to break at a fixed length.

    (let ((line x) (break-point *f90-output-line-length-max*))
      (princ (subseq line 0 break-point))
      (princ "&")
      (terpri)
      (princ "&")
      (setf line (subseq line break-point))
      
      (loop while (> (length line) break-point) do
        (princ (subseq line 0 break-point))
        (princ "&")
        (terpri)
        (princ "&")
        (setf line (subseq line break-point)))

      (if (> (length line) 0)
        (princ line)))

    (princ x))

  (terpri)
  '$done)

;; Takes a name and a matrix and prints a sequence of F90 assignment
;; statements of the form
;;  NAME(I,J) = <corresponding matrix element>
;; or, when the second argument is a list,
;;  NAME(I) = <list element>

(defmfun $f90mx (name mat)
  (cond ((not (symbolp name))
	 (merror "f90mx: first argument must be a symbol; found: ~M" name))
	((not (or ($matrixp mat) ($listp mat)))
	 (merror "f90mx: second argument must be a list or matrix; found: ~M" mat)))
  (cond
    (($matrixp mat)
     (do ((mat (cdr mat) (cdr mat)) (i 1 (1+ i)))
       ((null mat))
       (do ((m (cdar mat) (cdr m)) (j 1 (1+ j)))
         ((null m))
         (f90-print `((mequal) ((,name) ,i ,j) ,(car m))))))
    (($listp mat)
     (do ((mat (cdr mat) (cdr mat)) (i 1 (1+ i)))
       ((null mat))
       (f90-print `((mequal) ((,name) ,i) ,(car mat))))))
  '$done)

(defmspec $f90 (expr)
  (dolist (l (cdr expr))
  (let ((value (strmeval l)))
    (cond ((msetqp l) (setq value `((mequal) ,(cadr l) ,(meval l)))))
    (cond ((and (symbolp l) (or ($matrixp value) ($listp value)))
	   ($f90mx l value))
	  ((and (not (atom value)) (eq (caar value) 'mequal)
		(symbolp (cadr value)) (or ($matrixp (caddr value)) ($listp (caddr value))))
	   ($f90mx (cadr value) (caddr value)))
	  (t (f90-print value))))))