sicp/3_25.rkt

58 lines
1.6 KiB
Racket

#lang sicp
(#%require racket/trace)
(define (make-table)
(list '*table*))
(define (assoc key records)
(cond ((null? records) false)
((equal? key (caar records)) (car records))
(else (assoc key (cdr records)))))
(define (empty? table)
(not (list? (cdr table))))
(define (lookup keys table)
(cond ((null? keys) (cdr table))
((empty? table) false)
(else
(let ((subtable (assoc (car keys) (cdr table))))
(if subtable
(lookup (cdr keys) subtable)
false)))))
(define (insert! keys value table)
(define (insert-subtable! keys subtable)
(if (and (not (null? keys))
(not (null? subtable)))
(let* ((key (car keys))
(record (assoc (car keys) (cdr subtable))))
(if record
(if (= (length keys) 1)
(set-cdr! record value))
(set-cdr! subtable
(cons (cons key
(if (= (length keys) 1)
value
'()))
(cdr subtable))))
(let ((next-subtable (assoc key (cdr subtable))))
(insert-subtable! (cdr keys) next-subtable)))))
(insert-subtable! keys table)
'ok)
(#%require (only racket/base module+))
(module+ test
(#%require rackunit)
(test-begin
(define t (make-table))
(insert! '(10 10) 'a t)
(check-equal? (lookup '(10 10) t) 'a)
(check-equal? (lookup '(10 10 10) t) false)
(insert! '(20) 'b t)
(check-equal? (lookup '(20) t) 'b)))