-
Notifications
You must be signed in to change notification settings - Fork 1
/
table-imp.rkt
74 lines (60 loc) · 2.09 KB
/
table-imp.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#lang racket
(require compatibility/mlist)
(require rackunit)
(provide (rename-out [lookup2 get][insert2 put]) make-table)
; Author: Zilu Tian
; Date: March 20, 2020
; table
; https://web.mit.edu/alexmv/6.037/sicp.pdf, P.362
; 1D table represented as a headed list
(define (lookup key table)
(let [(record (assoc key (mcdr table)))]
(if record ; check the record is not empty
(mcdr record)
false)))
(define (assoc key records)
(cond [(null? records) false]
[(equal? key (mcar (mcar records))) (mcar records)]
[else (assoc key (mcdr records))]))
(define (insert! key value table)
(let [(record (assoc key (mcdr table)))]
(if record
(set-mcdr! record value)
(set-mcdr! table
(mcons (mcons key value)
(mcdr table))))))
(define (make-table)
(mlist '*table*))
; test
(test-case
"Check 1D table"
(define A (make-table))
(insert! 'add '+ A)
(check-equal? (mcdr A) (mcons (mcons 'add '+) '())) ; table content
(check-equal? (mcar A) '*table*)
(check-equal? (lookup 'add A) '+) ; lookup
(check-equal? (lookup 'minus A) #f) ; non-existent
(insert! 'add '+C A) ; overwrite
(check-equal? (lookup 'add A) '+C)) ; lookup overwrite
; 2D table
(define (lookup2 key1 key2 table)
(let [(subtable (assoc key1 (mcdr table)))]
(if subtable ; check the subtable is not empty
(lookup key2 subtable)
false)))
(define (insert2 key1 key2 value table)
(let [(subtable (assoc key1 (mcdr table)))]
(if subtable
(insert! key2 value subtable)
(set-mcdr! table
(mcons (mlist key1 (mcons key2 value))
(mcdr table))))))
(test-case
"Check 2D table"
(define B (make-table))
(insert2 'add 'complex '+C B) ; insert
(check-equal? (lookup2 'add 'complex B) '+C) ; lookup
(check-equal? (lookup2 'minus 'complex B) #f) ; non-existent
(insert2 'add 'real '+R B) ; overwrite
(check-equal? (lookup2 'add 'real B) '+R)
(check-equal? (lookup2 'add 'complex B) '+C)) ; lookup overwrite