Advertisement
Guest User

Untitled

a guest
May 2nd, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 7.96 KB | None | 0 0
  1. (module my-module-2 racket
  2.   (provide (all-defined-out)) ; wszystkie definicje z modułu są widoczne na zewnątrz
  3.   (require compatibility/mlist)
  4.   (require racket/mpair)
  5.   (require rackunit)
  6.   (require rackunit/text-ui)
  7.  
  8.   ;; definicja wyrażeń z let-wyrażeniami i if-wyrażeniami
  9.  
  10.   (struct variable (x)         #:transparent)
  11.   (struct const    (val)       #:transparent)
  12.   (struct op       (symb l r)  #:transparent)
  13.   (struct let-expr (x e1 e2)   #:transparent)
  14.   (struct if-expr  (b t e)     #:transparent)
  15.  
  16.   (define (expr? e)
  17.     (match e
  18.       [(variable s)       (symbol? s)]
  19.       [(const n)          (or (number? n)
  20.                               (boolean? n))]
  21.       [(op s l r)         (and (member s '(+ *))
  22.                                (expr? l)
  23.                                (expr? r))]
  24.       [(let-expr x e1 e2) (and (symbol? x)
  25.                                (expr? e1)
  26.                                (expr? e2))]
  27.       [(if-expr b t e)    (andmap expr? (list b t e))]
  28.       [_                 false]))
  29.  
  30.   ;; definicja instrukcji w języku WHILE
  31.  
  32.   (struct skip      ()       #:transparent) ; skip
  33.   (struct comp      (s1 s2)  #:transparent) ; s1; s2
  34.   (struct assign    (x e)    #:transparent) ; x := e
  35.   (struct while     (b s)    #:transparent) ; while (b) s
  36.   (struct if-stm    (b t e)  #:transparent) ; if (b) t else e
  37.   (struct var-block (x e s)  #:transparent) ; var x := e in s
  38.  
  39.   (define (stm? e)
  40.     (match e
  41.       [(skip) true]
  42.       [(comp s1 s2)   (and (stm? s1) (stm? s2))]
  43.       [(assign x e)   (and (symbol? x) (expr? e))]
  44.       [(while b s)    (and (expr? b) (stm? s))]
  45.       [(if-stm b t e) (and (expr? b) (stm? t) (stm? e))]
  46.       [_ false]))
  47.  
  48.   ;; wyszukiwanie wartości dla klucza na liście asocjacyjnej
  49.   ;; dwuelementowych list
  50.  
  51.   (define (lookup x xs)
  52.     (cond
  53.       [(null? xs)
  54.        (error x "unknown identifier :(")]
  55.       [(eq? (caar xs) x) (cadar xs)]
  56.       [else (lookup x (cdr xs))]))
  57.  
  58.   (define (env-lookup x xs)
  59.     ;(writeln xs)
  60.     (cond
  61.       [(null? xs)
  62.        (error x "unknown identifier :(")]
  63.       [(eq? (mcar (mcar xs)) x) (mcdr (mcar xs))]
  64.       [else (env-lookup x (mcdr xs))]))
  65.  
  66.   ;; aktualizacja środowiska dla danej zmiennej (koniecznie już
  67.   ;; istniejącej w środowisku!)
  68.  
  69.   (define (update x v xs)
  70.     (cond
  71.       [(null? xs)
  72.        (error x "unknown identifier :::(")]
  73.       [(eq? (mcar (mcar xs)) x)
  74.        ;(writeln (mcdr (mcar xs)))
  75.        (begin (set-mcdr! (mcar xs) v)
  76.               xs)]
  77.       ;(mcons (mcons (mcar (mcar xs)) v) (mcdr xs))]
  78.       ;{{'i . 5} ...}
  79.       [else
  80.        ;(writeln (mcdr xs))
  81.        (mcons (mcar xs) (update x v (mcdr xs)))]))
  82.  
  83.  
  84.  
  85.  
  86.  
  87.   ;; kilka operatorów do wykorzystania w interpreterze
  88.  
  89.   (define (op-to-proc x)
  90.     (lookup x `((+ ,+)
  91.                 (* ,*)
  92.                 (- ,-)
  93.                 (/ ,/)
  94.                 (%, modulo)
  95.                 (> ,>)
  96.                 (>= ,>=)
  97.                 (< ,<)
  98.                 (<= ,<=)
  99.                 (= ,=)
  100.                 (!= ,(lambda (x y) (not (= x y))))
  101.                 (&& ,(lambda (x y) (and x y)))
  102.                 (|| ,(lambda (x y) (or x y)))
  103.                 )))
  104.  
  105.   ;; interfejs do obsługi środowisk
  106.  
  107.   (define (env-empty) null)
  108.   (define (env-add x v env) (mcons (mcons x v) env))
  109.   (define env-update update)
  110.   (define env-discard mcdr)
  111.   (define (env-from-assoc-list xs) xs)
  112.  
  113.   ;; ewaluacja wyrażeń ze środowiskiem
  114.  
  115.   (define (eval e env)
  116.     (match e
  117.       [(const n) n]
  118.       [(op s l r)
  119.        ((op-to-proc s) (eval l env)
  120.                        (eval r env))]
  121.       [(let-expr x e1 e2)
  122.        (let ((v1 (eval e1 env)))
  123.          (eval e2 (env-add x v1 env)))]
  124.       [(variable x) (env-lookup x env)]
  125.       [(if-expr b t e) (if (eval b env)
  126.                            (eval t env)
  127.                            (eval e env))]))
  128.  
  129.   ;; interpretacja programów w języku WHILE, gdzie środowisko m to stan
  130.   ;; pamięci. Interpreter to procedura, która dostaje program i początkowy
  131.   ;; stan pamięci, a której wynikiem jest końcowy stan pamięci. Pamięć to
  132.   ;; aktualne środowisko zawierające wartości zmiennych
  133.  
  134.   (define (interp p m)
  135.     (match p
  136.       [(skip) m]
  137.       [(comp s1 s2)
  138.        ;(writeln m)
  139.        (interp s2 (interp s1 m))]
  140.       [(assign x e)
  141.        (env-update x (eval e m) m)]
  142.       [(while b s)
  143.        (if (eval b m)
  144.            (interp p (interp s m))
  145.            m)]
  146.       [(var-block x e s)
  147.        (env-discard
  148.         (interp s (env-add x (eval e m) m)))]
  149.       [(if-stm b t e) (if (eval b m)
  150.                           (interp t m)
  151.                           (interp e m))]))
  152.  
  153.   ;; silnia zmiennej i
  154.  
  155.   (define fact-in-WHILE
  156.     (var-block 'x (const 0)                                           ; var x := 0 in
  157.                (comp (assign 'x (const 1))                                    ;   x := 1
  158.                      (comp (while (op '> (variable 'i) (const 0))                   ;   while (i > 0)
  159.                                   (comp (assign 'x (op '* (variable 'x) (variable 'i))) ;     x := x * i
  160.                                         (assign 'i (op '- (variable 'i) (const 1)))))   ;     i := i - 1
  161.                            (assign 'i (variable 'x))))))                            ;   i := x
  162.  
  163.   (define (factorial n)
  164.     (env-lookup 'i (interp fact-in-WHILE
  165.                            (env-from-assoc-list (mlist (mcons 'i n))))))
  166.  
  167.  
  168.   ;; najmniejsza liczba pierwsza nie mniejsza niż i
  169.  
  170.   (define find-prime-in-WHILE
  171.     (var-block 'c (variable 'i)                                         ; var c := i in
  172.                (var-block 'continue (const true)                                   ; var continue := true in
  173.                           (comp
  174.                            (while (variable 'continue)                                        ; while (continue)
  175.                                   (var-block 'is-prime (const true)                                 ;   var is-prime := true in
  176.                                              (var-block 'x (const 2)                                           ;   var x := 2 in
  177.                                                         (comp
  178.                                                          (while (op '&& (variable 'is-prime)                             ;   while (is-prime &&
  179.                                                                     (op '< (variable 'x) (variable 'c)))             ;            x < c)
  180.                                                                 (comp (if-stm (op '= (op '% (variable 'c) (variable 'x))     ;     if (c % x =
  181.                                                                                   (const 0))                              ;                 0)
  182.                                                                               (assign 'is-prime (const false))               ;       is-prime := false
  183.                                                                               (skip))                                        ;     else skip
  184.                                                                       (assign 'x (op '+ (variable 'x) (const 1)))))          ;     x := x + 1
  185.                                                          (if-stm (variable 'is-prime)                                    ;   if (is-prime)
  186.                                                                  (assign 'continue (const false))                        ;     continue := false
  187.                                                                  (comp (assign 'continue (const true))                   ;   else continue := true
  188.                                                                        (assign 'c (op '+ (variable 'c) (const 1))))))))) ;        c := c + 1
  189.                            (assign 'i (variable 'c))))))                                      ; i := c
  190.  
  191.   (define (find-prime-using-WHILE n)
  192.     (env-lookup 'i (interp find-prime-in-WHILE
  193.                            (env-from-assoc-list (mlist (mcons 'i n) (mcons 'is-prime true))))))
  194.   )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement