;;; -*- Mode: lisp -*-

;;; This defsystem is used to convert the Fortran code to lisp.
;;;
;;; You need a copy of f2cl (see clocc.sourceforge.net) for this to
;;; work, of course.  Once you have that, you can convert the Fortran
;;; code to Lisp.
;;;
;;; If you add or modify any Fortran file, it is probably best to use
;;; (mk:oos "slatec" :compile :force t) to convert the code.  This is
;;; because f2cl uses knowledge of calling conventions of a known
;;; function to generate the call to that function.  If the function
;;; is not known, then the call could inefficient at best or erroneous
;;; at worst.
;;;
;;; This also means that you should get the file dependencies right so
;;; that mk:defsys will compile the files in the right order.

;;; Define a new language for defsys to use.
(mk:define-language :f2cl
    :compiler #'f2cl:f2cl
    :loader #'identity
    :source-extension "f"
    :binary-extension "lisp")

(mk:defsystem "slatec"
  :source-extension "f"
  :binary-extension "lisp"
  :components
  ((:module xermsg
	    :source-pathname "fortran"
	    :binary-pathname "."
	    :language :f2cl
	    :compiler-options (:array-slicing nil
			       :array-type :simple-array
			       :float-format double-float
			       :package :slatec)
	    :compile-only t
	    :components
	    (
	     (:file "fdump")
	     (:file "j4save")
	     (:file "xgetua")
	     (:file "xermsg"
		    :depends-on ("fdump" "j4save" "xercnt" "xerhlt" "xerprn" "xersve"))
	     (:file "xercnt")
	     (:file "xerhlt")
	     (:file "xerprn"
		    :depends-on ("xgetua"))
	     (:file "xersve"
		    :depends-on ("j4save"))))
   (:module fortran
	    :source-pathname "fortran"
	    :binary-pathname "."
	    :language :f2cl
	    :compiler-options (:array-slicing nil
			       :array-type :simple-array
			       :float-format double-float
			       :package :slatec)
	    :depends-on ("xermsg")
	    :compile-only t
	    :components
	    (
	     (:file "initds")
	     (:file "dcsevl")
	     
	     ;; Gamma function
	     (:file "d9lgmc"
		    :depends-on ("dcsevl" "initds"))
	     (:file "dgamlm")
	     (:file "dgamma"
		    :depends-on ("d9lgmc" "dcsevl" "dgamlm" "initds"))
	     (:file "dgamln")
	     (:file "dlngam"
		    :depends-on ("d9lgmc" "dgamma"))
	     
	     ;; Bessel J functions for real arg and order
	     (:file "d9b0mp"
		    :depends-on ("dcsevl" "initds"))
	     (:file "d9b1mp"
		    :depends-on ("dcsevl" "initds"))
	     (:file "dbesj0"
		    :depends-on ("d9b0mp" "dcsevl" "initds"))
	     (:file "dbesj1"
		    :depends-on ("d9b1mp" "dcsevl" "initds"))
	     (:file "djairy")
	     (:file "dasyjy"
		    :compiler-options (:array-slicing nil
				       :array-type :array
				       :float-format double-float
				       :package :slatec))
	     (:file "dbesj"
		    :depends-on ("dasyjy" "djairy" "dlngam")
		    :compiler-options (:array-slicing t
				       :array-type :simple-array
				       :float-format double-float
				       :package :slatec))
	     (:file "dbsynu"
		    :depends-on ("dgamma"))

	     (:file "dyairy")

	     
	     ;; Bessel J function for complex arg and real order.
	     (:file "zabs")
	     (:file "zacai"
		    :depends-on ("zabs" "zasyi" "zbknu" "zmlri" "zs1s2" "zseri"))
	     (:file "zairy"
		    :depends-on ("zabs" "zacai" "zbknu" "zexp" "zsqrt"))
	     (:file "zasyi"
		    :depends-on ("zabs" "zdiv" "zexp" "zmlt" "zsqrt"))
	     (:file "zbesj"
		    :depends-on ("zabs" "zbinu"))
	     (:file "zbinu"
		    :depends-on ("zabs" "zasyi" "zbuni" "zmlri" "zseri" "zuoik" "zwrsk"))
	     (:file "zbknu"
		    :depends-on ("dgamln" "zabs" "zdiv" "zexp" "zkscl"
					  "zlog" "zmlt" "zshch" "zsqrt" "zuchk"))
	     (:file "zbuni"
		    :depends-on ("zabs" "zuni1" "zuni2"))
	     (:file "zdiv")
	     (:file "zexp")
	     (:file "zkscl"
		    :depends-on ("zabs" "zlog" "zuchk"))
	     (:file "zlog"
		    :depends-on ("zabs"))
	     (:file "zmlri"
		    :depends-on ("dgamln" "zabs" "zexp" "zlog" "zmlt"))
	     (:file "zmlt")
	     (:file "zrati"
		    :depends-on ("zabs" "zdiv"))
	     (:file "zs1s2"
		    :depends-on ("zabs" "zexp" "zlog"))
	     (:file "zseri"
		    :depends-on ("dgamln" "zabs" "zdiv" "zlog" "zmlt" "zuchk"))
	     (:file "zshch")
	     (:file "zsqrt" :depends-on ("zabs"))
	     (:file "zuchk")
	     (:file "zunhj"
		    :depends-on ("zabs" "zdiv" "zlog" "zsqrt"))
	     (:file "zuni1"
		    :depends-on ("zabs" "zuchk" "zunik" "zuoik"))
	     (:file "zuni2"
		    :depends-on ("zabs" "zairy" "zuchk" "zunhj" "zuoik"))
	     (:file "zunik"
		    :depends-on ("zdiv" "zlog" "zsqrt"))
	     (:file "zuoik"
		    :depends-on ("zabs" "zlog" "zuchk" "zunhj" "zunik"))
	     (:file "zwrsk"
		    :depends-on ("zabs" "zbknu" "zrati"))

	     ;; Bessel Y functions for real or complex arg and real order
	     (:file "dbesy0"
		    :depends-on ("d9b0mp" "dbesj0" "dcsevl" "initds"))
	     (:file "dbesy1"
		    :depends-on ("d9b1mp" "dbesj1" "dcsevl" "initds"))
	     (:file "dbesy"
		    :depends-on ("dasyjy" "dbesy0" "dbesy1" "dbsynu" "dyairy"))
	     (:file "dbsynu"
		    :depends-on ("dgamma"))
	     (:file "dyairy")
	     
	     (:file "zbesy"
		    :depends-on ("zbesh"))
	     (:file "zbesh"
		    :depends-on ("zabs" "zacon" "zbknu" "zbunk" "zuoik"))
	     (:file "zacon"
		    :depends-on ("zabs" "zbinu" "zbknu" "zmlt" "zs1s2"))
	     (:file "zbunk"
		    :depends-on ("zunk1" "zunk2"))
	     (:file "zunk1"
		    :compiler-options (:array-slicing t
				       :float-format double-float
				       :package :slatec)
		    :depends-on ("zabs" "zs1s2" "zuchk" "zunik"))
	     (:file "zunk2"
		    :depends-on ("zabs" "zairy" "zs1s2" "zuchk" "zunhj"))

	     ;; Bessel I functions for real or complex arg and real order
	     (:file "dbsi0e"
		    :depends-on ("dcsevl" "initds"))
	     (:file "dbsi1e"
		    :depends-on ("dcsevl" "initds"))
	     (:file "dbesi0"
		    :depends-on ("dbsi0e" "dcsevl" "initds"))
	     (:file "dbesi1"
		    :depends-on ("dbsi1e" "dcsevl" "initds"))
	     (:file "dasyik"
		    :compiler-options (:array-slicing nil
				       :array-type :array
				       :float-format double-float
				       :package :slatec))
	     (:file "dbesi"
		    :depends-on ("dasyik" "dlngam")
		    :compiler-options (:array-slicing t
				       :array-type :array
				       :float-format double-float
				       :package :slatec))
	     (:file "zbesi"
		    :depends-on ("zabs" "zbinu"))

	     ;; Bessel K functions
	     (:file "dbesk0"
		    :depends-on ("dbesi0" "dbsk0e" "dcsevl" "initds"))
	     (:file "dbsk0e"
		    :depends-on ("dbesi0" "dcsevl" "initds"))
	     (:file "dbesk1"
		    :depends-on ("dbesi1" "dbsk1e" "dcsevl" "initds"))
	     (:file "dbsk1e"
		    :depends-on ("dbesi1" "dcsevl" "initds"))
	     (:file "dbesk"
		    :depends-on ("dasyik" "dbesk0" "dbesk1" "dbsk0e" "dbsk1e" "dbsknu"))
	     (:file "dbsknu"
		    :depends-on ("dgamma"))
	     (:file "zbesk"
		    :depends-on ("zabs" "zacon" "zbknu" "zbunk" "zuoik"))
	     
	     ;; Airy functions
	     (:file "d9aimp"
		    :depends-on ("dcsevl" "initds"))
	     (:file "daie"
		    :depends-on ("d9aimp" "dcsevl" "initds"))
	     (:file "dai"
		    :depends-on ("d9aimp" "daie" "dcsevl" "initds"))
	     (:file "dbie"
		    :depends-on ("d9aimp" "dcsevl" "initds"))
	     (:file "dbi"
		    :depends-on ("d9aimp" "dbie" "dcsevl" "initds"))
	     (:file "zbiry"
		    :depends-on ("zabs" "zbinu" "zdiv" "zsqrt"))

	     ;; Error functions
	     (:file "derf"
		    :depends-on ("dcsevl" "derfc" "initds"))
	     (:file "derfc"
		    :depends-on ("dcsevl" "initds"))
	     
	     ;; Exponential integrals
	     (:file "de1"
		    :depends-on ("dcsevl" "initds"))
	     (:file "dei"
		    :depends-on ("de1"))
	     ;; Spence's function, related to dilogarithm
	     (:file "dspenc"
		    :depends-on ("d9upak"))
	     (:file "d9upak")
	     ))
   (:module quadpack
	    :source-pathname "fortran"
	    :binary-pathname "."
	    :language :f2cl
	    ;; These are appropriate defaults for quadpack because
	    ;; some of the routines slice an array and pass it as an
	    ;; argument to other routines.
	    ;;
	    ;; If we want to make the routines faster, array-slicing
	    ;; and array-type should be overridden in the individual
	    ;; files.
	    :compiler-options (:array-slicing t
			       :array-type :array
			       :float-format double-float
			       :package :slatec)
	    :compile-only t
	    :depends-on ("xermsg")
	    :components
	      (
	       ;; Support
	       (:file "dqwgtf")
	       (:file "dqcheb")
	       (:file "dqk15w")
	       (:file "dqwgts")
	       (:file "dqwgtc")
	       (:file "dgtsl")
	       ;;(:file "xermsg")
	       
	       ;; Core integration routines
	       (:file "dqk15")
	       (:file "dqk31")
	       (:file "dqk41")
	       (:file "dqk51")
	       (:file "dqk61")
	       (:file "dqk21")
	       (:file "dqk15i")
	       (:file "dqelg")
	       (:file "dqpsrt")
	       (:file "dqc25s"
		      :depends-on ("dqcheb" "dqk15w"))
	       (:file "dqmomo")
	       (:file "dqc25c"
		      :depends-on ("dqcheb"
				   "dqk15w"))
	       (:file "dqc25f"
		      :depends-on ("dgtsl"
				   "dqcheb"
				   "dqk15w"
				   "dqwgtf"))
	       ;; Basic integrators
	       (:file "dqage"
		      :depends-on ("dqk15"
				   "dqk31"
				   "dqk41"
				   "dqk51"
				   "dqk61"
				   "dqk21"
				   "dqpsrt"))
	       (:file "dqagie"
		      :depends-on ("dqelg"
				   "dqk15i"
				   "dqpsrt"))
	       (:file "dqagpe"
		      :depends-on ("dqelg"
				   "dqpsrt"
				   "dqk21"
				   ))
	       (:file "dqagse"
		      :depends-on ("dqk21"
				   "dqelg"
				   "dqpsrt"))
	       (:file "dqawfe"
		      :depends-on ("dqagie"
				   "dqawoe"
				   "dqelg")
		      ;; If your defsystem doesn't support :compiler-options, use this:
		      ;; :language :f2cl-no-slice
		      ;; If your defsystem does support :compiler-options, use this:
		      :compiler-options (:array-slicing nil
					 :array-type :array
					 :float-format double-float
					 :package :slatec)
		      )
	       (:file "dqawoe"
		      :depends-on ("dqc25f"
				   "dqpsrt"
				   "dqelg"))
	       (:file "dqawse"
		      :depends-on ("dqc25s"
				   "dqmomo"
				   "dqpsrt"))
	       (:file "dqawce"
		      :depends-on ("dqc25c"
				   "dqpsrt"))
	       ;; Simplified interface routines
	       (:file "dqng")
	       (:file "dqag"
		      :depends-on ("dqage"))
	       (:file "dqags"
		      :depends-on ("dqagse"))
	       (:file "dqagi"
		      :depends-on ("dqagie"))
	       (:file "dqawf"
		      :depends-on ("dqawfe"))
	       (:file "dqawo"
		      :depends-on ("dqawoe"))
	       (:file "dqaws"
		      :depends-on ("dqawse"))
	       (:file "dqawc"
		      :depends-on ("dqawce")))
	    )))
