Advertisement
DoromaAnim

Untitled

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