5 — Simple Mutable Objects
Due Tuesday, 11 February, 6am
The purpose of this homework problem is to understand simplistic but mutable objects, as commonly found statements in a modern language, via a store-passing.
Delivery Deliver your solutions in a folder called 5 in your github repo:
xinterpreter as specified in the testing task below.
ITests/ as specified in the testing task below.
Other/, which contains the solutions to the programming tasks.
Maintenance Task Before you get to your programming task, make sure that the prelude is realized as the first and basic part of the general environment. What this means in general is that every function can be used as an infix primitive operation and every primitive operation can be used as a function.
Programming language researchers refer to this idea as uniformity. Uniformity greatly simplifies implementations. Whether programmers like uniformity is an open question.
the primitive operation form which may now take a potentially empty sequence of argument expressions to the right of the operator position:
- a JSON array of the shape [SFVExpr,Var,SFVExpr, ..., SFVExpr] where the
first SFVExpr is not a keyword
The arity of the pure arithmetic operators remains 2; a violation causes a failure. Your interpreter must still signal a "number of arguments" error.
- the declaration block, which once again permits arbitrary expressions on the right side:
Your interpreter must use store-passing style to determine the meaning of
all expressions; it must not use imperative assignments. The values of
all variables—
The interpretation of SFVDecl sequences starts with allocating locations for all variables, initialized to 0, and extending the environment with these newly allocated locations. Then the interpreter determines the value of each right-hand side expression, in the given order, and, when evaluated, stores the value at the corresponding location. Finally, the interpreter evaluates the body of the declaration block.
Step Two Once you have a store-passing interpreter and it passes the
existing test suite, you must adjust the interpretation of primitive
operations from the prelude—
@, which consumes one argument value, allocates a cell store location, sticks the given value into the store at this location this cell, and returns a cell. A cell value is distinct from both Ints and function values. Its only useful content is the newly allocated location.
!, which consumes one argument value—
a cell— and retrieves the current value in the location specified by this cell. =, which consumes two argument values—
a cell and an arbitrary value— sticks this second value into the location specified by this cell, and returns the value that used to be at this location.
Use natural numbers to represent store cells locations..
Your store-passing interpreter will use the four kinds of pre-existing error messages, but we reformulate the one for arithmetic error to "primop domain error", which is more appropriate given the new cell values and operations. You may also wish to experiment with a division operation in the prelude.
Testing Task Write the test harness and xinterpreter for your interpreter programs.
Create fifteen tests for xinterpreter. Place them in ITests/. A test consists of two files: N-in.json and N-out.json for N in [0 .. 14].
-- ["value",SAnswer] |
a value or an error string rendered as an answer |
a store--without prelude--rendered as an array |
Recall JSON: Simplicity and Complexity.