Homework 8
Creating a Syntactic Abstraction

Due: Monday, April 1, at 11:59 PM

Introduction

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:

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. 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.)

Be sure to update the header blocks in syntax-procs.rkt and homework08.rkt with your personal information!

The Little Language

You will begin with the little language we saw in Session 18, 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" 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

  1. Write syntax procedures for the new and and or expressions.

    For each, write a constructor, a type predicate, and accessors for the parts of the expression. Name the accessors and->arg1, and->arg2, or->arg1, and or->arg2.

    and and or are new keywords in the language. Add them to the list of keywords in the keyword? function, found in the variable references section of the file.

    Remember two things...
    • Add your type predicates to the general exp? type predicate, because and and or expressions are now legal expressions, too.
    • Add your syntax procedures to the provide clause at the top of the file, so that other files can use them.

  2. Modify preprocess to translate and and or expressions into equivalent if expressions, following the definitions you saw in your reading. Use the symbols 'TRUE and 'FALSE in place of boolean literals for true and false.

    Test your translations by passing programs that contain and and or expressions to the preprocessor to ensure they produce the expected output. You can also pass preprocessed and and or expressions to one of the static analysis functions in the homework08.rkt file.

    Here are a few examples expressions:
    (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)
    

  3. 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 if v is declared as a variable anywhere in exp, 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
    #t
    
    Remember two things...
    • Only a lambda expression can declare a variable in the core language.
    • A lambda expression can occur inside of other expressions, including a lambda expression.
    You must use the syntax procedures for the little language to implement your function.

Deliverables

By the due time and date, use the course submission system to submit the following files electronically:

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 autograder to find and run your code.