Skip to content

Instantly share code, notes, and snippets.

@SHoltzen
Last active January 30, 2024 15:02
Show Gist options
  • Save SHoltzen/2a1c05695b29230f70cd84fe300b585d to your computer and use it in GitHub Desktop.
Save SHoltzen/2a1c05695b29230f70cd84fe300b585d to your computer and use it in GitHub Desktop.
CS4400 Let language
#lang plait
(define-type Exp
[numE (n : Number)]
[plusE (l : Exp) (r : Exp)]
[varE (s : Symbol)]
[let1E (var : Symbol)
(assignment : Exp)
(body : Exp)])
; subst is like "search and replace"
(subst : (Symbol Number Exp -> Exp))
(define (subst id assignment body)
(type-case Exp body
[(numE n) (numE n)]
[(plusE l r) (plusE (subst id assignment l) (subst id assignment r))]
[(varE s) (if (symbol=? s id) (numE assignment) (varE s))]
[(let1E innervar innerassignment innerbody)
(let1E innervar (subst id assignment innerassignment)
; check for shadowing
; if id is being shadowed, then return inner body
; else, substitute inner body
(if (symbol=? innervar id)
innerbody
(subst id assignment innerbody))
)]))
(eval : (Exp -> Number))
(define (eval e)
(type-case Exp e
[(numE n) n]
[(plusE l r) (+ (eval l) (eval r))]
[(varE s) (error 'runtime "uninitialized")]
[(let1E id assignment body)
;Semantics of (let1E var assignment body):
;(1) evaluate assignment to value
;(2) substitute `var` with value in body
;(3) evaluate body
(eval (subst id (eval assignment) body))
]))
(test (eval (let1E 'x (numE 10)
(let1E 'x (numE 20)
(varE 'x)))) 20)
(test (eval (let1E 'x (numE 10) (plusE (varE 'x) (varE 'x)))) 20)
(test (eval (let1E 'x (numE 10)
(plusE (varE 'x)
(let1E 'x (numE 20) (varE 'x))))) 30)
(test (eval (plusE (let1E 'x (numE 10) (varE 'x)) (let1E 'x (numE 15) (varE 'x)))) 25)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment