<< Previous exercise (5.20) | Index | Next exercise (5.22) >>
;; a. (define (not-pair? lst) (not (pair? lst))) (define count-leaves (make-machine `((car ,car) (cdr ,cdr) (null? ,null?) (not-pair? ,not-pair?) (+ ,+)) '( start (assign continue (label done)) (assign n (const 0)) count-loop (test (op null?) (reg lst)) (branch (label null)) (test (op not-pair?) (reg lst)) (branch (label not-pair)) (save continue) (assign continue (label after-car)) (save lst) (assign lst (op car) (reg lst)) (goto (label count-loop)) after-car (restore lst) (assign lst (op cdr) (reg lst)) (assign continue (label after-cdr)) (save val) (goto (label count-loop)) after-cdr (restore n) (restore continue) (assign val (op +) (reg val) (reg n)) (goto (reg continue)) null (assign val (const 0)) (goto (reg continue)) not-pair (assign val (const 1)) (goto (reg continue)) done))) ;; b. (define count-leaves (make-machine `((car ,car) (cdr ,cdr) (pair? ,pair?) (null? ,null?) (+ ,+)) '( start (assign val (const 0)) (assign continue (label done)) (save continue) (assign continue (label cdr-loop)) count-loop (test (op pair?) (reg lst)) (branch (label pair)) (test (op null?) (reg lst)) (branch (label null)) (assign val (op +) (reg val) (const 1)) (restore continue) (goto (reg continue)) cdr-loop (restore lst) (assign lst (op cdr) (reg lst)) (goto (label count-loop)) pair (save lst) (save continue) (assign lst (op car) (reg lst)) (goto (label count-loop)) null (restore continue) (goto (reg continue)) done)))
;;b) (define c-m (make-machine '() (list (list 'null? null?) (list 'pair? pair?) (list '+ +) (list 'car car) (list 'cdr cdr)) '(controller (assign n (const 0)) (assign continue (label iter-done)) iter (test (op null?) (reg tree)) (branch (label null-tree)) (test (op pair?) (reg tree)) (branch (label pair-tree)) (assign n (op +) (reg n) (const 1)) (goto (reg continue)) null-tree (goto (reg continue)) pair-tree (save continue) (save tree) (assign tree (op car) (reg tree)) (assign continue (label after-left-tree)) (goto (label iter)) after-left-tree (restore tree) (assign tree (op cdr) (reg tree)) (assign continue (label after-right-tree)) (goto (label iter)) after-right-tree (restore continue) (goto (reg continue)) iter-done)))
(define count-leaves-machine (make-machine '(continue counter aux tree) (list (list 'null? null?) (list 'integer? integer?) (list 'symbol? symbol?) (list '+ +) (list 'car car) (list 'cdr cdr)) '( (assign continue (label cl-done)) cl-loop (test (op null?) (reg tree)) (branch (label null-case)) (test (op integer?) (reg tree)) (branch (label atom-case)) (test (op symbol?) (reg tree)) (branch (label atom-case)) (save continue) (save tree) (assign continue (label after-cl-1)) (assign tree (op car) (reg tree)) (goto (label cl-loop)) after-cl-1 (restore tree) (assign tree (op cdr) (reg tree)) (save counter) (assign continue (label after-cl-2)) (goto (label cl-loop)) after-cl-2 (restore aux) (assign counter (op +) (reg counter) (reg aux)) (restore continue) (goto (reg continue)) null-case (assign counter (const 0)) (goto (reg continue)) atom-case (assign counter (const 1)) (goto (reg continue)) cl-done ))) (set-register-contents! count-leaves-machine 'tree '(1 (3 4) 5 (6 (7 3) 9))) (start count-leaves-machine) (printf "~a~%" (get-register-contents count-leaves-machine 'counter)) (define count-leaves-machine (make-machine '(n tree source-tree continue) (list (list 'null? null?) (list 'integer? integer?) (list 'symbol? symbol?) (list '+ +) (list 'car car) (list 'cdr cdr)) '( (assign continue (label cl-done)) (assign tree (reg source-tree)) (assign n (const 0)) cl-loop (test (op null?) (reg tree)) (branch (label null-case)) (test (op integer?) (reg tree)) (branch (label atom-case)) (test (op symbol?) (reg tree)) (branch (label atom-case)) (save continue) (save tree) (assign continue (label after-cl-1)) (assign tree (op cdr) (reg tree)) (goto (label cl-loop)) after-cl-1 (restore tree) (assign tree (op car) (reg tree)) (assign continue (label after-cl-2)) (goto (label cl-loop)) after-cl-2 (restore continue) (goto (reg continue)) null-case (goto (reg continue)) atom-case (assign n (op +) (reg n) (const 1)) (goto (reg continue)) cl-done ))) (set-register-contents! count-leaves-machine 'source-tree '(1 (3 4) 5 (6 (7 3) 9))) (start count-leaves-machine) (printf "~a~%" (get-register-contents count-leaves-machine 'n))
meteorgan