Advertisement
Guest User

Untitled

a guest
Mar 22nd, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 9.55 KB | None | 0 0
  1. #lang racket
  2.  
  3. (require "opcodes.rkt")
  4. (provide make-stack-machine)
  5. (provide run-stack-machine)
  6. (provide get-stack)
  7. (provide get-varnames)
  8. (provide get-consts)
  9. (provide get-names)
  10. (provide get-code)
  11. (provide get-IC)
  12. (provide empty-stack)
  13. (provide make-stack)
  14. (provide push)
  15. (provide pop)
  16. (provide top)
  17.  
  18.  
  19. ;; TODO 1:
  20. ;; Alegeți metoda de reprezentarea a unei stive.
  21. ;; Implementați:
  22. (define empty-stack '())
  23. (define (make-stack) empty-stack)
  24.  
  25. (define (push value stack)
  26.   (cons value stack))
  27.  
  28. (define (top stack)
  29.   (if (null? stack)
  30.       '()
  31.       (car stack)))
  32.  
  33. (define (pop stack)
  34.   (if (null? stack)
  35.       '()
  36.       (cdr stack)))
  37.  
  38. ;; TODO 2:
  39. ;; Alegeți metoda de reprezentare a unei mașini stivă.
  40. ;; Definiți make-stack-machine, acesta trebuie sa primeasca cele 4 segmente de date
  41. ;; Veți avea nevoie de o stivă pentru execuție și un counter ca să stiți
  42. ;; la ce instrucțiune sunteți.
  43. (define (make-stack-machine stack co-varnames co-consts co-names co-code IC)
  44.   (cons stack (cons co-varnames (cons co-consts (cons co-names (cons co-code IC))))))
  45.  
  46. ;; Definiți funcțiile `get-varnames`, `get-consts`, `get-names`,
  47. ;; `get-code`, `get-stack`, `get-IC` care primesc o mașina stivă și întorc
  48. ;; componenta respectivă
  49.  
  50. ;; ex:
  51. ;; > (get-varnames (make-stack-machine empty-stack 'dummy-co-varnames (hash) (hash) (list) 0))
  52. ;; 'dummy-co-varnames
  53. (define (get-varnames stack-machine)
  54.   (cadr stack-machine))
  55.  
  56. ;; ex:
  57. ;; > (get-consts (make-stack-machine empty-stack (hash) 'dummy-co-consts (hash) (list) 0))
  58. ;; 'dummy-co-consts
  59. (define (get-consts stack-machine)
  60.   (caddr stack-machine))
  61.  
  62. ;; ex:
  63. ;; > (get-names (make-stack-machine empty-stack (hash) (hash) 'dummy-co-names (list) 0))
  64. ;; 'dummy-co-names
  65. (define (get-names stack-machine)
  66.   (cadddr stack-machine))
  67.  
  68. ;; ex:
  69. ;; > (get-code (make-stack-machine empty-stack (hash) (hash) (hash) 'dummy-co-code 0))
  70. ;; dummy-co-code
  71. (define (get-code stack-machine)
  72.   (cadddr (cdr stack-machine)))
  73.  
  74. ;; Întoarce stiva de execuție.
  75. ;; ex:
  76. ;; > (get-code (make-stack-machine 'dummy-exec-stack (hash) (hash) (hash) (list) 0))
  77. ;; dummy-exec-stack
  78. (define (get-stack stack-machine)
  79.   (car stack-machine))
  80.  
  81. ;; Întoarce instruction counterul.
  82. ;; ex:
  83. ;; > (get-code (make-stack-machine empty-stack (hash) (hash) (hash) (list) 0))
  84. ;; 0
  85. (define (get-IC stack-machine)
  86.   (cdr (cdr (cdr (cdr (cdr  stack-machine))))))
  87.  
  88. ;; Definiți funcția push-exec-stack care primește o masină stivă și o valoare
  89. ;; și intoarce o noua mașina unde valoarea este pusă pe stiva de execuție
  90. (define (push-exec-stack value stack-machine)
  91.   (make-stack-machine
  92.    (push value (get-stack stack-machine))
  93.    (get-varnames stack-machine)
  94.    (get-consts stack-machine)
  95.    (get-names stack-machine)
  96.    (get-code stack-machine)
  97.    (+ (get-IC stack-machine) 1)))
  98.  
  99. ;; TODO 4:
  100. ;; Definiți funcția run-stack-machine care execută operații pană epuizează co-code.
  101. (define (run-stack-machine stack-machine)
  102.   (let* ((current-IC (get-IC stack-machine))
  103.          (code (get-code stack-machine))
  104.          (code-length (length code)))
  105.     (if (>= current-IC code-length)
  106.             stack-machine
  107.             (run-stack-machine (execute (get current-IC code) stack-machine)))))
  108.  
  109. (define (execute command stack-machine)
  110.   (case (car command)
  111.     ('LOAD_CONST (push-exec-stack (hash-ref (get-consts stack-machine) (cdr command)) stack-machine))
  112.     ('LOAD_FAST (push-exec-stack (hash-ref (get-varnames stack-machine) (cdr command)) stack-machine))
  113.     ('LOAD_GLOBAL (push-exec-stack (hash-ref (get-names stack-machine) (cdr command)) stack-machine))
  114.     ('STORE_FAST (do-store-fast (cdr command) stack-machine))
  115.     ('BINARY_ADD (do-add-binary stack-machine))
  116.     ('BINARY_SUBTRACT (do-subtract-binary stack-machine))
  117.     ('BINARY_MODULO (do-modulo-binary stack-machine))
  118.     ('INPLACE_ADD (do-add-binary stack-machine))
  119.     ('INPLACE_SUBTRACT (do-subtract-binary stack-machine))
  120.     ('INPLACE_MODULO (do-modulo-binary stack-machine))
  121.     ('COMPARE_OP (do-compare-op (cdr command) stack-machine))
  122.     ('JUMP_ABSOLUT (do-jump-absolute (cdr command) stack-machine))
  123.     ('POP_JUMP_IF_TRUE (do-jump-if-true (cdr command) stack-machine))
  124.     ('POP_JUMP_IF_FALSE (do-jump-if-false (cdr command) stack-machine))
  125.     ('GET_ITER (do-nothing stack-machine))
  126.     ('POP_TOP (do-pop stack-machine))
  127.     ('FOR_ITER (do-for-iter (cdr command) stack-machine))
  128.     ('CALL_FUNCTION (do-call-function (cdr command) stack-machine))
  129.     (else (do-nothing stack-machine))))
  130.  
  131. (define (do-call-function number stack-machine)
  132.   (let* ((stack (get-stack stack-machine))
  133.          (arguments (take stack number))
  134.          (new-stack (drop stack number))
  135.          (function (top stack))
  136.          (result (case function
  137.                    (("print") (writeln (car arguments)))
  138.                    (("sqrt") (sqrt (car arguments)))
  139.                    (("prod") (apply * arguments)))))
  140.     (make-stack-machine
  141.      (push result new-stack)
  142.      (get-varnames stack-machine)
  143.      (get-consts stack-machine)
  144.      (get-names stack-machine)
  145.      (get-code stack-machine)
  146.      (+ (get-IC stack-machine) 1))))
  147.  
  148. (define (do-for-iter delta stack-machine)
  149.   (let* ((stack (get-stack stack-machine))
  150.          (first-element (top stack))
  151.          (current-IC (get-IC stack-machine)))
  152.     (if (null? first-element)
  153.         (make-stack-machine
  154.          stack
  155.          (get-varnames stack-machine)
  156.          (get-consts stack-machine)
  157.          (get-names stack-machine)
  158.          (get-code stack-machine)
  159.          (+ current-IC (quotient (+ delta 2) 2)))
  160.         (make-stack-machine
  161.          (push (car first-element) (push (cdr first-element) stack))
  162.          (get-varnames stack-machine)
  163.          (get-consts stack-machine)
  164.          (get-names stack-machine)
  165.          (get-code stack-machine)
  166.          (+ current-IC 1)))))
  167.  
  168. (define (do-pop stack-machine)
  169.   (make-stack-machine
  170.      (pop (get-stack stack-machine))
  171.      (get-varnames stack-machine)
  172.      (get-consts stack-machine)
  173.      (get-names stack-machine)
  174.      (get-code stack-machine)
  175.      (+ (get-IC stack-machine) 1)))
  176.  
  177.  
  178. (define (do-jump-if-false target stack-machine)
  179.   (let* ((stack (get-stack stack-machine)) (val (top stack)) (IC (get-IC stack-machine)))
  180.     (make-stack-machine
  181.      stack
  182.      (get-varnames stack-machine)
  183.      (get-consts stack-machine)
  184.      (get-names stack-machine)
  185.      (get-code stack-machine)
  186.      (if (eq? val #f) (quotient target 2) (+ IC 1)))))
  187.  
  188.  
  189. (define (do-jump-if-true target stack-machine)
  190.   (let* ((stack (get-stack stack-machine)) (val (top stack)) (IC (get-IC stack-machine)))
  191.     (make-stack-machine
  192.      stack
  193.      (get-varnames stack-machine)
  194.      (get-consts stack-machine)
  195.      (get-names stack-machine)
  196.      (get-code stack-machine)
  197.      (if (eq? val #t) (quotient target 2) (+ IC 1)))))
  198.  
  199. (define (do-compare-op op-index stack-machine)
  200.   (let* ((stack (get-stack stack-machine)) (first-element (top stack)) (second-element (top (pop stack))) (operator (get op-index cmpcodes)))
  201.     (make-stack-machine
  202.      (push (operator second-element first-element) (pop (pop stack)))
  203.      (get-varnames stack-machine)
  204.      (get-consts stack-machine)
  205.      (get-names stack-machine)
  206.      (get-code stack-machine)
  207.      (+ (get-IC stack-machine) 1))))
  208.  
  209. (define (do-jump-absolute target stack-machine)
  210.   (make-stack-machine
  211.      (get-stack stack-machine)
  212.      (get-varnames stack-machine)
  213.      (get-consts stack-machine)
  214.      (get-names stack-machine)
  215.      (get-code stack-machine)
  216.      (quotient target 2)))
  217.  
  218.  
  219. (define (do-add-binary stack-machine)
  220.   (let* ((stack (get-stack stack-machine)) (first-element (top stack)) (second-element (top (pop stack))) (sum (+ second-element first-element)))
  221.     (make-stack-machine
  222.      (push sum (pop (pop stack)))
  223.      (get-varnames stack-machine)
  224.      (get-consts stack-machine)
  225.      (get-names stack-machine)
  226.      (get-code stack-machine)
  227.      (+ (get-IC stack-machine) 1))))
  228.  
  229. (define (do-subtract-binary stack-machine)
  230.   (let* ((stack (get-stack stack-machine)) (first-element (top stack)) (second-element (top (pop stack))) (dif (- second-element first-element)))
  231.     (make-stack-machine
  232.      (push dif (pop (pop stack)))
  233.      (get-varnames stack-machine)
  234.      (get-consts stack-machine)
  235.      (get-names stack-machine)
  236.      (get-code stack-machine)
  237.      (+ (get-IC stack-machine) 1))))
  238.  
  239. (define (do-modulo-binary stack-machine)
  240.   (let* ((stack (get-stack stack-machine)) (first-element (top stack)) (second-element (top (pop stack))) (mod (modulo second-element first-element)))
  241.     (make-stack-machine
  242.      (push mod (pop (pop stack)))
  243.      (get-varnames stack-machine)
  244.      (get-consts stack-machine)
  245.      (get-names stack-machine)
  246.      (get-code stack-machine)
  247.      (+ (get-IC stack-machine) 1))))
  248.  
  249. (define (do-nothing stack-machine)
  250.   (make-stack-machine
  251.    (get-stack stack-machine)
  252.    (get-varnames stack-machine)
  253.    (get-consts stack-machine)
  254.    (get-names stack-machine)
  255.    (get-code stack-machine)
  256.    (+ (get-IC stack-machine) 1)))
  257.  
  258. (define (do-store-fast key stack-machine)
  259.   (let ((current-IC (get-IC stack-machine))
  260.         (varnames (get-varnames stack-machine))
  261.         (stack (get-stack stack-machine)))
  262.     (make-stack-machine
  263.      (pop stack)
  264.      (hash-set varnames key (top stack))
  265.      (get-consts stack-machine)
  266.      (get-names stack-machine)
  267.      (get-code stack-machine)
  268.      (+ current-IC 1))))
  269.                  
  270. (define (get nth L)
  271.   (if (= nth 0)
  272.       (car L)
  273.       (get (- nth 1) (cdr L))))
  274.  
  275. (define cmpcodes (list < <= eq? (compose not eq?) > >= member (compose not member)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement