Assignment 8, CSC430, Spring 2008
1 Guidelines
1.1 Contracts & Test Cases
For this and all remaining assignments, every function you develop must come with the following things:
A commented header line that expresses the result of the function in terms of its inputs, written in English. Be as precise as you can within the space of a line or two.
A commented contract line that gives the types of the inputs and the output. The contract should have the form <in-type> ... -> <out-type>. So, for instance, a numerical square function might have the contract line:
; number -> number
Test cases. A function without test cases is incomplete. Write the test cases first, please.
1.2 Handling errors
Your parser and interpreter must detect errors and explicitly signal them by calling (error ...). We will consider an error raised internally by Scheme to be a bug in your code.
For example, Scheme signals a "divide by zero" error if you attempt to evaluate (/ 1 0). Since we use Scheme’s division function to implement division in CFWAE, you may be tempted to leave it to Scheme to signal division by zero errors for you. However, you must signal the error yourself by explicitly testing for division by zero before calling Scheme’s division procedure.
Note that you may assume that your contracts are respected. That is, if your interp function’s contract indicates that it expects a CFWAE, you do not need to worry about miscreants that call it with a number or a string or another surprising value.
1.3 Language Level & File Format
NOTE: For this assignment, you must develop your solutions using the Programming Languages: Application and Interpretation: Pretty Big PLAI Scheme language level. Your test cases must use the (test ...) or (test/exn ...) form.
Your solution should take the form of a single file. Solve each problem separately, ands make sure that each solution appears in a separate part of the file, with comments separating each problem’s solution.
Hand in your solution using the handin server. For help with the handin server, please see the course web page.
2 Pair Programming
This assignment is a pair programming assignment. This means that you may work with at most one other person. You are not required to do so, but I strongly encourage it; if you don’t feel that you need the help, then work with someone who does.
To declare partners, both you and your partner must send me e-mail indicating this fact, at least three days before the assignment is due. In order to submit a pair programming assignment, use the string formed by joining your individual ids with a "+" in between. So, if my login is "clements" and my partner’s is "wilson", then we would submit as "clements+wilson". Don’t submit by yourself if you’re planning to work with a partner; an individual submission will prevent a later pair submission.
3 The Assignment
This assignment requires you to implement letcc. To do this, you’ll need to start with your solution from Assignment 3/4, convert it to continuation-passing-style, and then add letcc, as we discussed in class.
4 Syntax of KFAE
The syntax of the KFAE language with these additional features can be captured with the following EBNF:
KFAE |
| = |
| num |
|
| | |
| true |
|
| | |
| false |
|
| | |
| {+ KFAE KFAE} |
|
| | |
| {- KFAE KFAE} |
|
| | |
| {* KFAE KFAE} |
|
| | |
| {/ KFAE KFAE} |
|
| | |
| {and KFAE KFAE} |
|
| | |
| {or KFAE KFAE} |
|
| | |
| {not KFAE} |
|
| | |
| {= KFAE KFAE} |
|
| | |
| id |
|
| | |
| {if KFAE KFAE KFAE} |
|
| | |
| {with {{id KFAE}*} KFAE} |
|
| | |
| {fun {id *} KFAE} |
|
| | |
| {letcc id KFAE} |
|
| | |
| {KFAE KFAE *} |
with
... where an id is not true, false, +, -, *, /, and, or, not, =, with, if, fun, or letcc.
and num is a number.
If a fun or a with expression has duplicate identifiers, we consider it a syntax error. Therefore, such errors must be detected in parse. For example, parsing the following expressions must signal errors:
{with {{x 10} {x 20}} 50} |
|
{fun {x x} 10} |
...
5 Support Code
Your code must adhere to the following template, without any changes.
; represents an expression |
(define-type KFAE |
[num (n number?)] |
[bool (b boolean?)] |
[binop (op procedure?) (lhs KFAE?) (rhs KFAE?)] |
[id (name symbol?)] |
[ifexp (tst KFAE?) (then KFAE?) (els KFAE?)] |
[fun (params (listof symbol?)) (body KFAE?)] |
[letcc (k-var symbol?) (body KFAE?)] |
[app (f KFAE?) (args (listof KFAE?))]) |
|
; represents an environment during evaluation |
(define-type Env |
[mtEnv] |
[anEnv (name symbol?) (value KFAE-Value?) (env Env?)]) |
|
; represents a possible result of evaluation |
(define-type KFAE-Value |
[numV (n number?)] |
[boolV (b boolean?)] |
[closureV (params (listof symbol?)) |
(body KFAE?) |
(env Env?)] |
[contV (c procedure?)]) |
|
; parse : s-exp -> KFAE |
; Consumes an s-expression and generates the corresponding KFAE |
(define (parse sexp) |
...) |
|
; This procedure interprets the given KFAE and passes the final |
; KFAE-Value to the initial receiver |
; interp/inner : KFAE-Value? Env? receiver -> KFAE-Value? |
(define (interp expr env k) |
...) |