diff options
Diffstat (limited to 'jscheme.init')
-rw-r--r-- | jscheme.init | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/jscheme.init b/jscheme.init new file mode 100644 index 0000000..88c1623 --- /dev/null +++ b/jscheme.init @@ -0,0 +1,478 @@ +;;; "jscheme.init" SLIB Initialization for JScheme -*-scheme-*- +;;; Author: Aubrey Jaffer +;;; Additions by Ken Anderson. +;;; This code is in the public domain. + +;;; JScheme support of for the SLIB Scheme library. + +;;; The easiest way to get things going is to download the slib.zip to +;;; the lib directory and invoke JScheme with a script like this (UNIX): + +;;; java -classpath "lib/jscheme.jar:lib/slib.zip" jscheme.REPL slib/jscheme.init "$@" + +;;; AGJ: This line works on my RedHat-9.0 system: +;;; java -cp src:/usr/local/share/java/jscheme.jar:/usr/local/lib/slib jscheme.REPL jscheme.init + +;;; Alternatively, set the location of the slib directory using the +;;; -D SCHEME_LIBRARY_PATH=... system property. + +;;; Let me know, if there is a problem with a module you'd like to use +;;; (kanderson@bbn.com). + +;;@ (software-type) should be set to the generic operating system type. +;;; UNIX, VMS, MACOS, AMIGA and MS-DOS are supported. +;; (define (software-type) 'UNIX) +(define (software-type) + (if (.startsWith (System.getProperty "os.name") "Windows") + 'MS-DOS + 'UNIX)) + +;;@ (scheme-implementation-type) should return the name of the scheme +;;; implementation loading this file. +(define (scheme-implementation-type) 'JScheme) + +;;@ (scheme-implementation-home-page) should return a (string) URI +;;; (Uniform Resource Identifier) for this scheme implementation's home +;;; page; or false if there isn't one. +(define (scheme-implementation-home-page) "http://jscheme.sourceforge.net") + +;;@ (scheme-implementation-version) should return a string describing +;;; the version the scheme implementation loading this file. +(define (scheme-implementation-version) "6.2") + +;;@ (implementation-vicinity) should be defined to be the pathname of +;;; the directory where any auxillary files to your Scheme +;;; implementation reside. +(define implementation-vicinity + (let ((implvic (case (software-type) + ((MS-DOS) "C:\\TEMP\\") + (else "/tmp/")))) + (lambda () implvic))) + +(define (getenv path) + (define prop (System.getProperty path)) + (and (not (eq? prop #null)) prop)) + +(define (slib.zip-on-classpath?) + (let loop ((urls (vector->list (.getURLs (Import.getClassLoader))))) + (if (null? urls) #f + (or (.endsWith (.getFile (car urls)) "slib.zip") + (loop (cdr urls)))))) + +;;@ (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 + ;; Use this getenv if your implementation supports it. + (getenv "SCHEME_LIBRARY_PATH") + (and (or (slib.zip-on-classpath?) + (not (eq? #null (Scheme.openResource "slib/require.scm")))) + "slib/") + ;; Use this path if your scheme does not support GETENV + ;; or if SCHEME_LIBRARY_PATH is not set. + (case (software-type) + ((UNIX) "/usr/local/lib/slib/") + ((VMS) "lib$scheme:") + ((MS-DOS) "C:\\SLIB\\") + (else ""))))) + (lambda () library-path))) + +;;@ (home-vicinity) should return the vicinity of the user's HOME +;;; directory, the directory which typically contains files which +;;; customize a computer environment for a user. +(define (home-vicinity) + (define home (or (getenv "HOME") (getenv "user.home"))) + (and home + (case (software-type) + ((UNIX COHERENT MS-DOS) ;V7 unix has a / on HOME + (if (eqv? #\/ (string-ref home (+ -1 (string-length home)))) + home + (string-append home "/"))) + (else home)))) +;@ +(define in-vicinity string-append) +;@ +(define (user-vicinity) + (case (software-type) + ((VMS) "[.]") + (else ""))) + +(define *load-pathname* #f) +;@ +(define vicinity:suffix? + (let ((suffi + (case (software-type) + ((AMIGA) '(#\: #\/)) + ((MACOS THINKC) '(#\:)) + ((MS-DOS WINDOWS ATARIST OS/2) '(#\\ #\/)) + ((NOSVE) '(#\: #\.)) + ((UNIX COHERENT PLAN9) '(#\/)) + ((VMS) '(#\: #\])) + (else + (slib:warn "require.scm" 'unknown 'software-type (software-type)) + "/")))) + (lambda (chr) (and (memv chr suffi) #t)))) +;@ +(define (pathname->vicinity pathname) + (let loop ((i (- (string-length pathname) 1))) + (cond ((negative? i) "") + ((vicinity:suffix? (string-ref pathname i)) + (substring pathname 0 (+ i 1))) + (else (loop (- i 1)))))) +(define (program-vicinity) + (if *load-pathname* + (pathname->vicinity *load-pathname*) + (slib:error 'program-vicinity " called; use slib:load to load"))) +;@ +(define sub-vicinity + (case (software-type) + ((VMS) (lambda + (vic name) + (let ((l (string-length vic))) + (if (or (zero? (string-length vic)) + (not (char=? #\] (string-ref vic (- l 1))))) + (string-append vic "[" name "]") + (string-append (substring vic 0 (- l 1)) + "." name "]"))))) + (else (let ((*vicinity-suffix* + (case (software-type) + ((NOSVE) ".") + ((MACOS THINKC) ":") + ((MS-DOS WINDOWS ATARIST OS/2) "\\") + ((UNIX COHERENT PLAN9 AMIGA) "/")))) + (lambda (vic name) + (string-append vic name *vicinity-suffix*)))))) +;@ +(define (make-vicinity <pathname>) <pathname>) +;@ +(define with-load-pathname + (let ((exchange + (lambda (new) + (let ((old *load-pathname*)) + (set! *load-pathname* new) + old)))) + (lambda (path thunk) + (let* ((old (exchange path)) + (val (thunk))) + (exchange old) + val)))) + +;;@ *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") + vicinity + srfi-59 + + ;; Scheme report features + ;; R5RS-compliant implementations should provide all 9 features. + +;;; r5rs ;conforms to + eval ;R5RS two-argument eval + values ;R5RS multiple values +;;; dynamic-wind ;R5RS dynamic-wind +;;; macro ;R5RS high level macros + delay ;has DELAY and FORCE + multiarg-apply ;APPLY can take more than 2 args. +;;; char-ready? +;;; KRA 23DEC03: JScheme is missing: vector-fill! string-copy string-fill! +;;; rev4-optional-procedures ;LIST-TAIL, STRING-COPY, + ;STRING-FILL!, and VECTOR-FILL! + + ;; These four features are optional in both R4RS and R5RS + +;;; multiarg/and- ;/ and - can take more than 2 args. +;;; rationalize +;;; transcript ;TRANSCRIPT-ON and TRANSCRIPT-OFF +;;; with-file ;has WITH-INPUT-FROM-FILE and + ;WITH-OUTPUT-TO-FILE + + r4rs ;conforms to + +;;; ieee-p1178 ;conforms to + +;;; r3rs ;conforms to + +;;; rev2-procedures ;SUBSTRING-MOVE-LEFT!, + ;SUBSTRING-MOVE-RIGHT!, + ;SUBSTRING-FILL!, + ;STRING-NULL?, APPEND!, 1+, + ;-1+, <?, <=?, =?, >?, >=? +;;; object-hash ;has OBJECT-HASH + +;;; full-continuation ;can return multiple times + ieee-floating-point ;conforms to IEEE Standard 754-1985 + ;IEEE Standard for Binary + ;Floating-Point Arithmetic. + + ;; Other common features + +;;; srfi ;srfi-0, COND-EXPAND finds all srfi-* +;;; sicp ;runs code from Structure and + ;Interpretation of Computer + ;Programs by Abelson and Sussman. + defmacro ;has Common Lisp DEFMACRO +;;; record ;has user defined data structures +;;; string-port ;has CALL-WITH-INPUT-STRING and + ;CALL-WITH-OUTPUT-STRING +;;; sort +;;; pretty-print +;;; object->string +;;; format ;Common-lisp output formatting +;;; trace ;has macros: TRACE and UNTRACE +;;; compiler ;has (COMPILER) +;;; ed ;(ED) is editor +;;; system ;posix (system <string>) + getenv ;posix (getenv <string>) +;;; program-arguments ;returns list of strings (argv) + current-time ;returns time in seconds since 1/1/1970 + + ;; Implementation Specific features + + )) + +;;@ (OUTPUT-PORT-WIDTH <port>) +(define (output-port-width . arg) 79) + +;;@ (OUTPUT-PORT-HEIGHT <port>) +(define (output-port-height . arg) 24) + +;;@ (CURRENT-ERROR-PORT) +(define current-error-port + (let ((port (current-output-port))) + (lambda () port))) + +;;@ (TMPNAM) makes a temporary file name. +(define tmpnam (let ((cntr 100)) + (lambda () (set! cntr (+ 1 cntr)) + (string-append "slib_" (number->string cntr))))) + +;;@ (FILE-EXISTS? <string>) +;;; KRA 24DEC03: This allows load to find a file, resource or URL, but +;;; the rest of SLIB assumes f names a file. +(define (file-exists? f) (not (eq? (Scheme.open f) #null))) +;;;(define (file-exists? f) (.exists (java.io.File. f))) + +;;@ (DELETE-FILE <string>) +(define (delete-file f) (.delete (java.io.File. 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) + (.flush (if (pair? arg) (car args) + (current-output-port)))) + +;;; CALL-WITH-INPUT-STRING and CALL-WITH-OUTPUT-STRING are the string +;;; port versions of CALL-WITH-*PUT-FILE. + +;;@ "rationalize" adjunct procedures. +;;(define (find-ratio x e) +;; (let ((rat (rationalize x e))) +;; (list (numerator rat) (denominator rat)))) +;;(define (find-ratio-between x y) +;; (find-ratio (/ (+ x y) 2) (/ (- x y) 2))) + +;;@ CHAR-CODE-LIMIT is one greater than the largest integer which can +;;; be returned by CHAR->INTEGER. +(define char-code-limit (char->integer Character.MAX_VALUE$)) + +;;@ MOST-POSITIVE-FIXNUM is used in modular.scm +(define most-positive-fixnum Integer.MAX_VALUE$) + +;;@ Return argument +(define (identity x) x) + +;;@ 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 (constant? exp) + (if (pair? exp) (eq? (car exp) 'quote) (not (symbol? exp)))) + +(define (combine-skeletons left right exp) + (cond + ((and (constant? left) (constant? right)) + (if (and (eqv? (eval left) (car exp)) + (eqv? (eval right) (cdr exp))) + (list 'quote exp) + (list 'quote (cons (eval left) (eval right))))) + ((null? right) (list 'list left)) + ((and (pair? right) (eq? (car right) 'list)) + (cons 'list (cons left (cdr right)))) + (else (list 'cons left right)))) + +(define (expand-quasiquote exp nesting) + (cond + ((vector? exp) + (list 'apply 'vector (expand-quasiquote (vector->list exp) nesting))) + ((not (pair? exp)) + (if (constant? exp) exp (list 'quote exp))) + ((and (eq? (car exp) 'unquote) (= (length exp) 2)) + (if (= nesting 0) + (second exp) + (combine-skeletons ''unquote + (expand-quasiquote (cdr exp) (- nesting 1)) + exp))) + ((and (eq? (car exp) 'quasiquote) (= (length exp) 2)) + (combine-skeletons ''quasiquote + (expand-quasiquote (cdr exp) (+ nesting 1)) + exp)) + ((and (pair? (car exp)) + (eq? (caar exp) 'unquote-splicing) + (= (length (car exp)) 2)) + (if (= nesting 0) + (list 'append (second (first exp)) + (expand-quasiquote (cdr exp) nesting)) + (combine-skeletons (expand-quasiquote (car exp) (- nesting 1)) + (expand-quasiquote (cdr exp) nesting) + exp))) + (else (combine-skeletons (expand-quasiquote (car exp) nesting) + (expand-quasiquote (cdr exp) nesting) + exp)))) + +(define quasiquote + (set-procedure-name! + (macro (x) + (expand-quasiquote x 0)) + 'quasiquote)) + +(define-macro (defmacro name args . body) + `(define-macro ,(cons name args) ,@body)) +;@ +(define (defmacro? m) + (and (.isDefined m) (eq? (.getClass (eval m)) Macro.class))) +;@ + +(tryCatch ; once-only + macroexpand-1 + (lambda (e) (set! macroexpand-1 macroexpand))) + +;@ +(define (macroexpand e) + (if (pair? e) + (let ((a (car e))) + (cond ((and (symbol? a) (defmacro? a)) + (macroexpand (macroexpand-1 e))) + (else e))) + e)) +;@ +(define gentemp + (let ((*gensym-counter* -1)) + (lambda () + (set! *gensym-counter* (+ *gensym-counter* 1)) + (string->symbol + (string-append "slib:G" (number->string *gensym-counter*)))))) + +(define base:eval slib:eval) +;@ +;;; (define (defmacro:eval x) (base:eval (defmacro:expand* x))) +(define defmacro:eval base:eval) + +(define (defmacro:expand* x) + (require 'defmacroexpand) (apply defmacro:expand* x '())) +;@ +(define (defmacro:load <pathname>) + (slib:eval-load <pathname> defmacro:eval)) +;; slib:eval-load definition moved to "require.scm" + +;@ +(define slib:warn + (lambda args + (let ((cep (current-error-port))) + (if (provided? 'trace) (print-call-stack cep)) + (display "Warn: " cep) + (for-each (lambda (x) (display #\ cep) (write x cep)) args)))) + +;;@ define an error procedure for the library +(define (slib:error . args) + (if (provided? 'trace) (print-call-stack (current-error-port))) + (apply error args)) +;@ +(define (make-exchanger obj) + (lambda (rep) (let ((old obj)) (set! obj rep) old))) +(define (open-file filename modes) + (case modes + ((r rb) (open-input-file filename)) + ((w wb) (open-output-file filename)) + (else (slib:error 'open-file 'mode? modes)))) +(define (port? obj) (or (input-port? port) (output-port? port))) +(define (call-with-open-ports . ports) + (define proc (car ports)) + (cond ((procedure? proc) (set! ports (cdr ports))) + (else (set! ports (reverse ports)) + (set! proc (car ports)) + (set! ports (reverse (cdr ports))))) + (let ((ans (apply proc ports))) + (for-each close-port ports) + ans)) +(define (close-port port) + (cond ((input-port? port) + (close-input-port port) + (if (output-port? port) (close-output-port port))) + ((output-port? port) (close-output-port port)) + (else (slib:error 'close-port 'port? port)))) +;@ +(define (browse-url url) + (define (try cmd end) (zero? (system (string-append cmd url end)))) + (or (try "netscape-remote -remote 'openURL(" ")'") + (try "netscape -remote 'openURL(" ")'") + (try "netscape '" "'&") + (try "netscape '" "'"))) + +;;@ define these as appropriate for your system. +(define slib:tab (integer->char 9)) +(define slib:form-feed (integer->char 12)) + +;;@ Support for older versions of Scheme. Not enough code for its own file. +(define (last-pair l) (if (pair? (cdr l)) (last-pair (cdr l)) l)) +(define t #t) +(define nil #f) + +;;@ Define these if your implementation's syntax can support it and if +;;; they are not already defined. +(define (1+ n) (+ n 1)) +(define (-1+ n) (+ n -1)) +(define 1- -1+) + +;;@ Define SLIB:EXIT to be the implementation procedure to exit or +;;; return if exiting not supported. +(define (slib:exit) (System.exit 0)) + +;;@ Here for backward compatability +(define (scheme-file-suffix) ".scm") + + +;;@ (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 f) (load (string-append f ".scm"))) + +;;@ (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) + +;;@ At this point SLIB:LOAD must be able to load SLIB files. +(define slib:load slib:load-source) + +(slib:load (in-vicinity (library-vicinity) "require")) + +(define (current-time) (/ (System.currentTimeMillis) 1000)) + +(if (not (.isDefined 'old-require)) + (begin + (set! old-require require) + (set! require + (lambda (feature) + (let ((jsyntax U.useJavaSyntax$)) + (set! U.useJavaSyntax$ #f) + (Procedure.tryFinally + (lambda () (old-require feature)) + (lambda () (set! U.useJavaSyntax$ jsyntax)))))))) |