scsh-0.6/scheme/vm/vm-tables.scm

110 lines
3.3 KiB
Scheme

; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
; Copyright (c) 1993-1999 by Richard Kelsey and Jonathan Rees. See file COPYING.
; String hash tables for managing three tables:
; the symbol table : string -> symbol
; exported-bindings : string -> shared-binding
; imported-bindings : string -> shared-binding
; Size of the hash vectors (is this a reasonable size?).
(define hash-table-slots 1024)
(define hash-table-size (vm-vector-size hash-table-slots))
; All hash table values are required to have their own link fields.
(define hash-table-entry-size 0)
(define (hash-table-index string)
(bitwise-and (vm-string-hash string)
(- hash-table-slots 1)))
; All buckets are initially false.
(define (make-hash-table key)
(let ((table (vm-make-vector hash-table-slots key)))
(natural-for-each (lambda (index)
(vm-vector-set! table index false))
hash-table-slots)
table))
; Return a procedure for adding FOO's to tables.
(define (table-adder foo-string set-foo-next!)
(lambda (table foo)
(let ((index (hash-table-index (foo-string foo))))
(set-foo-next! foo (vm-vector-ref table index))
(vm-vector-set! table index foo))))
; Return a function for looking up strings in a Foo table. A new Foo is
; made if none is found.
(define (table-searcher foo-string foo-next make-foo)
(lambda (table string key)
(let* ((index (hash-table-index string))
(bucket (vm-vector-ref table index)))
(let loop ((foo bucket))
(cond ((vm-eq? foo false)
(let ((new (make-foo string bucket key)))
(vm-vector-set! table index new)
new))
((vm-string=? string (foo-string foo))
foo)
(else
(loop (foo-next foo))))))))
; Same thing, except we remove the entry if it is found.
(define (table-remover foo-string foo-next set-foo-next!)
(lambda (table string)
(let* ((index (hash-table-index string))
(bucket (vm-vector-ref table index)))
(let loop ((previous-foo false) (foo bucket))
(cond ((vm-eq? foo false)
(unspecific))
((not (vm-string=? string (foo-string foo)))
(loop foo (foo-next foo)))
((vm-eq? previous-foo false)
(vm-vector-set! table index (foo-next foo)))
(else
(set-foo-next! previous-foo (foo-next foo))))))))
; Return a procedure that will apply PROC to every element of TABLE.
(define (table-walker foo-next)
(lambda (proc table)
(natural-for-each (lambda (index)
(let loop ((entry (vm-vector-ref table index)))
(if (not (vm-eq? entry false))
(begin
(proc entry)
(loop (foo-next entry))))))
hash-table-slots)))
; Copy a table, treating the entries weakly.
(define (table-cleaner foo-next set-foo-next!)
(let ((entry-cleaner (entry-cleaner foo-next set-foo-next!)))
(lambda (table)
(let ((table (s48-trace-value table)))
(natural-for-each
(lambda (index)
(vm-vector-set! table
index
(entry-cleaner (vm-vector-ref table index))))
hash-table-slots)))))
(define (entry-cleaner foo-next set-foo-next!)
(lambda (foo)
(let loop ((foo foo) (okay false))
(if (vm-eq? foo false)
okay
(loop (foo-next foo)
(if (s48-extant? foo)
(let ((new-foo (s48-trace-value foo)))
(set-foo-next! new-foo okay)
new-foo)
okay))))))