CS558 Homework #1
Due 4:00 PM, Tuesday, January 14, 2014

Homework must be submitted via D2L. All submitted files (five for this assignment) must be submitted in the appropriate D2L directory in the drop box HW1. It is your responsibility to submit the homework in the proper format.

All programs mentioned can be downloaded from the this document

Purpose of this homework.

One of the goals of this course is for students to learn how to modify programs in languages they are not familiar with. There are several things that make this possible. We also want you to learn how to install and use new languages. This homework is meant to help you exeercise these skills. You might want to study the links on the language resource page, install both python and haskell on your machine, visit and try the languages on the machnes in the linux labs, read a few tutorials, and discuss what you have found with class mates. Remember, what you turn in must be your own work, that you write up after your discussions.

Part A. Getting Started

(try this now!).

Consider the programs Hw1A.py and Hw1A.hs. Each defines a function that takes a string parameter "w" as input, and writes the string: "Hello w!" to standard output.

Each program can be run within the language's interactive read-eval-print loop, by calling "hi" with a string argument, or by executing the program from the command line, where the first command line argument is used as the input to "hi".

You may use any of these methods when you run and test your code.

Your task is to alter each of these programs so that it reverses the characters in w before doing its output.

For example, if the input string is Andrew, the output of the altered program should be Hello werdnA!.

Programs should have a function "hi" with single string parameter "w" just as before. Your extended programs should be called sol1A.py and sol1A.hs Respectively. (5 points each).

Hint: Before you try to take the string apart by hand, look at the functions available on strings and lists in the standard libraries of the two languages. Submit (just) the files sol1A.py and sol1A.hs.

Part B. The Expression Interpreter.

Consider a very simple language of expressions, which we'll call E1 Its abstract syntax is given by the following tree grammar:

Prog : Program -> Exp
Add : Exp -> Exp Exp
Sub : Exp -> Exp Exp
Mul : Exp -> Exp Exp
Div : Exp -> Exp Exp
Int : Exp -> (int)

To actually read and write programs in the language, we'll use a LISP-style concrete syntax that maps directly to the abstract syntax, specified by the following grammar:

exp := int
     | '(' '+' exp exp ')'
     | '(' '-' exp exp ')'
     | '(' '*' exp exp ')'
     | '(' '/' exp exp ')'

int := digit
     | digit int
This problem asks you to modify interpreters for E1, written in Python and Haskell, living in files called Hw1B.py and Hw1B.hs. respectively. These interpreters read a file containing an E1 program in the LISP-style concrete syntax described above and evaluate the expression, producing an integer result.

The interpreters are primarily designed to be executed from the shell command line, passing the filename to be interpreted as an command-line argument, e.g., python3 Hw1B.py foo.e1 or runhaskell Hw1B.hs foo.e1.

It is also possible to execute the interpreters from within the read-eval-print loop, as discussed in Part A of this assignment by starting the interpretor and then typing Interp.interp "foo.e1";; in Python, or interp "foo.e1" in Haskell.

For example, if foo.e1 contains the following text:

(/ { Integer division rounds results down }
(+ 7
(- 0 2)) { Here's how to make a negative number }

then both interpreters should return the answer 1.

Note that programs can be broken arbitrarily across multiple lines. Any text within curly braces will be treated as a comment.

Here are your tasks:

  1. Add a new feature to each interpreter: support for a remainder ( % ) operator. The relationship of this operator to the existing operators is defined by the following equation: (a/b)*b+(a%b) = a, for all and b, regardless of sign.

    Notice that the Haskell version and the Python version behave differently on division operations involving negative numbers but that should not stop you from implementing % as specified here.

    Note: The Haskell version does not evaluate the program AST directly; instead, it compiles it into a sequence of stack machine instructions, and then executes the resulting stack machine program.

    In adding support for the remainder operator, you must not change the instruction set or implementation of the stack machine Implementation.

    Hint: Look at the code for an existing binary operator, e.g., +. In the Python version, you need to add a new class for % expressions. In the Haskell version, you will need to add a new constructor to the Exp datatype and corresponding clauses to functions that match over that type using case statements.

    In each, you'll need to make two small additions to the lexer/parser.

    Put your Python solution into a file sol1B.py and put your Haskell solution into a file sol1B.hs.

    Submit these two files. (30 points each).

  2. The Haskell version and the Python version of the compilers also behave differently on some programs involving large integers. Find out what the differences are, and why they occur. Write a single simple program in the E1 language, that behaves differently under the two interpreters. That is if you run the Python interpreter on the file, and you run the Haskell interpreter on the same file, you get different answers. Submit this program in a file sol1B.e1, which you submit with the other files using D2L. This file must contain a comment explaining the differences and the reasons for them. (Note: There are several differences. Your sample program may illustrate only one of them, but your comment should describe all that you find. (10 points for the program, 20 points for the comment).