Advertisement
Guest User

Untitled

a guest
May 19th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 4.46 KB | None | 0 0
  1. #lang racket
  2.  
  3. ;; arithmetic expressions
  4.  
  5. (define (const? t)
  6.   (number? t))
  7.  
  8. (define (op? t)
  9.   (and (list? t)
  10.        (member (car t) '(+ - * /))))
  11.  
  12. (define (op-op e)
  13.   (car e))
  14.  
  15. (define (op-args e)
  16.   (cdr e))
  17.  
  18. (define (op-cons op args)
  19.   (cons op args))
  20.  
  21. (define (op->proc op)
  22.   (cond [(eq? op '+) +]
  23.         [(eq? op '*) *]
  24.         [(eq? op '-) -]
  25.         [(eq? op '/) /]))
  26.  
  27. ;; lets
  28.  
  29. (define (let-def? t)
  30.   (and (list? t)
  31.        (= (length t) 2)
  32.        (symbol? (car t))))
  33.  
  34. (define (let-def-var e)
  35.   (car e))
  36.  
  37. (define (let-def-expr e)
  38.   (cadr e))
  39.  
  40. (define (let-def-cons x e)
  41.   (list x e))
  42.  
  43. (define (let? t)
  44.   (and (list? t)
  45.        (= (length t) 3)
  46.        (eq? (car t) 'let)
  47.        (let-def? (cadr t))))
  48.  
  49. (define (let-def e)
  50.   (cadr e))
  51.  
  52. (define (let-expr e)
  53.   (caddr e))
  54.  
  55. (define (let-cons def e)
  56.   (list 'let def e))
  57.  
  58. ;; variables
  59.  
  60. (define (var? t)
  61.   (symbol? t))
  62.  
  63. (define (var-var e)
  64.   e)
  65.  
  66. (define (var-cons x)
  67.   x)
  68.  
  69. ;; pairs
  70.  
  71. (define (cons? t)
  72.   (and (list? t)
  73.        (= (length t) 3)
  74.        (eq? (car t) 'cons)))
  75.  
  76. (define (cons-fst e)
  77.   (second e))
  78.  
  79. (define (cons-snd e)
  80.   (third e))
  81.  
  82. (define (cons-cons e1 e2)
  83.   (list 'cons e1 e2))
  84.  
  85. (define (car? t)
  86.   (and (list? t)
  87.        (= (length t) 2)
  88.        (eq? (car t) 'car)))
  89.  
  90. (define (car-expr e)
  91.   (second e))
  92.  
  93. (define (cdr? t)
  94.   (and (list? t)
  95.        (= (length t) 2)
  96.        (eq? (car t) 'cdr)))
  97.  
  98. (define (cdr-expr e)
  99.   (second e))
  100.  
  101. ;; lambdas
  102.  
  103. (define (lambda? t)
  104.   (and (list? t)
  105.        (= (length t) 3)
  106.        (eq? (car t) 'lambda)
  107.        (list? (cadr t))
  108.        (andmap symbol? (cadr t))))
  109.  
  110. (define (lambda-vars e)
  111.   (cadr e))
  112.  
  113. (define (lambda-expr e)
  114.   (caddr e))
  115.  
  116. ;; applications
  117.  
  118. (define (app? t)
  119.   (and (list? t)
  120.        (> (length t) 0)))
  121.  
  122. (define (app-proc e)
  123.   (car e))
  124.  
  125. (define (app-args e)
  126.   (cdr e))
  127.  
  128. ;; expressions
  129.  
  130. (define (expr? t)
  131.   (or (const? t)
  132.       (and (op? t)
  133.            (andmap expr? (op-args t)))
  134.       (and (let? t)
  135.            (expr? (let-expr t))
  136.            (expr? (let-def-expr (let-def t))))
  137.       (var? t)
  138.       (and (cons? t)
  139.            (expr? (cons-fst t))
  140.            (expr? (cons-snd t)))
  141.       (and (car? t)
  142.            (expr? (car-expr t)))
  143.       (and (cdr? t)
  144.            (expr? (cdr-expr t)))
  145.       (and (lambda? t)
  146.            (expr? (lambda-expr t)))
  147.       (and (app? t)
  148.            (expr? (app-proc t))
  149.            (andmap expr? (app-args t)))))
  150.  
  151. ;; environments
  152.  
  153. (define empty-env
  154.   null)
  155.  
  156. (define (add-to-env x v env)
  157.   (cons (list x v) env))
  158.  
  159. (define (find-in-env x env)
  160.   (cond [(null? env) (error "undefined variable" x)]
  161.         [(eq? x (caar env)) (cadar env)]
  162.         [else (find-in-env x (cdr env))]))
  163.  
  164. ;; closures
  165.  
  166. (define (closure-cons xs expr env)
  167.   (list 'closure xs expr env))
  168.  
  169. (define (closure? c)
  170.   (and (list? c)
  171.        (= (length c) 4)
  172.        (eq? (car c) 'closure)))
  173.  
  174. (define (closure-vars c)
  175.   (cadr c))
  176.  
  177. (define (closure-expr c)
  178.   (caddr c))
  179.  
  180. (define (closure-env c)
  181.   (cadddr c))
  182.  
  183. ;; evaluator
  184.  
  185. (define (eval-env e env)
  186.   (cond [(const? e) e]
  187.         [(op? e)
  188.          (apply (op->proc (op-op e))
  189.                 (map (lambda (a) (eval-env a env))
  190.                      (op-args e)))]
  191.         [(let? e)
  192.          (eval-env (let-expr e)
  193.                    (env-for-let (let-def e) env))]
  194.         [(var? e) (find-in-env (var-var e) env)]
  195.         [(cons? e)
  196.          (cons (eval-env (cons-fst e) env)
  197.                (eval-env (cons-snd e) env))]
  198.         [(car? e)
  199.          (car (eval-env (car-expr e) env))]
  200.         [(cdr? e)
  201.          (cdr (eval-env (cdr-expr e) env))]
  202.         [(lambda? e)
  203.          (closure-cons (lambda-vars e) (lambda-expr e) env)]
  204.         [(app? e)
  205.          (apply-closure
  206.            (eval-env (app-proc e) env)
  207.            (map (lambda (a) (eval-env a env))
  208.                 (app-args e)))]))
  209.  
  210. (define (apply-closure c args)
  211.   (eval-env (closure-expr c)
  212.             (env-for-closure
  213.               (closure-vars c)
  214.               args
  215.               (closure-env c))))
  216.  
  217. (define (env-for-closure xs vs env)
  218.   (cond [(and (null? xs) (null? vs)) env]
  219.         [(and (not (null? xs)) (not (null? vs)))
  220.          (add-to-env
  221.            (car xs)
  222.            (car vs)
  223.            (env-for-closure (cdr xs) (cdr vs) env))]
  224.         [else (error "arity mismatch")]))
  225.  
  226. (define (env-for-let def env)
  227.   (add-to-env
  228.     (let-def-var def)
  229.     (eval-env (let-def-expr def) env)
  230.     env))
  231.  
  232. (define (eval e)
  233.   (eval-env e empty-env))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement