Homework must be submitted via D2L. All submitted files (four for this assignment sol2A.e2, sol2B.py, sol2B.hs, sol2C.txt) 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 2 Tom Smith tom_smith@gmail.com
All programs mentioned can be downloaded from the this document
prog := exp exp := var | int | '(' ':=' var exp ')' | '(' 'while' exp exp ')' | '(' 'if' exp exp exp ')' | '(' 'write' exp ')' | '(' 'block' { exp } ')' | '(' '+' exp exp ')' | '(' '-' exp exp ')' | '(' '*' exp exp ')' | '(' '/' exp exp ')' | '(' '<=' exp exp ')' var := string of lettersAs before, comments may be included by enclosing them between comment braces '{-' and '-}' and they may be nested.
An informal semantics for E2 is as follows. The evaluation of each expression (and hence of a program) yields a single integer result.
An example program primes.e2 written in this language is available for you to view.
Two E2 interpreters have been provided, one in Python ( Hw2.py ) and the other in Haskell ( Hw2.hs ).
Each interpreter reads a file containing an E2 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.
The Python program interprets the abstract syntax directly. The Haskell program first translates it into stack machine code (for an extended and somewhat different version of the stack machine from Homework 1), prints out the stack code (for debugging purposes), and then executes it. For example, here is a trace from inside GHCI on the file count.e2
*Main> interp "count.e2" Expression: (block (:= n 1) (while (<= n 2) (block (write n) (:= n (+ n 1)) )) ) Compiles to: [Const 1, Dup, Store n, Pop, Label 0:, Const 2, Load n, Swap, Leq, Branchz 1, Load n, Dup, Print, Pop, Const 1, Load n, Plus, Dup, Store n, Pop, Branch 0, Label 1:, Const 0] Executing: 1 2 Evaluates to: 0
For more debugging help, you can trace the behavior of the stack machine by typing "trace" at the GHCI prompt, This commnad flips the state of the tracing flag. Here is a transcript of turing the trace on and reexecuting count.e2. One should do this before executing the Haskell function interp to start the read-eval-print function.
One can also control tracing programatically by using the IO action writeIORef trace_on True inside a Haskell function with type IO.
The for expression has the following syntax: exp := '(' 'for' var exp exp exp ')'
Evaluating (for x e1 e2 e3 ) first evaluates e1 to a value v1 and stores v1 into x . It then repeats the following steps: evaluate e2 to a value v2 ; fetch x ; if x > v2 then terminate evaluation of the for, yielding the value 0; otherwise, evaluate e3 and discard the yielded result, fetch x , add one to it, store back into x , and repeat.
When modifying the code, study carefully how the "while" statement is implemented. Look for how "while" statements are parsed, how they are evaluated (in python) and how they are translated to stack machine code (in Haskell). This will be a good guide for modifying the code to add "for" statements. Searching for "while" and 'While' in the source will help identify places in the code where things neeed to be added or modified.
For example,
(for i 1 10 (write i))
prints the numbers from 1 to 10, and yields the value 0. Make sure you get the order of evaluation right. For example, the bizarre program
(for i i (block (:= i (+ i 2)) 10) (block (write i) (:= i (+ i 3))))
prints out the numbers 2,8 and yields the value 0. Hints: Model your code on the existing code for while. The Haskell version may require some tricky stack manipulation to get the order of evaluation right; once again, you may find the SWAP instruction useful.
Put your revised Python interpreter in sol2B.py (30 points), and your revised Haskell interpreter in sol2B.hs (30 points), and submit both these files.
gif E1 -> S1 | E2 -> S2 ... | En -> Sn end
where the Ei are boolean expressions. This statement is executed by non-deterministically choosing any one i such that Ei evaluates to true, and executing the corresponding Si . Among other things, this statement gives an elegant, symmetric way to express functions like max , e.g.
gif x1 >= x2 -> max := x1 | x2 >= x1 -> max := x2 end
Note that if x1 = x2 then either branch might be chosen non-deterministically. In this example, the resulting value of max will be the same either way, but we can also write guarded gif's that are intentionally non-determinstic, e.g., to simulate a coin toss:
gif true -> coin := 0 | true -> coin := 1 end { coin }This question has two parts. Type your answers to both parts into a file sol2C.txt, and submit this file.
{ z < 0 } while (x > -5) do gif x <= 0 -> y := -x | x >= 0 -> y := x end; z := z - y end { z < 0 }(15 points)
Remember to label each node in the tree with the appropriate axiom or rule of inference. You'll need one (WHILE), one (COMP), one (GIF), three (ASSIGN), and four (CONSEQ) steps. Don't worry about formatting your answer beautifully, so long as it is clear.