X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=jars.git;a=blobdiff_plain;f=mars.scm;h=2f4db9de8672d3b44b66020ad03437e68253f1d5;hp=57e3e13e3f77809ca51d491c4682e1b5afcc0282;hb=d77eebde986b6bd5e5c25c40523920dfcac96f13;hpb=c30656b58f082be264e382d0da5866c4c04a10f7 diff --git a/mars.scm b/mars.scm index 57e3e13..2f4db9d 100644 --- a/mars.scm +++ b/mars.scm @@ -2,6 +2,10 @@ ;;; An implementation of the Memory Array Redcode Simulator (MARS) ;;; +(import (chicken io) + (chicken string) + matchable) + ;;; Constants ;; @@ -18,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 @@ -40,24 +50,51 @@ ;;; Main loop ;; -(define (list-rot l) - (if (> (length l) 1) - (append (cdr l) (list (car l))) - l)) - -(define (run playerA playerB step) +(define (run players step) (cond - ((> step max-steps) 'tie) - ((null? (player-ptrs playerA) playerB)) - ((null? (player-ptrs playerB) playerA)) + ((> step max-steps) players) ;Tie between remaining players + ((<= (length players) 1) players) ;There's only one player left who thus wins (else - (let ((ptrs (player-ptrs playerA))) - (player-set-ptrs! (append (cdr ptrs) - (execute-instr (car ptrs))))) - (run playerB player A (+ step 1))))) + (let ((player (car players)) + (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))) - (match instr - ()))) + (let* ((instr (vector-ref core ptr)) + (A-operand (eval-operand (instr-A-mode instr) (instr-A-num) ptr)) + (B-operand (eval-operand (instr-B-mode instr) (instr-B-num) ptr))) + (case (instr-opcode instr) + ((DAT)) + ((MOV)) + ((ADD)) + ((SUB)) + ((MUL)) + ((DIV)) + ((MOD)) + ((JMP)) + ((JMN)) + ((DJN)) + ((SEQ CMP)) + ((SNE)) + ((SLT)) + ((SPL)) + ((NOP)) + (else + (error "Unrecognised opcode" (instr-opcode instr)))))) +(define (eval-operand mode num ptr) + (case mode + ((immediate)) + ((direct)) + ((indirect-A)) + ((indirect-B)) + ((pre-indirect-A)) + ((pre-indirect-B)) + ((post-indirect-A)) + ((post-indirect-B))))