sicp-ex-5.24



<< Previous exercise (5.23) | Index | Next exercise (5.25) >>


meteorgan

  
  
  
 ev-cond 
 (assign expr (op cond-clauses) (reg expr)) 
 (test (op null?) (reg expr))   
 (branch (label ev-cond-end)) 
 (assign unev (op car) (reg expr)) 
 (assign expr (op cdr) (reg expr)) 
 (test (op cond-else-clauses?) (reg unev)) 
 (branch (label cond-else)) 
 (save env) 
 (save continue) 
 (save unev) 
 (save expr) 
 (assign continue (label ev-cond-loop)) 
 (assign expr (op cond-predicate) (reg unev)) 
 (goto (label ev-dispatch)) 
  
 ev-cond-loop 
 (restore expr) 
 (test (op true?) (reg val)) 
 (branch (label cond-result)) 
 (restore unev) 
 (restore continue) 
 (restore env) 
 (goto (label ev-cond)) 
  
 ; this does not restore continue so it wont return to the caller. 
 ; it also leaves env on the stack which would accumulate with 
 ; each call to a cond. 
 cond-result 
 (restore unev) 
 (assign expr (op cond-actions) (reg unev)) 
 (assign expr (op sequence->exp) (reg expr)) 
 (goto (label ev-dispatch)) 
  
 cond-else 
 (assign unev (op cond-actions) (reg unev)) 
 (assign expr (op sequence->exp) (reg unev)) 
 (goto (label ev-dispatch)) 
  
 ev-cond-end    
 (goto (reg continue)) 
  

This is a shorter version.

  
      ev-cond 
        (save continue)                  ; save continue for ev-sequence 
        (assign unev (op cond-clauses) (reg exp)) 
      ev-cond-loop 
        (test (op null?) (reg unev))     ; no more clauses 
        (branch (label ev-cond-unspec))   
        (asssign exp (op cond-first-clause-predicate) (reg unev)) 
        (test (op cond-else-predicate?) (reg exp)) 
        (branch (label ev-cond-true)) 
        (save unev)                      ; save clauses 
        (save env)                       ; and env to evaluate each clause 
        (assign continue (label ev-cond-decide))  
        (goto (label eval-dispatch))     ; eval first-predicate 
      ev-cond-decide 
        (restore env)                    ; get the env 
        (restore unev)                   ; get the cluases 
        (test (op true?) (reg val))      ; if predicate evluates to true 
        (branch (label ev-cond-true))    ; goto ev-cond-true 
        (assign unev (op cond-rest-cluases) (reg unev)) 
        (goto (label ev-cond-loop)) 
      ev-cond-true                       ; we found a true cluase same as before 
        (assign unev (op cond-first-clause-actions) (reg unev))  
        (goto (label ev-sequence))       ; go to ev-sequence. 
 ; if there was no else, and no true clause 
 ; you could also leave val to be false here.  
 ; But in the implementations I tested 
 ; it was unspecified, or void. 
      ev-cond-unspec 
        (assign val (const 'unspecified)) ; assign val unspecified 
        (restore continue)               ; go directly to caller. 
        (goto (reg continue))