155 lines
4 KiB
Markdown
155 lines
4 KiB
Markdown
# Lab 11: Denotational Semantics
|
|
|
|
*CSci 2041: Advanced Programming Principles, Spring 2017*
|
|
|
|
**Due:** Friday, April 7 at 5:00pm. You should be able to complete
|
|
this work during lab.
|
|
|
|
|
|
## Lab goals
|
|
This lab will explore the interpreter that we wrote in lecture and
|
|
extend it a bit.
|
|
|
|
## Getting started.
|
|
Copy the file ``interpreter.ml`` from either the
|
|
``SamplePrograms/Sec_01_1:25pm`` or
|
|
``SamplePrograms/Sec_10_3:35pm`` directory of
|
|
the public class repository into a
|
|
new directory named ``Lab_11``. Name the copy of this file
|
|
``interpreter.ml``.
|
|
|
|
## Review
|
|
Open the file and familiarize your self with the data types and the
|
|
functions ``eval`` and ``exec``.
|
|
|
|
Run ``exec program_2 []``. And enter ``10``. How many times does
|
|
``sum`` appear in the final state?
|
|
|
|
Create a let-binding in your file of the from
|
|
```
|
|
let num_sum = ...
|
|
```
|
|
where ``...`` is replaced by the number of times that ``sum`` appears
|
|
in the final state.
|
|
|
|
|
|
## Add and conditional statement -- if-then-else
|
|
|
|
Add a new constructor of the following form to ``stmt``:
|
|
```
|
|
| IfThenElse expr * stmt * stmt
|
|
```
|
|
Then write to clause for this new constructor in the ``match``
|
|
expression in ``exec``.
|
|
|
|
Next, add a modulus operator constructor to ``expr``:
|
|
```
|
|
| Mod of expr * expr
|
|
```
|
|
Then write the clause for this new constructor in the ``match``
|
|
expression in ``eval``.
|
|
|
|
Hint: in OCaml, ``mod`` is the infix operator for modulus. Try it out
|
|
in ``utop``.
|
|
|
|
## Another program:
|
|
Construct a new program of type ``stmt`` named ``program_3``. It
|
|
should correspond to the following comment already in
|
|
``interpreter.ml``. Note how ``program_1`` and ``program_2`` both
|
|
have similar comments for them. You need to construct a let-binding
|
|
for ``program_3`` that corresponds to the program in the comment below:
|
|
```
|
|
(* read x;
|
|
i = 0;
|
|
sum_evens = 0;
|
|
sum_odds = 0;
|
|
while (i < x) {
|
|
write i;
|
|
if i mod 2 = 0 then
|
|
sum_evens = sum_evens + i;
|
|
else
|
|
sum_odds = sum_odds + i;
|
|
i = i + 1
|
|
}
|
|
write sum_evens;
|
|
write sum_odds
|
|
*)
|
|
```
|
|
|
|
## Test your extended ``exec``
|
|
|
|
Run ``exec program_3 []`` and enter ``8`` when prompted to enter a
|
|
number.
|
|
|
|
It should print out the integers from 0 to 7 and the print 12 and then
|
|
16.
|
|
|
|
Run ``exec program_3 []`` and enter ``15`` when prompted.
|
|
|
|
Create the following let-bindings in your file:
|
|
```
|
|
let val_sum_evens =
|
|
let val_sum_odds =
|
|
let num_sum_evens =
|
|
let num_sum_odds =
|
|
```
|
|
+ give ``val_sum_evens`` the value of ``sum_evens`` in the final state
|
|
+ give ``val_sum_odds`` the value of ``sum_odds`` in the final state
|
|
+ give ``num_sum_evens`` the number of times ``sum_evens`` appears in
|
|
the final state
|
|
+ give ``num_sum_odds`` the number of times ``sum_odds`` appears in
|
|
the final state
|
|
|
|
|
|
## Create a testable version of program_3
|
|
Define ``program_3_test`` in your file to be the same as
|
|
``program_3``, but replace
|
|
```
|
|
Read "x"
|
|
```
|
|
with
|
|
```
|
|
Assign ("x", Value (Int 12))
|
|
```
|
|
|
|
|
|
The following should evaluate to ``Int 30``
|
|
```
|
|
lookup "sum_evens" (exec program_3_test [])
|
|
```
|
|
|
|
This is one of the automated tests.
|
|
|
|
## An if-then and a skip statement
|
|
Add the following constructors to ``stmt``:
|
|
```
|
|
| IfThen of expr * stmt
|
|
| Skip
|
|
```
|
|
The first is the if-then statement you should expect. The second is a
|
|
"skip" statement that does nothing. It is like ``pass`` in Python or
|
|
a "noop" in assembly language.
|
|
|
|
Complete the implementation of ``exec`` to handle these new
|
|
constructs. You might implement the ``IfThen`` construct based on
|
|
the observation that executing "if ...cond... then ...stmt..." is the same as
|
|
executing "if ...cond... then ...stmt... else skip".
|
|
|
|
Next, define ``program_4`` to correspond to to the following comment:
|
|
```
|
|
(* y = 0;
|
|
if x mod 2 = 0 then y = y + 2;
|
|
if x mod 3 = 0 then y = y + 3;
|
|
if x mod 4 = 0 then y = y + 4;
|
|
*)
|
|
```
|
|
Now try ``exec program_4 [ ("x",Int 4) ]``.
|
|
|
|
For example ``lookup "y" (exec program_4 [ ("x",Int 4) ])`` should
|
|
evaluate to ``Int 6``.
|
|
|
|
## Push your work.
|
|
Now be sure to commit and push your work. Check the feedback file
|
|
that should be generated each time you push this work.
|
|
|
|
|