csci2041/public-class-repo/Labs/Lab_11_Apr_04.md
Michael Zhang 399845160c
f
2018-01-29 17:35:31 -06:00

4 KiB

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.