ParselTongue Core Interpreter Assignment
In this assignment, you'll be implementing a core interpreter for ParselTongue. If you've completed the desugar assignment, you can compose your desugarer for ParselTongue with the core interpreter you write to create a full implementation. If your desugarer doesn't work fully, you can use our desugarer to generate your full implementation. In either case, your core interpreter should work with our desugarer.
This assignment uses almost exactly the same test suite as the desugaring assignment, except for one notable exception below.
The materials for this assignment are similar to the desugar assignment:
- A test and support code bundle interp-bundle.zip
- An assignment binary for your platform
Language and Value Definitions
The file typed-lang2.rkt has been augmented with a few extra definitions:
ValueC
holds the specification of runtime values for the core interpreter. Values are:NumV
s, which are the runtime representation of numbersStrV
s, which are the runtime representation of stringsTrueV
andFalseV
, which are the runtime representation of booleansObjectV
, which is the runtime representation of objects (note that fields are held in an ordered list).ClosureV
, which is the runtime representation of closures. This refers to a structure for representing environments,Env
, which is similar to the structures we've talked about in class.Env
s map identifiers (symbols) toLocation
s, which are just an alias for numbers.
interp-error
takes a string and raises it as an exception that our test harness recognizespretty-value
takes aValueC
and produces its string representation, as per the specifications "Pretty" metafunctionLocation
is a type alias fornumber
, which will be used in the store
Implementing the Interpreter
Your task is to implement all of the core
features of ParselTongue,
starting with the template we provide,
typed-interp-template.rkt. It draw
follows closely the store-passing style we studied in class and the
notes. It defines a Store
as:
(define-type Cell
[cell (location : Location) (value : ValueC)])
(define-type-alias Store (listof Cell))
And the signature for the interpreter itself has two parts:
(define-type Result
[v*s (value : ValueC) (store : Store)])
(define (interp-full [exprC : ExprC] [env : Env] [store : Store]) : Result
(type-case ExprC exprC
;; your code here...
))
(define (interp [exprC : ExprC]) : ValueC
(type-case Result (interp-full exprC empty empty)
[v*s (value store) value]))
That is, your interpreter, defined in interp
must evaluated ExprC
s
into ValueC
s. However, we expect that the function interp-full
will
do the heavy lifting, which also takes an environment and a store, and
produces a value and an updated store. This is the signature that's
needed to make store passing style work, and will be necessary for
implementing ParselTongues stateful Set!C
operation.
A ParselTongue Change
We've made one change to the specification of ParselTongue for this assignment, which affects the implementation you should create. In our ParselTongue implementation, the following program:
x = 5
Generated the error
hash-ref: no value for key
key: 'x
This was an underlying Racket error leaking into the implementation of ParselTongue. We've fixed it in the interpreter we've provided (so you can update any tests accordingly), to instead give the error:
Unbound identifier: x
The test brown/assign/unbound.psl
(at least) tests for this behavior,
so you can check if you have implemented it correctly.
Assignment Binary
The assignment binary has a few options:
--stdout <filename>
--stderr <filename>
--stdin <filename>
Change the appropriate port to use <filename>
--brief
Briefer test output
--set-desugar <filename>
A file that holds the definition of desguar. If omitted, uses our
implementation of desugar. You shouldn't need this for this
assignment, but it's included so you can test with your desugarer.
--set-interp <filename>
A file that holds the definition of your intepreter. If omitted,
uses our implementation (for reference and convenience).
--test <dirname>
Compose the interpreter and run it against the tests in <dirname>
--interp
Run standard input as a ParselTongue program, using the provided desugar
and interp. If you don't set either, this runs the standard interpreter.
--report <filename>
Generates a grade report using an evaluator built from our
desugarer and the definition of interp at <filename>.
Handin
Submit your grade report and a single Racket file that defines interp at the handin link.