Homework 9
Boom, A Little Arithmetic Language
Due: Monday, April 21, at 11:59 PM
Introduction
This assignment gets you started on your work for the rest of the semester: an interpreter and other tools for processing a small language. This language may seem a bit more useful to you than the little language we have worked with up to now, because it will has real numbers and real operations, and it solves real problems.
Before going any farther, read the Boom language specification. It defines the language and talks about some of the Racket you can use to implement your homework.
Code and Files
For this assignment, you will implement the initial components of a Boom interpreter, including syntax procedures that define its abstract syntax, a pre-processor to eliminate syntactic abstractions, and an evaluator. Organize your code as follows.
-
Create a directory named
boom-hw09/
, which will contain all your files for the project. -
Place all syntax procedures in a file named
syntax-procs.rkt
. -
Place all other functions that operate on the language in a file
named
interpreter.rkt
. This includespreprocess
andeval-exp
, plus any language-specific helper functions of those two. -
Place any generic helper functions that you intend to use
in a file named
utilities.rkt
. This file might include functions such aslist-of?
,list-index
, andevery?
. -
Place all tests in a file named
tests.rkt
.
Make sure that each file provide
s all of its
public functions so that other files can
require
them.
For example, interpreter.rkt
will require
syntax-procs.rkt
and provide only the
preprocessor and evaluator. Any file may want to require
utilities.rkt
in order to use one or more of its
functions.
We will extend the Boom language and interpreter on future homework assignments. Please comment your source code so that you and I can easily find the various pieces.
Problems
-
Define a complete set of syntax procedures for Boom.
For each type of expression in the BNF description, define:- a type predicate,
- a constructor, and
- one or more access procedures that retrieve the relevant parts of the expression.
?
". The names your choose for your accessors may be short, but they should be descriptive.
Finally, create a general type predicate named(boom-exp? arg)
that returns true if and only ifarg
is a legal expression in the language: a number, a unary expression, or a binary expression. -
Define a function named
(preprocess sugared-exp)
.
sugared-exp
is a Boom expression from the full syntax of the language, which includes the operatorssq
and@
.
preprocess
returns an expression in the core Boom language, with the syntactic abstractions translated into equivalent expressions, and all other expressions preserved. For example:> (preprocess '(3 @ 9)) ((3 + 9) / 2) > (preprocess '(- (3 @ 9))) (- ((3 + 9) / 2)) > (preprocess '((2 * 14) + (13 @ 29))) ((2 * 14) + ((13 + 29) / 2))
-
Define a function named
(eval-exp exp)
.
exp
is a Boom expression from the full syntax of the language. Ifexp
is not a legal Boom expression,eval-exp
signals an error. For example:> (eval-exp '(4 sq 3)) boom: illegal expression -- (4 sq 3)
eval-exp
returns the value ofexp
as its result, according to the language's semantics.
Note thatexp
can contain sugar, soeval-exp
must pre-process its argument before evaluating it! You may want to makeeval-exp
an interface procedure that ensures its argument is a legal expression, preprocesses it, and calls a helper to evaluate the resulting core expression.
For example:> (eval-exp '(- 3)) -3 > (eval-exp '(sq 3)) 9 > (eval-exp '(9 + 6)) 15 > (eval-exp '((- 3) + (sq (4 * 2)))) 61 > (eval-exp '(8 & 3)) boom: illegal expression -- (8 & 3) > (eval-exp '(3 @ 9)) 6 > (eval-exp '((2 * 14) + (13 @ 29))) 49 > (eval-exp '(((130 - 2) / 4) @ (15 / (17 % (sq 4))))) 23
The language description provides more sample expressions for testing. You can also find other simple test expressions in the description of Boom's semantics. Be sure to test other expressions, including some that are more complex.
Some notes on the use of Racket to implement the evaluator:-
You may not use Racket's
eval
function in your solution. The job of your Boom evaluator is to handle all of it operations directly. -
You may find Racket's
quotient
andremainder
functions useful when implementing Boom's integer division operations. -
You may find Racket's
expt
function useful when implementing Boom's^
operation.
-
You may not use Racket's
Deliverables
By the due time and date, use the course submission system to submit the following files electronically:
syntax-procs.rkt
interpreter.rkt
tests.rkt
utilities.rkt
(optional)
Be sure that your submission follows the submission requirements. As always, use the specified names for your files. This enables the auto-grader to find and run your code.