; Execute the program (if it's legal) starting with the instruction ; at the given address (the "program counter"). (define (MLexecute program pc) (cond ((not (legalML? program)) '(*** Attempt to execute an illegal program)) ((not (number? pc)) '(*** Nonnumeric program counter)) ((or (< pc 0) (> pc 99)) '(*** Program counter out of range)) (else (execute-prog (padded program 100) pc 0)) ) ) ; Return true exactly when the program represents a legal CARDIAC ; machine language program. (define (legalML? program) (and (list? program) (<= (length program) 100) (every (lambda (instr) (and (list? instr) (or (= (length instr) 3) (and (= (length instr) 4) (equal? (last-pair instr) '(-)) ) ) (and (>= (car instr) 0) (< (car instr) 10)) (and (>= (cadr instr) 0) (< (cadr instr) 10)) (and (>= (caddr instr) 0) (< (caddr instr) 10)) ) ) program) ) ) ; Execute the given 100-instruction CARDIAC machine language ; program with the given accumulator value and the given ; "program counter" (address of the next instruction to be ; executed). (define (execute-prog program pc accum) (if (> pc 99) (append '(*** ERROR Program counter) (list pc) '(out of range)) (let ((instr (abs (car (list-ref program pc))))) (display (append '(executing) (list-ref program pc) '(at location) (list pc) '(with accumulator) (list accum) )) (newline) ( _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ _____________________________________________ ))) ) (define (execute-input address program pc accum) (display '(INPUT VALUE)) (execute-prog (my-replace program address (unintegerize (remainder (read) 1000)) ) (+ pc 1) accum)) (define (execute-load address program pc accum) (execute-prog program (+ pc 1) (integerize (list-ref program address)) )) (define (execute-add address program pc accum) _____________________________________________ ) (define (execute-jump-if-neg address program pc accum) _____________________________________________ ) (define (execute-shift address program pc accum) _____________________________________________ ) (define (execute-output address program pc accum) (display (append '(PROGRAM OUTPUT at address) (list pc))) (display (integerize (list-ref program address))) (newline) (execute-prog program (+ pc 1) accum ) ) (define (execute-store address program pc accum) _____________________________________________ ) (define (execute-subtract address program pc accum) _____________________________________________ ) (define (execute-jump address program pc accum) _____________________________________________ ) (define (execute-halt address program pc accum) (display (append '(PROGRAM HALT at address) (list pc)) )) (define f-list (list execute-input execute-load execute-add execute-jump-if-neg execute-shift execute-output execute-store execute-subtract execute-jump execute-halt)) ; Return the result of padding the program to be n instructions, ; by adding the correct number of 000 instructions at the end. (define (padded program n) _____________________________________________ ) ; Return the integer equivalent of a list of three digits, possibly ; followed by a minus sign. (define (integerize L) (integerize-helper 0 L) ) (define (integerize-helper so-far L) (cond ((null? L) so-far) ((equal? L '(-)) (- so-far)) (else (integerize-helper (+ (* 10 so-far) (car L)) (cdr L))) ) ) ; Given an integer, return a list of its three digits, followed by ; a minus sign if the number is negative. (define (unintegerize k) (if (< k 0) (append (unint-helper (abs k)) '(-)) (unint-helper k) ) ) (define (unint-helper k) (list (truncate (/ k 100)) (remainder (truncate (/ k 10)) 10) (remainder k 10) ) ) ; Return the result of replacing the nth word of sent by x. (define (my-replace sent n x) _____________________________________________ )