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:
Language and Value Definitions
The file typed-lang2.rkt has been augmented with a few extra definitions:
ValueCholds the specification of runtime values for the core interpreter. Values are:
NumVs, which are the runtime representation of numbers
StrVs, which are the runtime representation of strings
FalseV, which are the runtime representation of booleans
ObjectV, 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.
Envs map identifiers (symbols) to
Locations, which are just an alias for numbers.
interp-errortakes a string and raises it as an exception that our test harness recognizes
ValueCand produces its string representation, as per the specifications "Pretty" metafunction
Locationis a type alias for
number, 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
(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
ValueCs. However, we expect that the function
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
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
brown/assign/unbound.psl (at least) tests for this behavior,
so you can check if you have implemented it correctly.
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>.
Submit your grade report and a single Racket file that defines interp at the handin link.