Advertisement
Guest User

New homework 1 2 3

a guest
Mar 22nd, 2024
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 7.90 KB | None | 0 0
  1. #lang plait
  2.  
  3. (define-type Value
  4.   (numV [n : Number])
  5.   (closV [arg : Symbol]
  6.          [body : Exp]
  7.          [env : Env]))
  8.  
  9. (define-type Exp
  10.   (numE [n : Number])
  11.   (idE [s : Symbol])
  12.   (plusE [l : Exp]
  13.          [r : Exp])
  14.   (lamE [n : Symbol]
  15.         [body : Exp])
  16.   (appE [fun : Exp]
  17.         [arg : Exp])
  18.   (if0E [tst : Exp]
  19.         [thn : Exp]
  20.         [els : Exp]))
  21.  
  22.  
  23. (define-type Binding
  24.   (bind [name : Symbol]
  25.         [val : Value]))
  26.  
  27. (define-type-alias Env (Listof Binding))
  28.  
  29. (define mt-env empty)
  30.  
  31. (define extend-env cons)
  32.  
  33.  
  34. (module+ test
  35.   (print-only-errors #t))
  36.  
  37. ;; parse ----------------------------------------
  38.  
  39. (define (parse [s : S-Exp]) : Exp
  40.   (cond
  41.     [(s-exp-match? `NUMBER s) (numE (s-exp->number s))]
  42.     [(s-exp-match? `SYMBOL s) (idE (s-exp->symbol s))]
  43.     [(s-exp-match? `{+ ANY ANY} s)
  44.      (plusE (parse (second (s-exp->list s)))
  45.             (parse (third (s-exp->list s))))]
  46.     [(s-exp-match? `{let {[SYMBOL ANY]} ANY} s)
  47.      (let ([bs (s-exp->list (first
  48.                              (s-exp->list (second
  49.                                            (s-exp->list s)))))])
  50.        (appE (lamE (s-exp->symbol (first bs))
  51.                    (parse (third (s-exp->list s))))
  52.              (parse (second bs))))]
  53.     ;; added new case for letrec:
  54.     [(s-exp-match? `{letrec {[SYMBOL ANY]} ANY} s)
  55.      (let ([name (first (s-exp->list (first (s-exp->list (second (s-exp->list s))))))]
  56.            [rhs (second (s-exp->list (first (s-exp->list (second (s-exp->list s))))))]
  57.            [body (third (s-exp->list s))])
  58.        (parse `{let {[,name {,mk-rec-fun {lambda {,name} ,rhs}}]} ,body}))]
  59.    
  60.     [(s-exp-match? `{lambda {SYMBOL} ANY} s)
  61.      (lamE (s-exp->symbol (first (s-exp->list
  62.                                   (second (s-exp->list s)))))
  63.            (parse (third (s-exp->list s))))]
  64.     [(s-exp-match? `{if0 ANY ANY ANY} s)
  65.      (if0E (parse (second (s-exp->list s)))
  66.            (parse (third (s-exp->list s)))
  67.            (parse (fourth (s-exp->list s))))]
  68.     [(s-exp-match? `{ANY ANY} s)
  69.      (appE (parse (first (s-exp->list s)))
  70.            (parse (second (s-exp->list s))))]
  71.     [else (error 'parse "invalid input")]))
  72.  
  73.  
  74. ;; added definition for some kind of Y-combinator:
  75. (define mk-rec-fun
  76.     `{lambda {body-proc}
  77.        {let {[fX {lambda {fX}
  78.                    {let {[f {lambda {x}
  79.                               {{fX fX} x}}]}
  80.                      {body-proc f}}}]}
  81.         {fX fX}}})
  82.  
  83. (module+ test
  84.   (test (parse `2)
  85.         (numE 2))
  86.  
  87.   (test (parse `x) ; note: backquote instead of normal quote
  88.         (idE 'x))
  89.  
  90.   (test (parse `{+ 2 1})
  91.         (plusE (numE 2) (numE 1)))
  92.  
  93.   (test (parse `{+ {+ 3 4} 8})
  94.         (plusE (plusE (numE 3) (numE 4))
  95.                (numE 8)))
  96.  
  97. (test (parse `{let {[x {+ 1 2}]}
  98.                 y})
  99.       (appE (lamE 'x (idE 'y))
  100.             (plusE (numE 1) (numE 2))))
  101.  
  102. (test (parse `{lambda {x} 9})
  103.       (lamE 'x (numE 9)))
  104.  
  105. (test (parse `{if0 1 2 3})
  106.       (if0E (numE 1) (numE 2) (numE 3)))
  107.  
  108. (test (parse `{double 9})
  109.       (appE (idE 'double) (numE 9)))
  110.  
  111. (test/exn (parse `{{+ 1 2}})
  112.           "invalid input"))
  113.  
  114.  
  115. ;; interp ----------------------------------------
  116.  
  117. (define (interp [a : Exp] [env : Env]) : Value
  118.   (type-case Exp a
  119.     [(numE n) (numV n)]
  120.     [(idE s) (lookup s env)]
  121.     [(plusE l r) (num+ (interp l env) (interp r env))]
  122.     [(lamE n body)
  123.      (closV n body env)]
  124.     [(appE fun arg)
  125.      (type-case Value (interp fun env)
  126.        [(closV n body c-env)
  127.         (interp body
  128.                 (extend-env
  129.                  (bind n
  130.                        (interp arg env))
  131.  
  132.                  c-env))]
  133.        [else (error 'interp "not a function")])]
  134.     [(if0E tst thn els)
  135.      (interp (if (num-zero? (interp tst env))
  136.                  thn
  137.                  els)
  138.              env)]))
  139.  
  140.  
  141.  
  142. (module+ test
  143.  
  144.   (test (interp (parse `2) mt-env)
  145.         (numV 2))
  146.  
  147.   (test/exn (interp (parse `x) mt-env)
  148.             "free variable")
  149.  
  150.   (test (interp (parse `x)
  151.                 (extend-env (bind 'x (numV 9)) mt-env))
  152.         (numV 9))
  153.  
  154.   (test (interp (parse `{+ 2 1}) mt-env)
  155.         (numV 3))
  156.  
  157.   (test (interp (parse `{+ {+ 2 3} {+ 5 8}})
  158.                 mt-env)
  159.         (numV 18))
  160.  
  161.   (test (interp (parse `{lambda {x} {+ x x}})
  162.                 mt-env)
  163.         (closV 'x (plusE (idE 'x) (idE 'x)) mt-env))
  164.  
  165.   (test (interp (parse `{let {[x 5]}
  166.                           {+ x x}})
  167.                 mt-env)
  168.         (numV 10))
  169.  
  170. (test (interp (parse `{let {[x 5]}
  171.                         {let {[x {+ 1 x}]}
  172.                           {+ x x}}})
  173.               mt-env)
  174.       (numV 12))
  175.  
  176. (test (interp (parse `{let {[x 5]}
  177.                         {let {[y 6]}
  178.                           x}})
  179.               mt-env)
  180.       (numV 5))
  181.  
  182. (test (interp (parse `{{lambda {x} {+ x x}} 8})
  183.               mt-env)
  184.       (numV 16))
  185.  
  186. (test (interp (parse `{if0 0 2 3})
  187.               mt-env)
  188.       (numV 2))
  189.  
  190. (test (interp (parse `{if0 1 2 3})
  191.               mt-env)
  192.       (numV 3))
  193.  
  194. (test/exn (interp (parse `{1 2}) mt-env)
  195.           "not a function")
  196.  
  197. (test/exn (interp (parse `{+ 1 {lambda {x} x}}) mt-env)
  198.           "not a number")
  199.  
  200. (test/exn (interp (parse `{if0 {lambda {x} x} 2 3})
  201.                   mt-env)
  202.           "not a number")
  203.  
  204. (test/exn (interp (parse `{let {[bad {lambda {x} {+ x y}}]}
  205.                             {let {[y 5]}
  206.                               {bad 2}}})
  207.                   mt-env)
  208.           "free variable"))
  209.  
  210.  
  211.  
  212. ;; num+ ----------------------------------------
  213.  
  214. (define (num-op [op : (Number Number -> Number)] [l : Value] [r : Value]) : Value
  215. (cond
  216.   [(and (numV? l) (numV? r))
  217.    (numV (op (numV-n l) (numV-n r)))]
  218.   [else
  219.    (error 'interp "not a number")]))
  220.  
  221. (define (num+ [l : Value] [r : Value]) : Value
  222.   (num-op + l r))
  223.  
  224. (define (num-zero? [v : Value]) : Boolean
  225.   (type-case Value v
  226.     [(numV n) (zero? n)]
  227.     [else (error 'interp "not a number")]))
  228.  
  229.  
  230. (module+ test
  231.   (test (num+ (numV 1) (numV 2))
  232.         (numV 3))
  233.  
  234.   (test (num-zero? (numV 0))
  235.         #t)
  236.  
  237.   (test (num-zero? (numV 1))
  238.         #f))
  239.  
  240.  
  241. ;; lookup ----------------------------------------
  242.  
  243. (define (lookup [n : Symbol] [env : Env]) : Value
  244.   (type-case (Listof Binding) env
  245.     [empty (error 'lookup "free variable")]
  246.     [(cons b rst-env)
  247.      (cond
  248.        [(symbol=? n (bind-name b)) (bind-val b)]
  249.        [else (lookup n rst-env)])]))
  250.  
  251.  
  252. (module+ test
  253.   (test/exn (lookup 'x mt-env)
  254.             "free variable")
  255.  
  256.   (test (lookup 'x (extend-env (bind 'x (numV 8)) mt-env))
  257.         (numV 8))
  258.  
  259. (test (lookup 'x (extend-env
  260.                   (bind 'x (numV 9))
  261.                   (extend-env (bind 'x (numV 8)) mt-env)))
  262.       (numV 9))
  263.  
  264. (test (lookup 'y (extend-env
  265.                   (bind 'x (numV 9))
  266.                   (extend-env (bind 'y (numV 8)) mt-env)))
  267.       (numV 8)))
  268.  
  269.  
  270.  
  271.  
  272. ;; added definition for plus:
  273. (define plus `{lambda {x} {lambda {y} {+ x y}}})
  274.  
  275. ;; added definition for times:
  276. (define times `{lambda {x}
  277.                  {lambda {y}
  278.                    {letrec {[fn {lambda {z}
  279.                                   {if0 z 0 {+ x {fn {+ z -1}}}}}]}
  280.                      {fn y}}}})
  281.  
  282.  
  283.  
  284. (module+ test
  285.  
  286.   ;; added new test for letrec:
  287.   (test (interp (parse `{letrec {[f {lambda {n}
  288.                                       {if0 n
  289.                                            0
  290.                                            {+ {f {+ n -1}} -1}}}]}
  291.                           {f 10}})
  292.                 mt-env)
  293.         (numV -10))
  294.  
  295.   ;; added new test for plus:
  296.   (test (interp (parse `{let {[m 2]}
  297.                           {let {[n 3]}
  298.                             {{,plus m} n}}})
  299.                 mt-env)
  300.         (numV 5))
  301.  
  302.   ;; added new test for times:
  303.   (test (interp (parse `{let {[m 3]}
  304.                           {let {[n 5]}
  305.                             {{,times m} n}}})
  306.                 mt-env)
  307.         (numV 15)))
  308.  
  309.  
  310.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement