Skip to content

Commit 2386ac7

Browse files
committed
scoping test for eval
1 parent 3fe7b9e commit 2386ac7

File tree

1 file changed

+64
-15
lines changed

1 file changed

+64
-15
lines changed

src/eval/eval.scm

Lines changed: 64 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
((assignment? exp) (eval-assignment exp env))
3131
((definition? exp) (eval-definition exp env))
3232
((if? exp) (eval-if exp env))
33-
((lambda? exp)
33+
((lambda? exp) ; evaluated when define procedure
3434
(make-procedure (lambda-params exp)
3535
(lambda-body exp)
3636
env))
@@ -43,6 +43,7 @@
4343
((letstar? exp) (seck-eval (let*->nested-let exp) env))
4444
((for? exp) (seck-eval (for->let exp) env))
4545
((application? exp)
46+
; evaluated when call procedure
4647
(seck-apply (seck-eval (operator exp) env)
4748
(list-of-values (operand exp) env)))
4849
(else
@@ -54,6 +55,9 @@
5455
(eq? (car exp) tag)
5556
#f))
5657

58+
(define (unassigned? value)
59+
(eq? value '*unassigned*))
60+
5761
; @(environment)
5862

5963
(define (make-env base)
@@ -65,7 +69,11 @@
6569
(let ((ret (dict-lookup (cur-env-var-dict) var)))
6670
(let ((found (car ret))
6771
(value (cadr ret)))
68-
(cond (found value)
72+
(cond ((and found
73+
(not (unassigned? value)))
74+
value)
75+
(found
76+
(error 'lookup "variabled looked up is unassigned"))
6977
((empty-env? (base-env))
7078
(error 'lookup "variable not defined" var))
7179
(else
@@ -249,6 +257,21 @@
249257
(seck-eval (first-exp exps) env)
250258
(eval-sequence (rest-exps exps) env))
251259
))
260+
; proc-body is a sequence of expressions to be evaluated
261+
(define (scan-out-defines proc-body)
262+
(let ((definitions (filter definition? proc-body))
263+
(non-definitions (filter (compose not definition?)
264+
proc-body)))
265+
(make-let (map (lambda (exp)
266+
(list (definition-var exp)
267+
'*unassigned*))
268+
definitions)
269+
(append (map (lambda (exp)
270+
(list 'set!
271+
(definition-var exp)
272+
(definition-value exp)))
273+
definitions)
274+
non-definitions))))
252275

253276
; @(assignment)
254277

@@ -465,6 +488,7 @@
465488
(define (for-body exp) (cddddr exp))
466489

467490

491+
468492
; @(application)
469493
(define application? pair?)
470494
(define (operator exp) (car exp))
@@ -486,12 +510,20 @@
486510
(extend-environment
487511
(procedure-parameters procedure)
488512
arguments
513+
; Here, we eval the expression in
514+
; a new env which extends procedure env(the
515+
; env in which procedure is defined). This
516+
; ensures lexical scoping.
517+
; If we evaluate the procedure bodyin
518+
; the env that seck-apply is called, then
519+
; it will be dynamic scoping.
489520
(procedure-env procedure))))
490521
(else
491522
(error
492523
'seck-apply
493524
"Unknown procedure type" procedure))))
494525

526+
495527
; @(global env)
496528
(define (setup-environment)
497529
(extend-environment (primitive-names)
@@ -563,18 +595,35 @@
563595
new-env)
564596
55))
565597
)
566-
(seck-eval '((lambda ()
567-
(define (foo a) a)
568-
(foo 3)
569-
)
598+
(seck-eval '((lambda ()
599+
(define (foo a) a)
600+
(foo 3)
570601
)
571-
global-env)
572-
'pass)
573-
574-
(define (simple-test)
575-
(seck-eval '(define (foo x)
576-
x)
602+
)
577603
global-env)
578-
(display (seck-eval '(map foo '(1 2 3))
579-
global-env))
580-
)
604+
'pass)
605+
606+
(define proc (make-procedure '(c)
607+
'((define b (+ a x))
608+
(define a 5)
609+
(+ a b c))
610+
global-env))
611+
(define (test-scan-out-definitons)
612+
(scan-out-defines (procedure-body proc)))
613+
614+
(define (test-scoping)
615+
; if it's lexical scoping, it will return 7
616+
; but if it's dynamic scoping, it will return 8
617+
(let ((new-env (make-env global-env)))
618+
(seck-eval '(define a 4)
619+
new-env)
620+
(seck-eval '(define (foo)
621+
(+ a 3))
622+
new-env)
623+
(seck-eval '(define (bar)
624+
(define a 5)
625+
(foo))
626+
new-env)
627+
(println (seck-eval '(bar)
628+
new-env))
629+
))

0 commit comments

Comments
 (0)