📄 boot-9.scm
字号:
;;; installed-scm-file;;;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 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;;;;;;;; As a special exception, the Free Software Foundation gives permission;;;; for additional uses of the text contained in its release of GUILE.;;;;;;;; The exception is that, if you link the GUILE library with other files;;;; to produce an executable, this does not by itself cause the;;;; resulting executable to be covered by the GNU General Public License.;;;; Your use of that executable is in no way restricted on account of;;;; linking the GUILE library code into it.;;;;;;;; This exception does not however invalidate any other reasons why;;;; the executable file might be covered by the GNU General Public License.;;;;;;;; This exception applies only to the code released by the;;;; Free Software Foundation under the name GUILE. If you copy;;;; code from other Free Software Foundation releases into a copy of;;;; GUILE, as the General Public License permits, the exception does;;;; not apply to the code that you add in this way. To avoid misleading;;;; anyone as to the status of such modified files, you must delete;;;; this exception notice from them.;;;;;;;; If you write modifications of your own for GUILE, it is your choice;;;; whether to permit this exception to apply to your modifications.;;;; If you do not wish that, delete this exception notice.;;;;;;; Commentary:;;; This file is the first thing loaded into Guile. It adds many mundane;;; definitions and a few that are interesting.;;;;;; The module system (hence the hierarchical namespace) are defined in this;;; file.;;;;;; Code:;;; {Deprecation};;;;; We don't have macros here, but we do want to define;; `begin-deprecated' early.(define begin-deprecated (procedure->memoizing-macro (lambda (exp env) (if (include-deprecated-features) `(begin ,@(cdr exp)) `#f))));;; {Features};;(define (provide sym) (if (not (memq sym *features*)) (set! *features* (cons sym *features*))));;; Return #t iff FEATURE is available to this Guile interpreter.;;; In SLIB, provided? also checks to see if the module is available.;;; We should do that too, but don't.(define (provided? feature) (and (memq feature *features*) #t));;; presumably deprecated.(define feature? provided?);;; let format alias simple-format until the more complete version is loaded(define format simple-format);;; {R4RS compliance}(primitive-load-path "ice-9/r4rs.scm");;; {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)(define (warn . stuff) (with-output-to-port (current-error-port) (lambda () (newline) (display ";;; WARNING ") (display stuff) (newline) (car (last-pair stuff)))));;; {Trivial Functions};;;(define (identity x) x)(define (1+ n) (+ n 1))(define (1- n) (+ n -1))(define (and=> value procedure) (and value (procedure value)))(define (make-hash-table k) (make-vector k '()))(begin-deprecated (define (id x) (issue-deprecation-warning "`id' is deprecated. Use `identity' instead.") (identity x)) (define (-1+ n) (issue-deprecation-warning "`-1+' is deprecated. Use `1-' instead.") (1- n)) (define (return-it . args) (issue-deprecation-warning "`return-it' is deprecated. Use `noop' instead.") (apply noop args)));;; apply-to-args is functionally redundant 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))))(begin-deprecated (define (string-character-length s) (issue-deprecation-warning "`string-character-length' is deprecated. Use `string-length' instead.") (string-length s)) (define (flags . args) (issue-deprecation-warning "`flags' is deprecated. Use `logior' instead.") (apply logior args)));;; {Symbol Properties};;;(define (symbol-property sym prop) (let ((pair (assoc prop (symbol-pref sym)))) (and pair (cdr pair))))(define (set-symbol-property! sym prop val) (let ((pair (assoc prop (symbol-pref sym)))) (if pair (set-cdr! pair val) (symbol-pset! sym (acons prop val (symbol-pref sym))))))(define (symbol-property-remove! sym prop) (let ((pair (assoc prop (symbol-pref sym)))) (if pair (symbol-pset! sym (delq! pair (symbol-pref sym))))));;; {General Properties};;;;; This is a more modern interface to properties. It will replace all;; other property-like things eventually.(define (make-object-property) (let ((prop (primitive-make-property #f))) (make-procedure-with-setter (lambda (obj) (primitive-property-ref prop obj)) (lambda (obj val) (primitive-property-set! prop obj val)))));;; {Arrays};;;(if (provided? 'array) (primitive-load-path "ice-9/arrays.scm"));;; {Keywords};;;(define (symbol->keyword symbol) (make-keyword-from-dash-symbol (symbol-append '- symbol)))(define (keyword->symbol kw) (let ((sym (symbol->string (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))));;; {Structs}(define (struct-layout s) (struct-ref (struct-vtable s) vtable-index-layout));;; Environments(define the-environment (procedure->syntax (lambda (x e) e)))(define the-root-environment (the-environment))(define (environment-module env) (let ((closure (and (pair? env) (car (last-pair env))))) (and closure (procedure-property closure 'module))));;; {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 (get-print-state old-port) (port-with-print-state new-port (get-print-state 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 string-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)))) (local-eval `(lambda ,field-names (make-struct ',rtd 0 ,@(map (lambda (f) (if (memq f field-names) f #f)) (record-type-fields rtd)))) the-root-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)) (local-eval `(lambda (obj) (and (eq? ',rtd (record-type-descriptor obj)) (struct-ref obj ,pos))) the-root-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)) (local-eval `(lambda (obj val) (and (eq? ',rtd (record-type-descriptor obj)) (struct-set! obj ,pos val))) the-root-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);;; {Booleans};;;(define (->bool x) (not (not x)));;; {Symbols};;;(define (symbol-append . args) (string->symbol (apply string-append (map symbol->string args))))(define (list->symbol . args) (string->symbol (apply list->string args)))(define (symbol . args) (string->symbol (apply string args)));;; {Lists};;;(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)))));;; {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...) ...);;;;; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -