Homework must be submitted via D2L. All submitted files (5 for this assignment sol3A.e3, sol3B.hs, sol3C.hs, sol3C.e3, sol3D.pdf ) must be submitted in the appropriate D2L directory in the drop box HW2. It is your responsibility to submit the homework in the proper format with the proper names. For example.
-- Homework 3 Tom Smith tom_smith@gmail.com
All programs mentioned can be downloaded from the this document
All the questions concern a simple language with imperative expressions, functions, global variables, and pairs, which we'll call E3. Its "concretized" abstract syntax is given by the following grammar:
prog := '(' { def } ')' exp def := globaldef | fundef globaldef := '(' 'global' var exp ')' fundef := '(' 'fun' fname '(' { var } ')' exp ')' exp := var | int | '(' ':=' var exp ')' | '(' 'while' exp exp ')' | '(' 'if' exp exp exp ')' | '(' 'write' exp ')' | '(' 'block' { exp } ')' | '(' '@' fname { exp } ')' | '(' '+' exp exp ')' | '(' '-' exp exp ')' | '(' '*' exp exp ')' | '(' '/' exp exp ')' | '(' '<=' exp exp ')' | '(' 'pair' exp exp ')' | '(' 'fst' exp ')' | '(' 'snd' exp ')' | '(' 'ispair' exp ')' fname := letter { letter | digit } var := letter { letter | digit }
As before, comments may be included by enclosing them between comment braces '{-' and '-}' characters, and they may be nested.
The informal semantics of E3 programs is as follows. Values include integers and pairs, each of which has a left and a right component value. A program (d1 ... dn) e is evaluated by elaborating each definition d1 , . . . dn in that order and then evaluating the top-level expression e , whose value is the program result. A global definition (global x e ) is elaborated by evaluating its initializing expression e to a value v and extending the variable environment with a binding from x to v . A function definition is elaborated by recording the function name in an environment of available functions.
Functions and variables live in separate name spaces, so their names may overlap. The language uses a combination of static and dynamic scope rules. Function names are handled dynamically; the most recently elaborated definition with a matching name is used. Global variable names and the formal parameters of functions are statically scoped. A global variable's scope reaches from its definition to the end of the file in which it appears. The scope of a formal parameter is statically limited to the body of the function. If a second global variable has the same name as a previous global, the second hides the first. In a similar manner, if a formal parameter has the same name as a global, the parameter hides the global. It is a checked runtime error to use an undefined function or variable name.
The semantics of E3 expressions are similar to those of E2, with the following extensions:
As usual, it reads a file containing an E3 program in the syntax described above, echoes the program (to confirm correct parsing), evaluates the program (possibly producing output from write expressions), and displays the evaluation result, and then enters a READ-EVAL-PRINT loop. Users may type in expressions and see what they evaluate to. To exit the loop type ":q", one may also flip the tracing mode by typing "trace".
Write the following list-manipulation functions in E3. Put both your function definitions and a test expression that exercises them in a single file sol3A.e3 and submit that file. Some useful list manipulation examples are in lists.e3 . You may find it easier (or just more fun!) to write your solutions in recursive functional style (like the append example) rather than in imperative style (like gen and length).
(@zip (@list3 1 2 3) (@list3 4 5 6))
yields
((1.4).((2.5).((3.6).0))).
Also,
(@length (@zip l1 l2)) = (@min (@list2 (@length l1) (@length l2)))
Hint: The recursive functional style really works better here. (25 points)
Modify the E3 interpreter to support local variables, by adding a new expression form:
exp := ... | '(' 'local' '(' { var exp } ')' exp ')'where the parenthesized list specifies a set of local variable names and associated initializing expressions.
The informal semantics of (local ( x1 e1 ... xn en ) e) is as follows: evaluate e1 ,. . . , en in that order, bind the resulting values to newly created local variables x1 , . . . , xn respectively, then evaluate e in the resulting environment, and yield the resulting value. (Do not worry about what happens if two of the variables have the same name.)
The scope of the local variables is just the expression e . If a local variable has the same name as a parameter or global, it hides the parameter or global.
For example, the program
( (global a 10) ) (local (a 1 b a) (block (local (a 100) (block (:= b (+ a b)) (:= a 0))) (+ a b)))
should evaluate to 111 .
Most of the necessary parsing support is already present in hw3.hs . All you have to do is
Put your solution in a file sol3B.hs. Hint: You don't need to introduce an additional environment component for local variables; just use the existing vars environment which currently holds parameters. You might want to study the interpE case for (At f args) (near line 213). The function application case has some similar components to the local case. Remember that local expressions can be nested. (25 points)
exp := ... | '(' 'setfst' exp exp ')' | '(' 'setsnd' exp exp ')'
Most of the necessary parsing support is already present in hw3.hs . All you have to do is
The informal semantics of these expressions is as follows. To evaluate (setfst e1 e2) , first evaluate e1 to a value v1 , which must be a pair, then evaluate e2 to a value v2 , then update the left component of v1 with v2 , and yield the (updated) pair v1 as result. setsnd is similar, except that the right component of v1 is updated. For either expression, it is a checked runtime error if v1 is not a pair.
Note that the value printing code can now go into an infinite loop for some programs that use setfst and setsnd; don't worry about this. Put your solution in a file sol3C.hs (25 points).
This problem can be written using paper and pencil, scanned and then submitted. You are are also allowed to use any other tools that will let you create a *.pdf document for submission. Consider the operational semantics rules presented in lecture.
<(local x 1 (block (alias y x (+ (:= x 3) (:= y 5))) x)),Ø,Ø> ¥ <5,Ø>
Use symbolic names (e.g., l1 ; l2 ; ... ) for locations. When writing concrete environments and stores, use set notation, e.g. Suppose E = { x -> lx ; y -> ly }. We may treat the environment E as a function. If we apply it to name, we get the location of that name. For example E ( x ) = lx and E( y ) = ly . Write Ø for the empty environment or store. (Hint: use a pencil and a broad sheet of paper. Your completed tree should have ten nodes.). Submit your answer as file sol3D.pdf (15 points) to D2L.