⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatch.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
字号:
;;;; 	Copyright (C) 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.;;;; (define-module (oop goops dispatch)  :use-module (oop goops)  :use-module (oop goops util)  :use-module (oop goops compile)  :export (memoize-method!)  :no-backtrace  );;;;;; This file implements method memoization.  It will finally be;;; implemented on C level in order to obtain fast generic function;;; application also during the first pass through the code.;;;;;;;;; Constants;;;(define hashsets 8)(define hashset-index 7)(define hash-threshold 3)(define initial-hash-size 4) ;must be a power of 2 and >= hash-threshold(define initial-hash-size-1 (- initial-hash-size 1))(define the-list-of-no-method '(no-method));;;;;; Method cache;;;;; (#@dispatch args N-SPECIALIZED #((TYPE1 ... ENV FORMALS FORM1 ...) ...) GF);; (#@dispatch args N-SPECIALIZED HASHSET MASK;;             #((TYPE1 ... ENV FORMALS FORM1 ...) ...);;             GF);;; Representation;; non-hashed form(define method-cache-entries cadddr)(define (set-method-cache-entries! mcache entries)  (set-car! (cdddr mcache) entries))(define (method-cache-n-methods exp)  (n-cache-methods (method-cache-entries exp)))(define (method-cache-methods exp)  (cache-methods (method-cache-entries exp)));; hashed form(define (set-hashed-method-cache-hashset! exp hashset)  (set-car! (cdddr exp) hashset))(define (set-hashed-method-cache-mask! exp mask)  (set-car! (cddddr exp) mask))(define (hashed-method-cache-entries exp)  (list-ref exp 5))(define (set-hashed-method-cache-entries! exp entries)  (set-car! (list-cdr-ref exp 5) entries));; either form(define (method-cache-generic-function exp)  (list-ref exp (if (method-cache-hashed? exp) 6 4)));;; Predicates(define (method-cache-hashed? x)  (integer? (cadddr x)))(define max-non-hashed-index (- hash-threshold 2))(define (passed-hash-threshold? exp)  (and (> (vector-length (method-cache-entries exp)) max-non-hashed-index)       (struct? (car (vector-ref (method-cache-entries exp)				 max-non-hashed-index)))));;; Converting a method cache to hashed form(define (method-cache->hashed! exp)  (set-cdr! (cddr exp) (cons 0 (cons initial-hash-size-1 (cdddr exp))))  exp);;;;;; Cache entries;;;(define (n-cache-methods entries)  (do ((i (- (vector-length entries) 1) (- i 1)))      ((or (< i 0) (struct? (car (vector-ref entries i))))       (+ i 1))))(define (cache-methods entries)  (do ((i (- (vector-length entries) 1) (- i 1))       (methods '() (let ((entry (vector-ref entries i)))		      (if (struct? (car entry))			  (cons entry methods)			  methods))))      ((< i 0) methods)));;;;;; Method insertion;;;(define (method-cache-insert! exp entry)  (let* ((entries (method-cache-entries exp))	 (n (n-cache-methods entries)))    (if (>= n (vector-length entries))	;; grow cache	(let ((new-entries (make-vector (* 2 (vector-length entries))					the-list-of-no-method)))	  (do ((i 0 (+ i 1)))	      ((= i n))	    (vector-set! new-entries i (vector-ref entries i)))	  (vector-set! new-entries n entry)	  (set-method-cache-entries! exp new-entries))	(vector-set! entries n entry))))(define (hashed-method-cache-insert! exp entry)  (let* ((cache (hashed-method-cache-entries exp))	 (size (vector-length cache)))    (let* ((entries (cons entry (cache-methods cache)))	   (size (if (<= (length entries) size)		     size		     ;; larger size required		     (let ((new-size (* 2 size)))		       (set-hashed-method-cache-mask! exp (- new-size 1))		       new-size)))	   (min-misses size)	   (best #f))      (do ((hashset 0 (+ 1 hashset)))	  ((= hashset hashsets))	(let* ((test-cache (make-vector size the-list-of-no-method))	       (misses (cache-try-hash! min-misses hashset test-cache entries)))	  (cond ((zero? misses)		 (set! min-misses 0)		 (set! best hashset)		 (set! cache test-cache)		 (set! hashset (- hashsets 1)))		((< misses min-misses)		 (set! min-misses misses)		 (set! best hashset)		 (set! cache test-cache)))))      (set-hashed-method-cache-hashset! exp best)      (set-hashed-method-cache-entries! exp cache))));;;;;; Caching;;;(define environment? pair?)(define (cache-hashval hashset entry)  (let ((hashset-index (+ hashset-index hashset)))    (do ((sum 0)	 (classes entry (cdr classes)))	((environment? (car classes)) sum)      (set! sum (+ sum (struct-ref (car classes) hashset-index))))))(define (cache-try-hash! min-misses hashset cache entries)  (let ((max-misses 0)	(mask (- (vector-length cache) 1)))    (catch 'misses	   (lambda ()	     (do ((ls entries (cdr ls))		  (misses 0 0))		 ((null? ls) max-misses)	       (do ((i (logand mask (cache-hashval hashset (car ls)))		       (logand mask (+ i 1))))		   ((not (struct? (car (vector-ref cache i))))		    (vector-set! cache i (car ls)))		 (set! misses (+ 1 misses))		 (if (>= misses min-misses)		     (throw 'misses misses)))	       (if (> misses max-misses)		   (set! max-misses misses))))	   (lambda (key misses)	     misses))));;;;;; Memoization;;;;; Backward compatibility(if (not (defined? 'lookup-create-cmethod))    (define (lookup-create-cmethod gf args)      (no-applicable-method (car args) (cadr args))))(define (memoize-method! gf args exp)  (if (not (slot-ref gf 'used-by))      (slot-set! gf 'used-by '()))  (let ((applicable ((if (eq? gf compute-applicable-methods)			 %compute-applicable-methods			 compute-applicable-methods)		     gf args)))    (cond (applicable	   ;; *fixme* dispatch.scm needs rewriting Since the current	   ;; code mutates the method cache, we have to work on a	   ;; copy.  Otherwise we might disturb another thread	   ;; currently dispatching on the cache.  (No need to copy	   ;; the vector.)	   (let* ((new (list-copy exp))		  (res		   (cond ((method-cache-hashed? new)			  (method-cache-install! hashed-method-cache-insert!						 new args applicable))			 ((passed-hash-threshold? new)			  (method-cache-install! hashed-method-cache-insert!						 (method-cache->hashed! new)						 args						 applicable))			 (else			  (method-cache-install! method-cache-insert!						 new args applicable)))))	     (set-cdr! (cdr exp) (cddr new))	     res))	  ((null? args)	   (lookup-create-cmethod no-applicable-method (list gf '())))	  (else	   ;; Mutate arglist to fit no-applicable-method	   (set-cdr! args (list (cons (car args) (cdr args))))	   (set-car! args gf)	   (lookup-create-cmethod no-applicable-method args)))))(set-procedure-property! memoize-method! 'system-procedure #t)(define method-cache-install!  (letrec ((first-n	    (lambda (ls n)	      (if (or (zero? n) (null? ls))		  '()		  (cons (car ls) (first-n (cdr ls) (- n 1)))))))    (lambda (insert! exp args applicable)      (let* ((specializers (method-specializers (car applicable)))	     (n-specializers	      (if (list? specializers)		  (length specializers)		  (+ 1 (slot-ref (method-cache-generic-function exp)				 'n-specialized)))))	(let* ((types (map class-of (first-n args n-specializers)))	       (entry+cmethod (compute-entry-with-cmethod applicable types)))	  (insert! exp (car entry+cmethod)) ; entry = types + cmethod	  (cdr entry+cmethod) ; cmethod	  )))))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -