1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;
|
|
|
|
|
;;;; i n i t . s t k -- The file launched at startup
|
|
|
|
|
;;;;
|
1999-02-02 06:13:40 -05:00
|
|
|
|
;;;; Copyright <20> 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;
|
1999-09-05 07:16:41 -04:00
|
|
|
|
;;;; Permission to use, copy, modify, distribute,and license this
|
|
|
|
|
;;;; software and its documentation for any purpose is hereby granted,
|
|
|
|
|
;;;; provided that existing copyright notices are retained in all
|
|
|
|
|
;;;; copies and that this notice is included verbatim in any
|
|
|
|
|
;;;; distributions. No written agreement, license, or royalty fee is
|
|
|
|
|
;;;; required for any of the authorized uses.
|
|
|
|
|
;;;; This software is provided ``AS IS'' without express or implied
|
|
|
|
|
;;;; warranty.
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;;
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;; Author: Erick Gallesio [eg@kaolin.unice.fr]
|
|
|
|
|
;;;; Creation date: ??-Sep-1993 ??:??
|
1999-09-27 07:20:21 -04:00
|
|
|
|
;;;; Last file update: 14-Sep-1999 21:50 (eg)
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;==============================================================================
|
|
|
|
|
;;;
|
|
|
|
|
;;; Define some global variables (i.e. in the STk module)
|
|
|
|
|
;;;
|
|
|
|
|
;;;==============================================================================
|
|
|
|
|
|
|
|
|
|
(with-module STk
|
|
|
|
|
(import Scheme)
|
|
|
|
|
(define *print-banner* #t) ; #f to avoid the Copyright message
|
|
|
|
|
(define *debug* #f) ; #t for debuggging (disable macro inlining)
|
|
|
|
|
(define *argc* (length *argv*))
|
|
|
|
|
(define Tk:initialized? #f)
|
|
|
|
|
(define *shared-suffix* (cond
|
1999-09-05 07:16:41 -04:00
|
|
|
|
((string=? (machine-type) "Ms-Win32") "dll")
|
1998-04-10 06:59:06 -04:00
|
|
|
|
((string=? (substring (machine-type) 0 2) "HP") "sl")
|
|
|
|
|
(else "so")))
|
|
|
|
|
(define *load-suffixes* (list "stk" "stklos" "scm" *shared-suffix*))
|
|
|
|
|
(define *load-path* #f)
|
|
|
|
|
(define *load-verbose* #f))
|
|
|
|
|
|
|
|
|
|
;;;==============================================================================
|
|
|
|
|
;;;
|
|
|
|
|
;;; The following code is in the Scheme module (since this file is loaded in the
|
|
|
|
|
;;; Scheme module)
|
|
|
|
|
;;;
|
|
|
|
|
;;;==============================================================================
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define call-with-current-continuation ;; The R5RS one
|
|
|
|
|
(let ((call/cc call-with-current-continuation)) ;; The R4RS one
|
|
|
|
|
(lambda (proc)
|
|
|
|
|
(call/cc (lambda (cont)
|
|
|
|
|
(proc (lambda l (cont (apply values l)))))))))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define call/cc call-with-current-continuation) ;; To make life easier
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define ! system)
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(define (os-kind)
|
|
|
|
|
(if (string=? (machine-type) "Ms-Win32")
|
|
|
|
|
'Windows
|
|
|
|
|
'Unix))
|
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Some stuff for defining macros
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define define-macro #f)
|
|
|
|
|
(define %replace #f)
|
|
|
|
|
(define %beginify #f)
|
|
|
|
|
|
|
|
|
|
(let ((if if) (and and) (begin begin) (set-car! set-car!) (set-cdr! set-cdr!)
|
|
|
|
|
(not not) (pair? pair?) (car car) (cdr cdr)
|
|
|
|
|
(null? null?) (cons cons)
|
|
|
|
|
(let let) (macro macro) (list list) (append append))
|
|
|
|
|
|
|
|
|
|
(set! %replace
|
|
|
|
|
(lambda (before after)
|
|
|
|
|
(if (and (not *debug*) (pair? before) (pair? after))
|
|
|
|
|
(begin
|
|
|
|
|
(set-car! before (car after))
|
|
|
|
|
(set-cdr! before (cdr after))))
|
|
|
|
|
after))
|
|
|
|
|
|
|
|
|
|
(set! %beginify
|
|
|
|
|
(lambda (forms)
|
|
|
|
|
(if (null? (cdr forms)) (car forms) (cons 'begin forms))))
|
|
|
|
|
|
|
|
|
|
(set! define-macro
|
|
|
|
|
(macro form
|
|
|
|
|
(let ((name (car (car (cdr form))))
|
|
|
|
|
(args (cdr (car (cdr form)))))
|
|
|
|
|
(list 'define name
|
|
|
|
|
(list 'macro 'params
|
|
|
|
|
(list '%replace
|
|
|
|
|
'params
|
|
|
|
|
(list 'apply
|
|
|
|
|
(append (list 'lambda args)
|
|
|
|
|
(cdr (cdr form)))
|
|
|
|
|
(list 'cdr 'params)))))))))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Some utilities
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define gensym
|
|
|
|
|
(let ((counter 0))
|
|
|
|
|
(lambda prefix
|
|
|
|
|
(set! counter (+ counter 1))
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(string->uninterned-symbol
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(string-append (if (null? prefix) "G" (car prefix))
|
|
|
|
|
(number->string counter))))))
|
|
|
|
|
|
|
|
|
|
(define (apropos s)
|
|
|
|
|
(if (not (symbol? s)) (error "apropos: bad symbol" s))
|
|
|
|
|
(let ((res '())
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(env (the-environment))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(str (symbol->string s)))
|
|
|
|
|
|
|
|
|
|
(do ((l (cdr (environment->list env)) (cdr l))); cdr to avoid the binding to "s"
|
1998-04-10 06:59:06 -04:00
|
|
|
|
((null? l) (if (null? res) #f (list->set res)))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(do ((v (car l) (cdr v)))
|
|
|
|
|
((null? v))
|
|
|
|
|
(if (and (string-find? str (symbol->string (caar v)))
|
|
|
|
|
(symbol-bound? (caar v)))
|
|
|
|
|
(set! res (cons (caar v) res)))))))
|
|
|
|
|
|
|
|
|
|
(define (documentation x)
|
|
|
|
|
"provides documentation for its parameter if it exists"
|
|
|
|
|
(define (nodoc)
|
|
|
|
|
(format #t "No documentation available for ~A\n" x))
|
|
|
|
|
(cond
|
|
|
|
|
((closure? x) (let ((body (procedure-body x)))
|
|
|
|
|
(if (string? (caddr body))
|
|
|
|
|
(format #t "~A\n" (caddr body))
|
|
|
|
|
(nodoc))))))
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define make-unbound
|
|
|
|
|
(let ((unbound (make-vector 1)))
|
|
|
|
|
(lambda ()
|
|
|
|
|
(vector-ref unbound 0))))
|
|
|
|
|
|
|
|
|
|
(define unbound?
|
|
|
|
|
(let ((unbound (make-unbound)))
|
|
|
|
|
(lambda (o)
|
|
|
|
|
(eq? o unbound))))
|
|
|
|
|
|
|
|
|
|
(define (make-undefined)
|
|
|
|
|
(if #f #t))
|
|
|
|
|
|
|
|
|
|
(define (undefined? o)
|
|
|
|
|
(eq? o (if #f #t)))
|
|
|
|
|
|
|
|
|
|
(define-macro (define-variable var value) ;; The Elisp/CL defvar
|
|
|
|
|
`(with-module STk
|
|
|
|
|
(unless (symbol-bound? ',var) (define ,var ,value))))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(define-macro (receive vars producer . body)
|
|
|
|
|
`(call-with-values (lambda () ,producer)
|
|
|
|
|
(lambda ,vars ,@body)))
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;
|
|
|
|
|
;;;; Random
|
|
|
|
|
;;;; This version of random is constructed over the C one. It can return
|
|
|
|
|
;;;; bignum numbers. Idea is due to Nobuyuki Hikichi <hikichi@sra.co.jp>
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define random
|
|
|
|
|
(let ((C-random random)
|
|
|
|
|
(max-rand #x7fffffff)) ; Probably more on 64 bits machines
|
|
|
|
|
(letrec ((rand (lambda (n)
|
|
|
|
|
(cond
|
|
|
|
|
((zero? n) 0)
|
|
|
|
|
((< n max-rand) (C-random n))
|
|
|
|
|
(else (+ (* (rand (quotient n max-rand)) max-rand)
|
|
|
|
|
(rand (remainder n max-rand))))))))
|
|
|
|
|
(lambda (n)
|
|
|
|
|
(if (zero? n)
|
|
|
|
|
(error "random: bad number: 0")
|
|
|
|
|
(rand n))))))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; do
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define-macro (do inits test . body)
|
|
|
|
|
(let ((loop-name (gensym)))
|
|
|
|
|
`(letrec ((,loop-name
|
|
|
|
|
(lambda ,(map car inits)
|
|
|
|
|
(if ,(car test)
|
|
|
|
|
(begin ,@(if (null? (cdr test))
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(list (make-undefined))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(cdr test)))
|
|
|
|
|
(begin ,@body
|
|
|
|
|
(,loop-name ,@(map (lambda (init)
|
|
|
|
|
(if (null? (cddr init))
|
|
|
|
|
(car init)
|
|
|
|
|
(caddr init)))
|
|
|
|
|
inits)))))))
|
|
|
|
|
(,loop-name ,@(map cadr inits)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; dotimes
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define-macro (dotimes binding . body)
|
|
|
|
|
(if (list? binding)
|
|
|
|
|
;; binding is a list
|
|
|
|
|
(let ((var #f) (count #f) (result #f))
|
|
|
|
|
(case (length binding)
|
|
|
|
|
(2 (set! var (car binding))
|
1999-09-27 07:20:21 -04:00
|
|
|
|
(set! count (cadr binding))
|
|
|
|
|
(set! result (make-undefined)))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(3 (set! var (car binding))
|
|
|
|
|
(set! count (cadr binding))
|
|
|
|
|
(set! result (caddr binding)))
|
|
|
|
|
(else (error "dotimes: bad binding construct: ~S" binding)))
|
|
|
|
|
`(do ((,var 0 (+ ,var 1)))
|
1999-09-27 07:20:21 -04:00
|
|
|
|
((>= ,var ,count) ,result)
|
1996-09-27 06:29:02 -04:00
|
|
|
|
,@body))
|
|
|
|
|
;; binding is ill-formed
|
|
|
|
|
(error "dotimes: binding is not a list: ~S" binding)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; case
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define-macro (case key . clauses)
|
|
|
|
|
;; conditionally execute the clause eqv? to key
|
|
|
|
|
(define (case-make-clauses key)
|
|
|
|
|
`(cond ,@(map
|
|
|
|
|
(lambda (clause)
|
|
|
|
|
(if (pair? clause)
|
|
|
|
|
(let ((case (car clause))
|
|
|
|
|
(exprs (cdr clause)))
|
|
|
|
|
(cond ((eq? case 'else)
|
|
|
|
|
`(else ,@exprs))
|
|
|
|
|
((pair? case)
|
|
|
|
|
(if (= (length case) 1)
|
|
|
|
|
`((eqv? ,key ',(car case)) ,@exprs)
|
|
|
|
|
`((memv ,key ',case) ,@exprs)))
|
|
|
|
|
(else
|
|
|
|
|
`((eqv? ,key ',case) ,@exprs))))
|
|
|
|
|
(error "case: invalid syntax in ~a" clause)))
|
|
|
|
|
clauses)))
|
|
|
|
|
(if (pair? key)
|
|
|
|
|
(let ((newkey (gensym)))
|
|
|
|
|
`(let ((,newkey ,key))
|
|
|
|
|
,(case-make-clauses newkey)))
|
|
|
|
|
(case-make-clauses key)))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; fluid-let
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define-macro (fluid-let bindings . body)
|
|
|
|
|
(let* ((vars (map car bindings))
|
|
|
|
|
(vals (map cadr bindings))
|
|
|
|
|
(tmps (map (lambda (x) (gensym)) vars)))
|
|
|
|
|
`(let ,(map list tmps vars)
|
|
|
|
|
(dynamic-wind
|
|
|
|
|
(lambda () ,@(map (lambda (x y) `(set! ,x ,y)) vars vals))
|
|
|
|
|
(lambda () ,@body)
|
|
|
|
|
(lambda () ,@(map (lambda (x y) `(set! ,x ,y)) vars tmps))))))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Some usal macros
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define-macro (unquote form)
|
|
|
|
|
(error "Usage of unquote outside of quasiquote in ,~A" form))
|
|
|
|
|
|
|
|
|
|
(define-macro (unquote-splicing form)
|
|
|
|
|
(error "Usage of unquote-splicing outside of quasiquote in ,@~A" form))
|
|
|
|
|
|
|
|
|
|
(define 1+ (macro form (list + (cadr form) 1)))
|
|
|
|
|
(define 1- (macro form (list - (cadr form) 1)))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Section 6.10
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define (call-with-input-file string proc)
|
|
|
|
|
(let* ((file (open-input-file string))
|
|
|
|
|
(result (proc file)))
|
|
|
|
|
(close-input-port file)
|
|
|
|
|
result))
|
|
|
|
|
|
|
|
|
|
(define (call-with-output-file string proc)
|
|
|
|
|
(let* ((file (open-output-file string))
|
|
|
|
|
(result (proc file)))
|
|
|
|
|
(close-output-port file)
|
|
|
|
|
result))
|
|
|
|
|
|
1999-09-05 07:16:41 -04:00
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(define (call-with-input-string string proc)
|
|
|
|
|
(proc (open-input-string string)))
|
|
|
|
|
|
|
|
|
|
(define (call-with-output-string proc)
|
|
|
|
|
(let ((str (open-output-string)))
|
|
|
|
|
(proc str)
|
|
|
|
|
(get-output-string str)))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; File management
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define (build-path-from-shell-variable var)
|
|
|
|
|
(let ((path (getenv var)))
|
|
|
|
|
(if path
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(split-string path (if (eqv? (os-kind) 'Unix) ":" ";"))
|
1998-04-10 06:59:06 -04:00
|
|
|
|
'())))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(let ((lib (%library-location)))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;; If user has specified a load path with STK_LOAD_PATH, use it
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;; Always append STK_LIBRARY at end to be sure to find our files
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(set! *load-path* (append (list ".")
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(build-path-from-shell-variable "STK_LOAD_PATH")
|
|
|
|
|
(list (expand-file-name
|
|
|
|
|
(string-append lib "/../site-scheme"))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(string-append lib "/STk")
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(string-append lib "/" (machine-type))))))
|
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; Require/Provide/Provided?
|
|
|
|
|
;;;
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define require #f) ; This is a little bit tricky here: variables are
|
|
|
|
|
(define provide #f) ; defined in the Scheme module, but their associated
|
|
|
|
|
(define provided? #f) ; closure is in the STk module. In this way, the
|
|
|
|
|
; LOAD done in the REQUIRE procedure is done in the
|
|
|
|
|
; global namespace, which is what is desired for REQUIRE.
|
|
|
|
|
|
|
|
|
|
(with-module STk
|
|
|
|
|
(let ((provided '()))
|
|
|
|
|
|
|
|
|
|
(set! require (lambda (what)
|
|
|
|
|
(unless (member what provided)
|
|
|
|
|
(load what (current-module))
|
|
|
|
|
(unless (member what provided)
|
|
|
|
|
(format #t "WARNING: ~S was not provided~%" what)))
|
|
|
|
|
what))
|
|
|
|
|
|
|
|
|
|
(set! provide (lambda (what)
|
|
|
|
|
(unless (member what provided)
|
|
|
|
|
(set! provided (cons what provided)))
|
|
|
|
|
what))
|
|
|
|
|
|
|
|
|
|
(set! provided? (lambda (what)
|
|
|
|
|
(and (member what provided) #t)))))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Port conversions
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define (port->string p)
|
|
|
|
|
(unless (or (input-port? p) (input-string-port? p))
|
|
|
|
|
(error "port->string: Bad port ~S" p))
|
|
|
|
|
(let loop ((res '()))
|
|
|
|
|
(let ((line (read-line p)))
|
|
|
|
|
(if (eof-object? line)
|
|
|
|
|
(apply string-append (reverse res))
|
|
|
|
|
(loop (cons "\n" (cons line res)))))))
|
|
|
|
|
|
|
|
|
|
(define (port->list reader p)
|
|
|
|
|
(unless (or (input-port? p) (input-string-port? p))
|
|
|
|
|
(error "port->list: Bad port ~S" p))
|
|
|
|
|
;; Read all the lines of port and put them in a list
|
|
|
|
|
(let loop ((res '()) (sexp (reader p)))
|
|
|
|
|
(if (eof-object? sexp)
|
|
|
|
|
(reverse res)
|
|
|
|
|
(loop (cons sexp res) (reader p)))))
|
|
|
|
|
|
|
|
|
|
(define (port->sexp-list p)
|
|
|
|
|
(port->list read p))
|
|
|
|
|
|
|
|
|
|
(define (port->string-list p)
|
|
|
|
|
(port->list read-line p))
|
|
|
|
|
|
|
|
|
|
(define (exec command)
|
|
|
|
|
(call-with-input-file (string-append "| " command) port->string))
|
|
|
|
|
|
|
|
|
|
(define (exec-string-list command)
|
|
|
|
|
(call-with-input-file (string-append "| " command) port->string-list))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Misc
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
|
|
|
|
|
(define (closure? obj)
|
|
|
|
|
(and (procedure? obj) (procedure-body obj) #t))
|
|
|
|
|
|
|
|
|
|
(define (primitive? obj)
|
|
|
|
|
(and (procedure? obj) (not (procedure-body obj)) #t))
|
|
|
|
|
|
|
|
|
|
(define (widget? obj)
|
|
|
|
|
(and (tk-command? obj) (not (catch (obj 'configure)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (& . l)
|
|
|
|
|
(let loop ((l l) (res ""))
|
|
|
|
|
(if (null? l)
|
|
|
|
|
res
|
|
|
|
|
(let ((e (car l)))
|
|
|
|
|
(loop (cdr l)
|
|
|
|
|
(string-append res
|
|
|
|
|
(cond
|
|
|
|
|
((string? e) e)
|
|
|
|
|
((symbol? e) (symbol->string e))
|
|
|
|
|
((widget? e) (widget->string e))
|
|
|
|
|
((number? e) (number->string e))
|
|
|
|
|
(ELSE (format #f "~S" e)))))))))
|
|
|
|
|
|
|
|
|
|
(define-macro (unwind-protect body . unwind-forms)
|
|
|
|
|
`(dynamic-wind
|
|
|
|
|
(lambda () #f)
|
|
|
|
|
(lambda () ,body)
|
|
|
|
|
(lambda () ,@unwind-forms)))
|
|
|
|
|
|
|
|
|
|
(define-macro (when test . body)
|
|
|
|
|
`(if ,test ,@(if (= (length body) 1) body `((begin ,@body)))))
|
|
|
|
|
|
|
|
|
|
(define-macro (unless test . body)
|
|
|
|
|
`(if (not ,test) ,@(if (= (length body) 1) body `((begin ,@body)))))
|
|
|
|
|
|
|
|
|
|
(define-macro (multiple-value-bind vars form . body)
|
|
|
|
|
`(apply (lambda ,vars ,@body) ,form))
|
|
|
|
|
|
1998-09-30 07:11:02 -04:00
|
|
|
|
(define (map* fn . l) ; A map which accepts dotted lists (arg lists
|
|
|
|
|
(cond ; must be "isomorph"
|
|
|
|
|
((null? (car l)) '())
|
|
|
|
|
((pair? (car l)) (cons (apply fn (map car l))
|
|
|
|
|
(apply map* fn (map cdr l))))
|
|
|
|
|
(else (apply fn l))))
|
|
|
|
|
|
|
|
|
|
(define (for-each* fn . l) ; A for-each which accepts dotted lists (arg lists
|
|
|
|
|
(cond ; must be "isomorph"
|
|
|
|
|
((null? (car l)) '())
|
|
|
|
|
((pair? (car l)) (apply fn (map car l)) (apply for-each* fn (map cdr l)))
|
|
|
|
|
(else (apply fn l))))
|
|
|
|
|
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(define (some pred l)
|
|
|
|
|
(if (null? l)
|
|
|
|
|
#f
|
|
|
|
|
(or (pred (car l))
|
|
|
|
|
(some pred (cdr l)))))
|
|
|
|
|
|
|
|
|
|
(define (every pred l)
|
|
|
|
|
(if (null? l)
|
|
|
|
|
#t
|
|
|
|
|
(and (pred (car l) )
|
|
|
|
|
(every pred (cdr l)))))
|
|
|
|
|
|
1999-02-02 06:13:40 -05:00
|
|
|
|
|
|
|
|
|
;; Tell if the parameter string is a complete (or a set of complete) sexpr
|
|
|
|
|
(define (complete-sexpr? s)
|
|
|
|
|
(with-input-from-string s
|
|
|
|
|
(lambda ()
|
|
|
|
|
(let Loop ()
|
|
|
|
|
(let ((sexpr #f))
|
|
|
|
|
(if (catch (set! sexpr (read)))
|
|
|
|
|
#f
|
|
|
|
|
(or (eof-object? sexpr) (Loop))))))))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
|
|
|
|
;;;; Set functions
|
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(define (list->set l)
|
|
|
|
|
(letrec ((rem-dupl (lambda (l res)
|
|
|
|
|
(cond
|
|
|
|
|
((null? l) res)
|
|
|
|
|
((memv (car l) res) (rem-dupl (cdr l) res))
|
1998-09-30 07:11:02 -04:00
|
|
|
|
(ELSE (rem-dupl (cdr l) (cons (car l)
|
|
|
|
|
res)))))))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
(rem-dupl l '())))
|
|
|
|
|
|
|
|
|
|
(define (set-union l1 l2)
|
|
|
|
|
(list->set (append l1 l2)))
|
|
|
|
|
|
|
|
|
|
(define (set-intersection l1 l2)
|
|
|
|
|
(cond ((null? l1) l1)
|
|
|
|
|
((null? l2) l2)
|
|
|
|
|
((memv (car l1) l2) (cons (car l1) (set-intersection (cdr l1) l2)))
|
|
|
|
|
(else (set-intersection (cdr l1) l2))))
|
|
|
|
|
|
|
|
|
|
(define (set-difference l1 l2)
|
|
|
|
|
(cond ((null? l1) l1)
|
|
|
|
|
((memv (car l1) l2) (set-difference (cdr l1) l2))
|
|
|
|
|
(else (cons (car l1) (set-difference (cdr l1) l2)))))
|
|
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
|
;;;;
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;; Module stuff
|
1996-09-27 06:29:02 -04:00
|
|
|
|
;;;;
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define-macro (export . l)
|
|
|
|
|
`(begin
|
|
|
|
|
,@(map (lambda (x)
|
|
|
|
|
(let ((x (if (and (pair? x) (eq? (car x) 'setter))
|
|
|
|
|
(extended-name->scheme-name x)
|
|
|
|
|
x)))
|
|
|
|
|
`(export-symbol ',x (current-module))))
|
|
|
|
|
l)
|
|
|
|
|
,(make-undefined)))
|
|
|
|
|
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define ~ with-module)
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
#| FIXME: Probably more harmful than useful. Delete it?
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define-macro (duplicate-module-exports from to . prefix)
|
|
|
|
|
(let* ((prefix (if (null? prefix) "" (symbol->string (car prefix))))
|
|
|
|
|
(exports (module-exports (find-module from)))
|
|
|
|
|
(symbols (map (lambda (x)
|
|
|
|
|
(string->symbol (string-append prefix (symbol->string x))))
|
|
|
|
|
exports)))
|
|
|
|
|
`(with-module ,to
|
|
|
|
|
,@(map (lambda (x y)
|
|
|
|
|
`(define ,x (with-module ,from ,y)))
|
|
|
|
|
symbols exports))))
|
|
|
|
|
|#
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
|
|
|
|
;;;
|
|
|
|
|
;;; quit and bye procedures. Since Tk redefine exit, they cannot be simple aliases
|
|
|
|
|
;;;
|
|
|
|
|
(define quit (lambda l (apply exit l)))
|
|
|
|
|
(define bye (lambda l (apply exit l)))
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;==============================================================================
|
|
|
|
|
;;;
|
|
|
|
|
;;; Code for STklos autoloading
|
|
|
|
|
;;;
|
|
|
|
|
;;;==============================================================================
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define-module STklos
|
|
|
|
|
(import Scheme)
|
|
|
|
|
(export define-class define-method define-generic describe make method)
|
|
|
|
|
|
|
|
|
|
(autoload "stklos" define-class define-method define-generic make method)
|
|
|
|
|
(autoload "describe" describe))
|
1996-09-27 06:29:02 -04:00
|
|
|
|
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
;;;==============================================================================
|
|
|
|
|
;;;
|
|
|
|
|
;;; Finish initializations
|
|
|
|
|
;;;
|
|
|
|
|
;;;==============================================================================
|
|
|
|
|
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(with-module Scheme
|
|
|
|
|
(autoload "defsyntax" define-syntax)
|
|
|
|
|
;; SRFIs
|
|
|
|
|
(autoload "srfi-0" cond-expand)
|
|
|
|
|
(autoload "srfi-2" land*)
|
|
|
|
|
(autoload "srfi-7" program))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(with-module STk
|
|
|
|
|
;; Make the STklos autoload symbols accessible from the global scope
|
|
|
|
|
(import STklos)
|
|
|
|
|
|
|
|
|
|
;; Define some useful autoload
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(autoload "fs" basename dirname decompose-file-name)
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(autoload "process" run-process process?)
|
|
|
|
|
(autoload "regexp" string->regexp regexp? regexp-replace regexp-replace-all)
|
|
|
|
|
(autoload "trace" trace untrace)
|
|
|
|
|
(autoload "hash" make-hash-table hash-table-hash)
|
|
|
|
|
(autoload "socket" make-server-socket make-client-socket)
|
|
|
|
|
(autoload "match" match-case match-lambda)
|
|
|
|
|
(autoload "ffi" define-external external-exists?)
|
|
|
|
|
(autoload "extset" setter extended-name->scheme-name)
|
|
|
|
|
(autoload "pp" pp) ;; martine pretty-print package
|
1999-09-05 07:16:41 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Procedure used for writing the components of toplevel result. This
|
|
|
|
|
;; is far from perfect, but this is sufficient for the most obvious
|
|
|
|
|
;; cases (shared sublists, which are not circular structures, typically
|
|
|
|
|
;; for n-queens problems ...)
|
|
|
|
|
(define repl-write (lambda (x) ((if (list? x) write write*) x)))
|
1998-04-10 06:59:06 -04:00
|
|
|
|
|
|
|
|
|
;; Procedure called for prompting the user
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(define (repl-display-prompt module)
|
|
|
|
|
(let ((RDP (lambda (module)
|
|
|
|
|
(let ((p (current-error-port))
|
|
|
|
|
(n (module-name module)))
|
|
|
|
|
(flush) ; flush *stdout* before printing the prompt
|
|
|
|
|
(format p "~A> " (case n
|
|
|
|
|
((stk) "STk")
|
|
|
|
|
((stklos) "STklos")
|
|
|
|
|
((scheme) "Scheme")
|
|
|
|
|
((tk) "Tk")
|
|
|
|
|
(else n)))
|
|
|
|
|
(flush p)))))
|
|
|
|
|
;; RDP is the real prompt procedure. The body of this function is
|
|
|
|
|
;; only executed for the displaying the first prompt
|
|
|
|
|
(when Tk:initialized?
|
|
|
|
|
;; This autoload was in tk-init but it causes problems when an
|
|
|
|
|
;; error occur in the file loaded before the first prompt
|
|
|
|
|
;; appears. Now, we use the graphical report error only when
|
|
|
|
|
;; everything is correctly initialized.
|
|
|
|
|
(tk-set-error-handler!)) ; make STk:report-error and bgerror autoload
|
|
|
|
|
|
|
|
|
|
(set! repl-display-prompt RDP)
|
|
|
|
|
(repl-display-prompt module)))
|
1998-04-10 06:59:06 -04:00
|
|
|
|
|
1998-06-09 07:07:40 -04:00
|
|
|
|
;; Procedure called for printing toplevel results
|
1998-04-10 06:59:06 -04:00
|
|
|
|
(define (repl-display-result result)
|
1998-06-09 07:07:40 -04:00
|
|
|
|
(if (eqv? result (make-undefined))
|
|
|
|
|
(when *last-defined*
|
|
|
|
|
(format #t "~S\n" *last-defined*)
|
|
|
|
|
(set! *last-defined* #f))
|
|
|
|
|
(call-with-values (lambda () result)
|
|
|
|
|
(lambda l
|
1999-09-05 07:16:41 -04:00
|
|
|
|
(for-each (lambda (x) (repl-write x) (newline)) l))))))
|