Skip to content

Instantly share code, notes, and snippets.

@AiziChen
Last active November 17, 2022 08:49
Show Gist options
  • Save AiziChen/7e2b74776ca695ca5ff2de282f65035c to your computer and use it in GitHub Desktop.
Save AiziChen/7e2b74776ca695ca5ff2de282f65035c to your computer and use it in GitHub Desktop.
a very simple interpreter
#lang racket/base
(require racket/match)
(define env0 '())
(define ext-env
(lambda (x v env)
(cons `(,x . ,v) env)))
(define lookup
(lambda (x env)
(let ([p (assq x env)])
(and p (cdr p)))))
(struct Closure (f env))
(define interp
(lambda (exp env)
(match exp
[(? symbol? x)
(let ([v (lookup x env)])
(or v (error "undefined variable")))]
[(? number? x) x]
[`(lambda (,x) ,e)
(Closure exp env)]
[`(let ([,var ,e1]) ,e2)
(let ([v1 (interp e1 env)])
(interp e2 (ext-env var v1 env)))]
[`(,e1 ,e2)
(let ([v1 (interp e1 env)]
[v2 (interp e2 env)])
(match v1
[(Closure `(lambda (,x) ,e) env-save)
(interp e (ext-env x v2 env-save))]))]
[`(,op ,e1 ,e2)
(let ([v1 (interp e1 env)]
[v2 (interp e2 env)])
(case op
[(+) (+ v1 v2)]
[(-) (- v1 v2)]
[(*) (* v1 v2)]
[(/) (/ v1 v2)]))])))
(define r2
(lambda (exp)
(interp exp env0)))
;;;;;;;;;;;;;;;;;;;;
;; Test Result ;;
;;;;;;;;;;;;;;;;;;;;
#|
Welcome to DrRacket, version 8.7 [cs].
Language: racket/base, with debugging; memory limit: 128 MB.
> (r2 '(+ 1 2))
3
> (r2 '(* 2 3))
6
> (r2 '(* 2 (+ 3 4)))
14
> (r2 '(* (+ 1 2) (+ 3 4)))
21
> (r2 '((lambda (x) (* 2 x)) 3))
6
> (r2
'(let ([x 2])
(let ([f (lambda (y) (* x y))])
(f 10))))
20
> (r2
'(let ([x 2])
(let ([f (lambda (y) (* x y))])
(f 3))))
6
> (r2
'(let ([x 2])
(let ([f (lambda (y) (* x y))])
(let ([x 4])
(f 3)))))
6
> (r2 '(let ([x 1])
(+ (let ([x 2])
x)
x)))
3
|#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment