sicp-ex-5.49



<< Previous exercise (5.48) | Index | Next exercise (5.50) >>


ypeels

  
 (load "ch5-regsim.scm") ; for (make-machine) and (assemble) 
 (load "ch5-compiler.scm") ; for (compile) 
 (load "ch5-eceval-support.scm") ; for syntax and utility procedures 
 (load "ch5-eceval-compiler.scm") ; for operation list, needed by assembler 
  
 ; return linkage makes compiled code return to print-result below 
 (define (compile-and-assemble expr) 
     (assemble 
         (statements (compile expr 'val 'return)) 
         ec-comp-exec)) 
  
 ; compiler expects same register set as eceval 
 (define ec-comp-exec-registers 
     '(expr env val proc argl continue unev)) 
      
 (define ec-comp-exec-operations  
     (append  
         eceval-operations ; from ch5-eceval-compiler.scm 
         (list (list 'compile-and-assemble compile-and-assemble))))     
      
      
      
 (define ec-comp-exec-controller-text '( 
  
 ; main loop same as eceval 
 read-compile-exec-print-loop 
     (perform (op initialize-stack))  
     (perform (op prompt-for-input) (const ";;; EC-Comp-Exec input:")) 
     (assign expr (op read)) 
     (assign env (op get-global-environment)) 
     (assign continue (label print-result))  
     (goto (label compile-and-execute)) ; ** label name changed 
 print-result 
     (perform (op print-stack-statistics)) 
     (perform (op announce-output) (const ";;; EC-Comp-Exec value:")) 
     (perform (op user-print) (reg val)) 
     (goto (label read-compile-exec-print-loop)) 
  
      
 ; the entirety of the new machine! as per the problem statement,  
 ; all complexity is deferred to "primitives" (compile) and (assemble) 
 compile-and-execute 
     (assign val (op compile-and-assemble) (reg expr)) 
     (goto (reg val)) 
      
 )) 
  
  
  
 (define ec-comp-exec (make-machine 
     ec-comp-exec-registers 
     ec-comp-exec-operations  
     ec-comp-exec-controller-text)) 
  
 (define (start-ec-comp-exec) 
     (set! the-global-environment (setup-environment)) 
     (ec-comp-exec 'start) 
 ) 
  
 (start-ec-comp-exec) 
  

codybartfast




Controller
==========

  (define rcep-controller
    '((assign env (op get-global-environment))
      read
      (perform (op prompt-for-input) (const ";;; RCEP-RM input:"))
      (assign val (op read))
      (assign val (op compile) (reg val))
      (assemble-val)
      (assign continue (label after-execute))
      (goto (reg val))
      after-execute
      (perform (op announce-output) (const ";;; RCEP-RM value:"))
      (perform (op user-print) (reg val))
      (goto (label read))))

Assemble-val is the same as in the previous exercise.


Operations
==========

  (define operations
    (append eceval-operations
            (list (list 'read read)
                  (list 'compile statements-with-return)
                  (list 'prompt-for-input prompt-for-input)
                  (list 'announce-output announce-output)
                  (list 'user-print user-print))

Statements-with-return is the same as in the previous exercise.


Running the Read-Compile-Execute-Print Loop
===========================================

  (start (make-machine operations rcep-controller))


Data-Path
=========

                                                                    ^
                                                                   / \
                                          ───────────────────   after-exc
                                           \ get-globl-env /     /     \
                                            ───────┬───────     ────┬────
                                                   │                │
                                                 1 x              6 x
                                                   │                │
                                                   v                v
                     ───────────────────     ┌───────────┐    ┌───────────┐
                      \     read      /      │    env    │    │ continue  │
                       ───────┬───────       └─────┬─────┘    └─────┬─────┘
                              │                    │                │
                              │                    │                │
                            3 x                    │                │
               ┌─────────┐    │    ┌─────────┐     │     ┌──────────┘
               v         │    v    │         v     v     v
───────────────────     ┌┴─────────┴┐     ───────────────────
 \    compile    /      │    val    │      \    execute    /
  ─────────────┬─       └─────┬──┬──┘       ─┬─────────────
               │         ^ ^  │  │ ^         │
               └─────x───┘ │  │  │ └───x─────┘
                     4     │  │  │     7
                         5 x  │  │
                           │  │  └─────────────────────┐
                           │  │                        │
                 ┌─────────┘  │                        │
                 │            v                        v
                 │   ───────────────────      ───────────────────
                 │    \   assemble    /        \  user-print   /
                 │     ───────┬───────          ───────┬───────
                 └────────────┘                      9 x


                              ^                        ^
                             / \                      / \
                            /;;;\                    /;;;\
                           /input\                  /outpt\
                          ────┬────                ────┬────
                              │                        │
                              v                        v
                     ───────────────────      ───────────────────
                      \prompt-for-inpt/        \announce-output/
                       ───────┬───────          ───────┬───────
                            2 x                      8 x


Controller Diagram
==================

    ┌─────────────────────────┐
  1 │ get-global-environment  │
    └────────────┬────────────┘
                 │
                 v
    ┌─────────────────────────┐
  2 │    prompt-for-input     │<───┐
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  3 │          read           │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  4 │         compile         │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  5 │        assemble         │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  6 │     assign-continue     │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  7 │         execute         │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  8 │     announce-output     │    │
    └────────────┬────────────┘    │
                 │                 │
                 v                 │
    ┌─────────────────────────┐    │
  9 │       user-print        │    │
    └────────────┬────────────┘    │
                 │                 │
                 └─────────────────┘


Demo
====

;;; RCEP-RM input:
(define (factorial n)
        (if (= n 1)
            1
            (* (factorial (- n 1)) n)))

;;; RCEP-RM value:
ok

;;; RCEP-RM input:
(factorial 5)

;;; RCEP-RM value:
120

;;; RCEP-RM input: