Advertisement
DoromaAnim

dsf

Apr 24th, 2019
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.37 KB | None | 0 0
  1. #lang racket
  2.  
  3. (provide (all-defined-out))
  4.  
  5. ;; definicja wyrażeń z let-wyrażeniami i if-wyrażeniami
  6.  
  7. (struct variable (x) #:transparent)
  8. (struct const (val) #:transparent)
  9. (struct op (symb l r) #:transparent)
  10. (struct let-expr (x e1 e2) #:transparent)
  11. (struct if-expr (b t e) #:transparent)
  12.  
  13. (define (expr? e)
  14. (match e
  15. [(variable s) (symbol? s)]
  16. [(const n) (or (number? n)
  17. (boolean? n))]
  18. [(op s l r) (and (member s '(+ *))
  19. (expr? l)
  20. (expr? r))]
  21. [(let-expr x e1 e2) (and (symbol? x)
  22. (expr? e1)
  23. (expr? e2))]
  24. [(if-expr b t e) (andmap expr? (list b t e))]
  25. [_ false]))
  26.  
  27. ;; definicja instrukcji w języku WHILE
  28.  
  29. (struct skip () #:transparent) ; skip
  30. (struct comp (s1 s2) #:transparent) ; s1; s2
  31. (struct assign (x e) #:transparent) ; x := e
  32. (struct while (b s) #:transparent) ; while (b) s
  33. (struct if-stm (b t e) #:transparent) ; if (b) t else e
  34. (struct var-block (x e s) #:transparent) ; var x := e in s
  35. (struct ++ (x) #:transparent)
  36. (struct for (e1 e2 s1 s2))
  37.  
  38. (define (stm? e)
  39. (match e
  40. [(skip) true]
  41. [(comp s1 s2) (and (stm? s1) (stm? s2))]
  42. [(assign x e) (and (symbol? x) (expr? e))]
  43. [(while b s) (and (expr? b) (stm? s))]
  44. [(if-stm b t e) (and (expr? b) (stm? t) (stm? e))]
  45. [_ false]))
  46.  
  47. ;; wyszukiwanie wartości dla klucza na liście asocjacyjnej
  48. ;; dwuelementowych list
  49.  
  50. (define (lookup x xs)
  51. (cond
  52. [(null? xs)
  53. (error x "unknown identifier :(")]
  54. [(eq? (caar xs) x) (cadar xs)]
  55. [else (lookup x (cdr xs))]))
  56.  
  57. ;; aktualizacja środowiska dla danej zmiennej (koniecznie już
  58. ;; istniejącej w środowisku!)
  59.  
  60. (define (update x v xs)
  61. (cond
  62. [(null? xs)
  63. (error x "unknown identifier :(")]
  64. [(eq? (caar xs) x)
  65. (cons (list (caar xs) v) (cdr xs))]
  66. [else
  67. (cons (car xs) (update x v (cdr xs)))]))
  68.  
  69. ;; kilka operatorów do wykorzystania w interpreterze
  70.  
  71. (define (op-to-proc x)
  72. (lookup x `((+ ,+)
  73. (* ,*)
  74. (- ,-)
  75. (/ ,/)
  76. (%, modulo)
  77. (> ,>)
  78. (>= ,>=)
  79. (< ,<)
  80. (<= ,<=)
  81. (= ,=)
  82. (!= ,(lambda (x y) (not (= x y))))
  83. (&& ,(lambda (x y) (and x y)))
  84. (|| ,(lambda (x y) (or x y)))
  85. )))
  86.  
  87. ;; interfejs do obsługi środowisk
  88.  
  89. (define (env-empty) null)
  90. (define env-lookup lookup)
  91. (define (env-add x v env) (cons (list x v) env))
  92. (define env-update update)
  93. (define env-discard cdr)
  94. (define (env-from-assoc-list xs) xs)
  95.  
  96. ;; ewaluacja wyrażeń ze środowiskiem
  97.  
  98. (define (eval e env)
  99. (match e
  100. [(const n) n]
  101. [(op s l r) ((op-to-proc s) (eval l env)
  102. (eval r env))]
  103. [(let-expr x e1 e2)
  104. (let ((v1 (eval e1 env)))
  105. (eval e2 (env-add x v1 env)))]
  106. [(variable x) (env-lookup x env)]
  107. [(if-expr b t e) (if (eval b env)
  108. (eval t env)
  109. (eval e env))]))
  110.  
  111. ;; interpretacja programów w języku WHILE, gdzie środowisko m to stan
  112. ;; pamięci. Interpreter to procedura, która dostaje program i początkowy
  113. ;; stan pamięci, a której wynikiem jest końcowy stan pamięci. Pamięć to
  114. ;; aktualne środowisko zawierające wartości zmiennych
  115.  
  116. (define (interp p m)
  117. (match p
  118. [(skip) m]
  119. [(comp s1 s2) (interp s2 (interp s1 m))]
  120. [(assign x e)
  121. (env-update x (eval e m) m)]
  122. [(while b s)
  123. (if (eval b m)
  124. (interp p (interp s m))
  125. m)]
  126. [(var-block x e s)
  127. (env-discard
  128. (interp s (env-add x (eval e m) m)))]
  129. [(if-stm b t e) (if (eval b m)
  130. (interp t m)
  131. (interp e m))]
  132. [(++ x) (env-update x (+ 1 (lookup x m)) m)]
  133. [(for e1 e2 s1)(env-discard (var-block `x (eval e1)
  134. (if (eval e2 m)
  135. (interp p (interp (comp s2 s1) m))
  136. m)))]))
  137.  
  138. ;; silnia zmiennej i
  139.  
  140. (define fact-in-WHILE
  141. (var-block 'x (const 0) ; var x := 0 in
  142. (comp (assign 'x (const 1)) ; x := 1
  143. (comp (while (op '> (variable 'i) (const 0)) ; while (i > 0)
  144. (comp (assign 'x (op '* (variable 'x) (variable 'i))) ; x := x * i
  145. (assign 'i (op '- (variable 'i) (const 1))))) ; i := i - 1
  146. (assign 'i (variable 'x)))))) ; i := x
  147.  
  148. (define (factorial n)
  149. (env-lookup 'i (interp fact-in-WHILE
  150. (env-from-assoc-list `((i ,n))))))
  151.  
  152. (define fib-in-WHILE
  153. (++ `i))
  154.  
  155. (define (fib n)
  156. (env-lookup `i (interp fib-in-WHILE (env-from-assoc-list `((i ,n))))))
  157.  
  158. ;(fib 1)
  159. ;(fib 2)
  160. ;(fib 3)
  161. ;(fib 4)
  162. ;(fib 5)
  163.  
  164. (define nth-fib-in-WHILE
  165. (var-block 'x (const 0)
  166. (var-block `y (const 1)
  167. (var-block `z (const 0)
  168. (if-stm (op `= (variable `i) (const 0))
  169. (assign `i (variable `x))
  170. (if-stm (op `= (variable `i) (const 1))
  171. (assign `i (variable `y))
  172. (comp (while (op `!= (variable `i) (const 1))
  173. (comp (assign `z (op `+ (variable `x) (variable `y)))
  174. (comp (assign `x (variable `y))
  175. (comp (assign `y (variable `z))
  176. (assign `i (op `- (variable `i) (const 1)))))))
  177. (assign `i (variable `y)))))))))
  178.  
  179. (define (nth-fib n)
  180. (env-lookup `i (interp nth-fib-in-WHILE (env-from-assoc-list `((i ,n))))))
  181.  
  182.  
  183.  
  184.  
  185.  
  186. ;; najmniejsza liczba pierwsza nie mniejsza niż i
  187.  
  188. (define find-prime-in-WHILE
  189. (var-block 'c (variable 'i) ; var c := i in
  190. (var-block 'continue (const true) ; var continue := true in
  191. (comp
  192. (while (variable 'continue) ; while (continue)
  193. (var-block 'is-prime (const true) ; var is-prime := true in
  194. (var-block 'x (const 2) ; var x := 2 in
  195. (comp
  196. (while (op '&& (variable 'is-prime) ; while (is-prime &&
  197. (op '< (variable 'x) (variable 'c))) ; x < c)
  198. (comp (if-stm (op '= (op '% (variable 'c) (variable 'x)) ; if (c % x =
  199. (const 0)) ; 0)
  200. (assign 'is-prime (const false)) ; is-prime := false
  201. (skip)) ; else skip
  202. (assign 'x (op '+ (variable 'x) (const 1))))) ; x := x + 1
  203. (if-stm (variable 'is-prime) ; if (is-prime)
  204. (assign 'continue (const false)) ; continue := false
  205. (comp (assign 'continue (const true)) ; else continue := true
  206. (assign 'c (op '+ (variable 'c) (const 1))))))))) ; c := c + 1
  207. (assign 'i (variable 'c)))))) ; i := c
  208.  
  209. (define (find-prime-using-WHILE n)
  210. (env-lookup 'i (interp find-prime-in-WHILE
  211. (env-from-assoc-list `((i ,n) (is-prime ,true))))))
  212.  
  213. ;; porownajmy wydajnosc!
  214.  
  215. ;; ten sam algorytm do wyszukiwania liczby pierwszej nie mniejszej niż n
  216. ;; zapisany funkcyjnie jest dosc brzydki, ale odpowiada temu zapisanemu w WHILE
  217.  
  218. (define (find-prime-native n)
  219. (define (is-prime c isp x)
  220. (if (and isp (< x c))
  221. (if (= (modulo c x) 0)
  222. (is-prime c false (+ x 1))
  223. (is-prime c isp (+ x 1)))
  224. isp))
  225. (if (is-prime n true 2)
  226. n
  227. (find-prime-native (+ n 1))))
  228.  
  229. ;; testujemy, żeby dowiedzieć się, jak dużo wydajności tracimy przez
  230. ;; uruchamianie programu w naszym interpreterze
  231.  
  232. (define (test)
  233. (begin
  234. (display "wait...\n")
  235. (flush-output (current-output-port))
  236. (test-performance)))
  237.  
  238. (define (test-performance)
  239. (let-values
  240. (((r1 cpu1 real1 gc1) (time-apply find-prime-using-WHILE (list 1111111)))
  241. ((r2 cpu2 real2 gc2) (time-apply find-prime-native (list 1111111))))
  242. (begin
  243. (display "WHILE time (cpu, real, gc): ")
  244. (display cpu1) (display ", ")
  245. (display real1) (display ", ")
  246. (display gc1) (display "\n")
  247. (display "native time (cpu, real, gc): ")
  248. (display cpu2) (display ", ")
  249. (display real2) (display ", ")
  250. (display gc2) (display "\n"))))
  251.  
  252. (define (make-cycle xs)
  253. (define (iter ys)
  254. (if (null? (mcdr ys))
  255. (begin (set-mcdr! ys xs)
  256. xs)
  257. (iter (mcdr ys))))
  258. (iter xs))
  259.  
  260. (make-cycle (mcons 1 (mcons 2 (mcons 3 null))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement