;;;; Template for configuration of *features* for STk -*-scheme-*-
;;; Copyright (C) 1991, 1992, 1993 Aubrey Jaffer.

;; Author Erick Gallesio (eg@unice.fr)

(require "unix")

;;; (software-type) should be set to the generic operating system type.
;;; UNIX, VMS, MACOS, AMIGA and MSDOS are supported.

(define (software-type) 'UNIX)

;;; (scheme-implementation-type) should return the name of the scheme
;;; implementation loading this file.

(define (scheme-implementation-type) '|STk|)

;;; (scheme-implementation-version) should return a string describing
;;; the version the scheme implementation loading this file.

(define (scheme-implementation-version) (version))

;;; (implementation-vicinity) should be defined to be the pathname of
;;; the directory where any auxillary files to your Scheme
;;; implementation reside.

(define (implementation-vicinity) "/usr/local/lib/stk/")

;;; (library-vicinity) should be defined to be the pathname of the
;;; directory where files of Scheme library functions reside.

(define library-vicinity
  (let ((library-path (or (getenv "SCHEME_LIBRARY_PATH") "/usr/local/lib/slib/")))
    (lambda () library-path)))

;;; *FEATURES* should be set to a list of symbols describing features
;;; of this implementation.  Suggestions for features are:

(define *features*
      '(
	source				;can load scheme source files
					;(slib:load-source "filename")
	compiled			;can load compiled files
					;(slib:load-compiled "filename")
	rev4-report			;conforms to
;	rev3-report			;conforms to
;	ieee-p1178			;conforms to
;	sicp				;runs code from Structure and
					;Interpretation of Computer
					;Programs by Abelson and Sussman.
	rev4-optional-procedures	;LIST-TAIL, STRING->LIST,
					;LIST->STRING, STRING-COPY,
					;STRING-FILL!, LIST->VECTOR,
					;VECTOR->LIST, and VECTOR-FILL!
;	rev3-procedures			;LAST-PAIR, T, and NIL
;	rev2-procedures			;SUBSTRING-MOVE-LEFT!,
					;SUBSTRING-MOVE-RIGHT!,
					;SUBSTRING-FILL!,
					;STRING-NULL?, APPEND!, 1+,
					;-1+, <?, <=?, =?, >?, >=?
	multiarg/and-			;/ and - can take more than 2 args.
	multiarg-apply			;APPLY can take more than 2 args.
;	rationalize
	delay				;has DELAY and FORCE
	with-file			;has WITH-INPUT-FROM-FILE and
					;WITH-OUTPUT-FROM-FILE
	string-port			;has CALL-WITH-INPUT-STRING and
					;CALL-WITH-OUTPUT-STRING
;	transcript			;TRANSCRIPT-ON and TRANSCRIPT-OFF
;	char-ready?
;	macro				;has R4RS high level macros
;	defmacro			;has Common Lisp DEFMACRO
	eval				;SLIB:EVAL is single argument eval
;	record				;has user defined data structures
;	values				;proposed multiple values
	dynamic-wind			;proposed dynamic-wind
	ieee-floating-point		;conforms to
	full-continuation		;can return multiple times
;	object-hash			;has OBJECT-HASH

;	sort				; commented because icomplete
;	queue				;queues
;	pretty-print
;	object->string
;	format
;	compiler			;has (COMPILER)
	ed				;(ED) is editor
	system				;posix (system <string>)
	getenv				;posix (getenv <string>)
;	program-arguments		;returns list of strings (argv)
;	Xwindows			;X support
;	curses				;screen management package
;	termcap				;terminal description package
;	terminfo			;sysV terminal description
	))

;;; (OUTPUT-PORT-WIDTH <port>)
(define (output-port-width . arg) 79)

;;; (OUTPUT-PORT-HEIGHT <port>)
(define (output-port-height . arg) 24)

;;; (TMPNAM) makes a temporary file name.
(define tmpnam (let ((cntr 100))
		 (lambda () (set! cntr (+ 1 cntr))
			 (string-append "slib_" (number->string cntr)))))

;;; (DELETE-FILE <string>)
(define (delete-file f) (system (format #f "/bin/rm ~A" f)))

;;; FORCE-OUTPUT flushes any pending output on optional arg output port
;;; use this definition if your system doesn't have such a procedure.
(define (force-output . arg) (apply flush arg))

;;; CHAR-CODE-LIMIT is one greater than the largest integer which can
;;; be returned by CHAR->INTEGER.
(define char-code-limit 256)

;;; MOST-POSITIVE-FIXNUM is used in modular.scm
(define most-positive-fixnum #x0fffffff)

;;; If your implementation provides eval SLIB:EVAL is single argument
;;; eval using the top-level (user) environment.
(define slib:eval eval)

;;; If your implementation provides R4RS macros:
;(define macro:eval slib:eval)
;(define macro:load load)

(define *macros* '())

(define-macro (defmacro name args . body)
  `(begin
     (define-macro (,name ,@args) ,@body)
     (set! *macros* (cons ,name *macros*))))


(define (defmacro? m) (and (memv m *macros*) #t))

(define macroexpand-1 MACRO-EXPAND-1)
(define macroexpand   MACRO-EXPAND)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define gentemp   GENSYM)
(define base:eval slib:eval)

(define (defmacro:eval x) (base:eval (defmacro:expand* x)))
(define (defmacro:expand* x)
  (require 'defmacroexpand) (apply defmacro:expand* x '()))

(define (defmacro:load <pathname>)
  (slib:eval-load <pathname> defmacro:eval))

(define (slib:eval-load <pathname> evl)
  (if (not (file-exists? <pathname>))
      (set! <pathname> (string-append <pathname> (scheme-file-suffix))))
  (call-with-input-file <pathname>
    (lambda (port)
      (let ((old-load-pathname *load-pathname*))
	(set! *load-pathname* <pathname>)
	(do ((o (read port) (read port)))
	    ((eof-object? o))
	  (evl o))
	(set! *load-pathname* old-load-pathname)))))

;;; define an error procedure for the library
(define (slib:error . args)
  (error (apply string-append (map (lambda (x) (format #f " ~a" x)) args))))


;;; define these as appropriate for your system.
(define slib:tab 	(integer->char 9))
(define slib:form-feed  (integer->char 12))

;;; Define these if your implementation's syntax can support it and if
;;; they are not already defined.
(define -1+ 1-)

(define in-vicinity string-append)

;;; Define SLIB:EXIT to be the implementation procedure to exit or
;;; return if exitting not supported.
(define slib:exit exit)

;;; Here for backward compatability
(define scheme-file-suffix
  (let ((suffix (case (software-type)
		  ((NOSVE) "_scm")
		  (else ".scm"))))
    (lambda () suffix)))

;;; (SLIB:LOAD-SOURCE "foo") should load "foo.scm" or with whatever
;;; suffix all the module files in SLIB have.  See feature 'SOURCE.

(define slib:load-source LOAD)

;;; (SLIB:LOAD-COMPILED "foo") should load the file that was produced
;;; by compiling "foo.scm" if this implementation can compile files.
;;; See feature 'COMPILED.

(define slib:load-compiled load)

;;;
;;; Retain original require/provide before loading "require.scm"
;;;
(define stk:require require)
(define stk:provide provide)
(define stk:provided? provided?)

(define slib:load slib:load-source)
(slib:load (in-vicinity (library-vicinity) "require"))


;;;
;;; Redefine require/provide so that symbols use SLIB one and strings use STk one
;;;

(define require
  (let ((slib:require require))
    (lambda (item)
      ((if (symbol? item) slib:require stk:require) item ))))

(define provide
  (let ((slib:provide provide))
    (lambda (item)
      ((if (symbol? item) slib:provide stk:provide) item))))

(define provided?
  (let ((slib:provided? provided?))
    (lambda (item)
      ((if (symbol? item) slib:provided? stk:provided?) item))))
