0% found this document useful (0 votes)
20 views14 pages

13 Midterm

The document is a midterm exam for CS 320, Spring 2013, consisting of various questions related to programming principles and language interpretation. It includes tasks such as rewriting code, explaining concepts like infinite loops and scoping, and interpreting expressions in different programming languages. Students are instructed to complete the exam within 150 minutes and can write their answers in Korean.

Uploaded by

vedapac571
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views14 pages

13 Midterm

The document is a midterm exam for CS 320, Spring 2013, consisting of various questions related to programming principles and language interpretation. It includes tasks such as rewriting code, explaining concepts like infinite loops and scoping, and interpreting expressions in different programming languages. Students are instructed to complete the exam within 150 minutes and can write their answers in Korean.

Uploaded by

vedapac571
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

Midterm Exam

CS 320, Spring 2013


Student id: Name:

Instructions: You have 150 minutes to complete this closed-book, closed-note, closed-computer exam. Please
write all answers in the provided space. You’re free to write your answers in Korean.

0) (5pts) Answer the following questions:


a) Did you take CS220 Programming Principles (프로그래밍의 이해)? If so, when?

b) Do you have any suggestions for this course?

1) (5pts) Rewrite the following FWAE code in FAE, that is, rewrite it without using with:

{with {x {fun {n} {+ x n}}} {fun {n} {x {- 10 n}}}}

2) (5pts) Given the following expression in the FWAE language:

{with {f {with {g {fun {x} {x g}}}


{g f}}}
{+ z {with {y {f z}}
{g y}}}}
a) Draw arrows on the above expression from each bound variable to its binding occurrence.
b) List the names of free variables:

and bound variables:

1
3) (5pts) Which of the following produce different results in an eager language and a lazy language? Both
produce the same result if they both produce the same number or they both produce a procedure (even
if the procedure doesn’t behave exactly the same when applied). Show the results of each expression
in an eager language and a lazy language.

a) {+ 8 {fun {x} 42}}

eager: lazy:

b) {{fun {n} 42} {1 2}}

eager: lazy:

c) {fun {m} {{fun {n} 42} {9 2}}}

eager: lazy:

d) {+ 1 {{fun {x} {+ 1 13}} {+ 1 {fun {z} 12}}}}

eager: lazy:

e) {+ 1 {{fun {x} {+ x 13}} {+ 1 {fun {z} 12}}}}

eager: lazy:

4) (5pts) Which of the following are examples of shadowing?


a) {with {’m 3}
{with {’n 7} {+ 18 ’m}}}

b) {with {’m 24}


{with {’m 9} {+ 17 ’m}}}

c) {with {’m {with {’m 20} {+ 17 ’m}}}


{+ 73 ’m}}

2
5) (5pts) Explain why the following code is an infinite loop and describe how to break the infinite loop:

1 (let ([fac
2 (let ([facX
3 (lambda (facX)
4 (let ([fac (facX facX)])
5 (lambda (n)
6 (if (zero? n)
7 1
8 (* n (fac (- n 1)))))))])
9 (facX facX))])
10 (fac 10))

6) (5pts) The following code is an implementation of the interpreter for FAE. Describe whether the code
implements static scope or dynamic scope, and why. Then, explain how to change the code to imple-
ment the other scoping semantics:

; interp : FAE DefrdSub -> FAE-Value


(define (interp fae ds)
(type-case FAE fae
[num (n) (numV n)]
[add (l r) (num+ (interp l ds) (interp r ds))]
[sub (l r) (num- (interp l ds) (interp r ds))]
[id (s) (lookup name ds)]
[fun (x b) (closureV x b ds)]
[app (f a) (local [(define f-val (interp f ds))
(define a-val (interp a ds))]
(interp (closureV-body f-val)
(aSub (closureV-param f-val)
a-val
(closureV-ds f-val))))]))

3
7) (5pts) In our implementation of the interpreter for LFAE, we call the strict function to enforce
evaluation. Where did we call the strict function in our implementation? If we instead call the
strict function when we look up identifiers, what difference would it make?

8) (5pts) Note that there is a nested strict call in the following:

; strict : LFAE-Value -> LFAE-Value


(define (strict v)
(type-case LFAE-Value v
[exprV (expr ds) (strict (interp expr ds))]
[else v]))

Write an example showing the need for the nested strict call.

4
9) (5pts) The following strict code results in redundant evaluations:

; strict : LFAE-Value -> LFAE-Value


(define (strict v)
(type-case LFAE-Value v
[exprV (expr ds) (strict (interp expr ds))]
[else v]))

Instead, we cache strict results using the following data structure:

(define-type LFAE-Value
[numV (n number?)]
[closureV (param symbol?) (body LFAE?) (ds DefrdSub?)]
[exprV (expr LFAE?) (ds DefrdSub?)
(value (box/c (or/c false LFAE-Value?)))])
Rewrite the above strict code using cached strict results.

5
10) (10pts) The following code is an excerpt from the implementation of the interpreter for BFAE:

(define (interp expr ds st)


...
[app (f a)
(interp-two f a ds st
(lambda (fv av st1)
(interp (closureV-body fv)
(aSub (closureV-param fv)
av
(closureV-ds fv))
st1)))]
...)

In BMFAE, we introduce variables so that DefrdSub maps names (symbols) to addresses (integers) and
Store maps addresses (integers) to values (BMFAE-Value). Rewrite the above app case for BMFAE.

6
11) (10pts) Change the implementation of setbox in interp for BFAE so that the old value of the box is
dropped (i.e., replaced with the new value) instead of merely hidden by the outside-in search order of
store-lookup. Define your helper function with its purpose and contract.

12) (10pts) Extend the implementation of interp for BFAE with with. Explain why or why not you use
interp-two.

7
13) (10pts) Given the following expression:

{{fun {b1}
{{fun {b2}
{seqn {setbox b1 8}
{openbox b2}}}
b1}}
{newbox 7}}

write out the arguments to and results of interp each time it is called during the evaluation of a
program. Write them out in the order in which the calls to interp occur during evaluation.
Write down the environments and stores using the {} notation, not using the more verbose data
constructors. Also, use an arrow notation for both the store and the environment.
An example, if the first call to interp were:

(interp (parse ‘{+ x y})


(aSub ’x (numV 3) (aSub ’y (numV 4) (mtSub)))
(mtSto))

then a model solution would be:

exp: {+ x y}
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 7) {}

exp: x
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 3) {}

exp: y
env: {x -> (numV 3), y -> (numV 4)}
sto: {}
ans: (numV 4) {}

Note that the environment and store read in order from left to right.

8
9
10
14) (10pts) Consider the following language <MYE>:

<MYE> ::= <num>


| {+ <MYE> <MYE>}
| <id>
| {* <id>}
| {& <id>}
| {with {<id> <MYE>} <MYE>}
| {seqn <MYE> <MYE>}
| {set <id> <MYE>}
| {set* <id> <MYE>}

where a value of the language is either a number or an address:

(define-type MYE-Value
[numV (n number?)]
[boxV (address integer?)])

and an environment maps names to addresses and a store maps addresses to values:

(define-type DefrdSub
[mtSub]
[aSub (name symbol?) (address integer?) (rest DefrdSub?)])
(define-type Store
[mtSto]
[aSto (address integer?) (value MYE-Value?) (rest Store?)])

The semantics of some constructs are as follows:

– The value of an identifier <id> is the value in the store at the address denoted by the identifier
in the environment.
– The value of {* <id>} is the value in the store at the address denoted by the value of the identifier.
– The value of {& <id>} is the address denoted by the identifier in the environment.
– The evaluation of {set <id> <MYE>} maps the address denoted by the identifier to the value of
<MYE>, which is the value of the whole expression.
– The evaluation of {set* <id> <MYE>} maps the address denoted by the value of the identifier to
the value of <MYE>, which is the value of the whole expression.
Using the following functions to lookup environments and stores:

;; lookup : symbol DefrdSub -> integer


(define (lookup name ds) ...)

;; store-lookup : integer Store -> MYE-Value


(define (store-lookup addr st) ...)

11
fill in the blanks below:

;; interp : MYE DefrdSub Store -> Value*Store


(define (interp mye ds st)
(type-case MYE mye
[num (n)
(v*s (numV n) st)]
[add (l r)
(interp-two l r ds st
(lambda (v1 v2 st1) (v*s (num+ v1 v2) st1)))]
[id (name)
________________________________________________]
[id* (name)
________________________________________________
________________________________________________
________________________________________________]
[id& (name)
________________________________________________]
[with (x i e)
(local [(define a (malloc st))]
(type-case Value*Store (interp i ds st)
[v*s (v1 st1)
(interp e (aSub x a ds) (aSto a v1 st1))]))]
[seqn (a b)
(interp-two a b ds st
(lambda (v1 v2 st1) (v*s v2 st1)))]
[set (x e)
________________________________________________
________________________________________________
________________________________________________]
[set* (x e)
________________________________________________
________________________________________________
________________________________________________]))

12
#lang plai

(define-type BFAE
[num (n number?)]
[add (lhs BFAE?) (rhs BFAE?)]
[sub (lhs BFAE?) (rhs BFAE?)]
[id (name symbol?)]
[fun (param symbol?) (body BFAE?)]
[app (fun-expr BFAE?) (arg-expr BFAE?)]
[newbox (val-expr BFAE?)]
[setbox (box-expr BFAE?) (val-expr BFAE?)]
[openbox (box-expr BFAE?)]
[seqn (first BFAE?) (second BFAE?)])
(define-type BFAE-Value
[numV (n number?)]
[closureV (param symbol?) (body BFAE?) (ds DefrdSub?)]
[boxV (address integer?)])
(define-type DefrdSub
[mtSub]
[aSub (name symbol?) (value BFAE-Value?) (rest DefrdSub?)])
(define-type Store
[mtSto]
[aSto (address integer?) (value BFAE-Value?) (rest Store?)])
(define-type Value*Store
[v*s (value BFAE-Value?) (store Store?)])

;; -------------------------------------------------------------

;; parse : S-expr -> BFAE


(define (parse sexp)
(cond
[(number? sexp) (num sexp)]
[(symbol? sexp) (id sexp)]
[(pair? sexp)
(case (car sexp)
[(+) (add (parse (second sexp)) (parse (third sexp)))]
[(-) (sub (parse (second sexp)) (parse (third sexp)))]
[(fun) (fun (first (second sexp)) (parse (third sexp)))]
[(newbox) (newbox (parse (second sexp)))]
[(setbox) (setbox (parse (second sexp)) (parse (third sexp)))]
[(openbox) (openbox (parse (second sexp)))]
[(seqn) (seqn (parse (second sexp)) (parse (third sexp)))]
[else (app (parse (first sexp)) (parse (second sexp)))])]))

;; -------------------------------------------------------------

;; num-op : (number number -> number) -> (BFAE-Value BFAE-Value -> BFAE-Value)
(define (num-op op x y) (numV (op (numV-n x) (numV-n y))))
(define (num+ x y) (num-op + x y))
(define (num- x y) (num-op - x y))

;; malloc : Store -> integer


(define (malloc store)
(type-case Store store
[mtSto () 0]
[aSto (addr val rest) (+ addr 1)]))

;; lookup : symbol DefrdSub -> BFAE-Value


(define (lookup name ds)
(type-case DefrdSub ds
[mtSub () (error ’lookup "free variable")]
[aSub (sub-name val rest-ds)
(if (symbol=? sub-name name)
val
(lookup name rest-ds))]))

13
;; store-lookup : number Store -> BFAE-Value
(define (store-lookup addr st)
(type-case Store st
[mtSto () (error ’store-lookup "unallocated")]
[aSto (sto-addr val rest-st)
(if (= addr sto-addr)
val
(store-lookup addr rest-st))]))

;; -------------------------------------------------------------

;; interp : BFAE DefrdSub Store -> Value*Store


(define (interp bfae ds st)
(type-case BFAE bfae
[num (n) (v*s (numV n) st)]
[add (l r) (interp-two l r ds st
(lambda (v1 v2 st1) (v*s (num+ v1 v2) st1)))]
[sub (l r) (interp-two l r ds st
(lambda (v1 v2 st1) (v*s (num- v1 v2) st1)))]
[id (name) (v*s (lookup name ds) st)]
[fun (param body-expr)
(v*s (closureV param body-expr ds) st)]
[app (fun-expr arg-expr)
(interp-two fun-expr arg-expr ds st
(lambda (fun-val arg-val st1)
(interp (closureV-body fun-val)
(aSub (closureV-param fun-val)
arg-val
(closureV-ds fun-val))
st1)))]
[newbox (expr)
(type-case Value*Store (interp expr ds st)
[v*s (val st1)
(local [(define a (malloc st1))]
(v*s (boxV a)
(aSto a val st1)))])]
[setbox (bx-expr val-expr)
(interp-two bx-expr val-expr ds st
(lambda (bx-val val st1)
(v*s val
(aSto (boxV-address bx-val)
val
st1))))]
[openbox (bx-expr)
(type-case Value*Store (interp bx-expr ds st)
[v*s (bx-val st1)
(v*s (store-lookup (boxV-address bx-val)
st1)
st1)])]
[seqn (a b) (interp-two a b ds st
(lambda (v1 v2 st1) (v*s v2 st1)))]))

;; interp-two : BFAE BFAE DefrdSub Store (Value Value Store -> Value*Store)
;; -> Value*Store
(define (interp-two expr1 expr2 ds st handle)
(type-case Value*Store (interp expr1 ds st)
[v*s (val1 st2)
(type-case Value*Store (interp expr2 ds st2)
[v*s (val2 st3)
(handle val1 val2 st3)])]))

14

You might also like