|
|
@ -9,22 +9,14 @@
|
|
|
|
(define (make-runner program [calling-thd (current-thread)])
|
|
|
|
(define (make-runner program [calling-thd (current-thread)])
|
|
|
|
(thread (λ ()
|
|
|
|
(thread (λ ()
|
|
|
|
(define regs (string->regs program))
|
|
|
|
(define regs (string->regs program))
|
|
|
|
(define (grow-regs! len)
|
|
|
|
(define (maybe-enlarge-regs len)
|
|
|
|
(define newvec (make-vector (add1 len) 0))
|
|
|
|
(unless (< len (vector-length regs))
|
|
|
|
(vector-copy! newvec 0 regs)
|
|
|
|
(define newvec (make-vector (add1 len) 0))
|
|
|
|
(set! regs newvec))
|
|
|
|
(vector-copy! newvec 0 regs)
|
|
|
|
(define (reg-ref ptr)
|
|
|
|
(set! regs newvec))
|
|
|
|
(cond
|
|
|
|
regs)
|
|
|
|
[(< ptr (vector-length regs)) (vector-ref regs ptr)]
|
|
|
|
(define (reg-ref ptr) (vector-ref (maybe-enlarge-regs ptr) ptr))
|
|
|
|
[else
|
|
|
|
(define (reg-set! ptr val) (vector-set! (maybe-enlarge-regs ptr) ptr val))
|
|
|
|
(grow-regs! (add1 ptr))
|
|
|
|
|
|
|
|
(reg-ref ptr)]))
|
|
|
|
|
|
|
|
(define (reg-set! ptr val)
|
|
|
|
|
|
|
|
(cond
|
|
|
|
|
|
|
|
[(< ptr (vector-length regs)) (vector-set! regs ptr val)]
|
|
|
|
|
|
|
|
[else
|
|
|
|
|
|
|
|
(grow-regs! (add1 ptr))
|
|
|
|
|
|
|
|
(reg-set! ptr val)]))
|
|
|
|
|
|
|
|
(define relative-base 0)
|
|
|
|
(define relative-base 0)
|
|
|
|
(let/ec terminate
|
|
|
|
(let/ec terminate
|
|
|
|
(let loop ([ptr 0])
|
|
|
|
(let loop ([ptr 0])
|
|
|
@ -36,36 +28,35 @@
|
|
|
|
(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)])
|
|
|
|
(λ (ptr [io-mode? 'read])
|
|
|
|
(λ (ptr)
|
|
|
|
((if (eq? io-mode? 'read) reg-ref values)
|
|
|
|
(define ptr-adjusted (+ ptr offset))
|
|
|
|
(let ([ptr-adjusted (+ ptr offset)])
|
|
|
|
(match mode-val
|
|
|
|
(match mode-val
|
|
|
|
[0 (reg-ref ptr-adjusted)] ; position
|
|
|
|
[0 (reg-ref ptr-adjusted)] ; position
|
|
|
|
[1 ptr-adjusted] ; immediate
|
|
|
|
[1 ptr-adjusted] ; immediate
|
|
|
|
[2 (+ relative-base (reg-ref ptr-adjusted))]))))])) ; relative
|
|
|
|
[2 (+ relative-base (reg-ref ptr-adjusted))]))))))])) ; relative
|
|
|
|
|
|
|
|
(define next-ptr
|
|
|
|
(define next-ptr
|
|
|
|
(match 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! (mode-3 ptr 'write) ((match opcode
|
|
|
|
(reg-set! (mode-3 ptr) ((match opcode
|
|
|
|
[1 +]
|
|
|
|
[1 +]
|
|
|
|
[2 *]
|
|
|
|
[2 *]
|
|
|
|
[7 (binarize <)]
|
|
|
|
[7 (binarize <)]
|
|
|
|
[8 (binarize =)]) (mode-1 ptr) (mode-2 ptr)))
|
|
|
|
[8 (binarize =)]) (reg-ref (mode-1 ptr)) (reg-ref (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 'write) (thread-receive))]
|
|
|
|
[3 (reg-set! (mode-1 ptr) (thread-receive))]
|
|
|
|
[4 (thread-send calling-thd (mode-1 ptr))]
|
|
|
|
[4 (thread-send calling-thd (reg-ref (mode-1 ptr)))]
|
|
|
|
[9 (set! relative-base (+ relative-base (mode-1 ptr)))])
|
|
|
|
[9 (set! relative-base (+ relative-base (reg-ref (mode-1 ptr))))])
|
|
|
|
(+ ptr 2)]
|
|
|
|
(+ ptr 2)]
|
|
|
|
[(or 5 6) ; 3-arity: jump
|
|
|
|
[(or 5 6) ; 3-arity: jump
|
|
|
|
(if ((match opcode
|
|
|
|
(if ((match opcode
|
|
|
|
[5 not]
|
|
|
|
[5 not]
|
|
|
|
[6 values]) (zero? (mode-1 ptr)))
|
|
|
|
[6 values]) (zero? (reg-ref (mode-1 ptr))))
|
|
|
|
(mode-2 ptr)
|
|
|
|
(reg-ref (mode-2 ptr))
|
|
|
|
(+ ptr 3))]
|
|
|
|
(+ ptr 3))]
|
|
|
|
[99 (thread-send calling-thd 'done) (terminate)]
|
|
|
|
[99 (thread-send calling-thd 'done) (terminate)]
|
|
|
|
[_ (error "unknown-opcode" opcode)]))
|
|
|
|
[_ (error "unknown opcode" opcode)]))
|
|
|
|
(loop next-ptr))))))
|
|
|
|
(loop next-ptr))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -92,8 +83,16 @@
|
|
|
|
(run "104,1125899906842624,99")
|
|
|
|
(run "104,1125899906842624,99")
|
|
|
|
'(1125899906842624))
|
|
|
|
'(1125899906842624))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; 1
|
|
|
|
(define t1 (make-runner (file->string "09.rktd")))
|
|
|
|
(define t1 (make-runner (file->string "09.rktd")))
|
|
|
|
(thread-send t1 1)
|
|
|
|
(thread-send t1 1)
|
|
|
|
(check-equal?
|
|
|
|
(check-equal?
|
|
|
|
(run t1)
|
|
|
|
(run t1)
|
|
|
|
'(3601950151))
|
|
|
|
'(3601950151))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; 2
|
|
|
|
|
|
|
|
(define t2 (make-runner (file->string "09.rktd")))
|
|
|
|
|
|
|
|
(thread-send t2 2)
|
|
|
|
|
|
|
|
(check-equal?
|
|
|
|
|
|
|
|
(run t2)
|
|
|
|
|
|
|
|
'(64236))
|