[Back]

5.2 一个寄存器机器模拟器

5.7

(define exp-machine
    (make-machine
        `(cnt b val)
        (list (list `* *) (list `= =) (list `- -))
        `((assign val (const 1))
            test-cnt
            (test (op =) (reg cnt) (const 0))
            (branch (label exp-done))
            (assign val (op *) (reg val) (reg b))
            (assign cnt (op -) (reg cnt) (const 1))
            (goto (label test-cnt))
            exp-done)))

5.8

由于extract的fold-right积累和assoc的fold-left查找,应该是第一个here被执行了,答案为3

只需在cons label之前assoc以下

5.9

(define (make-operation-exp expr machine labels operations) 
  (let ((op (lookup-prim (operation-exp-op expr) operations)) 
            (aprocs 
                 (map (lambda (e) 
                           (if (label-exp? e) 
                               (error "can't operate on label -- MAKE-OPERATION-EXP" e) 
                               (make-primitive-exp e machine labels))) 
                      (operation-exp-operands expr)))) 
   (lambda () 
           (apply op (map (lambda (p) (p)) aprocs))))) 

5.10

搁置

5.11

删除(assign n (reg val)) 的操作

 (define (allocate-stack name) 
         (if (assoc name stack-table) 
             (error "Multiply defined stacks: " name) 
             (set! stack-table 
                   (cons 
                     (list name 
                           (make-stack)) 
                     stack-table))) 
         'stack-allocated) 
  
 (for-each (lambda (reg-name)
                 ((machine 'allocate-stack) 
                  reg-name)) 
               register-names) 
  
 (the-ops 
    (list (list 'initialize-stack 
                (lambda () 
                       (for-each (lambda (stack) 
                                   (stack 'initialize)) 
                                 (map cadr stack-table)))))) 

5.12

搁置

5.13

(define (lookup-register name) 
      (let ((val (assoc name register-table))) 
       (if val 
           (cadr val) 
           (begin 
            (allocate-register name) 
            (lookup-register name))))) 

随用随定义,漂亮的思想

5.14

F(n) = 2(n - 1)

5.15

(define (excute)
    (let ((lists (get-contents pc)))
        (if (null? lists)
            `done
            (begin  
                ((instruction-execution-proc (car insts)))
                (set! counter (+ counter 1))
                (excute)))))
(define (print-cnt)
    (display "Execution Times : " counter)
    ((set! counter 0)))

5.16

(define (excute)
    (let ((lists (get-contents pc)))
        (if (null? lists)
            `done
            (begin  
                (if trace-on
                    (display (caar insts)))
                ((instruction-execution-proc (car insts)))
                (set! counter (+ counter 1))
                (excute)))))

5.17

(define (excute)
    (let ((lists (get-contents pc)))
        (if (null? lists)
            `done
            (begin  
                (if trace-on
                    (display current-label)
                    (display (caar insts)))
                ((instruction-execution-proc (car insts)))
                (set! counter (+ counter 1))
                (if (or (tagged-list? (instruction-text inst) 'goto) 
                          (and (tagged-list? (instruction-text inst) 'branch) 
                               (get-contents flag))) 
                      (set! current-label 
                            (label-exp-label (cadr (instruction-text))))) 
                (excute)))))

5.18

给寄存器的消息分发定义一个打印函数即可

5.19

使用一个表格保存断点

在excute的时候assoc断点表查看该不该停止

proceed就是调用excute,在这之前把这个断点设置为false

这个想法有一定的不完善度,因为它无法单步执行。