CS 496: Homework Assignment 3 Due: 25 February, 11:55pm
1 Assignment Policies
Collaboration Policy. It is acceptable for students to collaborate in understanding the material but not in solving the problems or programming. Use of the Internet is allowed, but should not include searching for existing solutions.
Under absolutely no circumstances code can be exchanged between students from different teams. Excerpts of code presented in class can be used.
Assignments from previous offerings of the course must not be re-used. Viola- tions will be penalized appropriately.
2 Assignment
This assignment consists in implementing a series of extensions to the interpreter for the language called LET that we saw in class. The concrete syntax of the extensions, the abstract syntax of the extensions (ast.ml) and the parser that converts the concrete syntax into the abstract syntax is already provided for you. Your task is to complete the definition of the interpreter, that is, the function eval_expr so that it is capable of handling the new language features.
Before addressing the extensions, we briefly recall the concrete and abstract syntax of LET. The concrete syntax is given by the grammar in Fig. 1. Each line in this grammar is called a production of the grammar. We will be adding new productions to this grammar corresponding to the extensions of LET that we shall study. These shall be presented in Section 3.
Next we recall the abstract syntax of LET, as presented in class. We shall also be extending this syntax with new cases for the new language features that we shall add to LET.
<Program> ::= <Expression>
<Expression> ::= <Number>
<Expression> ::= <Identifier>
<Expression> ::= <Expression> - <Expression>
<Expression> ::= zero? ( <Expression>)
<Expression> ::= if <Expression>
then <Expression> else <Expression>
<Expression> ::= let <Identifier> = <Expression> in <Expression>
<Expression> ::= ( <Expression>)
Figure 1: Concrete Syntax of LET
type expr =
| Var of string
| Int of int
| Sub of expr*expr
| Let of string*expr*expr
| IsZero of expr
| ITE of expr*expr*expr
3 Extensions to LET
This section lists the extensions to LET that you have to implement. This must be achieved by adding these extensions to your local copy of the repository of the LET language. Com- plete the implementation of the function eval_expr in the file PLaF/src/let/lib/interp.ml. Any helper functions must be placed in PLaF/src/let/lib/ds.ml. No other files should be modified.
3.1 Lists
Extend the interpreter to be able to handle the operators listed below. Whenever you are requested to produce an error, no specific error string is required (use any reasonable one).
- emptylist() (creates an empty list)
- cons (adds an element to a list; if the second argument is not a list, it should produce
an error) - hd (returns the head of a list; if the list is empty it should produce an error)
- tl (returns the tail of a list; if the list is empty it should produce an error)
- empty? (checks whether a list is empty or not; if the argument is not a list it should produce an error)
Note that in order to implement these extensions, the set of expressed values must be extended accordingly:
type exp_val =
| NumVal of int
| BoolVal of bool
| ListVal of exp_val list
Examples of evaluation of expressions involving the new constructs are:
# interp "cons(1,emptylist())";;
- : exp_val Let.Ds.result = Ok (ListVal [NumVal 1])
# interp "cons(cons(1,emptylist()),emptylist())";;
- : exp_val Let.Ds.result = Ok (ListVal [ListVal [NumVal 1]])
# interp "let x = 4 in cons(x,
cons(cons(x-1, emptylist()),
emptylist()))";;
-: exp_val Let.Ds.result = Ok (ListVal [NumVal 4; ListVal [NumVal 3]])
# interp "empty?(emptylist())";;
- : exp_val Let.Ds.result = Ok (BoolVal true)
# interp "empty?(tl(cons(cons(1,emptylist()),emptylist())))";; - : exp_val Let.Ds.result = Ok (BoolVal true)
# interp "tl(cons(cons(1,emptylist()),emptylist()))";;
- : exp_val Let.Ds.result = Ok (ListVal [])
# interp "cons(cons(1,emptylist()),emptylist())";;
- : exp_val Let.Ds.result = Ok (ListVal [ListVal [NumVal 1]])
-
Here is the stub for the interpreter:
The additional production to the concrete syntax is:
<Expression> <Expression> <Expression> <Expression> <Expression>
::= emptylist()
::= hd ( <Expression>)
::= tl ( <Expression>)
::= empty? ( <Expression>)
::= cons ( <Expression>, <Expression>)
The abstract syntax node for this extension is as follows:
type expr = ...
| Cons of expr*expr | Hd of expr
| Tl of expr
| IsEmpty of expr
| Emptylist of texpr option
let rec eval_expr : expr -> exp_val ea_result = fun e ->
match e with
| Int n -> return (NumVal n)
...
| Cons(e1, e2) -> failwith "Implement me!"
| Hd(e) -> failwith "Implement me!" | Tl(e) -> failwith "Implement me!"
| IsEmpty(e) -> failwith "Implement me!"
| Emptylist(_t) -> failwith "Implement me!"
3.2 Tuples
Extend the interpreter to be able to handle the operators
- <e1,...,en> that creates a tuple with the values of each of the ei.
- let <id1,...,idn> = e1 in e2 that evaluates e1, makes sure it is a tuple, extracts each of the n components of the tuple and binds them to the identifiers id1, ..., idn, respectively, and the evaluates e2 under the extended environment.
Examples of programs in this extension are:
- <2,3,4>
- <2,3,zero?(0)>
- < <7,9>,3> (note the use of a space)
- let x=2 in <zero?(4),11-x>
- let <x,y,z> = <3, <5 , 12>,4> in x
- let x = 34 in let <y,z>=<2,x> in z evaluates to Ok (NumVal 34).
# interp "<2,3,4>";;
- : exp_val Let.Ds.result = Ok (TupleVal [NumVal 2; NumVal 3; NumVal 4])
# interp "<2,3,zero?(0)>";;
- : exp_val Let.Ds.result = Ok (TupleVal [NumVal 2; NumVal 3; BoolVal true])
# interp "<<7,9>,3>";;
- : exp_val Let.Ds.result =
Ok (TupleVal [TupleVal [NumVal 7; NumVal 9]; NumVal 3])
# interp "let x=2 in <zero?(4),11-x>";;
- : exp_val Let.Ds.result = Ok (TupleVal [BoolVal false; NumVal 9])
# interp "let <x,y,z> = <3, <5 , 12>,4> in x";;
- : exp_val Let.Ds.result = Ok (NumVal 3)
# interp "let x = 34 in let <y,z>=<2,x> in z";; - : exp_val Let.Ds.result = Ok (NumVal 34)
# interp "let <x,y> = <1,2,3> in x";;
- : exp_val Let.Ds.result =
Error "extend_env_list: Arguments do not match parameters!"
# interp "let <x,y,z> = <1,2> in x";;
- : exp_val Let.Ds.result =
4
Error "extend_env_list: Arguments do not match parameters!"
# interp "let <x,y,z> = 1 in x";;
- : exp_val Let.Ds.result = Error "Expected a tuple!"
The additional production to the concrete syntax is:
<Expression> ::= < <Expression> ∗(,)>
<Expression> ::= let < <Identifier> ∗(,)> = <Expression> in <Expression>
The ∗(, ) above the nonterminal indicates zero or more copies separated by commas. The angle brackets construct a tuple with the values of its arguments. An expression of the form let <x1,...,xn>=e1 in e2 first evaluates e1, makes sure it is a tuple of n values, say v1 to vn, and then evaluates e2 in the extended environment where each identifier xi is bound to vi.
type expr =
...
| Tuple of expr list
| Untuple of string list * expr*expr
The abstract syntax node for this extension is as follows:
Here is the stub for the interpreter:
let rec eval_expr : expr -> exp_val ea_result = fun e ->
match e with
| Int n -> return (NumVal n)
...
| Tuple(es) -> failwith "Implement me!"
| Untuple(ids,e1,e2) -> failwith "Implement me!" and
eval_exprs : expr list -> (exp_val list) ea_result = fun es ->
match es with
| [] -> return []
| h::t -> eval_expr h >>= fun i -> eval_exprs t >>= fun l ->
return (i::l)
4 Submission instructions
Hand in the interp.ml and ds.ml files ONLY, as one zip file called hw3.zip. Please write the names of the members of your group as a comment in interp.ml Your grade will be determined as follows, for a total of 100 points:
Section Grade
3.1 3.2
60 40
5
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。