1 ;; macros.l - all the basic macros
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;;;;;;;Copyright (c) University of Waikato;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4 ;;;;;;;;Hamilton, New Zeland 1992-95 - all rights reserved;;;;;;;;;;;;;;;;
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8 (defparameter *f2cl-macros-version
*
9 "$Id: macros.l,v 3fe93de3be82 2012/05/06 02:17:14 toy $")
12 #+gcl
(compile load eval
)
13 #-gcl
(:compile-toplevel
:load-toplevel
:execute
)
14 (proclaim '(special *verbose
*)))
15 ;;----------------------------------------------------------------------------
16 (defvar *check-array-bounds
* nil
17 "If non-NIL, generated code checks for array bounds. If NIL, checking
20 ;;------------------------------------------------------------------------------
22 ;; Define the equivalent types between Fortran and Lisp. This MUST
23 ;; match the types given in f2cl1.l so keep it in sync!
27 ;; Decide what you want integer*4 to be. Good choices are fixnum or
28 ;; (signed-byte 32). The latter is good only if your compiler does a
29 ;; good job with this type. If you aren't sure, use fixnum. CMUCL
30 ;; does a good job with (signed-byte 32).
32 ;; If you change this, you may need to change some of the macros
33 ;; below, such as INT and AINT!
35 #+(or cmu scl sbcl ecl
)
36 (deftype integer4
(&optional
(low #x-80000000
) (high #x7fffffff
))
37 `(integer ,low
,high
))
38 #-
(or cmu scl sbcl ecl
)
39 (deftype integer4
(&optional low high
)
40 (declare (ignore low high
))
52 `(complex single-float
))
54 `(complex double-float
))
56 (deftype array-double-float
()
57 `(array double-float
(*)))
58 (deftype array-integer4
()
59 `(array integer4
(*)))
60 (deftype array-single-float
()
61 `(array single-float
(*)))
62 (deftype array-strings
()
65 (defconstant %false% nil
)
66 (defconstant %true% t
)
68 ;;------------------------------------------------------------------------------
70 ;;-----------------------------------------------------------------------------
72 ;; Array dimensions are (d1, d2, d3, ...)
74 ;; Then x(n1, n2, n3, ...) means index is
76 ;; n1 + d1*(n2 + d2*(n3 + d3*(n4 + d4*(n5))))
78 ;; Return an expression that computes the column major index given the
79 ;; indices and the bounds on each dimension. The bounds are a list of
80 ;; the upper and lower bounds for each dimension.
81 (defun col-major-index (indices dims
)
82 (flet ((get-offset (n bound
)
83 (let ((lo (first bound
)))
84 (if (and (numberp lo
) (zerop lo
))
86 `(the fixnum
(- (the fixnum
,n
) (the fixnum
,lo
))))))
88 (destructuring-bind (lo hi
)
98 `(the fixnum
(- ,hi
(the fixnum
(- (the fixnum
,lo
) 1)))))))))
99 (let* ((rev-idx (reverse indices
))
100 (rev-dim (reverse dims
))
101 (idx (get-offset (first rev-idx
) (first rev-dim
))))
102 (do ((d (rest rev-dim
) (rest d
))
103 (n (rest rev-idx
) (rest n
)))
106 (setf idx
`(the fixnum
(+ ,(get-offset (first n
) (first d
))
107 (the fixnum
(* ,(get-size (first d
)) ,idx
)))))))))
109 (defun check-array-bounds (indices bounds
)
110 `(and ,@(mapcar #'(lambda (idx dim
)
111 `(<= ,(first dim
) ,idx
,(second dim
)))
114 (defmacro fref
(arr indices bounds
&optional offset
)
115 (if *check-array-bounds
*
116 `(aref ,arr
(if ,(check-array-bounds indices bounds
)
117 (the fixnum
(+ (the fixnum
,(or offset
0)) ,(col-major-index indices bounds
)))
118 (error "Out of bounds index for array ~S"
120 `(aref ,arr
(the fixnum
(+ (the fixnum
,(or offset
0)) ,(col-major-index indices bounds
))))))
123 `(setf (fref ,(second a
) ,@(cddr a
)) ,b
))
125 (defmacro fref-string
(s range
)
126 `(subseq ,s
(1- ,(first range
)) ,(second range
)))
128 (defmacro fset-string
(a b
)
129 `(setf (fref-string ,(second a
) ,(third a
)) (string ,b
)))
131 (defmacro f2cl-
// (a b
)
132 `(concatenate 'string
,a
,b
))
134 ;; (with-array-data ((data-var offset-var array))
138 (defun find-array-data (array)
139 (declare (type (array * (*)) array
))
141 (declare (type fixnum offset
)
142 (optimize (speed 3) (safety 0)))
144 (multiple-value-bind (displaced-to index-offset
)
145 (array-displacement array
)
146 (when (null displaced-to
)
147 (return-from find-array-data
(values array offset
)))
148 (incf offset index-offset
)
149 (setf array displaced-to
)))))
151 (defmacro with-array-data
((data-var offset-var array
) &rest body
)
152 `(multiple-value-bind (,data-var
,offset-var
)
153 (find-array-data ,array
)
156 (defun multi-array-data-aux (array-info body
)
157 (let ((results body
))
158 (dolist (a (reverse array-info
))
159 (destructuring-bind (array a-type var-name offset-var
)
161 (let ((atype (if (subtypep a-type
'character
)
163 `(simple-array ,a-type
(*)))))
165 `((multiple-value-bind (,var-name
,offset-var
)
166 (find-array-data ,array
)
167 (declare (ignorable ,offset-var
,var-name
)
168 (type f2cl-lib
:integer4
,offset-var
)
169 (type ,atype
,var-name
))
173 (defmacro with-multi-array-data
(array-info &rest body
)
174 (multi-array-data-aux array-info body
))
176 ;; Create an array slice for the array named VNAME whose elements are
177 ;; of type TYPE. The slice starts at the indices INDICES and the
178 ;; original array has dimensions given by BOUND.
180 ;; This is done by making a displaced array to VNAME with the
181 ;; appropriate offset.
182 (defmacro array-slice
(vname type indices bounds
&optional offset
)
183 ;; To figure the size of the sliced array, use ARRAY-TOTAL-SIZE
184 ;; instead of the f2cl derived/declared BOUNDS, just in case we
185 ;; screwed up or in case we changed the size of the array in some
186 ;; other way. This isn't possible in a function, but the array
187 ;; might be in a common block and we could change the dimensions of
188 ;; the common block at runtime. (Some Fortran code like mpfun does
189 ;; this, although it's actually illegal. Neat hack to "dynamically"
190 ;; change the dimensions. Of course, for this to work in Fortran,
191 ;; the common block has to contain exactly that one array, or the
192 ;; array must be the last element of the common block.)
194 ;; Note: In some places in LAPACK, an array slice is taken where the
195 ;; slice exceeds the bounds of the array. However, the array is
196 ;; never accessed. What are we to do? We could modify the LAPACK
197 ;; routines (everywhere!) to check for this, or we can silently make
198 ;; array-slice make a 0-element array. If the array is then
199 ;; accessed, we should get an error at the point of access, not the
200 ;; point of creation.
202 ;; This seems somewhat reasonable, so let's do that for array
204 `(make-array (max 0 (- (array-total-size ,vname
)
206 (+ ,(col-major-index indices bounds
)
210 :displaced-index-offset
(min (array-total-size ,vname
)
212 (+ ,(col-major-index indices bounds
)
215 ;; Compute an initializer for make-array given the data in the list
216 ;; DATA. The array has en element type of TYPE and has dimensions of
218 (defmacro array-initialize
(type dims data
)
219 (let ((data-list (gensym))
220 (data-len (length data
))
221 (total-length (gensym)))
222 `(let* ((,data-list
(list ,@data
))
223 (,total-length
(reduce #'* (list ,@dims
))))
224 (cond ((< ,data-len
,total-length
)
225 ;; Need to append some data.
226 (append ,data-list
(make-list (- ,total-length
,data-len
)
227 :initial-element
(coerce 0 ',type
))))
228 ((> ,data-len
,total-length
)
229 ;; Need to truncate some data
230 (subseq ,data-list
0 ,total-length
))
234 ;;----------------------------------------------------------------------------
236 #-aclpc
(defmacro while
(con &rest body
)
237 `(loop (if (not ,con
) (return t
)) ,@body
))
238 ;;------------------------------------------------------------------
240 (defmacro fortran_comment
(&rest args
)
241 (declare (ignore args
)))
243 ;;----------------------------------------------------------------------------
244 ;; fdo has similar syntax as do except there will only be one do_vble
246 (defmacro fdo
(do_vble_clause predicate_clause
&rest body
)
247 (let ((step (gensym (symbol-name '#:step-
)))
248 (iteration_count (gensym (symbol-name '#:cnt-
)))
249 (loop-var (first do_vble_clause
)))
250 `(prog* ((,step
,(third (third do_vble_clause
)))
253 (truncate (the integer4
254 (+ (the integer4
(- ,(third (first predicate_clause
))
255 ,(second do_vble_clause
)))
259 (declare (type integer4
,step
,iteration_count
))
260 ;; initialise loop variable
261 (setq ,loop-var
,(second do_vble_clause
))
264 (cond ; all iterations done
265 ((zerop ,iteration_count
) nil
)
266 ;; execute loop, in/de-crement loop vble and decrement cntr
272 (setq ,loop-var
(the integer4
,(third do_vble_clause
))
273 ,iteration_count
(the integer4
(1- ,iteration_count
)))))
277 ;;----------------------------------------------------------------------------
278 ;; macro for division
280 (defmacro f2cl
/ (x y
)
285 (if (and (typep ,top
'integer
)
286 (typep ,bot
'integer
))
287 (values (the integer4
(truncate ,top
,bot
)))
290 (defmacro int-add
(arg &rest more-args
)
293 (if (> (length more-args
) 1)
294 `(the integer4
(+ ,arg
(int-add ,@more-args
)))
295 `(the integer4
(+ ,arg
,@more-args
)))))
297 (defun convert-int-sub (args)
298 (let ((nargs (length args
)))
301 `(the integer4
(- ,(first args
))))
303 `(the integer4
(- ,(first args
) ,(second args
))))
305 (let ((result `(the integer4
(- ,(first args
) ,(second args
)))))
306 (dolist (arg (rest (rest args
)))
307 (setf result
`(the integer4
(- ,result
,arg
))))
310 (defmacro int-sub
(&rest args
)
311 (convert-int-sub args
))
313 (defmacro int-mul
(arg &rest more-args
)
316 (if (> (length more-args
) 1)
317 `(the integer4
(* ,arg
(int-mul ,@more-args
)))
318 `(the integer4
(* ,arg
,@more-args
)))))
321 ;; macro for a lisp equivalent of Fortran arithmetic IFs
322 (defmacro arithmetic-if
(pred s1 s2 s3
)
323 (let ((tst (gensym)))
325 (cond ((< ,tst
0) ,s1
)
329 ;; macro for a lisp equivalent of Fortran computed GOTOs
330 (defun computed-goto-aux (tags)
333 (dolist (tag tags
(nreverse result
))
335 (push `(,idx
(go ,tag
)) result
))))
337 (defmacro computed-goto
(tag-lst i
)
339 ,@(computed-goto-aux tag-lst
)))
341 ;; macro for a lisp equivalent of Fortran assigned GOTOs
343 #+gcl
(compile load eval
)
344 #-gcl
(:load-toplevel
:compile-toplevel
:execute
)
345 (defun make-label (n)
346 (read-from-string (concatenate 'string
(symbol-name :label
) (princ-to-string n
))))
349 (defun assigned-goto-aux (tag-list)
351 (dolist (tag tag-list
)
352 (push `(,tag
(go ,(f2cl-lib::make-label tag
)))
354 (push `(t (error "Unknown label for assigned goto")) cases
)
359 ;; macro for a lisp equivalent of Fortran assigned GOTOs
360 (defmacro assigned-goto
(var tag-list
)
362 ,@(assigned-goto-aux tag-list
)))
364 ;;-----------------------------------------------------------------------------
366 ;; Define the intrinsic functions
368 ;; Reference: The Fortran 77 standard found at www.fortran.com. Section 15.10
370 ;; INT is the generic name as well as the integer version. IFIX is
371 ;; the same. IDINT is the double version.
373 (declaim (inline int ifix idfix
))
377 ;; We use fixnum here because f2cl thinks Fortran integers are
378 ;; fixnums. If this should change, we need to change the ranges
384 (truncate (the (single-float #.
(float most-negative-fixnum
)
385 #.
(float most-positive-fixnum
))
388 (truncate (the (double-float #.
(float most-negative-fixnum
1d0
)
389 #.
(float most-positive-fixnum
1d0
))
391 ((complex single-float
)
393 (truncate (the (single-float #.
(float (- (ash 1 31)))
394 #.
(float (1- (ash 1 31))))
396 ((complex double-float
)
398 (truncate (the (double-float #.
(float (- (ash 1 31)) 1d0
)
399 #.
(float (1- (ash 1 31)) 1d0
))
404 ;; For CMUCL, we support the full 32-bit integer range, so INT can
405 ;; return a full 32-bit integer. Tell CMUCL that this is true so we
406 ;; generate fast code. If this is not true, the original Fortran
413 (truncate (the (single-float #.
(float (- (ash 1 31)))
414 #.
(float (1- (ash 1 31))))
418 (truncate (the (double-float #.
(float (- (ash 1 31)) 1d0
)
419 #.
(float (1- (ash 1 31)) 1d0
))
421 ((complex single-float
)
423 (truncate (the (single-float #.
(float (- (ash 1 31)))
424 #.
(float (1- (ash 1 31))))
426 ((complex double-float
)
428 (truncate (the (double-float #.
(float (- (ash 1 31)) 1d0
)
429 #.
(float (1- (ash 1 31)) 1d0
))
438 ;; AINT is the generic and specific function for real; DINT, for
439 ;; double. It truncates its arg towards zero and returns the integer
440 ;; as a floating-point number of the same type as its arg.
442 ;; ANINT is the generic and specific function for real; DNINT, for
443 ;; double. It rounds to the nearest integer and returns the result as
444 ;; a float of the same type.
446 ;; NINT is the generic and specific function for real; IDNINT, for
447 ;; double. Does the same as ANINT, but the result is an integer.
449 (declaim (inline aint dint anint dnint nint idnint
))
451 ;; This is based on the algorithm given by Anton Ertl in
452 ;; comp.arch.arithmetic on Oct. 26, 2002:
454 ;; #define X 9007199254740992. /* 2^53 */
455 ;; double rint(double r)
463 ;; This assumes that we in round-to-nearest mode (the default).
465 ;; These only work if you have IEEE FP arithmetic. There are 2
466 ;; versions given below. One is for non-x87, which assumes that
467 ;; single and double FP numbers are properly rounded after each
468 ;; operation. The version for x87 stores away a value to make sure
469 ;; the rounding happens correctly.
471 ;; Finally, the last version if for platforms where none of this
472 ;; holds and we call ftruncate.
474 ;; With CMUCL pre-18e on sparc, this definition of aint reduces the
475 ;; cost of MPNORM (from MPFUN) from 48.89 sec to 24.88 sec (a factor
476 ;; of 2!) when computing pi to 29593 digits or os.
478 (declaim (inline rint-s rint-d
))
479 #+(and cmu
(or :sse2
(not x86
)))
482 (declare (single-float x
))
483 (let ((const (scale-float 1f0
24)))
485 (+ (- x const
) const
)
486 (- (+ x const
) const
))))
489 (declare (double-float x
))
490 (let ((const (scale-float 1d0
53)))
492 (+ (- x const
) const
)
493 (- (+ x const
) const
))))
496 #+(and cmu
(and x86 x87
))
499 (declare (single-float x
))
500 (let ((junks (make-array 1 :element-type
'single-float
))
501 (const (scale-float 1f0
24)))
504 (setf (aref junks
0) (- x const
))
505 (+ (aref junks
0) const
))
507 (setf (aref junks
0) (+ x const
))
508 (- (aref junks
0) const
)))))
511 (declare (double-float x
))
512 (let ((junkd (make-array 1 :element-type
'double-float
))
513 (const (scale-float 1d0
53)))
516 (setf (aref junkd
0) (- x const
))
517 (+ (aref junkd
0) const
))
519 (setf (aref junkd
0) (+ x const
))
520 (- (aref junkd
0) const
)))))
523 ;; Truncate x to an integer.
526 ;; rint above is fast. We use it to round the number, and then
527 ;; adjust the result to truncate.
530 (let ((r (rint-s x
)))
531 (if (> (abs r
) (abs x
))
537 (let ((r (rint-d x
)))
538 (if (> (abs r
) (abs x
))
547 ;; ftruncate is exactly what we want.
551 (declare (optimize (space 0) (speed 3)))
552 (values (ftruncate (the single-float x
)))))
555 (declare (optimize (space 0) (speed 3)))
556 (values (ftruncate (the double-float x
)))))))
572 ;; FREAL is F2CL's version of the Fortran REAL which takes converts
573 ;; its arg to a real. SNGL is the same. DBLE returns a double. They
574 ;; also return the real part of a complex number. CMPLX takes one or
575 ;; two args and creates a complex number.
577 (declaim (inline freal sngl dble dfloat cmplx
))
579 (coerce (realpart x
) 'single-float
))
582 (coerce (realpart x
) 'single-float
))
585 (coerce (realpart x
) 'double-float
))
588 (coerce (realpart x
) 'double-float
))
590 (defun cmplx (x &optional y
)
591 (complex x
(if y y
0)))
593 (defun dcmplx (x &optional y
)
594 (coerce (complex x
(if y y
0)) '(complex double-float
)))
598 (char-int (aref c
0))
600 (defun fchar (i) ;intrinsic function char
603 (declaim (inline iabs dabs cabs cdabs amod dmod
))
606 (declare (type integer4 x
))
609 (declare (type double-float x
))
612 (declare (type complex x
))
615 (declare (type (complex double-float
) x
))
619 (declare (type single-float x y
))
622 (declare (type double-float x y
))
626 ;; Transfer of sign. SIGN is the generic and specific function for
627 ;; real. ISIGN is for integers; DSIGN for doubles. Basically
628 ;; computes sign(a2)*|a1|.
630 (declaim (inline isign sign dsign
))
633 (declare (type integer4 x y
))
635 (the integer4
(abs x
))
636 (the integer4
(- (the integer4
(abs x
))))))
638 ;; Fortran 77 says SIGN is a generic!
640 (declare (type (or integer4 single-float double-float
) x y
))
650 (declare (type double-float x y
))
653 ;; Positive difference. DIM is the generic and specific function for
654 ;; real. IDIM is for integers; DDIM, doubles.
656 ;; If a1 > a2, returns a1-a2, otherwise 0. Basically the same as
658 (declaim (inline idim dim ddim
))
660 (declare (type integer4 x y
))
664 (declare (type (or integer4 single-float double-float
) x y
))
674 (declare (type double-float x y
))
677 ;; Double-precision product. How this is done isn't specified, but I
678 ;; suspect the real args are converted to doubles and then the product
681 (declare (single-float x y
))
682 (* (float x
1d0
) (float y
1d0
)))
684 ;; The max and min functions.
686 ;; MAX is the generic. MAX0, AMAX1, and DMAX1 returns the max of the
687 ;; args with the same type as the args.
689 ;; AMAX0 takes integer args and returns the max as a real. MAX1 takes
690 ;; real args and returns the max as a integer. (How the conversion is
691 ;; done isn't specified.)
693 ;; Should we make these macros that expand directly to the appropriate
695 (defun max0 (x y
&rest z
)
696 #-gcl
(declare (integer x y
))
698 (defun amax1 (x y
&rest z
)
699 #-gcl
(declare (single-float x y
))
701 (defun dmax1 (x y
&rest z
)
702 #-gcl
(declare (double-float x y
))
704 (defun max1 (x y
&rest z
)
705 #-gcl
(declare (single-float x y
))
706 (int (apply #'max x y z
)))
707 (defun amax0 (x y
&rest z
)
708 #-gcl
(declare (type integer4 x y
))
709 (float (apply #'max x y z
) 1f0
))
711 (defun min0 (x y
&rest z
)
713 (defun amin1 (x y
&rest z
)
715 (defun dmin1 (x y
&rest z
)
718 (defun amin0 (x y
&rest z
)
719 (float (apply #'min x y z
)))
720 (defun min1 (x y
&rest z
)
721 (nint (apply #'min x y z
)))
723 ;; Define some compile macros for these max/min functions.
726 (define-compiler-macro max0
(&rest args
)
728 (define-compiler-macro amax1
(&rest args
)
730 (define-compiler-macro dmax1
(&rest args
)
732 (define-compiler-macro min0
(&rest args
)
734 (define-compiler-macro amin1
(&rest args
)
736 (define-compiler-macro dmin1
(&rest args
)
738 (define-compiler-macro min1
(&rest args
)
739 `(nint (min ,@args
)))
741 (define-compiler-macro amax0
(&rest args
)
742 `(float (max ,@args
)))
743 (define-compiler-macro max1
(&rest args
)
744 `(nint (max ,@args
)))
746 (define-compiler-macro amin0
(&rest args
)
747 `(float (min ,@args
)))
748 (define-compiler-macro min1
(&rest args
)
749 `(nint (min ,@args
)))
755 ;; From http://www.fortran.com/fortran/F77_std/rjcnf0001-sh-15.html#sh-15.10:
757 ;; INDEX(a1 ,a2) returns an integer value indicating the starting
758 ;; position within the character string a1 of a substring identical
759 ;; to string a2 . If a2 occurs more than once in a1 , the starting
760 ;; position of the first occurrence is returned.
762 ;; If a2 does not occur in a1 , the value zero is returned. Note
763 ;; that zero is returned if LEN(a1) < LEN(a2).
765 ;; Thus the arguments are in the opposite order for CL's SEARCH function.
767 (or (search s2 s1
) 0))
769 ;; These string operations need some work!
779 (defun fstring-/= (s1 s2
)
780 (not (string= s1 s2
)))
781 (defun fstring-= (s1 s2
)
783 (defun fstring-> (s1 s2
)
785 (defun fstring->= (s1 s2
)
787 (defun fstring-< (s1 s2
)
789 (defun fstring-<= (s1 s2
)
793 ;; AIMAG: imaginary part of a complex number
794 ;; CONJG: conjugate of a complex number
795 (declaim (inline aimag conjg dconjg dimag
))
799 (declare (type (complex double-float
) c
))
804 (declare (type (complex double-float
) c
))
807 (declaim (inline fsqrt flog
))
811 (sqrt (the (or (single-float (0f0)) (member 0f0
)) x
)))
813 (sqrt (the (or (double-float (0d0)) (member 0d0
)) x
)))
820 (log (the (or (single-float (0f0)) (member 0f0
)) x
)))
822 (log (the (or (double-float (0d0)) (member 0d0
)) x
)))
826 ;; Tell Lisp that the arguments always have the correct range. If
827 ;; this is not true, the original Fortran code was broken anyway, so
828 ;; GIGO (garbage in, garbage out).
830 (declaim (inline dsqrt csqrt zsqrt alog dlog clog alog10 dlog10
))
832 (declare (type (double-float 0d0
) x
))
839 (declare (type (or (single-float (0f0)) (member 0f0
)) x
))
842 (declare (type (or (double-float (0d0)) (member 0d0
)) x
))
847 (declare (type (or (single-float (0f0)) (member 0f0
)) x
))
850 (declare (type (or (double-float (0d0)) (member 0d0
)) x
))
853 (declaim (inline log10
))
857 (log (the (or (single-float (0.0f0
)) (member 0f0
)) x
) 10f0
))
859 (log (the (or (double-float (0.0d0
)) (member 0d0
)) x
) 10d0
))
863 ((complex double-float
)
865 ((complex single-float
)
868 (coerce 10 (type-of (realpart x
)))))))))
870 (declaim (inline dexp cexp
))
872 (declare (type double-float x
))
875 (declare (type complex x
))
878 (declaim (inline dsin csin dcos ccos dtan ctan dasin dacos datan atan2 datan2 dsinh dcosh dtanh
))
880 (declare (type double-float x
))
883 (declare (type complex x
))
887 (declare (type double-float x
))
890 (declare (type complex x
))
894 (declare (type double-float x
))
897 (declare (type complex x
))
901 (declare (type double-float x
))
904 (declare (type double-float x
))
907 (declare (type double-float x
))
909 ;; atan2 is the Fortran77 generic name, so it can take any float arg.
911 (declare (type float y x
))
914 (declare (type double-float x y
))
918 (declare (type double-float x
))
921 (declare (type double-float x
))
924 (declare (type double-float x
))
927 (declaim (inline ffloat
))
929 (coerce x
'single-float
))
931 (defun process-implied-do (ido array-bnds var-types init
)
932 (destructuring-bind (data-vars &rest looping
)
935 ((convert-type (type)
936 (if (eq type
'integer4
)
937 `(truncate (pop ,init
))
938 `(coerce (pop ,init
) ',type
)))
940 (mapcar #'(lambda (x b vt
)
941 `(fset (fref ,(first x
) ,(second x
) ,b
)
943 v array-bnds var-types
)))
944 (let ((body (map-vars data-vars
)))
945 (dolist (loopvar looping
)
946 (destructuring-bind (index-var start end
&optional step
)
948 (setf body
`((do ((,index-var
,start
(+ ,index-var
,(or step
1))))
949 ((> ,index-var
,end
))
954 ;; Process implied do loops for data statements
955 (defmacro data-implied-do
(implied-do array-bnds var-types vals
)
957 `(let ((,v
(list ,@vals
)))
958 ,(process-implied-do implied-do array-bnds var-types v
))))
960 ;;-----------------------------------------------------------------------------
962 ;; Map Fortran logical unit numbers to Lisp streams
965 (defparameter *lun-hash
*
972 (defun lun->stream
(lun &optional readp
)
973 (let ((stream (gethash lun
*lun-hash
*)))
977 ;; Always standard input
978 (setf (gethash lun
*lun-hash
*) *standard-input
*))
981 ;; Always standard output
982 (setf (gethash lun
*lun-hash
*) *standard-output
*))
984 ;; All other cases open a file fort<n>.dat
985 (setf (gethash lun
*lun-hash
*)
986 (open (format nil
"fort~d.dat" lun
)
988 :if-exists
:rename
)))
990 (setf (gethash lun
*lun-hash
*)
992 (make-string-input-stream lun
)
993 (make-string-output-stream))))))))
995 (defun init-fortran-io ()
996 "Initialize the F2CL Fortran I/O subsystem to sensible defaults"
998 (setf (gethash 6 *lun-hash
*) *standard-output
*)
999 (setf (gethash 5 *lun-hash
*) *standard-input
*)
1000 (setf (gethash t
*lun-hash
*) *standard-output
*))
1002 (defun close-fortran-io ()
1003 "Close all F2CL Fortran units (except for standard output and input)
1004 causing all pending operations to be flushed"
1005 (maphash #'(lambda (key val
)
1006 (when (and (streamp val
) (not (member key
'(5 6 t
))))
1007 (format t
"Closing unit ~A: ~A~%" key val
)
1011 (defun %open-file
(&key unit file status access form recl blank
)
1012 (declare (ignore unit
))
1013 ;; We should also check for values of form that we don't support.
1015 (error "F2CL-LIB does not support record lengths"))
1017 (error "F2CL-LIB does not support any BLANK mode for files"))
1018 (when (and access
(not (string-equal "sequential"
1019 (string-right-trim " " access
))))
1020 (error "F2CL-LIB does not support ACCESS mode ~S" access
))
1021 (when (and form
(not (string-equal "unformatted"
1022 (string-right-trim " " form
))))
1023 (error "F2CL-LIB does not support FORM ~S" form
))
1024 (let ((s (and status
(string-right-trim " " status
))))
1026 (cond ((or (null s
) (string-equal s
"unknown"))
1027 (open file
:direction
:io
:if-exists
:supersede
1028 :if-does-not-exist
:create
))
1029 ((string-equal s
"old")
1030 (open file
:direction
:io
:if-does-not-exist nil
:if-exists
:overwrite
))
1031 ((string-equal s
"new")
1032 (open file
:direction
:io
:if-exists nil
))
1034 (error "F2CL-LIB does not support this mode for OPEN: ~S~%"
1037 (defmacro open-file
(&key unit iostat err file status access form recl blank
)
1038 (let ((result (gensym)))
1039 `(prog ((,result
(%open-file
:unit
,unit
:file
,file
:status
,status
1040 :access
,access
:form
,form
:recl
,recl
:blank
,blank
)))
1042 (setf (gethash ,unit
*lun-hash
*) ,result
))
1043 ,(if err
`(unless ,result
(go ,(f2cl-lib::make-label err
))))
1044 ,(if iostat
`(setf ,iostat
(if ,result
0 1))))))
1046 (defun %rewind
(unit)
1047 (file-position (lun->stream unit
) :start
))
1049 (defmacro rewind
(&key unit iostat err
)
1050 (let ((result (gensym)))
1051 `(prog ((,result
(%rewind
,unit
)))
1052 (declare (ignorable ,result
))
1053 ,(if err
`(unless ,result
(go ,(f2cl-lib::make-label err
))))
1054 ,(if iostat
`(setf ,iostat
(if ,result
0 1))))))
1057 (defun %close
(&key unit status
)
1059 (error "F2CL-LIB does not support STATUS"))
1060 (cl:close
(lun->stream unit
)))
1062 (defmacro close$
(&key unit iostat err status
)
1063 (let ((result (gensym)))
1064 `(prog ((,result
(%close
:unit
,unit
:status
,status
)))
1065 (declare (ignorable ,result
))
1066 ,(if err
`(unless ,result
(go ,(f2cl-lib::make-label err
))))
1067 ,(if iostat
`(setf ,iostat
(if ,result
0 1))))))
1070 (declaim (ftype (function (t) stream
) lun-
>stream
))
1072 (defmacro fformat
(dest-lun format-cilist
&rest args
)
1073 (let ((stream (gensym)))
1074 `(let ((,stream
(lun->stream
,dest-lun
)))
1075 (execute-format-main ,stream
',format-cilist
,@args
)
1076 ,@(unless (or (eq t dest-lun
) (numberp dest-lun
))
1077 `((when (stringp ,dest-lun
)
1078 (replace ,dest-lun
(get-output-stream-string ,stream
))))))))
1080 (defun execute-format (top stream format arg-list
)
1081 (do ((formats format
(if (and top
(null formats
))
1084 ((or (null arg-list
)
1089 (format t
"~&end formats = ~S~%" formats
)
1090 (format t
"~&end arg-list = ~S~%" arg-list
))
1091 (do ((more formats
(rest more
)))
1092 ((not (stringp (first more
))))
1093 (format stream
(first more
)))
1096 (when (null formats
)
1097 ;; We're out of formats but not arguments. I think Fortran says
1098 ;; we should start over at the last repeat spec. So we look
1099 ;; over all the formats until we find the first number. That
1100 ;; means it's a repeat spec.
1102 ;; This is probably wrong for complicated format statements.
1103 (do ((f format
(cdr f
))
1106 (setf formats last-rep
))
1107 (when (or (eq (car f
) t
)
1111 (when (null formats
)
1112 ;; Now what? We couldn't find a repeat spec, so should we
1114 (setf formats format
)))
1116 (let ((*print-circle
* t
))
1117 (format t
"~&arg-list = ~S~%" arg-list
)
1118 (format t
"~&formats = ~S~%" formats
))
1119 (cond ((listp (first formats
))
1120 (format stream
(caar formats
) (pop arg-list
)))
1121 ((eq (first formats
) #\
:)
1122 ;; Terminate control if there are no more items
1123 (when (null arg-list
)
1124 (return-from execute-format
)))
1125 ((numberp (first formats
))
1126 ;; Repeat a group some fixed number of times
1127 (dotimes (k (first formats
))
1128 ;;(format t "k = ~A, format = ~S~%" k (second formats))
1130 (execute-format nil stream
(second formats
) arg-list
))
1131 ;; Gotta exit if we're out of arguments to print!
1134 (setf formats
(rest formats
))
1135 ;; Output a newline after the repeat (I think Fortran says this)
1136 ;;(format stream "~&")
1137 ;;(format t " cont with format = ~S~%" formats)
1139 ((eq (first formats
) t
)
1140 ;; Repeat "forever" (until we run out of data)
1141 (loop while arg-list do
1143 (execute-format nil stream
(second formats
) arg-list
))
1144 ;; Output a newline after the repeat (I think Fortran says this)
1145 (format stream
"~%")))
1147 (format stream
(car formats
))))))
1149 (defun flatten-list (x)
1150 (labels ((flatten-helper (x r
);; 'r' is the stuff to the 'right'.
1154 (t (flatten-helper (car x
)
1155 (flatten-helper (cdr x
) r
))))))
1156 (flatten-helper x nil
)))
1158 ;; Fortran G format, roughly. We use ~F for numbers "near" 1, and use
1161 ;; Note that g77 seems to use an exponent marker of E for single and
1162 ;; double floats, but Sun Fortran uses E and D. I think I like E and
1163 ;; D to distinguish between them. Also note that g77 uses just enough
1164 ;; digits for the numbers, but Sun Fortran seems to specify the number
1165 ;; of printed digits to be 16 or so. Thus 1.0 is "1.0" with g77, but
1166 ;; "1.0000000000000" with Sun Fortran. I like g77's style better.
1167 (defun fortran-format-g (stream arg colon-p at-p
&rest args
)
1168 (declare (ignore colon-p at-p args
))
1169 (let* ((marker (typecase arg
1171 (double-float "D")))
1173 ;; g77 uses limits 1d-4 and 1d9. Sun Fortran uses 1 and
1175 (format-string (if (or (zerop a
)
1179 (concatenate 'string
"~,,2,,,,'"
1182 (format stream format-string arg
)))
1184 ;; Output objects in Fortran style, roughly. This basically means
1185 ;; complex numbers are printed as "(<re>, <im>)", floats use
1186 ;; FORTRAN-FORMAT-G, integers use ~D, strings are printed as is, and
1187 ;; T/NIL become "T" or "F".
1188 (defun fortran-format (stream arg colon-p at-p
&rest args
)
1189 (declare (ignore colon-p at-p args
))
1193 (format stream
"(~/f2cl-lib::fortran-format-g/, ~/f2cl-lib::fortran-format-g/)"
1194 (realpart arg
) (imagpart arg
))
1197 (fortran-format-g stream
(realpart arg
) nil nil
)
1198 (fortran-format-g stream
(imagpart arg
) nil nil
)))
1201 (format stream
" ~/f2cl-lib::fortran-format-g/" arg
)
1203 (fortran-format-g stream arg nil nil
))
1205 (format stream
" ~D" arg
))
1207 (format stream
"~A" arg
))
1209 (format stream
(if arg
"T " "F ")))))
1211 (defun execute-format-main (stream format
&rest args
)
1213 ((eq format
:list-directed
)
1214 ;; This prints out the args separated by spaces and puts a line
1215 ;; break after about 80 columns.
1216 (format stream
"~& ~{~<~%~1,81:;~?~>~^~}~%"
1219 ;; Some special cases. Let FORTRAN-FORMAT handle
1220 ;; most cases, except strings, which we just print
1221 ;; out ourselves. Lists (from implied-do loops) and
1222 ;; arrays use FORTRAN-FORMAT for each element.
1226 (push (list v
) pars
))
1231 (push "~/f2cl-lib::fortran-format/" pars
)
1232 (push (list item
) pars
))
1235 (push (fortran-format nil item nil nil
) pars
))))
1237 (dotimes (k (length v
))
1240 (push "~/f2cl-lib::fortran-format/" pars
)
1241 (push (list (aref v k
)) pars
))
1245 (push (fortran-format nil
(list (aref v k
)) nil nil
)
1250 (push "~/f2cl-lib::fortran-format/" pars
)
1251 (push (list v
) pars
))
1255 (push (fortran-format nil
(list v
) nil nil
) pars
)))))
1256 ;;(format t "~S~%" (reverse pars))
1259 (let ((format-list (copy-tree format
))
1262 (map 'list
#'(lambda (x)
1263 (cond ((bigfloat:numberp x
)
1267 ((member x
'(t nil
))
1268 ;; Convert T and NIL to :T
1269 ;; and :F so we print out T
1270 ;; and F, respectively.
1281 (execute-format t stream format-list arg-list
)))))
1284 ;; Initialize a multi-dimensional array of character strings. I think
1285 ;; we need to do it this way to appease some picky compilers (like
1286 ;; CMUCL). The initial-element is needed to get rid of a warning
1287 ;; about the default initial element not being a simple
1288 ;; string. However, this initializes all elements of the array to
1289 ;; exactly the same string, so we loop over the entire array contents
1290 ;; and initialize each element with a string of the appropriate
1291 ;; length. The string is initialized with #\Space because it seems
1292 ;; that's what Fortran initializes it to.
1293 (defmacro f2cl-init-string
(dims len
&optional inits
)
1294 (let ((init (gensym (symbol-name '#:array-
)))
1295 (k (gensym (symbol-name '#:idx-
))))
1296 `(let ((,init
(make-array (* ,@dims
)
1297 :element-type
`(simple-array character
(,',@len
))
1298 :initial-element
(make-string ,@len
))))
1299 (dotimes (,k
(array-total-size ,init
))
1300 (setf (aref ,init
,k
)
1301 (make-string ,@len
:initial-element
#\Space
)))
1306 (push `(replace (aref ,init
,k
) ,val
) forms
)
1312 ;; This macro is supposed to set LHS to the RHS assuming that the LHS
1313 ;; is a Fortran CHARACTER type of length LEN.
1315 ;; Currently, converts the RHS to the appropriate length string and
1316 ;; assigns it to the LHS. However, this can generate quite a bit of
1317 ;; garbage. We might want to be a bit smarter and use loops to
1318 ;; replace the individual characters of the LHS with the appropriate
1319 ;; characters from the RHS.
1320 (defmacro f2cl-set-string
(lhs rhs
(string len
))
1321 (declare (ignore string
))
1324 ;; Assignment to a simple string.
1325 `(setf ,lhs
(f2cl-string ,rhs
,len
)))
1327 ;; Assignment to an array
1328 `(fset ,lhs
(f2cl-string ,rhs
,len
)))))
1330 (defun f2cl-string (string len
)
1331 ;; Create a string of the desired length by either appending spaces
1332 ;; or truncating the string.
1333 (let ((slen (length string
)))
1335 ;; Need to make a copy of the string, so we don't have
1336 ;; duplicated structure.
1339 ;; Truncate the string
1340 (subseq string
0 len
))
1342 ;; String is too short, so append some spaces
1343 (concatenate 'string string
(make-string (- len slen
) :initial-element
#\Space
))))))
1346 ;;; Strictly speaking, this is not part of Fortran, but so many
1347 ;;; Fortran packages use these routines, we're going to add them here.
1348 ;;; They're much easier to implement in Lisp than in Fortran!
1351 ;; DOUBLE-PRECISION MACHINE CONSTANTS
1352 ;; D1MACH( 1) = B**(EMIN-1), THE SMALLEST POSITIVE MAGNITUDE.
1353 ;; D1MACH( 2) = B**EMAX*(1 - B**(-T)), THE LARGEST MAGNITUDE.
1354 ;; D1MACH( 3) = B**(-T), THE SMALLEST RELATIVE SPACING.
1355 ;; D1MACH( 4) = B**(1-T), THE LARGEST RELATIVE SPACING.
1356 ;; D1MACH( 5) = LOG10(B)
1361 (1 least-positive-normalized-double-float
)
1362 (2 most-positive-double-float
)
1363 (3 #-
(or gcl ecl
) double-float-epsilon
1364 #+(or gcl ecl
) (scale-float (float #X10000000000001
1d0
) -
105))
1365 (4 (scale-float #-
(or gcl ecl
) double-float-epsilon
1366 #+(or gcl ecl
) (scale-float (float #X10000000000001
1d0
) -
105)
1368 (5 (log (float (float-radix 1d0
) 1d0
) 10d0
))))
1372 (1 least-positive-normalized-single-float
)
1373 (2 most-positive-single-float
)
1374 (3 single-float-epsilon
)
1375 (4 (scale-float single-float-epsilon
1))
1376 (5 (log (float (float-radix 1f0
)) 10f0
))))
1379 ;; This is the CMLIB version of I1MACH, the integer machine
1380 ;; constants subroutine originally developed for the PORT library.
1382 ;; I1MACH can be used to obtain machine-dependent parameters
1383 ;; for the local machine environment. It is a function
1384 ;; subroutine with one (input) argument, and can be called
1385 ;; as follows, for example
1389 ;; where I=1,...,16. The (output) value of K above is
1390 ;; determined by the (input) value of I. The results for
1391 ;; various values of I are discussed below.
1393 ;; I/O unit numbers.
1394 ;; I1MACH( 1) = the standard input unit.
1395 ;; I1MACH( 2) = the standard output unit.
1396 ;; I1MACH( 3) = the standard punch unit.
1397 ;; I1MACH( 4) = the standard error message unit.
1400 ;; I1MACH( 5) = the number of bits per integer storage unit.
1401 ;; I1MACH( 6) = the number of characters per integer storage unit.
1404 ;; assume integers are represented in the S-digit, base-A form
1406 ;; sign ( X(S-1)*A**(S-1) + ... + X(1)*A + X(0) )
1408 ;; where 0 .LE. X(I) .LT. A for I=0,...,S-1.
1409 ;; I1MACH( 7) = A, the base.
1410 ;; I1MACH( 8) = S, the number of base-A digits.
1411 ;; I1MACH( 9) = A**S - 1, the largest magnitude.
1413 ;; Floating-Point Numbers.
1414 ;; Assume floating-point numbers are represented in the T-digit,
1416 ;; sign (B**E)*( (X(1)/B) + ... + (X(T)/B**T) )
1418 ;; where 0 .LE. X(I) .LT. B for I=1,...,T,
1419 ;; 0 .LT. X(1), and EMIN .LE. E .LE. EMAX.
1420 ;; I1MACH(10) = B, the base.
1423 ;; I1MACH(11) = T, the number of base-B digits.
1424 ;; I1MACH(12) = EMIN, the smallest exponent E.
1425 ;; I1MACH(13) = EMAX, the largest exponent E.
1428 ;; I1MACH(14) = T, the number of base-B digits.
1429 ;; I1MACH(15) = EMIN, the smallest exponent E.
1430 ;; I1MACH(16) = EMAX, the largest exponent E.
1433 ;; What does the unit numbers really mean in Lisp? What do we
1436 ;; The standard input unit
1438 ;; The standard output unit
1440 ;; The standard punch unit
1442 ;; The standard error message unit
1445 ;; The number of bits per integer storage unit. What does this
1448 (integer-length most-positive-fixnum
))
1449 ;; The number of characters per integer storage unit. What does
1450 ;; this mean in Lisp?
1453 ;; The base of integers. Assume 2's complement
1455 ;; The number of base-2 digits. Assume fixnum size?
1456 (8 (integer-length most-positive-fixnum
))
1457 ;; The largest magnitude
1458 (9 most-positive-fixnum
)
1460 ;; Base of floating-poing representation
1461 (10 (float-radix 1f0
))
1462 ;; Number of digits in representation
1463 (11 (float-digits 1f0
))
1464 ;; Smallest exponent
1465 (12 (multiple-value-bind (frac exp sign
)
1466 (decode-float least-positive-normalized-single-float
)
1467 (declare (ignore frac sign
))
1470 (13 (multiple-value-bind (frac exp sign
)
1471 (decode-float most-positive-single-float
)
1472 (declare (ignore frac sign
))
1474 ;; Same for double-precision
1475 (14 (float-digits 1d0
))
1476 (15 (multiple-value-bind (frac exp sign
)
1477 (decode-float least-positive-normalized-double-float
)
1478 (declare (ignore frac sign
))
1480 (16 (multiple-value-bind (frac exp sign
)
1481 (decode-float most-positive-double-float
)
1482 (declare (ignore frac sign
))
1486 ;; F2cl cannot tell if a STOP statement is an error condition or just
1487 ;; the end of the program. So, by default, we signal a continuable
1488 ;; error. However, we give the user the option of silently returning
1490 (defvar *stop-signals-error-p
* nil
1491 "When non-NIL, STOP will signal an continuable error. Otherwise, STOP just returns")
1493 (defun stop (&optional arg
)
1495 (format cl
::*error-output
* "~A~%" arg
))
1496 (when *stop-signals-error-p
*
1497 (cerror "Continue anyway" "STOP reached")))
1499 (defmacro f2cl-copy-seq
(dst src dst-type src-type
)
1500 (flet ((copy-error ()
1501 (error "F2CL cannot copy arrays of element type ~A to ~A~%"
1502 src-type dst-type
)))
1503 (cond ((subtypep dst-type
'float
)
1504 ;; Copy to float array
1505 (cond ((subtypep src-type
'float
)
1506 `(replace ,dst
,src
))
1507 ((subtypep src-type
'complex
)
1508 ;; Copy complex to float by putting each real and
1509 ;; imaginary part into the float array, in order.
1510 (let ((idx (gensym "IDX-"))
1511 (el (gensym "EL-")))
1512 `(loop for
,idx of-type fixnum from
0 by
2 below
(length ,dst
)
1513 for
,el of-type
,src-type across
,src
1516 (setf (aref ,dst
,idx
) (realpart ,el
))
1517 (setf (aref ,dst
(1+ ,idx
)) (imagpart ,el
))))))
1520 ((subtypep dst-type
'complex
)
1521 ;; Copy to complex array
1522 (cond ((subtypep src-type
'float
)
1523 (let ((idx (gensym "IDX-"))
1524 (dst-idx (gensym "DST-IDX-")))
1525 `(loop for
,idx of-type fixnum from
0 by
2 below
(length ,src
)
1526 for
,dst-idx of-type fixnum from
0 below
(length ,dst
)
1528 (setf (aref ,dst
,dst-idx
) (complex (aref ,src
,idx
)
1529 (aref ,src
(1+ ,idx
)))))))
1530 ((subtypep src-type
'complex
)
1531 `(replace ,dst
,src
))
1537 (defmacro make-compatible-seq
(type array array-type
)
1538 (let ((element-type (second type
))
1539 (array-type (second array-type
)))
1540 (cond ((subtypep element-type
'float
)
1541 (cond ((subtypep array-type
'complex
)
1542 `(make-array (* 2 (length ,array
)) :element-type
',element-type
))
1544 `(make-array (length ,array
) :element-type
',element-type
))))
1545 ((subtypep element-type
'complex
)
1546 (cond ((subtypep array-type
'complex
)
1547 `(make-array (length ,array
) :element-type
',element-type
))
1549 `(make-array (ceiling (length ,array
) 2) :element-type
',element-type
))))
1551 (error "Don't know how to make an array with element-type ~A~%" element-type
)))))
1554 ;;;-------------------------------------------------------------------------
1557 ;;; $Id: macros.l,v 3fe93de3be82 2012/05/06 02:17:14 toy $
1559 ;;; Revision 1.117 2011/02/28 22:21:07 rtoy
1560 ;;; When opening an old file, we should set :if-exists to :overwrite to
1561 ;;; overwrite the file if written too.
1563 ;;; Revision 1.116 2011/02/20 20:51:04 rtoy
1564 ;;; Oops. STOP should signal an error if *STOP-SIGNALS-ERROR-P* is
1567 ;;; Revision 1.115 2010/12/28 00:06:52 rtoy
1568 ;;; Assert the type of the arg to fsqrt to be non-negative, excluding
1571 ;;; Revision 1.114 2010/05/17 01:42:14 rtoy
1573 ;;; o Need to know the actual type when making a compatible sequence.
1574 ;;; o Convert plain integer type to integer4 types, which is what Fortran
1575 ;;; would do. We don't want general Lisp integer type.
1578 ;;; o Change MAKE-COMPATIBLE-SEQ to be a macro.
1579 ;;; o Need to know the actual array type to create the correct type of
1582 ;;; Revision 1.113 2010/02/23 00:59:12 rtoy
1583 ;;; Support the Fortran capability of passing an array of one type
1584 ;;; to a routine expecting a different type. Currently only supports REAL
1585 ;;; and COMPLEX arrays (and their double precison versions).
1591 ;;; o Export new symbols f2cl-copy-seq and make-compatible-seq.
1594 ;;; o New variable *copy-array-parameter* for keeping track of the option
1595 ;;; for f2cl and f2cl-compile.
1596 ;;; o Update f2cl and f2cl-compile to recognize :copy-array-parameter.
1597 ;;; o Modify massage-arglist and generate-call-to-routine to handle the
1598 ;;; new :copy-array-parameter capability.
1601 ;;; o Fix issue where quoted elements were modified. They shouldn't be.
1602 ;;; o Fix issue where (array simple-float (*)) would get erroneously
1603 ;;; converted to (array simple-float (f2cl-lib:int-mul)). We want to
1604 ;;; leave bare * alone.
1607 ;;; o New macro f2cl-copy-seq to generate code to copy a sequence
1609 ;;; o New function to create a compatible array to support
1610 ;;; :copy-array-parameter.
1612 ;;; Revision 1.112 2009/01/08 12:57:19 rtoy
1614 ;;; o Export *STOP-SIGNALS-ERROR-P*
1617 ;;; o Add *STOP-SIGNALS-ERROR-P* to allow user to control whether STOP
1618 ;;; signals a continuable error or not. Default is to signal the
1621 ;;; Revision 1.111 2009/01/07 21:50:16 rtoy
1622 ;;; Use the fast rint-* functions for CMUCL with sse2 support.
1624 ;;; Revision 1.110 2009/01/07 21:42:45 rtoy
1625 ;;; Gcl doesn't recognize :compile-toplevel and friends. Use old style.
1627 ;;; Revision 1.109 2009/01/07 21:34:41 rtoy
1630 ;;; o Remove unused macro REXPT.
1631 ;;; o Remove duplicated function PROCESS-IMPLIED-DO.
1632 ;;; o Remove code that was commented out.
1634 ;;; Revision 1.108 2009/01/07 17:28:19 rtoy
1636 ;;; o Export new dfloat function, an alias for dble.
1637 ;;; o Merge some cleanups from Maxima.
1640 ;;; o Add dfloat to list of intrinsic functions.
1643 ;;; o Merge some cleanups and fixes from Maxima. Mostly for gcl and ecl.
1644 ;;; o Add implementation of dfloat.
1646 ;;; Revision 1.107 2009/01/07 02:22:00 rtoy
1647 ;;; Need to quit a repeated group if we're out of arguments to print.
1648 ;;; This prevents us from repeatedly print newlines and other strings when
1649 ;;; the repetition is more than the number of arguments we have left.
1651 ;;; Revision 1.106 2008/09/15 15:27:36 rtoy
1652 ;;; Fix serious bug in aint. aint(x) for x an integer was returning x-1
1653 ;;; (for positive x). It should have returned x.
1655 ;;; Revision 1.105 2008/09/10 18:53:49 rtoy
1656 ;;; The case where the arg was negative or zero was mishandled and ended
1657 ;;; up being printed using ~E. Should have been ~F.
1659 ;;; Revision 1.104 2008/08/22 21:27:43 rtoy
1660 ;;; Oops. Forgot one place to conditionalize on gcl.
1662 ;;; Revision 1.103 2008/08/21 20:16:49 rtoy
1663 ;;; Gcl doesn' like ~/ format specifier, so rearrange things so we don't
1664 ;;; use it. (Should we just do the same for every one?)
1666 ;;; Revision 1.102 2008/03/26 13:19:52 rtoy
1667 ;;; Lazily initialize the lun-hash table. *lun-hash* starts as an empty
1668 ;;; hash-table, and lun->stream will initialize units 5, 6, and t as
1671 ;;; Based on similar change in maxima to work around an issue with clisp
1672 ;;; where the predefined entries had closed streams.
1674 ;;; Revision 1.101 2008/03/08 12:49:08 rtoy
1675 ;;; Make :list-directed output be more like Fortran. There is quite a bit
1676 ;;; of variation between, say, g77 and Sun Fortran, so we pick something
1677 ;;; reasonably close. We have a mix of g77 and Sun Fortran output. Still
1678 ;;; needs some work.
1680 ;;; Revision 1.100 2008/03/07 23:15:01 rtoy
1681 ;;; Use ~? so we can control the format string to print out various
1682 ;;; objects for list-directed output.
1684 ;;; Revision 1.99 2008/03/06 21:20:41 rtoy
1685 ;;; Change the open mode from append to supersede. I think this makes
1686 ;;; more sense and seems to match g77 better.
1688 ;;; Revision 1.98 2008/03/06 20:04:10 rtoy
1689 ;;; Use ~G for list-directed I/O so that numbers come out reasonably.
1690 ;;; (F77 standard says E or F is used, depending on the magnitude of the
1691 ;;; number. The parameters for E and F are processor dependent as is the
1692 ;;; magnitude used to select between E or F. This is pretty close to how
1693 ;;; ~G works in Lisp.)
1695 ;;; Revision 1.97 2008/02/26 04:14:31 rtoy
1696 ;;; Explicitly check for T and NIL.
1698 ;;; Revision 1.96 2008/02/22 22:19:34 rtoy
1699 ;;; Use RCS Id as version.
1701 ;;; Revision 1.95 2008/02/22 22:13:18 rtoy
1702 ;;; o Add function F2CL-VERSION to get version info.
1703 ;;; o Add version string to each of the files so F2CL-VERSION can get the
1704 ;;; version info. The version string is basically the date of when the
1705 ;;; file was last checked in.
1707 ;;; Revision 1.94 2007/09/30 03:47:47 rtoy
1708 ;;; When we're out of formats, we restart with the last repeat spec.
1710 ;;; Revision 1.93 2007/09/28 22:01:08 rtoy
1711 ;;; First attempt at getting implied-do loops in data statements working
1712 ;;; with nested loops.
1715 ;;; o PARSE-DATA-IMPLIED-DO handles implied do loops even when the loops
1719 ;;; o Update PROCESS-IMPLIED-DO to handle the new forms returned by
1720 ;;; PARSE-DATA-IMPLIED-DO.
1721 ;;; o Don't create constants out of the initializer since we use POP to
1722 ;;; access them one by one.
1723 ;;; o Minor tweak for list-directed output to allow a slightly longer line
1724 ;;; length. This matches what g77 produces for one simple test case.
1726 ;;; Revision 1.92 2007/09/28 20:26:13 rtoy
1727 ;;; o For REWIND and CLOSE$, declare the result as ignorable.
1728 ;;; o For list-directed output, don't print out strings as an array with
1729 ;;; spaces between each element. Strings should go out as strings.
1731 ;;; Revision 1.91 2007/09/28 15:41:14 rtoy
1732 ;;; Some cleanup for list-directed output:
1734 ;;; o Complex numbers should be printed in the form (r, i), not #c(r, i)
1735 ;;; o Arrays should print out only the elements instead of #(...).
1737 ;;; Revision 1.90 2007/09/28 05:00:58 rtoy
1738 ;;; To support multidimensional arrays in implied do loops better, we need
1739 ;;; to pass the entire array bounds, including upper and lower limits so
1740 ;;; that array indexing can work.
1743 ;;; o Find the entire array bounds.
1744 ;;; o Don't use make-declaration to get the array type. Explicitly look
1745 ;;; through *explicit_vble_decls* to find the type. (Are there other
1746 ;;; places we need to look?)
1749 ;;; o Pass the entire list of array bounds to fref so we can handle
1750 ;;; multidimensional arrays.
1752 ;;; Revision 1.89 2007/09/27 14:56:39 rtoy
1753 ;;; When we run out of format specs, but there are still items to print,
1754 ;;; we go back and find the first repeat spec and start there.
1756 ;;; If there is no such thing, we just reuse the entire format spec. Not
1757 ;;; sure if this is right or if it's a bug. Maybe we should signal an
1760 ;;; Revision 1.88 2007/09/27 02:12:12 rtoy
1761 ;;; Support the L edit descriptor better.
1764 ;;; o Recognize the L descriptor and convert it to ~wA.
1767 ;;; o Convert T and NIL to :T and :F, respectively. When coupled with ~A,
1768 ;;; this prints as T and F, as desired.
1770 ;;; Revision 1.87 2007/09/26 13:11:06 rtoy
1771 ;;; Remove the unused FOREVER parameter from EXECUTE-FORMAT.
1773 ;;; Revision 1.86 2007/09/26 13:10:15 rtoy
1774 ;;; Better list-directed output.
1777 ;;; o For list-directed output (format is *), return :list-directed to
1778 ;;; tell format that we're using list-directed output. (The previous
1779 ;;; scheme didn't really work well.)
1782 ;;; o Add FLATTEN-LIST function
1783 ;;; o Don't output a newline for repeated items. We shouldn't do that.
1784 ;;; o Add support for :list-directed output. We recognize that and then
1785 ;;; just output all the args in a special way.
1787 ;;; Revision 1.85 2007/09/25 21:31:32 rtoy
1789 ;;; o Slight change in the format used for "*" format.
1790 ;;; o Change the repeatable descriptors to remove the repeat count if the
1791 ;;; count is 1. This was confusing the execute-format when determining
1792 ;;; when to print out newlines. This change applied to I, F, E, D, and
1796 ;;; o Handle printing of "repeat forever" loops better. An extra arg to
1797 ;;; EXECUTE-FORMAT tells us to repeat "forever".
1798 ;;; o Output a newline at the end of a repeated specification.
1800 ;;; Revision 1.84 2007/09/25 18:46:42 rtoy
1801 ;;; For repeated descriptors, we were printing a new line after each item
1802 ;;; instead of after all items had been printed. Output new line only
1803 ;;; once, when we're done.
1805 ;;; Revision 1.83 2007/09/25 18:17:50 rtoy
1806 ;;; Oops. We should always process #\: and exit only if there is more
1807 ;;; args to process.
1809 ;;; Revision 1.82 2007/09/25 17:31:05 rtoy
1811 ;;; o Return #\: when encountering a colon edit descriptor.
1814 ;;; o Recognize #\: and terminate processing if there are no arguments
1817 ;;; Revision 1.81 2007/09/23 20:51:43 rtoy
1818 ;;; Previous checkin changed how character strings are initialized.
1819 ;;; Modify code accordingly. (This needs to be rethought and made less
1822 ;;; Revision 1.80 2007/09/21 17:45:13 rtoy
1823 ;;; INDEX was calling SEARCH with the arguments in the wrong order.
1825 ;;; Revision 1.79 2007/09/20 21:27:12 rtoy
1826 ;;; Was not handling atoms correctly. This needs more work.
1828 ;;; Revision 1.78 2007/09/20 17:38:25 rtoy
1829 ;;; In ARRAY-INITIALIZE, we can't make a literal list of the data because
1830 ;;; the data might not be literal. (That is, the data might be constants
1831 ;;; from a parameter statement.)
1833 ;;; Revision 1.77 2007/06/18 15:50:16 rtoy
1834 ;;; Bug [ 1709300 ] unused key parameters
1836 ;;; o In %open-file, ignore UNIT, and produce an error if FORM is UNFORMATTED
1837 ;;; o In %close, produce an error if STATUS is specified.
1839 ;;; Revision 1.76 2006/12/01 04:23:43 rtoy
1843 ;;; o Cosmetic changes
1846 ;;; o Make code work with "modern"-mode lisps. (Ported from maxima.)
1848 ;;; Revision 1.75 2006/11/28 19:06:18 rtoy
1849 ;;; o Make sure the second arg to FSET-STRING is a string.
1850 ;;; o FCHAR was using the wrong function.
1851 ;;; o Cleanup FFORMAT so there are no compiler warnings about REPLACE
1852 ;;; being called on constant data. (This is probably a compiler bug in
1853 ;;; CMUCL, but we should get rid of the stuff ourselves, anyway, instead
1854 ;;; of depending on the compiler to do it for us.)
1856 ;;; Revision 1.74 2006/11/27 19:09:51 rtoy
1857 ;;; In some places in LAPACK, an array slice is taken where the slice
1858 ;;; exceeds the bounds of the array. However, the array is never
1859 ;;; accessed. What are we to do? We could modify the LAPACK routines
1860 ;;; (everywhere!) to check for this, or we can silently make array-slice
1861 ;;; make a 0-element array. If the array is then accessed, we should get
1862 ;;; an error at the point of access, not the point of creation.
1864 ;;; Revision 1.73 2006/11/21 22:05:03 rtoy
1865 ;;; Fix ichar to accept either a real character or (more likely) a
1868 ;;; Revision 1.72 2006/11/21 18:21:37 rtoy
1869 ;;; o Add CDABS and DCONJG functions.
1870 ;;; o Add some type declarations for DIMAG
1872 ;;; Revision 1.71 2006/05/02 22:12:02 rtoy
1874 ;;; o Try to make better declarations for variables defined in parameter
1875 ;;; statements. We'll declare them as (double-float 42d0 42d0) if the
1876 ;;; parameter was initialized to 42d0.
1877 ;;; o MAKE-DECLARATION updated to take an extra keyword argument to
1878 ;;; indicate if this is a parameter variable and to give the initial
1879 ;;; value of the parameter so we can make the appropriate declaration.
1880 ;;; o When initializing simple variables in data statements, try to bind
1881 ;;; the variable with the initial value instead binding a default 0 zero
1882 ;;; and setq'ing it later.
1885 ;;; o Change DEFTYPE for INTEGER4 to allow parameters so we can specify
1886 ;;; tight bounds if desired.
1888 ;;; Revision 1.70 2006/05/01 17:40:05 rtoy
1889 ;;; Change STOP to produce a continuable error instead of an error so that
1890 ;;; we can continue from the STOP statement, if we choose to. It's not
1891 ;;; necessarily an error in a converted program to reach a STOP statement.
1893 ;;; Revision 1.69 2006/04/27 17:44:01 rtoy
1895 ;;; o Export dimag, dcmplx, zsqrt
1898 ;;; o Add dcmplx, dimag, and zsqrt to the list of intrinsic function
1900 ;;; o When parsing "implicit none" statements, we don't modify
1901 ;;; *IMPLICIT_VBLE_DECLS*. I don't think it's needed and it can cause
1902 ;;; errors later on because :none is not a Lisp type.
1905 ;;; o Tell GET-FUN-ARG-TYPE about the result type of dcmplx, dsqrt, the
1906 ;;; complex*8 and complex*16 special functions.
1907 ;;; o ABS is an allowed lisp name. This gets rid of the spurious ABS$
1908 ;;; local variable whenever we use the ABS function.
1911 ;;; o Add implementations of dcmplx, dimag, and zsqrt. (We need to add
1914 ;;; Revision 1.68 2006/01/12 01:33:32 rtoy
1915 ;;; If status is not given or unknown, create the file if it doesn't
1918 ;;; Revision 1.67 2006/01/11 22:57:58 rtoy
1919 ;;; Add rudimentary support for opening files and reading from files.
1922 ;;; o Recognize and handle open, rewind, and close statements.
1925 ;;; o Update parser for read to handle unit numbers. Rudimentary support
1926 ;;; for implied-do lists too.
1927 ;;; o Add parser for open, rewind, and close statements.
1930 ;;; o Add functions and macros to handle opening, rewinding,
1931 ;;; and closing files. Needs more work still.
1933 ;;; Revision 1.66 2006/01/09 03:08:13 rtoy
1935 ;;; o Translate a Fortran STOP to be the stop function. Was just
1936 ;;; returning NIL, and this doesn't work so well.
1939 ;;; o Add STOP function. It prints out the any arg, and then signals an
1942 ;;; Revision 1.65 2006/01/09 00:37:43 rtoy
1944 ;;; o When looking for initializers, don't just remove initializers when
1945 ;;; the array is not a 1-D array. Keep them, and return a second value
1946 ;;; indicating if the array is 1-D or not.
1947 ;;; o MAKE-CHAR-DECL was not properly declaring and initializing 2-D
1948 ;;; arrays as 1-D arrays like we're supposed to. Compute the total size
1949 ;;; of the array if we can.
1952 ;;; o F2CL-INIT-STRING needs to make a 1-D array, even if the string array
1953 ;;; is multi-dimensional.
1955 ;;; Revision 1.64 2006/01/04 17:53:40 rtoy
1956 ;;; We were not correctly processing initialization of string arrays in
1957 ;;; data statements.
1960 ;;; o In PARSE-DATA1, return the entire list of initializers instead of
1961 ;;; just the first, in case we have an array of initializers.
1964 ;;; o In MERGE-DATA-AND-SAVE-INITS, we need to recognize the
1965 ;;; initialization of strings and such. We don't do anything special
1966 ;;; right now, like we do for arrays of numbers.
1967 ;;; o In INSERT-DECLARATIONS, we need to handle the case of REPLACE in the
1968 ;;; *data-init*'s. We assume it's been handled somewhere else, so
1969 ;;; there's nothing to do here.
1971 ;;; Revision 1.63 2005/05/19 15:06:24 rtoy
1972 ;;; Oops. make-label is in the f2cl-lib package.
1974 ;;; Revision 1.62 2005/05/16 15:50:25 rtoy
1975 ;;; o Replace single semicolons with multiple semicolons as appropriate.
1976 ;;; o GCL apparently doesn't like some declarations, so comment them out
1978 ;;; o GCL doesn't like the defparameter for *lun-hash*.
1979 ;;; o GCL doesn't seem to have least-positive-normalized-double-float, so
1980 ;;; make it the same as least-positive-double-float. Likewise for
1983 ;;; These changes come from maxima.
1985 ;;; Revision 1.61 2005/03/28 20:38:18 rtoy
1986 ;;; Make strings with an element-type of character instead of base-char,
1987 ;;; in case the Lisp implementation has unicode support.
1989 ;;; Revision 1.60 2004/09/01 14:17:57 rtoy
1990 ;;; atan2 takes single-float args, not double-float.
1992 ;;; Revision 1.59 2004/08/14 22:29:16 marcoxa
1993 ;;; Added an EVAL-WHEN to silence the LW compiler.
1995 ;;; Revision 1.58 2004/08/14 04:17:45 rtoy
1996 ;;; Need a definition for MAKE-LABEL.
1998 ;;; Revision 1.57 2003/11/23 14:10:11 rtoy
1999 ;;; FDO should not call function that are not in the F2CL-LIB package.
2000 ;;; Macros.l should be self-contained.
2002 ;;; Revision 1.56 2003/11/13 05:37:11 rtoy
2003 ;;; Add macro WITH-MULTI-ARRAY-DATA. Basically like WITH-ARRAY-DATA, but
2004 ;;; takes a list of array info so we don't get deeply nested code when
2005 ;;; there are lots of arrays.
2007 ;;; Keep WITH-ARRAY-DATA around for backward compatibility.
2009 ;;; Revision 1.55 2003/11/12 05:33:22 rtoy
2010 ;;; Macro to handle assigned gotos was wrong. Fix it.
2012 ;;; Revision 1.54 2003/09/25 03:43:43 rtoy
2013 ;;; Need to check for reserved names in the fdo macro. (I think.)
2015 ;;; Revision 1.53 2003/01/07 18:44:52 rtoy
2016 ;;; Add new implementations of aint. Speeds up mpnorm by a factor of 5 on
2019 ;;; Revision 1.52 2002/09/13 17:50:19 rtoy
2020 ;;; From Douglas Crosher:
2022 ;;; o Make this work with lower-case Lisps
2023 ;;; o Fix a few typos
2024 ;;; o Make a safer fortran reader.
2026 ;;; Revision 1.51 2002/06/30 13:08:51 rtoy
2027 ;;; Add some declarations to AINT so that CMUCL can completely inline the
2028 ;;; call to ftruncate.
2030 ;;; Revision 1.50 2002/05/05 23:41:17 rtoy
2031 ;;; Typo: extra paren.
2033 ;;; Revision 1.49 2002/05/05 23:38:47 rtoy
2034 ;;; The int-sub macro didn't handle things like (- 3 m m) correctly. It
2035 ;;; was returning (- 3 (- m m)) instead of (- (- 3 m) m)!
2037 ;;; Revision 1.48 2002/05/03 17:48:06 rtoy
2038 ;;; GCL doesn't have least-positive-normalized-{single/double}-float, so
2039 ;;; use just least-positive-{single/double}-float.
2041 ;;; Revision 1.47 2002/05/03 17:44:36 rtoy
2042 ;;; Replace row-major-aref with just aref because we don't need it and
2043 ;;; because gcl doesn't have it.
2045 ;;; Revision 1.46 2002/03/19 02:23:09 rtoy
2046 ;;; According to the rules of Fortran, the initializers in a DATA
2047 ;;; statement are supposed to be converted to match the type of the
2048 ;;; variable that is being initialized. Make it so by passing the
2049 ;;; variable type to the macro DATA-IMPLIED-DO so that the conversion can
2052 ;;; Revision 1.45 2002/03/18 23:34:16 rtoy
2053 ;;; Was not correctly handling some implied do loops containing multiple
2054 ;;; variables in the loop in data statements. Fix that and clean up some
2055 ;;; of the processing. (Should probably do this kind of work in the f2cl
2056 ;;; compiler instead of at runtime, but it's only done once at runtime, so
2057 ;;; it's not a big deal.)
2059 ;;; Revision 1.44 2002/03/11 16:44:00 rtoy
2060 ;;; o Remove an extra paren.
2061 ;;; o Indent FIND-ARRAY-DATA better.
2062 ;;; o Declare the iteration count to be of type INTEGER4.
2063 ;;; o Added macros INT-ADD, INT-SUB, INT-MUL to tell the compiler that the
2064 ;;; integer operation can't overflow. (First try.)
2065 ;;; o Tell the compiler that the result of truncate is an INTEGER4 in INT.
2067 ;;; Revision 1.43 2002/03/06 23:07:19 rtoy
2068 ;;; o Make INT return an integer4 type, not integer.
2069 ;;; o log10 was thinking it could generate complex result, but that's not
2070 ;;; true. Declare the arg correctly so the compiler knows it can't.
2072 ;;; Revision 1.42 2002/03/06 03:21:16 rtoy
2073 ;;; o Speed up FIND-ARRAY-DATA a little by declaring the offset to be a
2074 ;;; fixnum, which it has to be since it's an index to an array.
2075 ;;; o Remove the truncate/ftruncate-towards-zero functions.
2076 ;;; o For INT, AINT, and friends, TRUNCATE and FTRUNCATE are the right
2077 ;;; functions we want to use. (Stupid me!)
2078 ;;; o Update/correct some random comments.
2080 ;;; Revision 1.41 2002/02/17 15:55:29 rtoy
2081 ;;; o For all array accessors, wrap the offset calculations with (the
2082 ;;; fixnum ...) since they have to be anyway. Speeds up calculations
2084 ;;; o FREF takes an additional optional OFFSET arg to specify an offset
2085 ;;; for the new array slicing method.
2086 ;;; o Added WITH-ARRAY-DATA and FIND-ARRAY-DATA to support the new
2087 ;;; array-slicing method.
2088 ;;; o For FDO, add (the integer4 ...) for loop index calculations.
2089 ;;; o Add some more assertions for ISIGN and LOG10 to help the compiler
2090 ;;; generate better code.
2092 ;;; Revision 1.40 2002/02/10 03:43:51 rtoy
2093 ;;; Partial support for WRITE statements writing to a string instead of
2096 ;;; Revision 1.39 2002/02/09 15:59:26 rtoy
2097 ;;; o Add more and better comments
2098 ;;; o AINT was broken because it should accept any range of floats.
2099 ;;; o DIM and friends computed the wrong thing!
2100 ;;; o Change DPROD to convert to doubles first.
2101 ;;; o Some cleanup of MAX and MIN
2103 ;;; Revision 1.38 2002/02/08 23:38:36 rtoy
2104 ;;; Use ARRAY-TOTAL-SIZE to compute how many elements are in the slice
2105 ;;; instead of the f2cl declared/derived bounds so that we can dynamically
2106 ;;; change the size of the array. Useful for an array in a common block.
2108 ;;; Revision 1.37 2002/02/07 03:23:15 rtoy
2109 ;;; Add functions to initialize F2CL's Fortran I/O and to close all of
2110 ;;; F2CL's open units.
2112 ;;; Revision 1.36 2002/02/04 03:23:46 rtoy
2113 ;;; o Make *lun-hash* a defparameter instead of a defvar.
2114 ;;; o Fix up i1mach so that the unit numbers match *lun-hash*.
2116 ;;; Revision 1.35 2002/01/13 16:29:00 rtoy
2117 ;;; o This file is in the f2cl-lib package now
2118 ;;; o Deleted some unused code.
2119 ;;; o Moved *INTRINSIC-FUNCTION-NAMES* to f2cl1.l
2121 ;;; Revision 1.34 2002/01/06 23:11:04 rtoy
2122 ;;; o Rename *intrinsic_function_names* to use dashes.
2123 ;;; o Comment out some unused functions and macros.
2125 ;;; Revision 1.33 2001/04/30 15:38:12 rtoy
2126 ;;; Add a version of I1MACH.
2128 ;;; Revision 1.32 2001/04/26 17:49:19 rtoy
2129 ;;; o SIGN and DIM are Fortran generic instrinsics. Make it so.
2130 ;;; o Added D1MACH and R1MACH because they're very common in Fortran
2133 ;;; Revision 1.31 2001/02/26 15:38:23 rtoy
2134 ;;; Move *check-array-bounds* from f2cl1.l to macros.l since the generated
2135 ;;; code refers to it. Export this variable too.
2137 ;;; Revision 1.30 2000/08/30 17:00:42 rtoy
2138 ;;; o In EXECUTE-FORMAT, handle the case where the group is supposed to be
2139 ;;; repeated "forever" (as indicated by a repetition factor of T).
2140 ;;; o Remove some more unused code.
2142 ;;; Revision 1.29 2000/08/27 16:36:07 rtoy
2143 ;;; Clean up handling of format statements. Should handle many more
2144 ;;; formats correctly now.
2146 ;;; Revision 1.28 2000/08/07 19:00:47 rtoy
2147 ;;; Add type ARRAY-STRINGS to denote an array of strings.
2149 ;;; Revision 1.27 2000/08/03 13:45:53 rtoy
2150 ;;; Make FFORMAT1 handle lists that we get from implied do loops.
2152 ;;; The whole FFORMAT stuff needs to be rethought if we really want to
2153 ;;; support Fortran output.
2155 ;;; Revision 1.26 2000/08/01 22:10:41 rtoy
2156 ;;; o Try to make the Fortran functions to convert to integers work the
2157 ;;; way Fortran says they should.
2158 ;;; o Declaim most of the intrinsics as inline so we don't have an
2159 ;;; additional function call for simple things.
2160 ;;; o Add some compiler macros for Fortran max/min functions to call the
2161 ;;; Lisp max/min functions withouth using #'apply.
2162 ;;; o Try to declare the args to functions with branchs appropriately,
2163 ;;; even in the face of signed zeroes.
2165 ;;; Revision 1.25 2000/07/28 22:10:05 rtoy
2166 ;;; Remove unused var from ARRAY-SLICE.
2168 ;;; Revision 1.24 2000/07/28 17:09:13 rtoy
2169 ;;; o We are in the f2cl package now.
2170 ;;; o Remove the export expression.
2171 ;;; o // is now called F2CL-//, to prevent problems with the lisp variable
2173 ;;; o REAL is now called FREAL, to prevent problems with the lisp type
2176 ;;; Revision 1.23 2000/07/27 16:39:17 rtoy
2177 ;;; We want to be in the CL-USER package, not the USER package.
2179 ;;; Revision 1.22 2000/07/20 13:44:38 rtoy
2180 ;;; o Remove old fref macro
2181 ;;; o Add some comments
2182 ;;; o Add macro ARRAY-INITIALIZE to handle creating the appropriate for to
2183 ;;; give to make-array :initial-contents.
2185 ;;; Revision 1.21 2000/07/19 13:54:27 rtoy
2186 ;;; o Add the types ARRAY-DOUBLE-FLOAT, ARRAY-SINGLE-FLOAT, and
2188 ;;; o All arrays are 1-D now to support slicing of Fortran arrays
2190 ;;; o All arrays are in column-major order just like Fortran (and the
2191 ;;; opposite of Lisp). This is to support slicing of arrays. Modified
2192 ;;; FREF to support this by taking an extra arg for the dimensions of
2194 ;;; o Added macro ARRAY-SLICE to slice the array properly.
2195 ;;; o Optimized routine DMIN1 a bit. (Need to do that for more routines.)
2197 ;;; Revision 1.20 2000/07/14 15:50:59 rtoy
2198 ;;; Get rid of *dummy_var*. It's not used anymore.
2200 ;;; Revision 1.19 2000/07/13 16:55:34 rtoy
2201 ;;; To satisfy the Copyright statement, we have placed the RCS logs in
2202 ;;; each source file in f2cl. (Hope this satisfies the copyright.)
2204 ;;;-----------------------------------------------------------------------------