Skip to content

Commit 590c2d0

Browse files
committed
multiple scheme implementation support update
1 parent 61861f6 commit 590c2d0

File tree

5 files changed

+158
-117
lines changed

5 files changed

+158
-117
lines changed

src/eval/eval.scm

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
((or? exp) (seck-eval (or->if exp) env))
4242
((let? exp) (seck-eval (let->combination exp) env))
4343
((letstar? exp) (seck-eval (let*->nested-let exp) env))
44+
((letrec? exp) (seck-eval (letrec->let exp) env))
4445
((for? exp) (seck-eval (for->let exp) env))
4546
((application? exp)
4647
; evaluated when call procedure
@@ -239,7 +240,7 @@
239240
(define (make-procedure params body-seq env)
240241
(list 'procedure
241242
params
242-
(scan-out-defines body-seq)
243+
(scan-out-defines body-seq #f)
243244
env))
244245

245246
(define (procedure-parameters proc)
@@ -261,11 +262,12 @@
261262
(eval-sequence (rest-exps exps) env))
262263
))
263264
; proc-body is a sequence of expressions to be evaluated
264-
(define (scan-out-defines proc-body)
265+
(define (scan-out-defines proc-body do-scan-out)
265266
(let ((definitions (filter definition? proc-body))
266267
(non-definitions (filter (compose not definition?)
267268
proc-body)))
268-
(if (not (null? definitions))
269+
(if (and do-scan-out
270+
(not (null? definitions)))
269271
(list (make-let (map (lambda (exp)
270272
(list (definition-var exp)
271273
;; Here, we use '', since
@@ -488,6 +490,20 @@
488490
(let-vals exp) ; todo
489491
))
490492

493+
494+
(define (letrec? exp)
495+
(tagged-list? exp 'letrec))
496+
(define (letrec->let exp)
497+
(make-let
498+
(map (lambda (var)
499+
(list var ''*assigned*))
500+
(let-vars exp))
501+
(append (map (lambda (var value)
502+
(list 'set! var value))
503+
(let-vars exp)
504+
(let-vals exp))
505+
(let-body exp))))
506+
491507
; @(for)
492508

493509
(define (for? exp)
@@ -613,10 +629,32 @@
613629
global-env)
614630
'pass)
615631

616-
(define proc (make-procedure '(c)
617-
'((define b (+ a x))
618-
(define a 5)
619-
(+ a b c))
620-
global-env))
621-
(define (test-scan-out-definitons)
622-
(scan-out-defines (procedure-body proc)))
632+
633+
(define letrec-exp '(letrec ((even?
634+
(lambda (n)
635+
(if (= n 0)
636+
true
637+
(odd? (- n 1)))))
638+
(odd?
639+
(lambda (n)
640+
(if (= n 0)
641+
false
642+
(even? (- n 1))))))
643+
(even? x)))
644+
645+
(define (test-letrec)
646+
(seck-eval '(define (f x)
647+
(letrec ((even?
648+
(lambda (n)
649+
(if (= n 0)
650+
true
651+
(odd? (- n 1)))))
652+
(odd?
653+
(lambda (n)
654+
(if (= n 0)
655+
false
656+
(even? (- n 1))))))
657+
(even? x)))
658+
global-env)
659+
(seck-eval '(f 3) global-env)
660+
)

src/lib/r6rs/chez.scm

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
(library
2+
(chez)
3+
(export sleepfor
4+
parallel-execute
5+
make-semaphore
6+
semaphore-acquire
7+
semaphore-release
8+
rand
9+
random-in-range
10+
random-init
11+
random-update
12+
)
13+
(import (chezscheme))
14+
15+
; @(utils)
16+
; sleep for s seconds
17+
(define (sleepfor s)
18+
(sleep (make-time 'time-duration 0 s)))
19+
20+
; @(concurrency)
21+
(define (parallel-execute . args)
22+
(for-each fork-thread args))
23+
24+
(define (make-serializer)
25+
(let ((mutex (make-mutex)))
26+
(lambda (p)
27+
(define (serialized-p . args)
28+
(mutex 'acquire)
29+
(let ((val (apply p args)))
30+
(mutex 'release)
31+
val))
32+
serialized-p)))
33+
(define (make-semaphore n)
34+
(let ((mutex (make-mutex)))
35+
(define (acquire . args)
36+
(let ((block? (if (null? args)
37+
#t
38+
(car args))))
39+
; Note n's if test should be protected by mutex.
40+
(mutex-acquire mutex)
41+
(if (> n 0)
42+
(begin (set! n (- n 1))
43+
(mutex-release mutex)
44+
#t)
45+
(begin (mutex-release mutex)
46+
(if block?
47+
(acquire)
48+
#f)))
49+
))
50+
(define (release)
51+
(mutex-acquire mutex)
52+
(set! n (+ n 1))
53+
(mutex-release mutex))
54+
55+
(define (self msg)
56+
(cond ((eq? msg 'acquire) acquire)
57+
((eq? msg 'release) release)
58+
(else
59+
(error 'semaphore-self "UNKNOWN MESSAGE" msg))))
60+
self))
61+
62+
(define (semaphore-acquire sem . args)
63+
(apply (sem 'acquire) args))
64+
65+
(define (semaphore-release sem)
66+
(sem 'release))
67+
68+
; a not practical implementation of test-and-set!
69+
(define (test-and-set! cell)
70+
(if (car cell)
71+
#t
72+
(begin (set-car! cell #t)
73+
#f)))
74+
75+
(define (clear! cell)
76+
(set-car! cell #f))
77+
78+
(define (mutex-test-and-set-impl)
79+
(define (make-mutex)
80+
(let ((cell (list #f)))
81+
(define (self msg)
82+
(cond ((eq? msg 'acquire)
83+
(if (test-and-set! cell)
84+
(self 'acquire)
85+
#t))
86+
((eq? msg 'release)
87+
(clear! cell))))
88+
self)))
89+
90+
; [low high)
91+
(define (random-in-range low high)
92+
(let ((range (- high low)))
93+
(+ low (random range))))
94+
(define random-init (time-second (current-time)))
95+
(define (random-update x)
96+
(let ((a 40)
97+
(b 2641)
98+
(m 729))
99+
(modulo (+ (* a x) b) m)))
100+
101+
(define rand
102+
(let ((x random-init))
103+
(lambda ()
104+
(set! x (rand-update x))
105+
x)))
106+
)

src/lib/r6rs/concurrency.scm

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +0,0 @@
1-
(library
2-
(concurrency)
3-
(export parallel-execute
4-
make-semaphore
5-
semaphore-acquire
6-
semaphore-release)
7-
8-
(import (chezscheme))
9-
10-
(define (parallel-execute . args)
11-
(for-each fork-thread args))
12-
13-
(define (make-serializer)
14-
(let ((mutex (make-mutex)))
15-
(lambda (p)
16-
(define (serialized-p . args)
17-
(mutex 'acquire)
18-
(let ((val (apply p args)))
19-
(mutex 'release)
20-
val))
21-
serialized-p)))
22-
(define (make-semaphore n)
23-
(let ((mutex (make-mutex)))
24-
(define (acquire . args)
25-
(let ((block? (if (null? args)
26-
#t
27-
(car args))))
28-
; Note n's if test should be protected by mutex.
29-
(mutex-acquire mutex)
30-
(if (> n 0)
31-
(begin (set! n (- n 1))
32-
(mutex-release mutex)
33-
#t)
34-
(begin (mutex-release mutex)
35-
(if block?
36-
(acquire)
37-
#f)))
38-
))
39-
(define (release)
40-
(mutex-acquire mutex)
41-
(set! n (+ n 1))
42-
(mutex-release mutex))
43-
44-
(define (self msg)
45-
(cond ((eq? msg 'acquire) acquire)
46-
((eq? msg 'release) release)
47-
(else
48-
(error 'semaphore-self "UNKNOWN MESSAGE" msg))))
49-
self))
50-
51-
(define (semaphore-acquire sem . args)
52-
(apply (sem 'acquire) args))
53-
54-
(define (semaphore-release sem)
55-
(sem 'release))
56-
57-
; a not practical implementation of test-and-set!
58-
(define (test-and-set! cell)
59-
(if (car cell)
60-
#t
61-
(begin (set-car! cell #t)
62-
#f)))
63-
64-
(define (clear! cell)
65-
(set-car! cell #f))
66-
67-
(define (mutex-test-and-set-impl)
68-
(define (make-mutex)
69-
(let ((cell (list #f)))
70-
(define (self msg)
71-
(cond ((eq? msg 'acquire)
72-
(if (test-and-set! cell)
73-
(self 'acquire)
74-
#t))
75-
((eq? msg 'release)
76-
(clear! cell))))
77-
self)))
78-
)

src/lib/r6rs/rand.scm

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1 @@
1-
(library
2-
(rand)
3-
(import (chezscheme))
4-
(export rand
5-
random-init
6-
random-update)
7-
(define random-init (time-second (current-time)))
8-
(define (random-update x)
9-
(let ((a 40)
10-
(b 2641)
11-
(m 729))
12-
(modulo (+ (* a x) b) m)))
131

14-
(define rand
15-
(let ((x random-init))
16-
(lambda ()
17-
(set! x (rand-update x))
18-
x)))
19-
)

src/lib/r6rs/utils.scm

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
set-caddr!
88
inlist?
99
range
10-
random-in-range
11-
sleepfor
1210
divides?
1311
divisible?
1412
println
1513
average
1614
pythagorean-triple?)
17-
(import (chezscheme))
15+
16+
(import (rnrs)
17+
(rnrs r5rs)
18+
(rnrs mutable-pairs))
1819
(define (set-cadr! lst v)
1920
(set-car! (cdr lst) v))
2021

@@ -40,14 +41,6 @@
4041
((> a b) (cons a (range (- a 1) b)))
4142
((< a b) (cons a (range a (- b 1))))))
4243

43-
; [low high)
44-
(define (random-in-range low high)
45-
(let ((range (- high low)))
46-
(+ low (random range))))
47-
48-
; sleep for s seconds
49-
(define (sleepfor s)
50-
(sleep (make-time 'time-duration 0 s)))
5144
(define (divides? a b)
5245
(= (remainder b a) 0))
5346

0 commit comments

Comments
 (0)