Homework 8
Creating a Syntactic Abstraction
Due: Monday, April 6, at 11:59 PM
Introduction
Opening Paragraph
For this assignment, you will extend our little language with a new syntactic abstraction and write a function to do static analysis of programs in the language. It should help you understand more deeply the idea of syntactic sugar and prepare you to implement your own.
Template Source Files
Download the zipped directory
hw08.zip.
which contains two files that you will modify:
-
You will extend
syntax-procs.rktto supportandandorexpressions. -
You will modify the preprocessor in
homework08.rktin two ways:-
You will extend
preprocessto handle the new syntactic abstractionsandandor. - You will add two new static analysis functions that processes programs in the core little language.
-
You will extend
The zip file also contains:
The first two define functions that are used in the other
files. You will not modify them. The third,
homework08-tests.rkt, contains my tests for
the existing functionality. You may add tests to that file
for the code you write, if you want, but you are not
required to do so.
Organizing Code
Be sure to update the header blocks in
syntax-procs.rkt and homework08.rkt
with your personal information.
Put any helper functions you write for a problem after the main function of your solution.
If you create any generic helper functions to use in your
code, you may add them to utilities.rkt, if
you'd like.
(If you do, email me the file. The submission system will
not request it.)
You do not have to write Rackunit tests for the functions you write. However, I strongly encourage you to evaluate your code using the examples I give in the assignment and to think of other cases that test your functions.
For this assignment, you may use Racket let
expressions and any other Racket functions we have learned
in class. You may not use an internal
define — use a let
expression instead!
The Little Language
You will begin with the little language we saw in Session 19,
extended with a one-variable let expression
like the one we saw in Session 17. For this assignment, you
will add two new syntactic abstractions:
and and or.
--------------------------- CORE FEATURES
<exp> ::= <varref>
| (lambda (<var>*) <exp>)
| (<exp> <exp>*)
| (if <exp> <exp> <exp>)
--------------------------- ABSTRACTIONS
| (let (<var> <exp>) <exp>)
| (and <exp> <exp>) -- new
| (or <exp> <exp>) -- new
The core language consists of variable references,
lambda expressions, applications, and
if expressions.
The full language contains the core features plus
local variables (let expressions) and boolean
operators (and and or expressions).
let, and, and or
expressions are syntactic abstractions.
Note that any function that processes an expression in the
core language should consider only four cases:
variable references, lambda expressions,
applications, and if expressions.
Problems
-
Write syntax procedures for the new
andandorexpressions.For each, write a constructor, a type predicate, and accessors for the parts of the expression. Name the accessors:
and->arg1and->arg2or->arg1or->arg1
andandorare new keywords in the language. Add them to the list of keywords in thekeyword?function, found in the variable references section of the file.Remember two things...
-
Add your type predicates to the general
exp?type predicate, becauseandandorexpressions are now legal expressions, too. -
Add your syntax procedures to the
provideclause at the top of the file, so that other files can use them.
-
Modify
preprocessto translateandandorexpressions into equivalentifexpressions, following the definitions you saw in your reading.Use the symbols
'TRUEand'FALSEin place of boolean literals for true and false.Test your translations by passing programs that contain
andandorexpressions to the preprocessor to ensure they produce the expected output. You can also pass preprocessedandandorexpressions to one of the static analysis functions in thehomework08.rktfile.Here are a few sample expressions to test:
(or a b) (lambda (x) (and x y)) (f (or on paused)) (if (and j k) a b) (let (a (f x)) (if (and x y) a b)) ((if (and x y) f g) height weight)
-
Write a structurally recursive function named
(is-declared? v exp)that takes two arguments, a symbol and an expression in the core language.is-declared?returns true ifvis declared as a variable anywhere inexp, and false otherwise.For example:
> (is-declared? 'y 'y) #f > (is-declared? 'x '(lambda (x) x)) #t > (is-declared? 'x '(lambda (y) x)) #f > (is-declared? 'y '(f (lambda (y) x))) #t > (is-declared? 'x '( (lambda (y) y) ; x is not declared here (lambda (x) x) )) ; but x is declared here #tRemember two things...-
Only a
lambdaexpression can declare a variable in the core language. -
A
lambdaexpression can occur inside of other expressions, including alambdaexpression.
You must use the syntax procedures for the little language to implement your function.
Note: You wrote a version of this function for Quiz 2. Feel free to use your exam code, and any comments I made on it, as a starting point here.
-
Only a
-
Write a structurally recursive function named
(shadowed-vars exp)that takes one argument, an expression in the core language.(shadowed-vars exp)returns a list of all the variable declarations inexpthat are shadowed by another variable of the same name. A variable is shadowed if it is redeclared in the body of alambdaexpression.For example:
> (shadowed-vars '(lambda (x) (f x))) '() > (shadowed-vars '(lambda (f) (lambda (x) (f (lambda (f) (f x)))))) '(f)You will want to use your
is-declared?function from Problem 2 as a helper!Recall that, if two expressions return flat lists and you need to combine them into a single flat list, use the
appendfunction, rather thancons.
Deliverables
By the due time and date, use the course submission system to submit the following files electronically:
homework08.rktsyntax-procs.rkt
If you add functions to utilities.rkt or to
homework08-tests.rkt, please email those files
to me as well.
Be sure that your submission follows the submission requirements. Be sure to use the specified names for your files. This enables the auto-grader to find and run your code.