Now that we have parsing and unparsing down, we can get down to the business of writing an interpreter for a new language, Mini-Scheme.
We will start with a very basic version of Mini-Scheme, and gradually add language features. As we do so, we will update our parser and interpreter to implement the new language features.
As a convention, the parser and interpreter for Mini-Scheme-X will reside in "parse-X.ss" and "interp-X.ss" respectively. When you are asked to write an interpreter, you should turn in (at least) two files - "parse-X.ss" and "interp-X.ss".
Our first Mini-Scheme, Mini-Scheme-A, will be specified by the following concrete and abstract syntax:
<exp> ::= <number> lit (datum)
Admittedly, not very exciting. Our interpreter for Mini-Scheme-A will be very basic as well. It is contained in 2 files:
parse-a.ss | Datatype and parser definition | |
interp-a.ss | eval-exp definition |
The parser simply creates an exp-a-lit when it sees a number (and throws an error otherwise). It looks like this
As for the interpreter, you know that Scheme evaluates all integers as themselves. So our evaluation function will be very simple. It looks like this.(define parse (lambda (exp) (cond ((number? exp) (exp-a-lit exp)) (else (error 'parse "Invalid concrete syntax ~s" exp)))))
(define eval-exp (lambda (exp) (cases exp-a exp (exp-a-lit (datum) datum) (else (error 'eval-exp "Invalid abstract syntax: ~s" exp)))))
All we need to do to an interpret an expression, then, is pass eval-exp a parsed Mini-Scheme expression. Save parse-a.ss and interp-a.ss to your directories (use the above links) and then try the following in Dr. Scheme:
> (load "parse-a.ss") > (load "interp-a.ss") > (eval-exp (parse '2)) 2
You can tell that it quickly becomes tedious to always invoke your interpreter by specifically calling the interpreter eval-exp after calling the parser parse on the quoted expression. It would be nice if we could write a read-eval-print loop for Mini-Scheme. This is very easily accomplished with the code found in r-e-p.ss. Save r-e-p.ss to your directory and then
> (load "r-e-p.ss") > (load "parse-a.ss") > (load "interp-a.ss") > (read-eval-print) MS> 3 3 MS> 4 4 MS> howdy? parse : Invalid concrete syntax howdy? MS> 7 7 MS> exit returning to Scheme proper