aboutsummaryrefslogtreecommitdiff
path: root/lc.rkt
blob: 06fb7ebeeb3f24c81e0b7c7465340436383849df (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#lang racket
(require "lib.rkt")

;; the untyped lambda calculus

(define (interpret expr [ctx #hash()])
  (match expr
    [val #:when (or (number? val) (string? val)) val]
    [val #:when (symbol? val)
      (with-handlers
        ([exn:fail? (λ (exn) val)]) ; note: unbound identifiers are supported
        (interpret (dict-ref ctx val) ctx))]
    [`(λ ,id ,body) `(λ ,id ,body)]
    [`(,body ,arg)
      (match (interpret body ctx)
        [`(λ ,id ,body) (interpret body (dict-set ctx id (interpret arg ctx)))]
        [expr `(,(interpret expr ctx) ,(interpret arg ctx))])]
    [expr (err (format "unknown expression ~a" expr))]))

(require rackunit)
(check-equal? (interpret '(λ x x)) '(λ x x))
(check-equal? (interpret '((λ a a) (x y))) '(x y))
(check-equal? (interpret '((λ a (x y)) (λ z z))) '(x y))
(check-equal? (interpret '((λ a (a y)) x)) '(x y))