Skip to content

Instantly share code, notes, and snippets.

@jbclements
Created April 27, 2020 22:04
Show Gist options
  • Save jbclements/af00503373de838d706f3a8fea027478 to your computer and use it in GitHub Desktop.
Save jbclements/af00503373de838d706f3a8fea027478 to your computer and use it in GitHub Desktop.
#lang typed/racket
(require typed/rackunit)
;; an S-expression is one of:
;; a number
;; a string
;; a boolean
;; a symbol, or
;; (list S-expression ...)
;; concrete syntax of TL
"a string"
"abc"
"def"
'{"abc" + "def"} ; => "abcdef"
'{{"a" + "b"} + "cdef"}
'{"**" around "abc"} ; => "**abc**"
;; abstract syntax of TL
(define-type ExprC (U StrAppdC StrC IdC AppC FunC))
(struct StrC ([s : String]) #:transparent)
(struct IdC ([var : Symbol]) #:transparent)
(struct StrAppdC ([l : ExprC] [r : ExprC]) #:transparent)
(struct AppC ([fun : ExprC] [arg : ExprC]) #:transparent)
(struct FunC ([param : Symbol] [body : ExprC]))
#|
f(34)
(function (x) { return x + 4})(34)
|#
(define-type Value (U StrV FunV))
(struct StrV ([s : String]) #:transparent)
(struct FunV ([param : Symbol] [body : ExprC]))
;; parse concrete stx of
(define (parse [s : Sexp]) : ExprC
(match s
[(? string? str) (StrC str)]
[(list a '+ c) (StrAppdC (parse a) (parse c))]))
(check-equal? (parse '"abc")
(StrC "abc"))
(check-equal? (parse '{{"a" + "b"} + "cdef"})
(StrAppdC (StrAppdC (StrC "a")
(StrC "b"))
(StrC "cdef")))
;; interp a function in TL
(define (interp [e : ExprC] [env : Env]) : Value
(match e
[(StrC s) (StrV s)]
[(StrAppdC l r) (StrV (string-append (StrV-s (interp l env))
(StrV-s (interp r env))))]
[(IdC var) (env-lookup env var)]
[(AppC f a)
(define fn (interp f env))
(match fn
[(FunV param body)
(define argval (interp a env))
(define new-env (extend-env empty-env param argval))
(interp body new-env)])]
))
;; dynamic scope: scopes are periods of time
;; lexical scope: scopes are parts of the program
'{{func {f z}
{+ z x}}
{func {g x}
{f 9}}
{func {main}
{g 1234}}}
#|
def g(x):
return x + y
g(7)
|#
(check-equal? (interp (StrC "abc")) "abc")
(check-equal? (interp (StrAppdC (StrAppdC (StrC "a")
(StrC "b"))
(StrC "cdef")))
"abcdef")
;; map a program to an output
(define (top-interp [s : Sexp]) : String
(interp (desugar (parse s))))
(top-interp '{"a" + {{"d" + "arj"} + "mwnop"}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment