diff options
Diffstat (limited to 'ice-9')
-rw-r--r-- | ice-9/ChangeLog-environments | 37 | ||||
-rw-r--r-- | ice-9/arrays.scm | 106 | ||||
-rw-r--r-- | ice-9/check-version.scm | 22 | ||||
-rw-r--r-- | ice-9/config.scm | 830 | ||||
-rw-r--r-- | ice-9/defmacro.scm | 114 | ||||
-rw-r--r-- | ice-9/error.scm | 37 | ||||
-rw-r--r-- | ice-9/files.scm | 246 | ||||
-rw-r--r-- | ice-9/hooks.scm | 23 | ||||
-rw-r--r-- | ice-9/keywords.scm | 15 | ||||
-rw-r--r-- | ice-9/lists.scm | 23 | ||||
-rw-r--r-- | ice-9/macros.scm | 28 | ||||
-rw-r--r-- | ice-9/math.scm | 102 | ||||
-rw-r--r-- | ice-9/misc.scm | 333 | ||||
-rw-r--r-- | ice-9/modules.scm | 82 | ||||
-rw-r--r-- | ice-9/options.scm | 223 | ||||
-rw-r--r-- | ice-9/posix.scm | 260 | ||||
-rw-r--r-- | ice-9/provide.scm | 13 | ||||
-rw-r--r-- | ice-9/repl.scm | 478 | ||||
-rw-r--r-- | ice-9/run-test.scm | 5 | ||||
-rw-r--r-- | ice-9/structs.scm | 127 | ||||
-rw-r--r-- | ice-9/symbols.scm | 23 |
21 files changed, 2976 insertions, 151 deletions
diff --git a/ice-9/ChangeLog-environments b/ice-9/ChangeLog-environments new file mode 100644 index 000000000..963a335f5 --- /dev/null +++ b/ice-9/ChangeLog-environments @@ -0,0 +1,37 @@ +1999-08-24 Jost Boekemeier <jostobfe@calvados.zrz.tu-berlin.de> + + * guile.scm (error-catching-loop): Correct non-RnRS usage of internal + defines. + +1999-08-12 Jost Boekemeier <jostobfe@calvados.zrz.tu-berlin.de> + + * arrays.scm, check-version.scm defmacro.scm, error.scm, + files.scm, guile.scm, hooks.scm, keywords.scm lists.scm, + macros.scm, math.scm, misc.scm, modules.scm, options.scm + posix.scm, provide.scm, run-test.scm, structs.scm, symbols.scm: + new file + * Makefile.am: added files + + * debug.scm (define-module): the module imports the modules: + hooks, options, defmacro + (variable-set!): disabled + + * r4rs.scm (defined?): `defined?' is a special form now. + (%load-announce): added environment parameter + (load): `load' loads and evaluates expressions in + `interaction-environment' + + * boot-9.scm: added warning that this module is obsolete + (c-module-registry): load all c modules into the root environment + (primitive-load-path): load expressions in file "ice-9/r4rs" into + interaction-environment + (symbol-property): disabled + (record-constructor): evaluates expressions in interaction + environment + (record-accessor): dto. + (record-modifier): dto. + (modules): disabled + (scm-style-repl): evaluates expressions in interaction-environment + (environments): disabled + (macros): disabled + (variables): disabled diff --git a/ice-9/arrays.scm b/ice-9/arrays.scm index 51be69210..6e175fde1 100644 --- a/ice-9/arrays.scm +++ b/ice-9/arrays.scm @@ -1,83 +1,27 @@ -;;; installed-scm-file -;;;; Copyright (C) 1999 Free Software Foundation, Inc. -;;;; -;;;; This program is free software; you can redistribute it and/or modify -;;;; it under the terms of the GNU General Public License as published by -;;;; the Free Software Foundation; either version 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, -;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330, -;;;; Boston, MA 02111-1307 USA -;;;; + +;;; {Arrays} +;;; + +(begin + (define uniform-vector? array?) + (define make-uniform-vector dimensions->uniform-array) + ; (define uniform-vector-ref array-ref) + (define (uniform-vector-set! u i o) + (uniform-array-set1! u o i)) + (define uniform-vector-fill! array-fill!) + (define uniform-vector-read! uniform-array-read!) + (define uniform-vector-write uniform-array-write) + + (define (make-array fill . args) + (dimensions->uniform-array args () fill)) + (define (make-uniform-array prot . args) + (dimensions->uniform-array args prot)) + (define (list->array ndim lst) + (list->uniform-array ndim '() lst)) + (define (list->uniform-vector prot lst) + (list->uniform-array 1 prot lst)) + (define (array-shape a) + (map (lambda (ind) (if (number? ind) (list 0 (+ -1 ind)) ind)) + (array-dimensions a)))) -(define uniform-vector? array?) -(define make-uniform-vector dimensions->uniform-array) - -;; (define uniform-vector-ref array-ref) - -(define (uniform-vector-set! u i o) - (uniform-array-set1! u o i)) -(define uniform-vector-fill! array-fill!) -(define uniform-vector-read! uniform-array-read!) -(define uniform-vector-write uniform-array-write) - -(define (make-array fill . args) - (dimensions->uniform-array args () fill)) -(define (make-uniform-array prot . args) - (dimensions->uniform-array args prot)) -(define (list->array ndim lst) - (list->uniform-array ndim '() lst)) -(define (list->uniform-vector prot lst) - (list->uniform-array 1 prot lst)) -(define (array-shape a) - (map (lambda (ind) (if (number? ind) (list 0 (+ -1 ind)) ind)) - (array-dimensions a))) - -(let ((make-array-proc (lambda (template) - (lambda (c port) - (read:uniform-vector template port))))) - (for-each (lambda (char template) - (read-hash-extend char - (make-array-proc template))) - '(#\b #\a #\u #\e #\s #\i #\c #\y #\h #\l) - '(#t #\a 1 -1 1.0 1/3 0+i #\nul s l))) - -(let ((array-proc (lambda (c port) - (read:array c port)))) - (for-each (lambda (char) (read-hash-extend char array-proc)) - '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) - -(define (read:array digit port) - (define chr0 (char->integer #\0)) - (let ((rank (let readnum ((val (- (char->integer digit) chr0))) - (if (char-numeric? (peek-char port)) - (readnum (+ (* 10 val) - (- (char->integer (read-char port)) chr0))) - val))) - (prot (if (eq? #\( (peek-char port)) - '() - (let ((c (read-char port))) - (case c ((#\b) #t) - ((#\a) #\a) - ((#\u) 1) - ((#\e) -1) - ((#\s) 1.0) - ((#\i) 1/3) - ((#\c) 0+i) - (else (error "read:array unknown option " c))))))) - (if (eq? (peek-char port) #\() - (list->uniform-array rank prot (read port)) - (error "read:array list not found")))) - -(define (read:uniform-vector proto port) - (if (eq? #\( (peek-char port)) - (list->uniform-array 1 proto (read port)) - (error "read:uniform-vector list not found"))) diff --git a/ice-9/check-version.scm b/ice-9/check-version.scm new file mode 100644 index 000000000..fd3c9e8e6 --- /dev/null +++ b/ice-9/check-version.scm @@ -0,0 +1,22 @@ + +;;; {Check that the interpreter and scheme code match up.} + +(let ((show-line + (lambda args + (with-output-to-port (current-error-port) + (lambda () + (display (car (command-line))) + (display ": ") + (for-each (lambda (string) (display string)) + args) + (newline)))))) + + (load-from-path "ice-9/version.scm") + + (if (not (string=? + (libguile-config-stamp) ; from the interprpreter + (ice-9-config-stamp))) ; from the Scheme code + (begin + (show-line "warning: different versions of libguile and ice-9:") + (show-line "libguile: configured on " (libguile-config-stamp)) + (show-line "ice-9: configured on " (ice-9-config-stamp))))) diff --git a/ice-9/config.scm b/ice-9/config.scm new file mode 100644 index 000000000..f31bddd4d --- /dev/null +++ b/ice-9/config.scm @@ -0,0 +1,830 @@ +;;;; This is the (ice-9 config) module. It exports the module +;;;; configuration language and creates the (user guile) module. + +;; from r4rs +(define (call-with-current-continuation proc) + (@call-with-current-continuation proc)) + + +;; the export list +(define the-module-exports + '(the-module + module + module-go + go + module-ref + module-open + module-protect + module-export + module-export + module-access + module-close + module-create + module-use + (module-use (alias use-modules)) + (module-export (alias export)) + (module-export (alias export-syntax)) + define-module + define-public + module-config-export + module-config-protect + module-config-open + (define-public (alias define*)) + (define (alias define-private)) + symbol-property + set-symbol-property! + remove-symbol-property! + (remove-symbol-property! (alias symbol-property-remove!)) + )) + +(define the-module-protects + '(module-eval-environment + module-interface-environment + module-package-name + module-name)) + + + + +;;; Symbol properties +(define symbol-property + (procedure->memoizing-macro + (lambda (x env) + `(,environment-symbol-property (the-environment) ,(cadr x) ,(caddr x) )))) + +(define set-symbol-property! + (procedure->memoizing-macro + (lambda (x env) + `(,environment-set-symbol-property! (the-environment) ,(cadr x) ,(caddr x) ,(cadddr x) )))) + +(define remove-symbol-property! + (procedure->memoizing-macro + (lambda (x env) + `(,environment-remove-symbol-property! (the-environment) ,(cadr x) ,(caddr x) )))) + + +;;; {Error Handling} +;;; + +;; from ice-9 error +(define (error . args) + (if (null? args) + (scm-error 'misc-error #f "?" #f #f) + (let loop ((msg "%s") + (rest (cdr args))) + (if (not (null? rest)) + (loop (string-append msg " %S") + (cdr rest)) + (scm-error 'misc-error #f msg args #f))))) + + + +;;; {Low Level Modules} + + +;; the module-signature (also called `module') maps modules to: +;; (vector eval-env export-env protect-env package-sym module-sym) +(define (module-eval-environment module) (vector-ref module 0)) + + +;;; the accessor procedures + +;; export environment +(define (module-export-environment module) + (vector-ref module 1)) + +;;; protect environment +(define (module-protect-environment module) + (vector-ref module 2)) + +;;; package and module name +(define (module-package-name module) (vector-ref module 3)) +(define (module-name module) (vector-ref module 4)) +(define (make-module eval export protect package name) (vector eval export protect package name (list ))) + +;; Return the interface environment for module. The interface is +;; either the protect environment if the module is accessed from +;; another package or the module's export environment +(define module-interface-environment + (lambda (current-module module) + (if (eq? (module-package-name current-module) + (module-package-name module)) + (module-protect-environment module) + (module-export-environment module)))) + +;; export-list used by define-public +(define (module-export-list module) (vector-ref module 5)) +(define (module-set-export-list! module val) (vector-set! module 5 val)) + +;; return the current module-signature +(define the-module + (procedure->syntax + (lambda (x env) + (let ((m (hashq-ref (environment-module-hash) (car (reverse env))))) + (if (not m) + (error "PANIC: Could not find module for " (car (reverse env))) + m))))) + + +;;; Convert a list of symbols into a package/module name + +;; (ice-9 my boot) -> (ice-9/my/ . boot) +;; (boot) -> (user/ . boot) +(define symlist->package+module + (lambda (symlist) + (if (not (pair? symlist)) (error "not a symbol list:" symlist)) + (let ((symlist (if (null? (cdr symlist)) (cons 'user symlist) symlist))) + (let loop ((dirs "") + (syms symlist)) + (let ((sym (car syms))) + (if (not (symbol? sym)) (error "not a valid symbol:" sym)) + (if (null? (cdr syms)) + (cons (string->symbol dirs) sym) + (loop (string-append dirs sym "/") (cdr syms)))))))) + +;; (ice-9/my/ . boot) -> ice-9/my/boot +(define package+module->module-sym + (lambda (name-pair) + (string->symbol + (string-append (symbol->string (car name-pair)) + (symbol->string (cdr name-pair)))))) + +;; (ice-9/my/ . boot) -> ice-9/my/ +(define package+module->package-sym + (lambda (name-pair) + (car name-pair))) + +;; (ice-9 my boot) -> ice-9/my/boot +(define symlist->module-sym + (lambda (mod) + (package+module->module-sym (symlist->package+module mod)))) + + +;;; The implementation (low level proc. interface) + +;; load and evaluate package-sym module-sym in its own environment +(define module-load-internal + (lambda (package-sym module-sym) + (let* ( + (skel (make-module-skeleton package-sym module-sym)) + (skel-env (module-eval-environment skel)) + (c_name (string-append (symbol->string module-sym) ".scm")) + (full_name (%search-load-path c_name))) + + (if (not full_name) + ;; try to invoke c-function directly + (let ( + (c_module_init (and + (environment-bound? (c-module-registry) module-sym) + (environment-ref (c-module-registry) module-sym)))) + (if (not c_module_init) + (begin + ;; remove all references to the created module + (environment-undefine (module-registry) module-sym) + #f) + (begin + (c_module_init skel-env) + + ;; now modify the export and protect environment so + ;; that all cells are visible + (let ((export (module-export-environment skel))) + (interface-environment-set-interface! + export + (list (cons skel-env (environment-fold skel-env (lambda (sym val last) (cons sym last)) (list ))))) + (interface-environment-set-interface! (module-protect-environment skel) (list (cons export #f)))) + + skel))) + + (begin + (primitive-load full_name skel-env) + skel))))) + +;; load `(package module)' +(define module-load-proc + (lambda (mod) + (let* ( + (name-pair (symlist->package+module mod)) + (package-sym (package+module->package-sym name-pair)) + (module-sym (package+module->module-sym name-pair))) + (module-load-internal package-sym module-sym)))) + +(define last-indent 0) + +;; load package-sym/module-sym only if module has not been loaded +(define module-auto-load + (lambda (package-sym module-sym) + (let ( + (module (and + (environment-bound? (module-registry) module-sym) + (environment-ref (module-registry) module-sym))) + (indent (lambda (count) + (do ((i 0 (+ i 1))) ((= i count)) (display " "))))) + + (if (not module) + + (begin + (display "loading ") + (indent last-indent) + (display module-sym) (force-output) + (newline) + + (set! last-indent (+ last-indent 2)) + (let ((module (module-load-internal package-sym module-sym))) + + (set! last-indent (- last-indent 2)) + module)) + + module)))) + +;; Create a continuation to start a new repl in module. +;; #f means: start a repl in (user config) +(define module-go + (lambda (module) + + (define (y-or-n? question eof-value count) + (let ((i-port (current-input-port)) + (o-port (current-output-port))) + (let loop ((count count)) + (display question o-port) + (display " (y/n)? " o-port) + (force-output) + (let ((line (read i-port))) + (cond ((eof-object? line) + (newline o-port) + (if (= count 0) + eof-value + (begin (display "I'll only ask another " o-port) + (write count o-port) + (display " times." o-port) + (newline o-port) + (loop (- count 1))))) + ((< (string-length line) 1) (loop count)) + ((char=? (string-ref line 0) #\y) #t) + ((char=? (string-ref line 0) #\n) #f) + (else (loop count))))))) + + (let ((guile (module-access-proc '(ice-9 repl))) + (user/config (module-create (user config))) + (quit (lambda args + (apply throw 'quit args)))) + + ;; (user config) opens the current module (ice-9 config) and + ;; imports some symbols + (let ((interface (eval-environment-imported (module-eval-environment user/config))) + (export (module-export-environment (the-module))) + (import-list '(module-ref module-access module-close module-create the-module + module-use define-module module module-go go + (module-config-export (alias config-export)) + (module-config-protect (alias config-protect)) + (module-config-open (alias config-open))))) + + (interface-environment-set-interface! interface (list (cons export import-list)))) + + + (let ( + (top-repl (module-ref-proc (the-module) guile 'top-repl))) + + (let ( + (in-module (call-with-current-continuation (lambda (k) (set! module-go k) module)))) + + (letrec ( + (confirm + (lambda () + (newline) + (y-or-n? "Do you really want to quit guile" #t 1))) + + (user-repl + (lambda () + (set-interaction-environment! (module-eval-environment in-module)) + (let ((ret-val (top-repl in-module))) + (newline) + ret-val))) + + (config-repl + (lambda () + (set-interaction-environment! (module-eval-environment user/config)) + (top-repl user/config)))) + + (let ( + (ret-val + (or (and in-module (user-repl)) (config-repl)))) + + (if (not (confirm)) (module-go #f)) + + ret-val))))))) + +;; fix the interface of the guile module. +(let* ( + (guile-module (environment-ref (module-registry) 'ice-9/guile)) + (guile-eval-env (module-eval-environment guile-module)) + (guile-export-list (environment-fold guile-eval-env (lambda (sym val rest) (cons sym rest)) '())) + (guile-interface (list (cons guile-eval-env guile-export-list))) + (export (module-export-environment guile-module)) + (protect (module-protect-environment guile-module))) + + ;; get out your barf bag ... It is probably better to export + ;; %load-path from (ice-9 config) and *features* from whereever but + ;; not from the guile module + ;; + ; export mutable + (for-each (lambda (s) + (set-car! (memq s guile-export-list) (list s 'mutable-location))) + (list + '%load-path + '*features* + ; complete weired ... (from r4rs.scm) + '%load-hook + 'apply + ; argh... (popen.scm) + 'gc-thunk + )) + + + + ; now set the interface + (interface-environment-set-interface! export guile-interface) + (interface-environment-set-interface! protect guile-interface)) + +;; update the config module `(ice-9 config)' +(let* ( + (config-module (environment-ref (module-registry) 'ice-9/config)) + (eval (module-eval-environment config-module)) + (export (module-export-environment config-module)) + (protect (module-protect-environment config-module))) + + (interface-environment-set-interface! export (list (cons eval the-module-exports))) + (interface-environment-set-interface! protect (list (cons eval the-module-protects) (cons export #f)))) + +;; create a simple but full-featured module. +(define make-module-skeleton + (lambda (package-sym module-sym) + (let* ( + (config-export-env (module-export-environment + (environment-ref (module-registry) 'ice-9/config))) + (local (make-leaf-environment)) + (import (make-interface-environment (list (cons config-export-env #f)))) + (eval (make-eval-environment local import)) + (export (make-interface-environment (list (list eval)))) ;; export nothing + (protect (make-interface-environment (list (cons export #f) (list eval)))) + (module (make-module eval export protect package-sym module-sym))) + + (hashq-set! (environment-module-hash) eval module) + (environment-define (module-registry) module-sym module) + + module))) + +(define module-create-proc + (lambda (mod) + (let* ( + (name-pair (symlist->package+module mod)) + (package-sym (package+module->package-sym name-pair)) + (module-sym (package+module->module-sym name-pair)) + (module (and + (environment-bound? (module-registry) module-sym) + (environment-ref (module-registry) module-sym)))) + + (if (not module) + (let* ( + (c_name (string-append (symbol->string module-sym) ".scm")) + (full_name (%search-load-path c_name))) + (if (not full_name) + (let* ( + (skel (make-module-skeleton package-sym module-sym)) + (eval-env (module-eval-environment skel))) + skel) + + (error "module exists but has not been loaded" module-sym))) + (error "module exists and has been loaded" module-sym))))) + + +(define module-load-error + (lambda (module-sym) + (error "module could not be loaded" module-sym))) + +;; add an export environment to our module skeleton or set a new +(define (module-export-proc module export-list) + (let ( + (export (module-export-environment module)) + (eval (module-eval-environment module))) + + (if (pair? (module-export-list module)) + (error "You can either use `define-public' or `export', but not both.")) + + (module-set-export-list! module #f) ;; can't use `define-public' anymore + + (interface-environment-set-interface! export (list (cons eval export-list))) + (if #f #f))) + +;; package boundary +(define (module-protect-proc module protect-list) + (let ((protect (module-protect-environment module)) + (export (module-export-environment module)) + (eval (module-eval-environment module))) + + (interface-environment-set-interface! protect (list (cons eval protect-list) (cons export #f))) + (if #f #f))) + + +;; check for circular references +;; every interface-environment has a list of environment specs +;; an environment spec is a list of the environment and its exported symbols +;; every eval-environment has an interface-environment +(define referenced + (lambda (environment l) + (letrec ( + (search + (lambda (l) + (cond ((null? l) #f) + ((eq? (caar l) environment) #t) + (else + (or (search (get-list-from-env (caar l))) + (search (cdr l))))))) + + (get-list-from-env + (lambda (env) + (cond ((interface-environment? env) + (interface-environment-interface env)) + + ((eval-environment? env) + (get-list-from-env (eval-environment-imported env))) + + (else (error "FIXME: unsupported environment" env)))))) + + (search l)))) + + +(define module-access-proc + (lambda (mod) + (let* ( + (name-pair (symlist->package+module mod)) + (package-sym (package+module->package-sym name-pair)) + (module-sym (package+module->module-sym name-pair))) + + (or (module-auto-load package-sym module-sym) + (module-load-error module-sym))))) + + +;; remove module from module-registry +(define module-close-proc + (lambda (mod) + (let* ( + (name-pair (symlist->package+module mod)) + (package-sym (package+module->package-sym name-pair)) + (module-sym (package+module->module-sym name-pair))) + + (environment-undefine (module-registry) module-sym)))) + + +(define module-open-internal + (lambda (skel imports) + + (let* ( + (eval (module-eval-environment skel)) + (import (eval-environment-imported eval))) + + (if (referenced eval imports) + (error "Can't open modules: circular dependency for " eval)) + + (interface-environment-set-interface! import imports)))) + +(define import-symlist->import-list + (lambda (skel import-symlist) + (letrec + ((fix-imports + (lambda (l) + (cond + ((null? l) '()) + ((not (list? (caar l))) (cons (cons (car l) #f) (fix-imports (cdr l)))) + (else (cons (car l) (fix-imports (cdr l)))))))) + + (let* ( + (import-symlist (fix-imports import-symlist)) + (import-modlist (map (lambda (x) (cons (module-access-proc (car x)) (cdr x))) import-symlist)) + (import-list (map (lambda (x) (cons (module-interface-environment skel (car x)) (cdr x))) import-modlist))) + + import-list)))) + +(define module-open-proc + (lambda (skel import-symlist) + (module-open-internal skel (import-symlist->import-list skel import-symlist)))) + +(define module-use-proc + (lambda (skel import-symlist) + (let* ( + (eval (module-eval-environment skel)) + (interface-env (eval-environment-imported eval)) + (interface (interface-environment-interface interface-env)) + (import-list (import-symlist->import-list skel import-symlist))) + + (module-open-internal skel (append import-list interface)) + (if #f #f) + ))) + + +(define module-ref-proc + (lambda (curr module sym) + (let ( + (name (module-name module)) + (interface-env (module-interface-environment curr module)) + ) + + (cond + ((environment-bound? interface-env sym) + (environment-ref interface-env sym)) + + (else (scm-error 'misc-error #f "Symbol `%s' is not exported from `%s'." (list sym name) #f)))))) + + +(define (module-proc current-module args) + (let* ( + (mod (car args)) + (arglist (cdr args)) + (current-module-sym (module-name current-module)) + (sym (symlist->module-sym mod)) + (same-module (eq? current-module-sym sym)) + (has-exports (assq 'export arglist)) + (skel (if same-module current-module (module-create-proc mod)))) + + (let loop ((arglist arglist) + (modules '()) + (exports '()) + (protects '())) + + (if (null? arglist) + (begin + + (if (not same-module) + (error "Can't manipulate a foreign module's interface.")) + + (module-open-proc skel modules) + + (if has-exports (module-export-proc skel exports)) + + (module-protect-proc skel protects) + ) + + + (begin + (if (not (pair? (car arglist))) + (error "unrecognized module argument in" current-module-sym)) + + (let ((fkt (caar arglist))) + (case fkt + ((open) + (loop (cdr arglist) + (append modules (cdar arglist)) + exports + protects)) + + ((export) + (loop (cdr arglist) + modules + (append exports (cdar arglist)) + protects)) + + ((protect) + (loop (cdr arglist) + modules + exports + (append protects (cdar arglist)))) + (else + (error "unrecognized module argument in" current-module-sym))))))))) + +(define (go-proc module) + (module-go (module-access-proc module))) + + +;;; High level interface + +;; declare a module +(define module + (procedure->memoizing-macro + (lambda (x env) + `(,module-proc (,the-module) (,quote ,(cdr x) ))))) + +;; open module and start a repl in it +(define go + (procedure->memoizing-macro + (lambda (x env) + (if (not (list? (cadr x))) (error "not a list:" (cadr x))) + `(,go-proc (,quote ,(cadr x)))))) + + +;;; low level interface + +;; access symbol exported from module +(define module-ref + (procedure->memoizing-macro + (lambda (x env) + `(,module-ref-proc (,the-module) ,(cadr x) ,(caddr x))))) + +;; add module to import-list +(define module-use + (procedure->memoizing-macro + (lambda (x env) + `(,module-use-proc (,the-module) (,quote ,(cdr x)))))) + +;; start a new import-list +(define module-open + (procedure->memoizing-macro + (lambda (x env) + `(,module-open-proc (,the-module) (,quote ,(cdr x)))))) + +;; load a module +(define module-load + (procedure->memoizing-macro + (lambda (x env) + (if (not ( + list? (cadr x))) (error "not a list:" (cadr x))) + `(,module-load-proc (,quote ,(cadr x)))))) + +;; publish symbols (visible to all other modules) +(define module-protect + (procedure->memoizing-macro + (lambda (x env) + `(,module-protect-proc (,the-module) (,quote ,(cdr x) ))))) + +;; make symbols visible to modules that belong the current package +(define module-export + (procedure->memoizing-macro + (lambda (x env) + `(,module-export-proc (,the-module) (,quote ,(cdr x)))))) + +;; open a module and return a handle +(define module-access + (procedure->memoizing-macro + (lambda (x env) + (if (not (list? (cadr x))) (error "not a list:" (cadr x))) + `(,module-access-proc (,quote ,(cadr x)))))) + +;; close a module (remove it from the module-registry) +(define module-close + (procedure->memoizing-macro + (lambda (x env) + (if (not (list? (cadr x))) (error "not a list:" (cadr x))) + `(,module-close-proc (,quote ,(cadr x)))))) + +;; create a in-memory module and return a handle +(define module-create + (procedure->memoizing-macro + (lambda (x env) + (if (not (list? (cadr x))) (error "not a list:" (cadr x))) + `(,module-create-proc (,quote ,(cadr x) ))))) + +;; import symbols from other modules +(define module-config-open + (procedure->memoizing-macro + (lambda (x env) + `(,module-open-proc (,module-access-proc (,quote ,(cadr x))) (,quote ,(cddr x)))))) + +;; make symbols visible within the current package +(define module-config-protect + (procedure->memoizing-macro + (lambda (x env) + `(,module-protect-proc (,module-access-proc (,quote ,(cadr x))) (,quote ,(cddr x)))))) + +;; make symbols visible to the world +(define module-config-export + (procedure->memoizing-macro + (lambda (x env) + `(,module-export-proc (,module-access-proc (,quote ,(cadr x))) (,quote ,(cddr x)))))) + + +;;; For backward compatibility +;;; + +(define (define-module-proc current-module args) + (let* ( + (kws (cdr args)) + (current-module-sym (module-name current-module)) + (mod (car args)) + (sym (symlist->module-sym mod)) + + ;; do not create a new module if the module names are the + ;; same and the current module has not been closed + (same-module (and (eq? current-module-sym sym) + (environment-bound? (module-registry) current-module-sym))) + + (skel (if same-module + current-module + (module-create-proc mod)))) + + + (let loop ((kws kws) + (modules '())) + (if (null? kws) + (begin + ;; append (ice-9 guile) and (ice-9 config) for convenience + (module-open-proc skel (cons '(ice-9 config) (cons '(ice-9 guile) modules))) + (if (not same-module) (module-go (module-access-proc mod))) + ) + + (let ((keyword (car kws))) + (let ((keyword (if (keyword? keyword) (keyword->symbol keyword) keyword))) + (case keyword + ((use-module use-syntax autoload :use-module :use-syntax :autoload) + (let ( + (mod (cadr kws))) + + (if (not (pair? mod)) + (error "unrecognized defmodule argument" kws)) + + (loop (cddr kws) + (cons mod modules)))) + ((no-backtrace :no-backtrace) + (loop (cdr kws) modules)) + (else + (error "unrecognized defmodule argument" kws))))))))) + +(define define-module + (procedure->memoizing-macro + (lambda (x env) + `(,define-module-proc (,the-module) (,quote ,(cdr x) ))))) + +;; rewrite me +(define define-public + (procedure->memoizing-macro + (lambda (x env) + (let ((args (cdr x))) + (letrec ( + (syntax (lambda () + (error "bad syntax" (list 'define-public args)))) + (defined-name + (lambda (n) + (cond + ((symbol? n) n) + ((pair? n) (defined-name (car n))) + (else (syntax))))) + ) + + (if (null? args) (syntax)) + + (let ( + (name (defined-name (car args)))) + + `(begin + (letrec ( + ;; according to environment proposal either + ;; symbol or (sym tags) + (get-symbol + (lambda (s) + (cond + ((pair? s) (car s)) + (else s)))) + + ;; test if symbol is already exported + (exported? + (lambda (sym l) + (cond + ((null? l) #f) + ((eq? (get-symbol (car l)) sym) #t) + (else (exported? sym (cdr l))))))) + + (let* ( + (module-eval-environment ,module-eval-environment) + (module-export-environment ,module-export-environment) + (interface-environment-interface ,interface-environment-interface) + (environment-bound? ,environment-bound?) + (environment-ref ,environment-ref) + (environment-define ,environment-define) + (the-module ,the-module) + (the-environment ,the-environment) + (interface-environment-set-interface! ,interface-environment-set-interface!) + (module-export-list ,module-export-list) + + (module (the-module)) + (eval-env (module-eval-environment module)) + (export (module-export-environment module)) + (export-list (module-export-list module)) + + (val (,and (,environment-bound? eval-env ',name) + (,environment-ref eval-env ',name)))) + + (if (not (list? export-list)) + (,error "You can either use `define-public' or `export', but not both")) + + (if (not (memq ',name export-list)) + (begin + (environment-define eval-env ',name val) + (set! export-list (cons ',name export-list)) + (,module-set-export-list! module export-list) + (interface-environment-set-interface! + export + (list (cons eval-env export-list))))) + + + + ;; Now (re)define the var normally. Bernard URBAN + ;; suggests we use eval here to accomodate Hobbit; it lets + ;; the interpreter handle the define-private form, which + ;; Hobbit can't digest. + (eval '(define ,@ args) (the-environment)) + + ))))))))) + + +;; the entry point (called by (ice-9 repl)) +(define start + (lambda () + (module-go #f))) + diff --git a/ice-9/defmacro.scm b/ice-9/defmacro.scm new file mode 100644 index 000000000..c0c96a526 --- /dev/null +++ b/ice-9/defmacro.scm @@ -0,0 +1,114 @@ +(module (ice-9 defmacro) + (open (ice-9 error) + (ice-9 provide) + (ice-9 guile)) + (export defmacro gentemp defmacro:transformer defmacro:syntax-transformer)) + + +;;; {Macros} +;;; + +(define (primitive-macro? m) + (and (macro? m) + (not (macro-transformer m)))) + +;;; {Defmacros} +;;; +(define macro-table (make-weak-key-hash-table 523)) +(define xformer-table (make-weak-key-hash-table 523)) + +(define (defmacro? m) (hashq-ref macro-table m)) +(define (assert-defmacro?! m) (hashq-set! macro-table m #t)) +(define (defmacro-transformer m) (hashq-ref xformer-table m)) +(define (set-defmacro-transformer! m t) (hashq-set! xformer-table m t)) + +(define defmacro:transformer + (lambda (f) + (let* ((xform (lambda (exp env) + (copy-tree (apply f (cdr exp))))) + (a (procedure->memoizing-macro xform))) + (assert-defmacro?! a) + (set-defmacro-transformer! a f) + a))) + + +(define defmacro + (let ((defmacro-transformer + (lambda (name parms . body) + (let ((transformer `(lambda ,parms ,@body))) + `(define ,name + (,(lambda (transformer) + (defmacro:transformer transformer)) + ,transformer)))))) + (defmacro:transformer defmacro-transformer))) + + +; (defmacro defmacro-public args +; (define (syntax) +; (error "bad syntax" (list 'defmacro-public args))) +; (define (defined-name n) +; (cond +; ((symbol? n) n) +; (else (syntax)))) +; (cond +; ((null? args) (syntax)) + +; (#t +; (let ((name (defined-name (car args)))) +; `(begin +; (let* ( +; (module (the-module)) +; (eval (module-eval-environment module)) + +; ;; look up the old value first +; (val (if (environment-bound? eval ',name) +; (environment-ref eval ',name) +; (begin +; (environment-define eval ',name #f) +; #f))) + +; (export (module-export-environment module))) +; (if (not (environment? export)) +; (let ( ;; create export environment +; (export (make-export-environment eval (list ',name)))) +; (module-export-environment-set! module export) +; ) +; (environment-define export ',name val))) + +; ;; Now (re)define the var normally. +; ;; +; (defmacro ,@ args)))))) + +(define defmacro:syntax-transformer + (lambda (f) + (procedure->syntax + (lambda (exp env) + (copy-tree (apply f (cdr exp))))))) + + +;; XXX - should the definition of the car really be looked up in the +;; current module? + +(define (macroexpand-1 e) + (cond + ((pair? e) (let* ((a (car e)) + (val (and (symbol? a) (local-ref (list a))))) + (if (defmacro? val) + (apply (defmacro-transformer val) (cdr e)) + e))) + (#t e))) + +(define (macroexpand e) + (cond + ((pair? e) (let* ((a (car e)) + (val (and (symbol? a) (local-ref (list a))))) + (if (defmacro? val) + (macroexpand (apply (defmacro-transformer val) (cdr e))) + e))) + (#t e))) + +(define (gentemp) + (gensym "scm:G")) + +(provide 'defmacro) + diff --git a/ice-9/error.scm b/ice-9/error.scm new file mode 100644 index 000000000..8da006d4f --- /dev/null +++ b/ice-9/error.scm @@ -0,0 +1,37 @@ +;;; {Error Handling} +;;; + +(module (ice-9 error) + (open (ice-9 guile) + ((ice-9 repl) save-stack)) + (export error warn)) + +(define (error . args) + (save-stack) + (if (null? args) + (scm-error 'misc-error #f "?" #f #f) + (let loop ((msg "%s") + (rest (cdr args))) + (if (not (null? rest)) + (loop (string-append msg " %S") + (cdr rest)) + (scm-error 'misc-error #f msg args #f))))) + +;; bad-throw is the hook that is called upon a throw to a an unhandled +;; key (unless the throw has four arguments, in which case +;; it's usually interpreted as an error throw.) +;; If the key has a default handler (a throw-handler-default property), +;; it is applied to the throw. +;; +(define (bad-throw key . args) + (apply error "unhandled-exception:" key args)) + + +(define (warn . stuff) + (with-output-to-port (current-error-port) + (lambda () + (newline) + (display ";;; WARNING ") + (display stuff) + (newline) + (car (last-pair stuff)))))
\ No newline at end of file diff --git a/ice-9/files.scm b/ice-9/files.scm new file mode 100644 index 000000000..7c150530c --- /dev/null +++ b/ice-9/files.scm @@ -0,0 +1,246 @@ +(module (ice-9 files) + + (open (ice-9 posix) + (ice-9 guile) + (ice-9 provide) + ((ice-9 strorder) string=?)) + + (export scm-line-incrementors + read-line + file-exists? + file-is-directory? + has-suffix? + load-from-path + (dev (alias stat:dev)) + (ino (alias stat:ino)) + (mode (alias stat:mode)) + (nlink (alias stat:nlink)) + (uid (alias stat:uid)) + (gid (alias stat:gid)) + (rdev (alias stat:rdev)) + (size (alias stat:size)) + (atime (alias stat:atime)) + (mtime (alias stat:mtime)) + (ctime (alias stat:ctime)) + (blksize (alias stat:blksize)) + (blocks (alias stat:blocks)) + (type (alias stat:type)) + (perms (alias stat:perms)) + read-delimited + read-delimited! + )) + + +;;; {Line and Delimited I/O} + +;;; corresponds to SCM_LINE_INCREMENTORS in libguile. +(define scm-line-incrementors "\n") + +(define (read-line! string . maybe-port) + (let* ((port (if (pair? maybe-port) + (car maybe-port) + (current-input-port)))) + (let* ((rv (%read-delimited! scm-line-incrementors + string + #t + port)) + (terminator (car rv)) + (nchars (cdr rv))) + (cond ((and (= nchars 0) + (eof-object? terminator)) + terminator) + ((not terminator) #f) + (else nchars))))) + +(define (read-delimited! delims buf . args) + (let* ((num-args (length args)) + (port (if (> num-args 0) + (car args) + (current-input-port))) + (handle-delim (if (> num-args 1) + (cadr args) + 'trim)) + (start (if (> num-args 2) + (caddr args) + 0)) + (end (if (> num-args 3) + (cadddr args) + (string-length buf)))) + (let* ((rv (%read-delimited! delims + buf + (not (eq? handle-delim 'peek)) + port + start + end)) + (terminator (car rv)) + (nchars (cdr rv))) + (cond ((or (not terminator) ; buffer filled + (eof-object? terminator)) + (if (zero? nchars) + (if (eq? handle-delim 'split) + (cons terminator terminator) + terminator) + (if (eq? handle-delim 'split) + (cons nchars terminator) + nchars))) + (else + (case handle-delim + ((trim peek) nchars) + ((concat) (string-set! buf nchars terminator) + (+ nchars 1)) + ((split) (cons nchars terminator)) + (else (error "unexpected handle-delim value: " + handle-delim)))))))) + +(define (read-delimited delims . args) + (let* ((port (if (pair? args) + (let ((pt (car args))) + (set! args (cdr args)) + pt) + (current-input-port))) + (handle-delim (if (pair? args) + (car args) + 'trim))) + (let loop ((substrings ()) + (total-chars 0) + (buf-size 100)) ; doubled each time through. + (let* ((buf (make-string buf-size)) + (rv (%read-delimited! delims + buf + (not (eq? handle-delim 'peek)) + port)) + (terminator (car rv)) + (nchars (cdr rv)) + (join-substrings + (lambda () + (apply string-append + (reverse + (cons (if (and (eq? handle-delim 'concat) + (not (eof-object? terminator))) + (string terminator) + "") + (cons (make-shared-substring buf 0 nchars) + substrings)))))) + (new-total (+ total-chars nchars))) + (cond ((not terminator) + ;; buffer filled. + (loop (cons (substring buf 0 nchars) substrings) + new-total + (* buf-size 2))) + ((eof-object? terminator) + (if (zero? new-total) + (if (eq? handle-delim 'split) + (cons terminator terminator) + terminator) + (if (eq? handle-delim 'split) + (cons (join-substrings) terminator) + (join-substrings)))) + (else + (case handle-delim + ((trim peek concat) (join-substrings)) + ((split) (cons (join-substrings) terminator)) + + + (else (error "unexpected handle-delim value: " + handle-delim))))))))) + +;;; read-line [PORT [HANDLE-DELIM]] reads a newline-terminated string +;;; from PORT. The return value depends on the value of HANDLE-DELIM, +;;; which may be one of the symbols `trim', `concat', `peek' and +;;; `split'. If it is `trim' (the default), the trailing newline is +;;; removed and the string is returned. If `concat', the string is +;;; returned with the trailing newline intact. If `peek', the newline +;;; is left in the input port buffer and the string is returned. If +;;; `split', the newline is split from the string and read-line +;;; returns a pair consisting of the truncated string and the newline. + +(define (read-line . args) + (let* ((port (if (null? args) + (current-input-port) + (car args))) + (handle-delim (if (> (length args) 1) + (cadr args) + 'trim)) + (line/delim (%read-line port)) + (line (car line/delim)) + (delim (cdr line/delim))) + (case handle-delim + ((trim) line) + ((split) line/delim) + ((concat) (if (and (string? line) (char? delim)) + (string-append line (string delim)) + line)) + ((peek) (if (char? delim) + (unread-char delim port)) + line) + (else + (error "unexpected handle-delim value: " handle-delim))))) + + + +;;; {Files} +;;; +;;; If no one can explain this comment to me by 31 Jan 1998, I will +;;; assume it is meaningless and remove it. -twp +;;; !!!! these should be implemented using Tcl commands, not fports. + +;; Using the vector returned by stat directly is probably not a good +;; idea (it could just as well be a record). Hence some accessors. +(define (dev f) (vector-ref f 0)) +(define (ino f) (vector-ref f 1)) +(define (mode f) (vector-ref f 2)) +(define (nlink f) (vector-ref f 3)) +(define (uid f) (vector-ref f 4)) +(define (gid f) (vector-ref f 5)) +(define (rdev f) (vector-ref f 6)) +(define (size f) (vector-ref f 7)) +(define (atime f) (vector-ref f 8)) +(define (mtime f) (vector-ref f 9)) +(define (ctime f) (vector-ref f 10)) +(define (blksize f) (vector-ref f 11)) +(define (blocks f) (vector-ref f 12)) + +;; derived from stat mode. +(define (type f) (vector-ref f 13)) +(define (perms f) (vector-ref f 14)) + +(define file-exists? + (if (feature? 'posix) + (lambda (str) + (access? str F_OK)) + (lambda (str) + (let ((port (catch 'system-error (lambda () (open-file str OPEN_READ)) + (lambda args #f)))) + (if port (begin (close-port port) #t) + #f))))) + +(define file-is-directory? + (if (feature? 'i/o-extensions) + (lambda (str) + (eq? (type (stat str)) 'directory)) + (lambda (str) + (display str) + (newline) + (let ((port (catch 'system-error + (lambda () (open-file (string-append str "/.") + OPEN_READ)) + (lambda args #f)))) + (if port (begin (close-port port) #t) + #f))))) + +(define (has-suffix? str suffix) + (let ((sufl (string-length suffix)) + (sl (string-length str))) + (and (> sl sufl) + (string=? (substring str (- sl sufl) sl) suffix)))) + + +;;; {Loading by paths} + +;;; Load a Scheme source file named NAME, searching for it in the +;;; directories listed in %load-path, and applying each of the file +;;; name extensions listed in %load-extensions. +(define (load-from-path name) + (start-stack 'load-stack + (primitive-load-path name (interaction-environment)))) + diff --git a/ice-9/hooks.scm b/ice-9/hooks.scm new file mode 100644 index 000000000..a6e4f6c6b --- /dev/null +++ b/ice-9/hooks.scm @@ -0,0 +1,23 @@ +;;; {Hooks} +;;; +;;; Warning: Hooks are now first class objects and add-hook! and remove-hook! +;;; procedures. This interface is only provided for backward compatibility +;;; and will be removed. +;;; +(module-open (ice-9 guile)) +(if (not (defined? new-add-hook!)) + (begin + (define new-add-hook! add-hook!) + (define new-remove-hook! remove-hook!))) + +(define (run-hooks hook) + (if (and (pair? hook) (eq? (car hook) 'hook)) + (run-hook hook) + (for-each (lambda (thunk) (thunk)) hook))) + +(define *suppress-old-style-hook-warning* #f) + +(define abort-hook (make-hook)) + + + diff --git a/ice-9/keywords.scm b/ice-9/keywords.scm new file mode 100644 index 000000000..da45f046a --- /dev/null +++ b/ice-9/keywords.scm @@ -0,0 +1,15 @@ + +;;; {Keywords} +;;; + +(define (symbol->keyword symbol) + (make-keyword-from-dash-symbol (symbol-append '- symbol))) + +(define (keyword->symbol kw) + (let ((sym (keyword-dash-symbol kw))) + (string->symbol (substring sym 1 (string-length sym))))) + +(define (kw-arg-ref args kw) + (let ((rem (member kw args))) + (and rem (pair? (cdr rem)) (cadr rem)))) + diff --git a/ice-9/lists.scm b/ice-9/lists.scm new file mode 100644 index 000000000..654bab60e --- /dev/null +++ b/ice-9/lists.scm @@ -0,0 +1,23 @@ +;;; {Lists} +;;; +(module (ice-9 lists) + (open (ice-9 guile)) + (export list-index make-list)) + +(define (list-index l k) + (let loop ((n 0) + (l l)) + (and (not (null? l)) + (if (eq? (car l) k) + n + (loop (+ n 1) (cdr l)))))) + +(define (make-list n . init) + (if (pair? init) (set! init (car init))) + (let loop ((answer '()) + (n n)) + (if (<= n 0) + answer + (loop (cons init answer) (- n 1))))) + + diff --git a/ice-9/macros.scm b/ice-9/macros.scm new file mode 100644 index 000000000..e697861d1 --- /dev/null +++ b/ice-9/macros.scm @@ -0,0 +1,28 @@ +;;; {Macros} +;;; + +;; actually....hobbit might be able to hack these with a little +;; coaxing +;; +(module (ice-9 macros) + (export define-macro define-syntax-macro defmacro:transformer defmacro:syntax-transformer) + (open (ice-9 guile) (ice-9 defmacro))) + + +(defmacro define-macro (first . rest) + (let ((name (if (symbol? first) first (car first))) + (transformer + (if (symbol? first) + (car rest) + `(lambda ,(cdr first) ,@rest)))) + `(define ,name (defmacro:transformer ,transformer)))) + + +(defmacro define-syntax-macro (first . rest) + (let ((name (if (symbol? first) first (car first))) + (transformer + (if (symbol? first) + (car rest) + `(lambda ,(cdr first) ,@rest)))) + `(define ,name (defmacro:syntax-transformer ,transformer)))) + diff --git a/ice-9/math.scm b/ice-9/math.scm new file mode 100644 index 000000000..f60d284e1 --- /dev/null +++ b/ice-9/math.scm @@ -0,0 +1,102 @@ + +;;; {Transcendental Functions} +;;; +;;; Derived from "Transcen.scm", Complex trancendental functions for SCM. +;;; Written by Jerry D. Hedden, (C) FSF. +;;; See the file `COPYING' for terms applying to this program. +;;; + +(define (exp z) + (if (real? z) ($exp z) + (make-polar ($exp (real-part z)) (imag-part z)))) + +(define (log z) + (if (and (real? z) (>= z 0)) + ($log z) + (make-rectangular ($log (magnitude z)) (angle z)))) + +(define (sqrt z) + (if (real? z) + (if (negative? z) (make-rectangular 0 ($sqrt (- z))) + ($sqrt z)) + (make-polar ($sqrt (magnitude z)) (/ (angle z) 2)))) + +(define expt + (let ((integer-expt integer-expt)) + (lambda (z1 z2) + (cond ((exact? z2) + (integer-expt z1 z2)) + ((and (real? z2) (real? z1) (>= z1 0)) + ($expt z1 z2)) + (else + (exp (* z2 (log z1)))))))) + +(define (sinh z) + (if (real? z) ($sinh z) + (let ((x (real-part z)) (y (imag-part z))) + (make-rectangular (* ($sinh x) ($cos y)) + (* ($cosh x) ($sin y)))))) +(define (cosh z) + (if (real? z) ($cosh z) + (let ((x (real-part z)) (y (imag-part z))) + (make-rectangular (* ($cosh x) ($cos y)) + (* ($sinh x) ($sin y)))))) +(define (tanh z) + (if (real? z) ($tanh z) + (let* ((x (* 2 (real-part z))) + (y (* 2 (imag-part z))) + (w (+ ($cosh x) ($cos y)))) + (make-rectangular (/ ($sinh x) w) (/ ($sin y) w))))) + +(define (asinh z) + (if (real? z) ($asinh z) + (log (+ z (sqrt (+ (* z z) 1)))))) + +(define (acosh z) + (if (and (real? z) (>= z 1)) + ($acosh z) + (log (+ z (sqrt (- (* z z) 1)))))) + +(define (atanh z) + (if (and (real? z) (> z -1) (< z 1)) + ($atanh z) + (/ (log (/ (+ 1 z) (- 1 z))) 2))) + +(define (sin z) + (if (real? z) ($sin z) + (let ((x (real-part z)) (y (imag-part z))) + (make-rectangular (* ($sin x) ($cosh y)) + (* ($cos x) ($sinh y)))))) +(define (cos z) + (if (real? z) ($cos z) + (let ((x (real-part z)) (y (imag-part z))) + (make-rectangular (* ($cos x) ($cosh y)) + (- (* ($sin x) ($sinh y))))))) +(define (tan z) + (if (real? z) ($tan z) + (let* ((x (* 2 (real-part z))) + (y (* 2 (imag-part z))) + (w (+ ($cos x) ($cosh y)))) + (make-rectangular (/ ($sin x) w) (/ ($sinh y) w))))) + +(define (asin z) + (if (and (real? z) (>= z -1) (<= z 1)) + ($asin z) + (* -i (asinh (* +i z))))) + +(define (acos z) + (if (and (real? z) (>= z -1) (<= z 1)) + ($acos z) + (+ (/ (angle -1) 2) (* +i (asinh (* +i z)))))) + +(define (atan z . y) + (if (null? y) + (if (real? z) ($atan z) + (/ (log (/ (- +i z) (+ +i z))) +2i)) + ($atan2 z (car y)))) + +(set! abs magnitude) + +(define (log10 arg) + (/ (log arg) (log 10))) + diff --git a/ice-9/misc.scm b/ice-9/misc.scm new file mode 100644 index 000000000..6c892e7d7 --- /dev/null +++ b/ice-9/misc.scm @@ -0,0 +1,333 @@ +(module (ice-9 misc) + (export in-vicinity with-fluids) + (open (ice-9 structs) (ice-9 files) (ice-9 defmacro) (ice-9 provide) (ice-9 guile))) + + + +;;; {Simple Debugging Tools} +;; + +;; peek takes any number of arguments, writes them to the +;; current ouput port, and returns the last argument. +;; It is handy to wrap around an expression to look at +;; a value each time is evaluated, e.g.: +;; +;; (+ 10 (troublesome-fn)) +;; => (+ 10 (pk 'troublesome-fn-returned (troublesome-fn))) +;; + +(define (peek . stuff) + (newline) + (display ";;; ") + (write stuff) + (newline) + (car (last-pair stuff))) + +(define pk peek) + + + + +;;; {Trivial Functions} +;;; + +(define (id x) x) +(define (1+ n) (+ n 1)) +(define (-1+ n) (+ n -1)) +(define 1- -1+) +(define return-it noop) +(define (and=> value procedure) (and value (procedure value))) +(define (make-hash-table k) (make-vector k '())) + +;;; apply-to-args is functionally redunant with apply and, worse, +;;; is less general than apply since it only takes two arguments. +;;; +;;; On the other hand, apply-to-args is a syntacticly convenient way to +;;; perform binding in many circumstances when the "let" family of +;;; of forms don't cut it. E.g.: +;;; +;;; (apply-to-args (return-3d-mouse-coords) +;;; (lambda (x y z) +;;; ...)) +;;; + +(define (apply-to-args args fn) (apply fn args)) + + +;;; {Integer Math} +;;; + +(define (ipow-by-squaring x k acc proc) + (cond ((zero? k) acc) + ((= 1 k) (proc acc x)) + (else (ipow-by-squaring (proc x x) + (quotient k 2) + (if (even? k) acc (proc acc x)) + proc)))) + +(define string-character-length string-length) + + + +;; A convenience function for combining flag bits. Like logior, but +;; handles the cases of 0 and 1 arguments. +;; +(define (flags . args) + (cond + ((null? args) 0) + ((null? (cdr args)) (car args)) + (else (apply logior args)))) + + +;;; {Multiple return values} + +(define *values-rtd* + (make-record-type "values" + '(values))) + +(define values + (let ((make-values (record-constructor *values-rtd*))) + (lambda x + (if (and (not (null? x)) + (null? (cdr x))) + (car x) + (make-values x))))) + +(define call-with-values + (let ((access-values (record-accessor *values-rtd* 'values)) + (values-predicate? (record-predicate *values-rtd*))) + (lambda (producer consumer) + (let ((result (producer))) + (if (values-predicate? result) + (apply consumer (access-values result)) + (consumer result)))))) + + + +;;; {and-map and or-map} +;;; +;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...) +;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...) +;;; (map-in-order fn lst) is like (map fn lst) but definately in order of lst. +;;; + +;; and-map f l +;; +;; Apply f to successive elements of l until exhaustion or f returns #f. +;; If returning early, return #f. Otherwise, return the last value returned +;; by f. If f has never been called because l is empty, return #t. +;; +(define (and-map f lst) + (let loop ((result #t) + (l lst)) + (and result + (or (and (null? l) + result) + (loop (f (car l)) (cdr l)))))) + +;; or-map f l +;; +;; Apply f to successive elements of l until exhaustion or while f returns #f. +;; If returning early, return the return value of f. +;; +(define (or-map f lst) + (let loop ((result #f) + (l lst)) + (or result + (and (not (null? l)) + (loop (f (car l)) (cdr l)))))) + + +;;; {Booleans} +;;; + +(define (->bool x) (not (not x))) + + +;;; {Load Paths} +;;; + +;;; Here for backward compatability +;; +(define scheme-file-suffix (lambda () ".scm")) + +(define (in-vicinity vicinity file) + (let ((tail (let ((len (string-length vicinity))) + (if (zero? len) + #f + (string-ref vicinity (- len 1)))))) + (string-append vicinity + (if (or (not tail) + (eq? tail #\/)) + "" + "/") + file))) + + +;;; {Help for scm_shell} +;;; The argument-processing code used by Guile-based shells generates +;;; Scheme code based on the argument list. This page contains help +;;; functions for the code it generates. + +(define (command-line) (program-arguments)) + +;; This is mostly for the internal use of the code generated by +;; scm_compile_shell_switches. +(define (load-user-init) + (define (has-init? dir) + (let ((path (in-vicinity dir ".guile"))) + (catch 'system-error + (lambda () + (let ((stats (stat path))) + (if (not (eq? (stat:type stats) 'directory)) + path))) + (lambda dummy #f)))) + (let ((path (or (has-init? (or (getenv "HOME") "/")) + (has-init? (passwd:dir (getpw (getuid))))))) + (if path (primitive-load path)))) + + + +;;; {Reader Extensions} +;;; + +;;; Reader code for various "#c" forms. +;;; + +;;; Parse the portion of a #/ list that comes after the first slash. +(define (read-path-list-notation slash port) + (letrec + + ;; Is C a delimiter? + ((delimiter? (lambda (c) (or (eof-object? c) + (char-whitespace? c) + (string-index "()\";" c)))) + + ;; Read and return one component of a path list. + (read-component + (lambda () + (let loop ((reversed-chars '())) + (let ((c (peek-char port))) + (if (or (delimiter? c) + (char=? c #\/)) + (string->symbol (list->string (reverse reversed-chars))) + (loop (cons (read-char port) reversed-chars)))))))) + + ;; Read and return a path list. + (let loop ((reversed-path (list (read-component)))) + (let ((c (peek-char port))) + (if (and (char? c) (char=? c #\/)) + (begin + (read-char port) + (loop (cons (read-component) reversed-path))) + (reverse reversed-path)))))) + +(define (read-path-list-notation-warning slash port) + (if (not (getenv "GUILE_HUSH")) + (begin + (display "warning: obsolete `#/' list notation read from " + (current-error-port)) + (display (port-filename port) (current-error-port)) + (display "; see guile-core/NEWS." (current-error-port)) + (newline (current-error-port)) + (display " Set the GUILE_HUSH environment variable to disable this warning." + (current-error-port)) + (newline (current-error-port)))) + (read-hash-extend #\/ read-path-list-notation) + (read-path-list-notation slash port)) + + +(read-hash-extend #\' (lambda (c port) + (read port))) +(read-hash-extend #\. (lambda (c port) + (eval (read port) (the-environment)))) + +(if (feature? 'array) + (begin + (let ((make-array-proc (lambda (template) + (lambda (c port) + (read:uniform-vector template port))))) + (for-each (lambda (char template) + (read-hash-extend char + (make-array-proc template))) + '(#\b #\a #\u #\e #\s #\i #\c #\y #\h) + '(#t #\a 1 -1 1.0 1/3 0+i #\nul s))) + (let ((array-proc (lambda (c port) + (read:array c port)))) + (for-each (lambda (char) (read-hash-extend char array-proc)) + '(#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))))) + +;; pushed to the beginning of the alist since it's used more than the +;; others at present. +(read-hash-extend #\/ read-path-list-notation-warning) + +(define (read:array digit port) + (define chr0 (char->integer #\0)) + (let ((rank (let readnum ((val (- (char->integer digit) chr0))) + (if (char-numeric? (peek-char port)) + (readnum (+ (* 10 val) + (- (char->integer (read-char port)) chr0))) + val))) + (prot (if (eq? #\( (peek-char port)) + '() + (let ((c (read-char port))) + (case c ((#\b) #t) + ((#\a) #\a) + ((#\u) 1) + ((#\e) -1) + ((#\s) 1.0) + ((#\i) 1/3) + ((#\c) 0+i) + (else (error "read:array unknown option " c))))))) + (if (eq? (peek-char port) #\() + (list->uniform-array rank prot (read port)) + (error "read:array list not found")))) + +(define (read:uniform-vector proto port) + (if (eq? #\( (peek-char port)) + (list->uniform-array 1 proto (read port)) + (error "read:uniform-vector list not found"))) + + +;;; {IOTA functions: generating lists of numbers} + +(define (reverse-iota n) (if (> n 0) (cons (1- n) (reverse-iota (1- n))) '())) +(define (iota n) (reverse! (reverse-iota n))) + + +;;; {While} +;;; +;;; with `continue' and `break'. +;;; + +(defmacro while (cond . body) + `(letrec ((continue (lambda () (or (not ,cond) (begin (begin ,@ body) (continue))))) + (break (lambda val (apply throw 'break val)))) + (catch 'break + (lambda () (continue)) + (lambda v (cadr v))))) + +;;; {collect} +;;; +;;; Similar to `begin' but returns a list of the results of all constituent +;;; forms instead of the result of the last form. +;;; (The definition relies on the current left-to-right +;;; order of evaluation of operands in applications.) + +(defmacro collect forms + (cons 'list forms)) + +;;; {with-fluids} + +;; with-fluids is a convenience wrapper for the builtin procedure +;; `with-fluids*'. The syntax is just like `let': +;; +;; (with-fluids ((fluid val) +;; ...) +;; body) + +(defmacro with-fluids (bindings . body) + `(with-fluids* (list ,@(map car bindings)) (list ,@(map cadr bindings)) + (lambda () ,@body))) + + diff --git a/ice-9/modules.scm b/ice-9/modules.scm new file mode 100644 index 000000000..630a6e697 --- /dev/null +++ b/ice-9/modules.scm @@ -0,0 +1,82 @@ +;;; this is an add-on module for those who want to "load" the module +;;; system. + + +;; load the standard module system and add the module which exports +;; the module configuration language to the current module's import +;; list +(eval + `(letrec ( + + + ; return #f if module system + ; has already been loaded + (load-module-system + + (let ( + (load-sys-modules + (lambda (repl-env) + (if (not (environment-bound? (module-registry) 'ice-9/config)) + (begin + (eval '(make-guile-module) repl-env) + (eval '(make-repl-module) repl-env) + (eval '(make-user-module) repl-env) + (let ( + (ice-9/config (eval '(make-config-module) repl-env))) + (primitive-load-path "ice-9/config.scm" (vector-ref ice-9/config 0)) + #t)) + #f)))) + + (lambda () + ; the code that creates system + ; modules comes from the repl + ; module. + + (if (not (environment-bound? (module-registry) 'ice-9/repl)) + + (let* ( + (import (make-interface-environment (list (cons (scheme-guile-environment 2) #t)))) + (eval-env (make-eval-environment (make-leaf-environment) import))) + (primitive-load-path "ice-9/repl.scm" eval-env) + (load-sys-modules eval-env)) + (let* ( + (repl-module (environment-ref (module-registry) 'ice-9/repl)) + (eval-env (vector-ref repl-module 0))) + (load-sys-modules eval-env)))))) + + ; fix current interface + (set-new-interface + (lambda (current-interface-env) + (let ( + (guile-export (vector-ref (environment-ref (module-registry) 'ice-9/guile) 1)) + (config-export (vector-ref (environment-ref (module-registry) 'ice-9/config) 1))) + + (interface-environment-set-interface! + current-interface-env + (list (cons config-export #f) (cons guile-export #f)))))) + + + ; append config-export to + ; current interface + (append-interface + (lambda (current-interface-env) + (let ( + (import-interface (interface-environment-interface current-interface-env)) + (config-export (vector-ref (environment-ref (module-registry) 'ice-9/config) 1))) + + (if (not (assq config-export import-interface)) + (interface-environment-set-interface! + current-interface-env + (cons (cons config-export #t) import-interface))))))) + + (let* ( + (current-eval-env ,(the-environment)) + (current-interface-env (eval-environment-imported current-eval-env))) + + (if (load-module-system) + (set-new-interface current-interface-env) + (append-interface current-interface-env)))) + + (scheme-guile-environment 2)) + + diff --git a/ice-9/options.scm b/ice-9/options.scm new file mode 100644 index 000000000..8bc3e3fe7 --- /dev/null +++ b/ice-9/options.scm @@ -0,0 +1,223 @@ +(define-module (ice-9 options) :use-module (ice-9 defmacro)) +;;; {Command Line Options} +;;; + +(define (get-option argv kw-opts kw-args return) + (cond + ((null? argv) + (return #f #f argv)) + + ((or (not (eq? #\- (string-ref (car argv) 0))) + (eq? (string-length (car argv)) 1)) + (return 'normal-arg (car argv) (cdr argv))) + + ((eq? #\- (string-ref (car argv) 1)) + (let* ((kw-arg-pos (or (string-index (car argv) #\=) + (string-length (car argv)))) + (kw (symbol->keyword (substring (car argv) 2 kw-arg-pos))) + (kw-opt? (member kw kw-opts)) + (kw-arg? (member kw kw-args)) + (arg (or (and (not (eq? kw-arg-pos (string-length (car argv)))) + (substring (car argv) + (+ kw-arg-pos 1) + (string-length (car argv)))) + (and kw-arg? + (begin (set! argv (cdr argv)) (car argv)))))) + (if (or kw-opt? kw-arg?) + (return kw arg (cdr argv)) + (return 'usage-error kw (cdr argv))))) + + (else + (let* ((char (substring (car argv) 1 2)) + (kw (symbol->keyword char))) + (cond + + ((member kw kw-opts) + (let* ((rest-car (substring (car argv) 2 (string-length (car argv)))) + (new-argv (if (= 0 (string-length rest-car)) + (cdr argv) + (cons (string-append "-" rest-car) (cdr argv))))) + (return kw #f new-argv))) + + ((member kw kw-args) + (let* ((rest-car (substring (car argv) 2 (string-length (car argv)))) + (arg (if (= 0 (string-length rest-car)) + (cadr argv) + rest-car)) + (new-argv (if (= 0 (string-length rest-car)) + (cddr argv) + (cdr argv)))) + (return kw arg new-argv))) + + (else (return 'usage-error kw argv))))))) + +(define (for-next-option proc argv kw-opts kw-args) + (let loop ((argv argv)) + (get-option argv kw-opts kw-args + (lambda (opt opt-arg argv) + (and opt (proc opt opt-arg argv loop)))))) + +(define (display-usage-report kw-desc) + (for-each + (lambda (kw) + (or (eq? (car kw) #t) + (eq? (car kw) 'else) + (let* ((opt-desc kw) + (help (cadr opt-desc)) + (opts (car opt-desc)) + (opts-proper (if (string? (car opts)) (cdr opts) opts)) + (arg-name (if (string? (car opts)) + (string-append "<" (car opts) ">") + "")) + (left-part (string-append + (with-output-to-string + (lambda () + (map (lambda (x) (display (keyword-symbol x)) (display " ")) + opts-proper))) + arg-name)) + (middle-part (if (and (< (string-length left-part) 30) + (< (string-length help) 40)) + (make-string (- 30 (string-length left-part)) #\ ) + "\n\t"))) + (display left-part) + (display middle-part) + (display help) + (newline)))) + kw-desc)) + + + +(define (transform-usage-lambda cases) + (let* ((raw-usage (delq! 'else (map car cases))) + (usage-sans-specials (map (lambda (x) + (or (and (not (list? x)) x) + (and (symbol? (car x)) #t) + (and (boolean? (car x)) #t) + x)) + raw-usage)) + (usage-desc (delq! #t usage-sans-specials)) + (kw-desc (map car usage-desc)) + (kw-opts (apply append (map (lambda (x) (and (not (string? (car x))) x)) kw-desc))) + (kw-args (apply append (map (lambda (x) (and (string? (car x)) (cdr x))) kw-desc))) + (transmogrified-cases (map (lambda (case) + (cons (let ((opts (car case))) + (if (or (boolean? opts) (eq? 'else opts)) + opts + (cond + ((symbol? (car opts)) opts) + ((boolean? (car opts)) opts) + ((string? (caar opts)) (cdar opts)) + (else (car opts))))) + (cdr case))) + cases))) + `(let ((%display-usage (lambda () (display-usage-report ',usage-desc)))) + (lambda (%argv) + (let %next-arg ((%argv %argv)) + (get-option %argv + ',kw-opts + ',kw-args + (lambda (%opt %arg %new-argv) + (case %opt + ,@ transmogrified-cases)))))))) + + +;;; {Run-time options} + +((let* ((names '((eval-options-interface + (eval-options eval-enable eval-disable) + (eval-set!)) + + (debug-options-interface + (debug-options debug-enable debug-disable) + (debug-set!)) + + (evaluator-traps-interface + (traps trap-enable trap-disable) + (trap-set!)) + + (read-options-interface + (read-options read-enable read-disable) + (read-set!)) + + (print-options-interface + (print-options print-enable print-disable) + (print-set!)) + + (readline-options-interface + (readline-options readline-enable readline-disable) + (readline-set!)) + )) + (option-name car) + (option-value cadr) + (option-documentation caddr) + + (print-option (lambda (option) + (display (option-name option)) + (if (< (string-length + (symbol->string (option-name option))) + 8) + (display #\tab)) + (display #\tab) + (display (option-value option)) + (display #\tab) + (display (option-documentation option)) + (newline))) + + ;; Below follows the macros defining the run-time option interfaces. + + (make-options (lambda (interface) + `(lambda args + (cond ((null? args) (,interface)) + ((list? (car args)) + (,interface (car args)) (,interface)) + (else (for-each ,print-option + (,interface #t))))))) + + (make-enable (lambda (interface) + `(lambda flags + (,interface (append flags (,interface))) + (,interface)))) + + (make-disable (lambda (interface) + `(lambda flags + (let ((options (,interface))) + (for-each (lambda (flag) + (set! options (delq! flag options))) + flags) + (,interface options) + (,interface))))) + + (make-set! (lambda (interface) + `((name exp) + (,'quasiquote + (begin (,interface (append (,interface) + (list '(,'unquote name) + (,'unquote exp)))) + (,interface)))))) + ) + (procedure->macro + (lambda (exp env) + (cons 'begin + (apply append + (map (lambda (group) + (let ((interface (car group))) + (append (map (lambda (name constructor) + `(define ,name + ,(constructor interface))) + (cadr group) + (list make-options + make-enable + make-disable)) + (map (lambda (name constructor) + `(defmacro ,name + ,@(constructor interface))) + (caddr group) + (list make-set!))))) + names))))))) + +(export eval-options eval-enable eval-disable eval-set! debug-options +debug-enable debug-disable traps trap-enable trap-disable trap-set! +read-enable read-disable read-set! print-enable print-disable +print-set! readline-options readline-enable readline-disable +readline-set!) + diff --git a/ice-9/posix.scm b/ice-9/posix.scm index 9698a0b8a..14ce238da 100644 --- a/ice-9/posix.scm +++ b/ice-9/posix.scm @@ -1,70 +1,190 @@ -;;; installed-scm-file - -;;;; Copyright (C) 1999 Free Software Foundation, Inc. -;;;; -;;;; This program is free software; you can redistribute it and/or modify -;;;; it under the terms of the GNU General Public License as published by -;;;; the Free Software Foundation; either version 2, or (at your option) -;;;; any later version. -;;;; -;;;; This program is distributed in the hope that it will be useful, -;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. -;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330, -;;;; Boston, MA 02111-1307 USA -;;;; - -(define (stat:dev f) (vector-ref f 0)) -(define (stat:ino f) (vector-ref f 1)) -(define (stat:mode f) (vector-ref f 2)) -(define (stat:nlink f) (vector-ref f 3)) -(define (stat:uid f) (vector-ref f 4)) -(define (stat:gid f) (vector-ref f 5)) -(define (stat:rdev f) (vector-ref f 6)) -(define (stat:size f) (vector-ref f 7)) -(define (stat:atime f) (vector-ref f 8)) -(define (stat:mtime f) (vector-ref f 9)) -(define (stat:ctime f) (vector-ref f 10)) -(define (stat:blksize f) (vector-ref f 11)) -(define (stat:blocks f) (vector-ref f 12)) - -;; derived from stat mode. -(define (stat:type f) (vector-ref f 13)) -(define (stat:perms f) (vector-ref f 14)) - -(define (passwd:name obj) (vector-ref obj 0)) -(define (passwd:passwd obj) (vector-ref obj 1)) -(define (passwd:uid obj) (vector-ref obj 2)) -(define (passwd:gid obj) (vector-ref obj 3)) -(define (passwd:gecos obj) (vector-ref obj 4)) -(define (passwd:dir obj) (vector-ref obj 5)) -(define (passwd:shell obj) (vector-ref obj 6)) - -(define (group:name obj) (vector-ref obj 0)) -(define (group:passwd obj) (vector-ref obj 1)) -(define (group:gid obj) (vector-ref obj 2)) -(define (group:mem obj) (vector-ref obj 3)) - -(define (utsname:sysname obj) (vector-ref obj 0)) -(define (utsname:nodename obj) (vector-ref obj 1)) -(define (utsname:release obj) (vector-ref obj 2)) -(define (utsname:version obj) (vector-ref obj 3)) -(define (utsname:machine obj) (vector-ref obj 4)) - -(define (getpwent) (getpw)) -(define (setpwent) (setpw #t)) -(define (endpwent) (setpw)) - -(define (getpwnam name) (getpw name)) -(define (getpwuid uid) (getpw uid)) - -(define (getgrent) (getgr)) -(define (setgrent) (setgr #f)) -(define (endgrent) (setgr)) - -(define (getgrnam name) (getgr name)) -(define (getgrgid id) (getgr id)) +(module (ice-9 posix) + (open (ice-9 guile) + ((ice-9 config) define-public))) + + +;;; {Non-polymorphic versions of POSIX functions} + +(define-public (getgrnam name) (getgr name)) +(define-public (getgrgid id) (getgr id)) +(define-public (gethostbyaddr addr) (gethost addr)) +(define-public (gethostbyname name) (gethost name)) +(define-public (getnetbyaddr addr) (getnet addr)) +(define-public (getnetbyname name) (getnet name)) +(define-public (getprotobyname name) (getproto name)) +(define-public (getprotobynumber addr) (getproto addr)) +(define-public (getpwnam name) (getpw name)) +(define-public (getpwuid uid) (getpw uid)) +(define-public (getservbyname name proto) (getserv name proto)) +(define-public (getservbyport port proto) (getserv port proto)) +(define-public (endgrent) (setgr)) +(define-public (endhostent) (sethost)) +(define-public (endnetent) (setnet)) +(define-public (endprotoent) (setproto)) +(define-public (endpwent) (setpw)) +(define-public (endservent) (setserv)) +(define-public (getgrent) (getgr)) +(define-public (gethostent) (gethost)) +(define-public (getnetent) (getnet)) +(define-public (getprotoent) (getproto)) +(define-public (getpwent) (getpw)) +(define-public (getservent) (getserv)) +(define-public (reopen-file . args) (apply freopen args)) +(define-public (setgrent) (setgr #f)) +(define-public (sethostent) (sethost #t)) +(define-public (setnetent) (setnet #t)) +(define-public (setprotoent) (setproto #t)) +(define-public (setpwent) (setpw #t)) +(define-public (setservent) (setserv #t)) + +(define-public (passwd:name obj) (vector-ref obj 0)) +(define-public (passwd:passwd obj) (vector-ref obj 1)) +(define-public (passwd:uid obj) (vector-ref obj 2)) +(define-public (passwd:gid obj) (vector-ref obj 3)) +(define-public (passwd:gecos obj) (vector-ref obj 4)) +(define-public (passwd:dir obj) (vector-ref obj 5)) +(define-public (passwd:shell obj) (vector-ref obj 6)) + +(define-public (group:name obj) (vector-ref obj 0)) +(define-public (group:passwd obj) (vector-ref obj 1)) +(define-public (group:gid obj) (vector-ref obj 2)) +(define-public (group:mem obj) (vector-ref obj 3)) + +(define-public (hostent:name obj) (vector-ref obj 0)) +(define-public (hostent:aliases obj) (vector-ref obj 1)) +(define-public (hostent:addrtype obj) (vector-ref obj 2)) +(define-public (hostent:length obj) (vector-ref obj 3)) +(define-public (hostent:addr-list obj) (vector-ref obj 4)) + +(define-public (netent:name obj) (vector-ref obj 0)) +(define-public (netent:aliases obj) (vector-ref obj 1)) +(define-public (netent:addrtype obj) (vector-ref obj 2)) +(define-public (netent:net obj) (vector-ref obj 3)) + +(define-public (protoent:name obj) (vector-ref obj 0)) +(define-public (protoent:aliases obj) (vector-ref obj 1)) +(define-public (protoent:proto obj) (vector-ref obj 2)) + +(define-public (servent:name obj) (vector-ref obj 0)) +(define-public (servent:aliases obj) (vector-ref obj 1)) +(define-public (servent:port obj) (vector-ref obj 2)) +(define-public (servent:proto obj) (vector-ref obj 3)) + +(define-public (sockaddr:fam obj) (vector-ref obj 0)) +(define-public (sockaddr:path obj) (vector-ref obj 1)) +(define-public (sockaddr:addr obj) (vector-ref obj 1)) +(define-public (sockaddr:port obj) (vector-ref obj 2)) + +(define-public (utsname:sysname obj) (vector-ref obj 0)) +(define-public (utsname:nodename obj) (vector-ref obj 1)) +(define-public (utsname:release obj) (vector-ref obj 2)) +(define-public (utsname:version obj) (vector-ref obj 3)) +(define-public (utsname:machine obj) (vector-ref obj 4)) + +(define-public (tm:sec obj) (vector-ref obj 0)) +(define-public (tm:min obj) (vector-ref obj 1)) +(define-public (tm:hour obj) (vector-ref obj 2)) +(define-public (tm:mday obj) (vector-ref obj 3)) +(define-public (tm:mon obj) (vector-ref obj 4)) +(define-public (tm:year obj) (vector-ref obj 5)) +(define-public (tm:wday obj) (vector-ref obj 6)) +(define-public (tm:yday obj) (vector-ref obj 7)) +(define-public (tm:isdst obj) (vector-ref obj 8)) +(define-public (tm:gmtoff obj) (vector-ref obj 9)) +(define-public (tm:zone obj) (vector-ref obj 10)) + +(define-public (set-tm:sec obj val) (vector-set! obj 0 val)) +(define-public (set-tm:min obj val) (vector-set! obj 1 val)) +(define-public (set-tm:hour obj val) (vector-set! obj 2 val)) +(define-public (set-tm:mday obj val) (vector-set! obj 3 val)) +(define-public (set-tm:mon obj val) (vector-set! obj 4 val)) +(define-public (set-tm:year obj val) (vector-set! obj 5 val)) +(define-public (set-tm:wday obj val) (vector-set! obj 6 val)) +(define-public (set-tm:yday obj val) (vector-set! obj 7 val)) +(define-public (set-tm:isdst obj val) (vector-set! obj 8 val)) +(define-public (set-tm:gmtoff obj val) (vector-set! obj 9 val)) +(define-public (set-tm:zone obj val) (vector-set! obj 10 val)) + +(define-public (tms:clock obj) (vector-ref obj 0)) +(define-public (tms:utime obj) (vector-ref obj 1)) +(define-public (tms:stime obj) (vector-ref obj 2)) +(define-public (tms:cutime obj) (vector-ref obj 3)) +(define-public (tms:cstime obj) (vector-ref obj 4)) + +(define-public (file-position . args) (apply ftell args)) +(define-public (file-set-position . args) (apply fseek args)) + +(define-public (open-input-pipe command) (open-pipe command OPEN_READ)) +(define-public (open-output-pipe command) (open-pipe command OPEN_WRITE)) + +(define-public (move->fdes fd/port fd) + (cond ((integer? fd/port) + (dup->fdes fd/port fd) + (close fd/port) + fd) + (else + (primitive-move->fdes fd/port fd) + (set-port-revealed! fd/port 1) + fd/port))) + +(define-public (release-port-handle port) + (let ((revealed (port-revealed port))) + (if (> revealed 0) + (set-port-revealed! port (- revealed 1))))) + +(define-public (dup->port port/fd mode . maybe-fd) + (let ((port (fdopen (apply dup->fdes port/fd maybe-fd) + mode))) + (if (pair? maybe-fd) + (set-port-revealed! port 1)) + port)) + +(define-public (dup->inport port/fd . maybe-fd) + (apply dup->port port/fd "r" maybe-fd)) + +(define-public (dup->outport port/fd . maybe-fd) + (apply dup->port port/fd "w" maybe-fd)) + +(define-public (dup port/fd . maybe-fd) + (if (integer? port/fd) + (apply dup->fdes port/fd maybe-fd) + (apply dup->port port/fd (port-mode port/fd) maybe-fd))) + +(define-public (duplicate-port port modes) + (dup->port port modes)) + +(define-public (fdes->inport fdes) + (let loop ((rest-ports (fdes->ports fdes))) + (cond ((null? rest-ports) + (let ((result (fdopen fdes "r"))) + (set-port-revealed! result 1) + result)) + ((input-port? (car rest-ports)) + (set-port-revealed! (car rest-ports) + (+ (port-revealed (car rest-ports)) 1)) + (car rest-ports)) + (else + (loop (cdr rest-ports)))))) + +(define-public (fdes->outport fdes) + (let loop ((rest-ports (fdes->ports fdes))) + (cond ((null? rest-ports) + (let ((result (fdopen fdes "w"))) + (set-port-revealed! result 1) + result)) + ((output-port? (car rest-ports)) + (set-port-revealed! (car rest-ports) + (+ (port-revealed (car rest-ports)) 1)) + (car rest-ports)) + (else + (loop (cdr rest-ports)))))) + +(define-public (port->fdes port) + (set-port-revealed! port (+ (port-revealed port) 1)) + (fileno port)) + +(define-public (setenv name value) + (if value + (putenv (string-append name "=" value)) + (putenv name))) + diff --git a/ice-9/provide.scm b/ice-9/provide.scm new file mode 100644 index 000000000..a5d7a881c --- /dev/null +++ b/ice-9/provide.scm @@ -0,0 +1,13 @@ +;;; {Features} +;; +(module (ice-9 provide) + (open (ice-9 guile)) + (export provide feature?)) + +(define (provide sym) + (if (not (memq sym *features*)) + (set! *features* (cons sym *features*)))) + +(define (feature? feature) + (and (memq feature *features*) #t)) + diff --git a/ice-9/repl.scm b/ice-9/repl.scm new file mode 100644 index 000000000..3a09045e2 --- /dev/null +++ b/ice-9/repl.scm @@ -0,0 +1,478 @@ +;;; This is the module (ice-9 repl). +;;; + +;; the current module +(define make-repl-module + (lambda () + (let ((ice-9/repl (and (environment-bound? (module-registry) 'ice-9/repl) + (environment-ref (module-registry) 'ice-9/repl)))) + (if (not ice-9/repl) + (let* ( + (eval (the-environment)) + (export (make-interface-environment (list (list eval 'top-repl)))) + (protect (make-interface-environment (list (list eval 'top-repl 'save-stack 'abort-hook)))) + (ice-9/repl (vector eval export protect 'ice-9/ 'ice-9/repl))) + (environment-define (module-registry) 'ice-9/repl ice-9/repl) + (hashq-set! (environment-module-hash) eval ice-9/repl)) + ice-9/repl)))) + +;; the guile module +(define make-guile-module + (lambda () + (let ((ice-9/guile (and (environment-bound? (module-registry) 'ice-9/guile) + (environment-ref (module-registry) 'ice-9/guile)))) + + (if (not ice-9/guile) + (let* ( + (eval (scheme-guile-environment 2)) + (export (make-interface-environment (list (cons eval #t)))) + (protect (make-interface-environment (list (cons eval #t)))) + (ice-9/guile (vector eval export protect 'ice-9/ 'ice-9/guile))) + (environment-define (module-registry) 'ice-9/guile ice-9/guile) + (hashq-set! (environment-module-hash) eval ice-9/guile)) + ice-9/guile)))) + +(define make-user-module + (lambda () + (let ((user/guile (and (environment-bound? (module-registry) 'user/guile) + (environment-ref (module-registry) 'user/guile)))) + + (if (not user/guile) + (let* ( + (eval-env (guile-user-environment 2)) + (export (make-interface-environment (list (cons eval-env #t)))) + (protect (make-interface-environment (list (cons eval-env #t)))) + (user/guile (vector eval-env export protect 'user/ 'user/guile))) + + (environment-define (module-registry) 'user/guile user/guile) + (hashq-set! (environment-module-hash) eval-env user/guile)) + user/guile)))) + +(define make-config-module + (lambda () + (let ((ice-9/config (and (environment-bound? (module-registry) 'ice-9/config) + (environment-ref (module-registry) 'ice-9/config)))) + + (if (not ice-9/config) + (let* ((import (make-interface-environment (list (cons (scheme-guile-environment 2) #t)))) + (eval-env (make-eval-environment (make-leaf-environment) import)) + (export (make-interface-environment (list (cons eval-env #t)))) + (protect (make-interface-environment (list (cons eval-env #t)))) + (ice-9/config (vector eval-env export protect 'ice-9/ 'ice-9/config))) + + (environment-define (module-registry) 'ice-9/config ice-9/config) + (hashq-set! (environment-module-hash) eval-env ice-9/config)) + ice-9/config)))) + + + + +;;; some more redundancy + +(define (module-name module) (vector-ref module 4)) +(define (module-eval-environment module) (vector-ref module 0)) + +(define (run-hooks hook) + (if (and (pair? hook) (eq? (car hook) 'hook)) + (run-hook hook) + (for-each (lambda (thunk) (thunk)) hook))) + + + +;;; {Running Repls} +;;; + +(define (repl read evaler print) + (let loop ((source (read (current-input-port)))) + (print (evaler source)) + (loop (read (current-input-port))))) + +;; A provisional repl that acts like the SCM repl: +;; +(define scm-repl-silent #f) +(define (assert-repl-silence v) (set! scm-repl-silent v)) + +(define *unspecified* (if #f #f)) +(define (unspecified? v) (eq? v *unspecified*)) + +(define scm-repl-print-unspecified #f) +(define (assert-repl-print-unspecified v) (set! scm-repl-print-unspecified v)) + +(define scm-repl-verbose #f) +(define (assert-repl-verbosity v) (set! scm-repl-verbose v)) + +(define scm-repl-prompt "guile> ") + +(define (set-repl-prompt! v) (set! scm-repl-prompt v)) + +(define (default-lazy-handler key . args) + (save-stack lazy-handler-dispatch) + (apply throw key args)) + +(define enter-frame-handler default-lazy-handler) +(define apply-frame-handler default-lazy-handler) +(define exit-frame-handler default-lazy-handler) + +(define (lazy-handler-dispatch key . args) + (case key + ((apply-frame) + (apply apply-frame-handler key args)) + ((exit-frame) + (apply exit-frame-handler key args)) + ((enter-frame) + (apply enter-frame-handler key args)) + (else + (apply default-lazy-handler key args)))) + +(define abort-hook (make-hook)) + +;; these definitions are used if running a script. +;; otherwise redefined in error-catching-loop. +(define (set-batch-mode?! arg) #t) +(define (batch-mode?) #t) + +(define (error-catching-loop thunk) + (let ((status #f) + (interactive #t)) + (define (loop first) + (let ((next + (catch #t + + (lambda () + (lazy-catch #t + (lambda () + (dynamic-wind + (lambda () (unmask-signals)) + (lambda () + (with-traps + (lambda () + (first) + + ;; This line is needed because mark + ;; doesn't do closures quite right. + ;; Unreferenced locals should be + ;; collected. + ;; + (set! first #f) + (let loop ((v (thunk))) + (loop (thunk))) + #f))) + (lambda () (mask-signals)))) + + lazy-handler-dispatch)) + + (lambda (key . args) + (case key + ((quit) + (force-output) + (set! status (car args)) + #f) + + ((switch-repl) + (apply throw 'switch-repl args)) + + ((abort) + ;; This is one of the closures that require + ;; (set! first #f) above + ;; + (lambda () + (run-hook abort-hook) + (force-output) + (display "ABORT: " (current-error-port)) + (write args (current-error-port)) + (newline (current-error-port)) + (if interactive + (if (and (not has-shown-debugger-hint?) + (not (memq 'backtrace + (debug-options-interface))) + (stack? (fluid-ref the-last-stack))) + (begin + (newline (current-error-port)) + (display + "Type \"(backtrace)\" to get more information.\n" + (current-error-port)) + (set! has-shown-debugger-hint? #t))) + (primitive-exit 1)) + (set! stack-saved? #f))) + + (else + ;; This is the other cons-leak closure... + (lambda () + (cond ((= (length args) 4) + (apply handle-system-error key args)) + (else + (apply bad-throw key args)))))))))) + (if next (loop next) status))) + + (set! set-batch-mode?! (lambda (arg) + (cond (arg + (set! interactive #f) + (restore-signals)) + (#t + (error "sorry, not implemented"))))) + (set! batch-mode? (lambda () (not interactive))) + + (loop (lambda () #t)))) + +;;(define the-last-stack (make-fluid)) Defined by scm_init_backtrace () +(define stack-saved? #f) + +(define (save-stack . narrowing) + (or stack-saved? + (cond ((not (memq 'debug (debug-options-interface))) + (fluid-set! the-last-stack #f) + (set! stack-saved? #t)) + (else + (fluid-set! + the-last-stack + (case (stack-id #t) + ((repl-stack) + (apply make-stack #t save-stack eval #t 0 narrowing)) + ((load-stack) + (apply make-stack #t save-stack 0 #t 0 narrowing)) + ((tk-stack) + (apply make-stack #t save-stack tk-stack-mark #t 0 narrowing)) + ((#t) + (apply make-stack #t save-stack 0 1 narrowing)) + (else + (let ((id (stack-id #t))) + (and (procedure? id) + (apply make-stack #t save-stack id #t 0 narrowing)))))) + (set! stack-saved? #t))))) + +(define before-error-hook (make-hook)) +(define after-error-hook (make-hook)) +(define before-backtrace-hook (make-hook)) +(define after-backtrace-hook (make-hook)) + +(define has-shown-debugger-hint? #f) + +(define (handle-system-error key . args) + (let ((cep (current-error-port))) + (cond ((not (stack? (fluid-ref the-last-stack)))) + ((memq 'backtrace (debug-options-interface)) + (run-hook before-backtrace-hook) + (newline cep) + (display-backtrace (fluid-ref the-last-stack) cep) + (newline cep) + (run-hook after-backtrace-hook))) + (run-hook before-error-hook) + (apply display-error (fluid-ref the-last-stack) cep args) + (run-hook after-error-hook) + (force-output cep) + (throw 'abort key))) + + +;;(define has-shown-backtrace-hint? #f) Defined by scm_init_backtrace () + +;; Replaced by C code: +;;(define (backtrace) +;; (if (fluid-ref the-last-stack) +;; (begin +;; (newline) +;; (display-backtrace (fluid-ref the-last-stack) (current-output-port)) +;; (newline) +;; (if (and (not has-shown-backtrace-hint?) +;; (not (memq 'backtrace (debug-options-interface)))) +;; (begin +;; (display +;;"Type \"(debug-enable 'backtrace)\" if you would like a backtrace +;;automatically if an error occurs in the future.\n") +;; (set! has-shown-backtrace-hint? #t)))) +;; (display "No backtrace available.\n"))) + +(define (error-catching-repl r e p) + (error-catching-loop (lambda () (p (e (r))))))5 + +(define (gc-run-time) + (cdr (assq 'gc-time-taken (gc-stats)))) + +(define before-read-hook (make-hook)) +(define after-read-hook (make-hook)) + +;;; The default repl-reader function. We may override this if we've +;;; the readline library. +(define repl-reader + (lambda (prompt) + (display prompt) + (force-output) + (run-hook before-read-hook) + (read (current-input-port)))) + +(define (scm-style-repl module) + (letrec ( + (start-gc-rt #f) + (start-rt #f) + (repl-report-start-timing (lambda () + (set! start-gc-rt (gc-run-time)) + (set! start-rt (get-internal-run-time)))) + (repl-report (lambda () + (display ";;; ") + (display (inexact->exact + (* 1000 (/ (- (get-internal-run-time) start-rt) + internal-time-units-per-second)))) + (display " msec (") + (display (inexact->exact + (* 1000 (/ (- (gc-run-time) start-gc-rt) + internal-time-units-per-second)))) + (display " msec in gc)\n"))) + + (consume-trailing-whitespace + (lambda () + (let ((ch (peek-char))) + (cond + ((eof-object? ch)) + ((or (char=? ch #\space) (char=? ch #\tab)) + (read-char) + (consume-trailing-whitespace)) + ((char=? ch #\newline) + (read-char)))))) + + (-read (lambda () + (let ((val + (let ((prompt (string-append (module-name module) "> " ))) + (repl-reader prompt)))) + + (run-hooks after-read-hook) + (if (eof-object? val) + (begin + (repl-report-start-timing) + (if scm-repl-verbose + (begin + (newline) + (display ";;; EOF -- quitting") + (newline))) + (throw 'quit #f))) + + ;; As described in R4RS, the READ procedure updates the + ;; port to point to the first characetr past the end of + ;; the external representation of the object. This + ;; means that it doesn't consume the newline typically + ;; found after an expression. This means that, when + ;; debugging Guile with GDB, GDB gets the newline, which + ;; it often interprets as a "continue" command, making + ;; breakpoints kind of useless. So, consume any + ;; trailing newline here, as well as any whitespace + ;; before it. + (consume-trailing-whitespace) + + val))) + + (-eval (lambda (sourc) + (repl-report-start-timing) + (start-stack 'repl-stack (eval sourc (module-eval-environment module))))) + + (-print (lambda (result) + (if (not scm-repl-silent) + (begin + (if (or scm-repl-print-unspecified + (not (unspecified? result))) + (begin + (write result) + (newline))) + (if scm-repl-verbose + (repl-report)) + (force-output))))) + + (-quit (lambda (args) + (if scm-repl-verbose + (begin + (display ";;; QUIT executed, repl exitting") + (newline) + (repl-report))) + args)) + + (-abort (lambda () + (if scm-repl-verbose + (begin + (display ";;; ABORT executed.") + (newline) + (repl-report))) + (repl -read -eval -print)))) + + (let ((status (error-catching-repl -read + -eval + -print))) + (-quit status)))) + + +;; this is just (scm-style-repl) with a wrapper to install and remove +;; signal handlers. Every module may have exactly one repl. + + +(define (top-repl module) + (let ((old-handlers #f) + (signals `((,SIGINT . "User interrupt") + (,SIGFPE . "Arithmetic error") + (,SIGBUS . "Bad memory access (bus error)") + (,SIGSEGV . "Bad memory access (Segmentation violation)")))) + + (dynamic-wind + + ;; call at entry + (lambda () + (let ((make-handler (lambda (msg) + (lambda (sig) + (save-stack %deliver-signals) + (scm-error 'signal + #f + msg + #f + (list sig)))))) + (set! old-handlers + (map (lambda (sig-msg) + (sigaction (car sig-msg) + (make-handler (cdr sig-msg)))) + signals)))) + + ;; the protected thunk. + (lambda () + (scm-style-repl module)) + + + ;; call at exit. + (lambda () + (map (lambda (sig-msg old-handler) + (if (not (car old-handler)) + ;; restore original C handler. + (sigaction (car sig-msg) #f) + ;; restore Scheme handler, SIG_IGN or SIG_DFL. + (sigaction (car sig-msg) + (car old-handler) + (cdr old-handler)))) + signals old-handlers))))) + +;;; This hook is run at the very end of an interactive session. +;;; +(define exit-hook (make-hook)) + + + +;; now provide a function which starts the repl +(define start + (lambda () + (make-guile-module) + (make-repl-module) + (let ((user/guile (make-user-module))) + + (set-interaction-environment! (vector-ref user/guile 0)) + + (let ( + (ret-val (top-repl user/guile)) + + (start-module-system + (lambda () + ;; create (ice-9 config) and re-start the repl in there + (let* ((ice-9/config (make-config-module)) + (eval-env (vector-ref ice-9/config 0))) + (primitive-load-path "ice-9/config.scm" eval-env) + (eval '(start) eval-env))))) + + (if (and (eqv? #f ret-val) (isatty? (current-input-port))) + (begin + (newline) + (set! ret-val (start-module-system)))) + + (or ret-val 0))))) + + diff --git a/ice-9/run-test.scm b/ice-9/run-test.scm new file mode 100644 index 000000000..44c73d95f --- /dev/null +++ b/ice-9/run-test.scm @@ -0,0 +1,5 @@ +(define %library-dir + (lambda () (string-append (%package-data-dir) "/" (version)))) + +(chdir (string-append (%library-dir) "/ice-9")) +(define-module (ice-9 run-test) :use-module (ice-9 test))
\ No newline at end of file diff --git a/ice-9/structs.scm b/ice-9/structs.scm new file mode 100644 index 000000000..760e61d8e --- /dev/null +++ b/ice-9/structs.scm @@ -0,0 +1,127 @@ +(module (ice-9 structs) + + (export record-type? make-record-type record-type-name record-type-fields record-constructor record-predicate + record-accessor record-modifier record? record-type-descriptor) + + (open (ice-9 provide) (ice-9 symbols) (ice-9 lists) (ice-9 guile))) + +;;; {Structs} + +(define (struct-layout s) + (struct-ref (struct-vtable s) vtable-index-layout)) + + +;;; {Records} +;;; + +;; Printing records: by default, records are printed as +;; +;; #<type-name field1: val1 field2: val2 ...> +;; +;; You can change that by giving a custom printing function to +;; MAKE-RECORD-TYPE (after the list of field symbols). This function +;; will be called like +;; +;; (<printer> object port) +;; +;; It should print OBJECT to PORT. + +(define (inherit-print-state old-port new-port) + (if (pair? old-port) + (cons (if (pair? new-port) (car new-port) new-port) + (cdr old-port)) + new-port)) + +;; 0: type-name, 1: fields +(define record-type-vtable + (make-vtable-vtable "prpr" 0 + (lambda (s p) + (cond ((eq? s record-type-vtable) + (display "#<record-type-vtable>" p)) + (else + (display "#<record-type " p) + (display (record-type-name s) p) + (display ">" p)))))) + +(define (record-type? obj) + (and (struct? obj) (eq? record-type-vtable (struct-vtable obj)))) + +(define (make-record-type type-name fields . opt) + (let ((printer-fn (and (pair? opt) (car opt)))) + (let ((struct (make-struct record-type-vtable 0 + (make-struct-layout + (apply symbol-append + (map (lambda (f) "pw") fields))) + (or printer-fn + (lambda (s p) + (display "#<" p) + (display type-name p) + (let loop ((fields fields) + (off 0)) + (cond + ((not (null? fields)) + (display " " p) + (display (car fields) p) + (display ": " p) + (display (struct-ref s off) p) + (loop (cdr fields) (+ 1 off))))) + (display ">" p))) + type-name + (copy-tree fields)))) + ;; Temporary solution: Associate a name to the record type descriptor + ;; so that the object system can create a wrapper class for it. + (set-struct-vtable-name! struct (if (symbol? type-name) + type-name + (string->symbol type-name))) + struct))) + +(define (record-type-name obj) + (if (record-type? obj) + (struct-ref obj vtable-offset-user) + (error 'not-a-record-type obj))) + +(define (record-type-fields obj) + (if (record-type? obj) + (struct-ref obj (+ 1 vtable-offset-user)) + (error 'not-a-record-type obj))) + +(define (record-constructor rtd . opt) + (let ((field-names (if (pair? opt) (car opt) (record-type-fields rtd)))) + (eval `(lambda ,field-names + (make-struct ',rtd 0 ,@(map (lambda (f) + (if (memq f field-names) + f + #f)) + (record-type-fields rtd)))) + (the-environment)))) + +(define (record-predicate rtd) + (lambda (obj) (and (struct? obj) (eq? rtd (struct-vtable obj))))) + +(define (record-accessor rtd field-name) + (let* ((pos (list-index (record-type-fields rtd) field-name))) + (if (not pos) + (error 'no-such-field field-name)) + (eval `(lambda (obj) + (and (eq? ',rtd (record-type-descriptor obj)) + (struct-ref obj ,pos))) (the-environment)))) + +(define (record-modifier rtd field-name) + (let* ((pos (list-index (record-type-fields rtd) field-name))) + (if (not pos) + (error 'no-such-field field-name)) + (eval `(lambda (obj val) + (and (eq? ',rtd (record-type-descriptor obj)) + (struct-set! obj ,pos val))) (the-environment) ))) + + +(define (record? obj) + (and (struct? obj) (record-type? (struct-vtable obj)))) + +(define (record-type-descriptor obj) + (if (struct? obj) + (struct-vtable obj) + (error 'not-a-record obj))) + +(provide 'record) + diff --git a/ice-9/symbols.scm b/ice-9/symbols.scm new file mode 100644 index 000000000..cb2cfb504 --- /dev/null +++ b/ice-9/symbols.scm @@ -0,0 +1,23 @@ +;;; {Symbols} +;;; +(module (ice-9 symbols) + (open (ice-9 guile)) + (export symbol-append list->symbol symbol obarray-symbol-append obarray-gensym)) + +(define (symbol-append . args) + (string->symbol (apply string-append args))) + +(define (list->symbol . args) + (string->symbol (apply list->string args))) + +(define (symbol . args) + (string->symbol (apply string args))) + +(define (obarray-symbol-append ob . args) + (string->obarray-symbol (apply string-append ob args))) + +(define (obarray-gensym obarray . opt) + (if (null? opt) + (gensym "%%gensym" obarray) + (gensym (car opt) obarray))) + |