X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=jars.git;a=blobdiff_plain;f=mars.scm;h=b1aa9db8f03f1bd52c38fbce981ca6423de07d0a;hp=c77e2d3142f9338b0a90715aa749af07858ab316;hb=707bcb205c185815e2b94ab3fca5f769afb58264;hpb=8c9a5e7af566f647f2acb58dabe558008964f27f diff --git a/mars.scm b/mars.scm index c77e2d3..b1aa9db 100644 --- a/mars.scm +++ b/mars.scm @@ -22,7 +22,13 @@ ;;; Instructions ;; -(define (make-instr opcode modifier addrA modeA addrB modeB)) +(define (make-instr opcode modifier A-mode A-num B-mode B-num)) +(define (instr-opcode instr) (list-ref instr 0)) +(define (instr-modifier instr) (list-ref instr 1)) +(define (instr-A-mode instr) (list-ref instr 2)) +(define (instr-A-num instr) (list-ref instr 3)) +(define (instr-B-mode instr) (list-ref instr 4)) +(define (instr-B-num instr) (list-ref instr 5)) ;;; Players @@ -46,20 +52,23 @@ (define (run players step) (cond - ((> step max-steps) players) ;Tie between remaining players - ((null? players) '()) ;Somehow we have no players remaining + ((> step max-steps) players) ;Tie between remaining players + ((<= (length players) 1) players) ;There's only one player left who thus wins (else (let ((player (car players)) - (other-players (cdr players))) - (if (null? ptrs) - (run other-players (+ step 1)) ;Player is out - (let* ((ptrs (player-ptrs player)) - (new-ptrs (execute-instr (car ptrs)))) - (player-set-ptrs! (append (cdr ptrs) new-ptrs)) - (run (append other-players (list player)) (+ step 1)))))))) + (other-players (cdr players)) + (ptrs (player-ptrs player))) + (let ((new-ptrs (execute-instr (car ptrs)))) + (if (null? new-ptrs) + (run other-players (+ step 1)) + (begin + (player-set-ptrs! (append (cdr ptrs) new-ptrs)) + (run (append other-players (list player)) (+ step 1))))))))) (define (execute-instr ptr) - (let ((instr (vector-ref core ptr))) + (let* ((instr (vector-ref core ptr)) + (A-pointer (eval-operand (instr-A-mode instr) (instr-A-num) ptr)) + (B-pointer (eval-operand (instr-B-mode instr) (instr-B-num) ptr))) (case (instr-opcode instr) ((DAT)) ((MOV)) @@ -79,3 +88,29 @@ (else (error "Unrecognised opcode" (instr-opcode instr)))))) +(define (eval-operand mode num ptr) + (case mode + ((immediate) 0) + ((direct) num) + ((indirect-A) (+ num (instr-A-num (vector-ref core (+ ptr num))))) + ((indirect-B) (+ num (instr-B-num (vector-ref core (+ ptr num))))) + ((pre-indirect-A) + (let ((aux-instr (vector-ref core (+ ptr num)))) + (instr-set-A-num! aux-instr (- 1 (instr-A-num aux-instr))) + (+ num (instr-A-num aux-instr)))) + ((pre-indirect-B) + (let ((aux-instr (vector-ref core (+ ptr num)))) + (instr-set-B-num! aux-instr (- 1 (instr-B-num aux-instr))) + (+ num (instr-B-num aux-instr)))) + ((post-indirect-A) + (let* ((aux-instr (vector-ref core (+ ptr num))) + (old-A-num (instr-A-num aux-instr))) + (instr-set-A-num! aux-instr (+ 1 (instr-A-num aux-instr))) + (+ num old-A-num))) + ((post-indirect-B) + (let* ((aux-instr (vector-ref core (+ ptr num))) + (old-B-num (instr-B-num aux-instr))) + (instr-set-B-num! aux-instr (+ 1 (instr-B-num aux-instr))) + (+ num old-B-num))) + (else + (error "Unrecognized mode" mode))))