master
Matthew Butterick 5 years ago
parent df4dacafa3
commit 58bbbef2a8

@ -21,9 +21,9 @@
(reg-ref ptr)])) (reg-ref ptr)]))
(define (reg-set! ptr val) (define (reg-set! ptr val)
(cond (cond
[(< (reg-ref ptr) (vector-length regs)) (vector-set! regs (reg-ref ptr) val)] [(< ptr (vector-length regs)) (vector-set! regs ptr val)]
[else [else
(grow-regs! (add1 (reg-ref ptr))) (grow-regs! (add1 ptr))
(reg-set! ptr val)])) (reg-set! ptr val)]))
(define relative-base 0) (define relative-base 0)
(let/ec terminate (let/ec terminate
@ -31,30 +31,30 @@
(define inst (for/list ([c (in-string (~r (reg-ref ptr) #:min-width 5 #:pad-string "0"))]) (define inst (for/list ([c (in-string (~r (reg-ref ptr) #:min-width 5 #:pad-string "0"))])
(string->number (string c)))) (string->number (string c))))
(match-define (list opcode mode-1 mode-2 mode-3) (match-define (list opcode mode-1 mode-2 mode-3)
(match #R inst (match inst
[(list d4 d3 d2 d1 d0) [(list d4 d3 d2 d1 d0)
(cons (+ (* 10 d1) d0) (cons (+ (* 10 d1) d0)
(for/list ([mode-val (list d2 d3 d4)] (for/list ([mode-val (list d2 d3 d4)]
[offset '(1 2 3)]) [offset '(1 2 3)])
(match mode-val (λ (ptr [io-mode? 'read])
;; position ((if (eq? io-mode? 'read) reg-ref values)
[0 (λ (ptr) (reg-ref (reg-ref (+ ptr offset))))] (let ([ptr-adjusted (+ ptr offset)])
;; immediate (match mode-val
[1 (λ (ptr) (reg-ref (+ ptr offset)))] [0 (reg-ref ptr-adjusted)] ; position
;; relative [1 ptr-adjusted] ; immediate
[2 (λ (ptr) (reg-ref (+ relative-base (reg-ref (+ ptr offset)))))])))])) [2 (+ relative-base (reg-ref ptr-adjusted))]))))))])) ; relative
(define next-ptr (define next-ptr
(match #R opcode (match opcode
[(or 1 2 7 8) ; 4-arity: add & multiply & compare [(or 1 2 7 8) ; 4-arity: add & multiply & compare
(reg-set! (+ ptr 3) ((match opcode (reg-set! (mode-3 ptr 'write) ((match opcode
[1 +] [1 +]
[2 *] [2 *]
[7 (binarize <)] [7 (binarize <)]
[8 (binarize =)]) (mode-1 ptr) (mode-2 ptr))) [8 (binarize =)]) (mode-1 ptr) (mode-2 ptr)))
(+ ptr 4)] (+ ptr 4)]
[(or 3 4 9) ; 2-arity: input & output [(or 3 4 9) ; 2-arity: input & output
(match opcode (match opcode
[3 (reg-set! (mode-1 ptr) (thread-receive))] [3 (reg-set! (mode-1 ptr 'write) (thread-receive))]
[4 (thread-send calling-thd (mode-1 ptr))] [4 (thread-send calling-thd (mode-1 ptr))]
[9 (set! relative-base (+ relative-base (mode-1 ptr)))]) [9 (set! relative-base (+ relative-base (mode-1 ptr)))])
(+ ptr 2)] (+ ptr 2)]
@ -83,6 +83,7 @@
(run "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99") (run "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99")
'(109 1 204 -1 1001 100 1 100 1008 100 16 101 1006 101 0 99)) '(109 1 204 -1 1001 100 1 100 1008 100 16 101 1006 101 0 99))
(check-equal? (check-equal?
(run "1102,34915192,34915192,7,4,7,99,0") (run "1102,34915192,34915192,7,4,7,99,0")
'(1219070632396864)) '(1219070632396864))
@ -91,7 +92,8 @@
(run "104,1125899906842624,99") (run "104,1125899906842624,99")
'(1125899906842624)) '(1125899906842624))
(define t1 (make-runner (file->string "09.rktd"))) (define t1 (make-runner (file->string "09.rktd")))
(thread-send t1 1) (thread-send t1 1)
(run t1) (check-equal?
(run t1)
'(3601950151))