aboutsummaryrefslogtreecommitdiff
path: root/stlc-let.rkt
diff options
context:
space:
mode:
Diffstat (limited to 'stlc-let.rkt')
-rw-r--r--stlc-let.rkt36
1 files changed, 19 insertions, 17 deletions
diff --git a/stlc-let.rkt b/stlc-let.rkt
index 84bf588..b2de7c8 100644
--- a/stlc-let.rkt
+++ b/stlc-let.rkt
@@ -1,29 +1,31 @@
-#lang racket ; note: do NOT use racket/base
+#lang racket
(require "lib.rkt")
-;; the simply-typed lambda calculus, with let sugar
+;; The Simply-Typed Lambda Calculus, with let sugar
-(define (value? val) (or (number? val) (string? val)))
+(define (value? val) (or (number? val) (string? val) (symbol? val)))
-; note: default arguments MUST all be at the end
-; no function overloading ;_;
+; note: no function overloading ;_;
;; (interpret Expr Table[Sym, Expr]): Value
-(define (interpret expr [ctx #hash()]) (interpret- (strip expr) ctx))
+(define (interpret expr) (interpret- (strip expr) '()))
(define (interpret- expr ctx)
(match expr
- [val #:when (value? val) val]
- [val #:when (symbol? val)
- (with-handlers
- ([exn:fail? (λ (exn) val)])
- (interpret- (dict-ref ctx val) ctx))]
[`(λ ,id ,body) `(λ ,id ,body ,ctx)]
[`(λ ,id ,body ,env) `(λ ,id ,body ,env)]
- [`(,body ,arg)
- (match (interpret- body ctx)
- [`(λ ,id ,body) (interpret- body (dict-set ctx id (interpret- arg ctx)))]
- [`(λ ,id ,body ,env) (interpret- body (dict-set env id (interpret- arg ctx)))]
- [expr `(,(interpret- expr ctx) ,(interpret- arg ctx))])]
- ; desugaring and error handling
+ [`((λ ,id ,body) ,arg)
+ (interpret- body (dict-set ctx id (interpret- arg ctx)))]
+ [`((λ ,id ,body ,env) ,arg)
+ (interpret- body (dict-set env id (interpret- arg ctx)))]
+ [`(,id ,arg) #:when (dict-has-key? ctx id)
+ (interpret- `(,(interpret- (dict-ref ctx id) ctx) ,arg) ctx)]
+ [`(,body ,arg) ; todo: how to recognize an irreducible term? this is kinda cheating, i think
+ (let ([reduced (interpret- body ctx)])
+ (if (equal? body reduced)
+ `(,reduced ,(interpret- arg ctx))
+ (interpret- `(,reduced ,arg) ctx)))]
+ [id #:when (dict-has-key? ctx id)
+ (interpret- (dict-ref ctx id) ctx)]
+ [val #:when (value? val) val]
[`(let ,id ,expr ,body) (interpret- `((λ ,id ,body) ,expr) ctx)]
[expr (err (format "interpreting an unknown expression ~a" expr))]))