;; ------------------------------------------------------------------------ ;; | FILE : let-to-app02-little.rkt | ;; | AUTHOR : Eugene Wallingford | ;; | CREATION DATE : 2016/03/03 | ;; | DESCRIPTION : demonstrates let as a syntaction abstraction | ;; | and how the abstraction simplifies processing | ;; ------------------------------------------------------------------------ ;; | MODIFIED : 2017/02/28 Eugene Wallingford | ;; | DESCRIPTION : Modified to use occurs-free? and occurs-bound? | ;; | as examples to test our syntactic abstraction. | ;; ------------------------------------------------------------------------ ;; | MODIFIED : 2020/03/05 Eugene Wallingford | ;; | DESCRIPTION : Changed let->app and preprocess to use the | ;; | constructors little language expressions. | ;; ------------------------------------------------------------------------ ;; | MODIFIED : 2022/03/24 Eugene Wallingford | ;; | DESCRIPTION : Updated some of the comments and one of the | ;; | examples at the bottom of the file. | ;; ------------------------------------------------------------------------ ;; | MODIFIED : 2023/03/09 Eugene Wallingford | ;; | DESCRIPTION : Reorganized preprocess to show the natural stages | ;; | in how we think about the preprocessor. | ;; ------------------------------------------------------------------------ #lang racket (require "syntax-procs.rkt") (require "occurs-procs.rkt") ;; -------------------------------------------------------------------------- ;; 1. Add let to our little language. ;; -------------------------------------------------------------------------- ;; This code works with the following grammar: ;; ;; ::= ;; | ( lambda ( ) ) ;; | ( ) ;; | ( let ( ) ) <--- NEW FEATURE ;; -------------------------------------------------------------------------- ;; 2. Create syntax procedures for let expressions ;; -------------------------------------------------------------------------- ;; see "syntax-procs.rkt" ;; -------------------------------------------------------------------------- ;; 3. Translate a let expression into a lambda application ;; -------------------------------------------------------------------------- (define let->app ; for a "one level" let expression (lambda (let-exp) (let ((var (let->var let-exp)) (val (let->val let-exp)) (body (let->body let-exp))) (make-app (make-lambda var body) val)))) (define preprocess ; to support nested expressions (lambda (exp) (cond ; -------------------------------------------- abstraction ( (let? exp) (let ((var (let->var exp)) (val (let->val exp)) (body (let->body exp))) (make-app (make-lambda var (preprocess body)) (preprocess val)) ) ) ; ------------------------------------------ core features ( (varref? exp) (make-varref exp) ) ( (lambda? exp) (make-lambda (lambda->param exp) (preprocess (lambda->body exp))) ) ( (app? exp) (make-app (preprocess (app->proc exp)) (preprocess (app->arg exp))) ) ; -------------------------------------------------- oops! ( else (error 'preprocess "invalid expression ~a" exp) )))) ;; -------------------------------------------------------------------------- ;; 4. occurs-bound? and occurs-free? don't know about let. ;; Will they still work? ;; -------------------------------------------------------------------------- (define simple-let '(let (a b) (c a))) (define nested-let '(let (a b) (let (c (lambda (d) a)) (c e)))) ; (preprocess simple-let) ; (occurs-free? 'c (preprocess nested-let)) ;; --------------------------------------------------------------------------