Advertisement
Guest User

Untitled

a guest
Jan 20th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.64 KB | None | 0 0
  1. #lang br/quicklang
  2.  
  3. (provide cpy jnz inc dec
  4. ops pc a b c d result
  5. ops! a! b! c! d!
  6. next
  7. compile run
  8. read-syntax
  9. #%module-begin
  10. (all-from-out br/quicklang) ; basically racket/base
  11. )
  12.  
  13. ;;; support for: #lang reader "12i.rkt"
  14.  
  15. (module+ reader
  16. (provide read-syntax))
  17.  
  18. (define (read-syntax path port)
  19. (define ops (compile port))
  20. (datum->syntax #f `(module cpu-mod "12i.rkt"
  21. (provide pc a b c d result)
  22. (run (list ,@ops)))))
  23.  
  24. (define (compile port)
  25. (for/list ([line (in-lines port)]
  26. #:when (non-empty-string? line))
  27. (format-datum '(~a) line)))
  28.  
  29. (define (run opcodes [initial-values #f])
  30. ;; TODO
  31. ;; (displayln opcodes)
  32. ;; (set! opcodes (for/list ([op (in-list opcodes)])
  33. ;; (if (procedure? op)
  34. ;; op
  35. ;; ;; Unfortunately, (expand op) does this:
  36. ;; ;;
  37. ;; ;; (inc a) -> (#<syntax:... (#%app (#%top . inc) (#%top ....>)
  38. ;; (expand op))))
  39. ;; (displayln opcodes)
  40.  
  41. (ops! opcodes)
  42. ;; (when initial-values ; TODO
  43. ;; (set! pc (list-ref initial-values 0))
  44. ;; (set! a (list-ref initial-values 1))
  45. ;; (set! b (list-ref initial-values 2))
  46. ;; (set! c (list-ref initial-values 3))
  47. ;; (set! d (list-ref initial-values 4)))
  48. (void (next))
  49. (set! result `((pc ,pc) (a ,a) (b ,b) (c ,c) (d ,d)))
  50. result
  51. )
  52.  
  53. ;;; registers & memory
  54.  
  55. (define result #f)
  56. (define ops #f)
  57. (define ops-max #f)
  58. (define-values (pc a b c d) (values 0 0 0 0 0))
  59.  
  60. (define (ops! v)
  61. (set!-values (pc a b c d) (values 0 0 0 0 0))
  62. (set! ops (list->vector v))
  63. (set! ops-max (vector-length ops)))
  64. (define (pc+ n) (set! pc (+ pc n)))
  65. (define (pc++) (pc+ 1))
  66. (define (a! v) (set! a v))
  67. (define (b! v) (set! b v))
  68. (define (c! v) (set! c v))
  69. (define (d! v) (set! d v))
  70.  
  71. ;;; macros for ops
  72.  
  73. (begin-for-syntax
  74. (define (setter id) (format-id id "~a!" id)))
  75.  
  76. (define-syntax (cpy stx)
  77. (syntax-case stx ()
  78. [(cpy A B) #`(thunk (#,(setter #'B) A) (pc++) (next))]))
  79.  
  80. (define-syntax-rule (jnz A B)
  81. (thunk (pc+ (if (zero? A) 1 B)) (next)))
  82.  
  83. (define-syntax (inc stx)
  84. (syntax-case stx ()
  85. [(inc A) #`(thunk (#,(setter #'A) (add1 A)) (pc++) (next))]))
  86.  
  87. (define-syntax (dec stx)
  88. (syntax-case stx ()
  89. [(_ A) #`(thunk (#,(setter #'A) (sub1 A)) (pc++) (next))]))
  90.  
  91. (define (next)
  92. (and (< pc ops-max) ((vector-ref ops pc))))
  93.  
  94. (module* test racket
  95. (require rackunit)
  96. (require check-sexp-equal)
  97. (require br)
  98. (require (prefix-in my/ (submod "..")))
  99.  
  100. (check-equal? (my/compile (open-input-string "inc a"))
  101. '((inc a)))
  102.  
  103. ;; Have I wired up my module the way I thought?
  104. (check-sexp-equal? (test-reader my/read-syntax "inc a\ndec z")
  105. '(module cpu-mod "12i.rkt"
  106. (provide pc a b c d result)
  107. (run (list (inc a) (dec z)))))
  108.  
  109. ;; does this work in the slightest?
  110. (check-sexp-equal? (eval `(begin
  111. ,(test-reader my/read-syntax "inc a")
  112. (dynamic-require ''cpu-mod 'result)))
  113. '((pc 1) (a 1) (b 0) (c 0) (d 0)))
  114.  
  115. ;; does this reset properly?
  116. (check-sexp-equal? (eval `(begin
  117. ,(test-reader my/read-syntax "inc b\ninc b")
  118. (dynamic-require ''cpu-mod 'result)))
  119. '((pc 2) (a 0) (b 2) (c 0) (d 0)))
  120.  
  121. ;;; FAILS: because passing '((inc a)) instead of expanded thunks
  122. (check-equal? (my/run (my/compile (open-input-string "inc a")))
  123. '((pc 1) (a 1) (b 0) (c 0) (d 0)))
  124.  
  125. (displayln 'done))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement