-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathex522.scm
53 lines (47 loc) · 2.02 KB
/
ex522.scm
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
; Answers for 5-2-2
; Exercise 5.8
;; a will be 3, as the first here will be the first label in the lookup table.
;; It would be inefficient to check the whole list for duplicates for every
;; label added - O(n^2/2). Better would be to form a sorted list of label
;; names at the end of extracting labels, then check sequentially for
;; duplicates - O(n log n + n); n log n for the sort, n for the scan.
;; Alternatively, you could scan the list of label names, checking whether
;; they are in a set (implemented as a hash table); if not, add to the set; if
;; so, signal error. As hash-table look up is constant, this would be O(n).
(define (repeated-value sequence)
(define (iter last sequence)
(if (null? sequence)
false
(let ((first (car sequence))
(rest (cdr sequence)))
(if (equal? first last)
first
(iter first rest)))))
(if (null? sequence)
false
(iter (car sequence) (cdr sequence))))
(define (extract-labels text receive)
(define (label-names labels)
(map (lambda (label)
(symbol->string (car label))) labels))
(define (extract text receive)
"Original extract procedure"
(if (null? text)
(receive '() '())
(extract (cdr text)
(lambda (insts labels)
(let ((next-inst (car text)))
(if (symbol? next-inst)
(receive insts
(cons (make-label-entry next-inst
insts)
labels))
(receive (cons (make-instruction next-inst)
insts)
labels)))))))
(extract text (lambda (insts labels)
(let ((repeated
(repeated-value (sort (label-names labels) string<?))))
(if repeated
(error "Label redefined" repeated)
(receive insts labels))))))