prog-instrs
prog-offset
prog->string
+ dump-prog
install-progs
make-queue
queue-owner
queue-ptrs
+ dump-queue
make-core
run-mars)
(('->string)
(conc opcode
"." modifier
- " " (mode->string A-mode) A-num
+ "\t" (mode->string A-mode) A-num
", " (mode->string B-mode) B-num))
(else
(error "Invalid instr arguments" args)))))
(let loop ((remaining-fns set-functions))
(unless (null? remaining-fns)
((car remaining-fns) i n))))
+ (define (dump i)
+ (print* i ":\t" ((norm-ref core-vec i) '->string))
+ (let ((n (norm-ref names-vec i)))
+ (unless (null? n)
+ (print* "\t;" n)))
+ (print))
(let loop ((i 0))
(unless (>= i core-size)
(vector-set! core-vec i (initial-instr 'make-copy))
((i 'name) (norm-ref names-vec i))
(((? integer? i) v) ((norm-ref core-vec i) v))
(('->addr (? integer? i)) (norm-addr i))
- (('dump)
- (let loop ((i 0))
- (unless (>= i core-size)
- (print* i ":\t" ((vector-ref core-vec i) '->string))
- (let ((n (vector-ref names-vec i)))
- (unless (null? n)
- (print* "\t;" n)))
- (print)
- (loop (+ i 1)))))
+ (('dump i)
+ (let ((i1 (- i 4))
+ (i2 (+ i 4)))
+ (let loop ((idx i1))
+ (unless (> idx i2)
+ (if (= idx i)
+ (print* "*"))
+ (dump idx)
+ (loop (+ idx 1))))))
(('size) core-size)))))
;;; Programmes and task queues
;;
- (define (make-prog name instrs offset)
- (list name instrs offset))
+ (define (make-prog name author instrs offset)
+ (list name author instrs offset))
(define (prog-name prog) (list-ref prog 0))
- (define (prog-instrs prog) (list-ref prog 1))
- (define (prog-offset prog) (list-ref prog 2))
+ (define (prog-author prog) (list-ref prog 1))
+ (define (prog-instrs prog) (list-ref prog 2))
+ (define (prog-offset prog) (list-ref prog 3))
(define (install-prog core prog addr)
(let loop ((ptr addr)
(define (queue-set-ptrs! queue ptrs)
(set-cdr! queue ptrs))
+ (define (dump-queue queue core)
+ (let loop ((ptrs (queue-ptrs queue)))
+ (unless (null? ptrs)
+ (core 'dump (car ptrs))
+ (print)
+ (loop (cdr ptrs)))))
+
(define (prog->string prog)
(conc ";redcode\n\n"
- ";name " (prog-name prog) "\n\n"
+ ";name\t" (prog-name prog) "\n"
+ (if (not (null? (prog-author prog)))
+ (conc ";author\t" (prog-author prog) "\n\n")
+ "\n")
"ORG\t" (prog-offset prog) "\t; Execution offset\n\n"
(apply conc (map (lambda (instr) (conc (instr '->string) "\n")) (prog-instrs prog)))))
+
+ (define (dump-prog prog)
+ (print (prog->string prog)))
;;; Executive function
;;
(define (run-mars core queues steps-left)
(cond
((<= steps-left 0) queues) ;Tie between remaining players
- ;; ((<= (length queues) 1) queues) ;There's only one player left who thus wins
+ ((null? queues) queues) ;Everyone's dead
(else
(let* ((queue (car queues))
(remaining-queues (cdr queues))
(ptrs (queue-ptrs queue))
(new-ptrs (execute-instr core (car ptrs) (queue-owner queue))))
(if (null? new-ptrs)
- (run-mars remaining-queues (- steps-left 1))
+ (run-mars core remaining-queues (- steps-left 1))
(begin
(queue-set-ptrs! queue (append (cdr ptrs) new-ptrs))
(run-mars core (append remaining-queues (list queue)) (- steps-left 1))))))))
(define (execute-instr core ptr name)
+ ;; (print ptr "\t" (core ptr '->string) "\t(" name ")")
(let* ((A-ptr (eval-operand core (core ptr 'A-mode) (core ptr 'A-num) ptr name))
(B-ptr (eval-operand core (core ptr 'B-mode) (core ptr 'B-num) ptr name))
(modifier (core ptr 'modifier)))
(list (core '->addr (+ ptr 1))))
((exn arithmetic) '())))
((JMP)
- (list (core '->addr (+ ptr (core A-ptr 'A-num)))))
+ (list (core '->addr A-ptr)))
((JMZ)
- (list (core '->addr (+ ptr (if (instr-zero? B-ptr modifier #f name)
- (core A-ptr 'A-num)
- 1)))))
+ (list (core '->addr (if (instr-zero? core B-ptr modifier #f name)
+ A-ptr
+ (+ ptr 1)))))
((JMN)
- (list (core '->addr (+ ptr (if (not (instr-zero? B-ptr modifier #f name))
- (core A-ptr 'A-num)
- 1)))))
+ (list (core '->addr (if (not (instr-zero? core B-ptr modifier #f name))
+ A-ptr
+ (+ ptr 1)))))
((DJN)
- (list (core '->addr (+ ptr (if (not (instr-zero? B-ptr modifier #t name))
- (core A-ptr 'A-num)
- 1)))))
+ (list (core '->addr (if (not (instr-zero? core B-ptr modifier #t name))
+ A-ptr
+ (+ ptr 1)))))
((SEQ CMP)
(list (core '->addr (+ ptr (if (compare-instrs core A-ptr B-ptr modifier =) 2 1)))))
((SNE)
((SLT)
(list (core '->addr (+ ptr (if (compare-instrs core A-ptr B-ptr modifier <) 2 1)))))
((SPL)
- (list (core '->addr (+ ptr 1) (core '->addr (+ ptr (core A-ptr 'A-num))))))
+ (list (core '->addr (+ ptr 1) (core '->addr A-ptr))))
((NOP)
(list (core '->addr (+ ptr 1))))
(else