44 lines
No EOL
1.2 KiB
Text
44 lines
No EOL
1.2 KiB
Text
#lang racket
|
|
(define segments '(exps (def a 12)
|
|
(def b 24)
|
|
(l (b x) (+ a b x))
|
|
(def c 24)
|
|
(+ b a 13)))
|
|
|
|
(define (prime? op) (memq op '(%+ %- %* %/)))
|
|
|
|
(define (find_fv x)
|
|
(match x
|
|
[`(def ,x ,y) (set-subtract (find_fv y) `(,x))]
|
|
[`(l ,args ,y) (set-subtract (find_fv y) args)]
|
|
[(? integer? _) '()]
|
|
[(? symbol? _) `(,x)]
|
|
[(list (? prime? op) args ...) (remove-duplicates (flatten (map find_fv args))) ]
|
|
[(list args ...) (remove-duplicates (flatten (map find_fv args))) ]
|
|
))
|
|
|
|
(find_fv `(+ a b b c))
|
|
(find_fv `(def x y))
|
|
(find_fv `(l (x y) (%+ x y z)))
|
|
(find_fv `(l (x y) (+ x y z)))
|
|
|
|
|
|
(define (replace-fv env fv_list body)
|
|
(match body
|
|
['() body]
|
|
[(? list? _) (cons (replace-fv env fv_list (car body)) (replace-fv env fv_list (cdr body)))]
|
|
[(? (lambda (x) (memq x fv_list))) `(arr-ref ,env ,(index-of fv_list body))]
|
|
[_ body]
|
|
))
|
|
|
|
(define (clos-conv clos)
|
|
(match clos
|
|
[`(l ,args ,body) (let ((env (gensym 'env)) (fv_list (find_fv clos))) `((FUN ,(append args `(,env)) ,(replace-fv env fv_list body)) (DEF ,env (ARR ,fv_list))))]
|
|
[_ clos]
|
|
|
|
)
|
|
)
|
|
|
|
(clos-conv '(l (x y) (+ y z)))
|
|
(clos-conv '(def foo (l (y) (%+ y z))))
|
|
(clos-conv '((l (y x) (%+ x y z)) 3 5)) |