(load "util.scm") (display "\nex-5.31 - save-and-restore-for-apply\n") ; 1. save and restore env around operator ; 2. save and restore env around each operand (except last) ; 3. save and restore argl around each operand ; 4. save and restore proc around operand sequence ; (f 'x 'y) ; 1-4 are superfluous ; ((f) 'x 'y) ; 1-4 are superfluous ; no need to save env because compound-apply without args does ; not change env ; (f (g 'x) y) ; 1 is superfluous ; we need 2 because (g 'x) changes the env for y ; we need 3 because (g 'x) changes argl ; we need 4 because (g 'x) changes proc ; (f (g 'x) 'y) ; 1 is superfluous ; 1-2 are superfluous ; (g 'x) changes the env but we don't need it later (better save it anyway) ; 3-4 are still needed (display "[answered]\n") (display "\nex-5.32 - optimize-eceval-application\n") '( ev-application (save continue) (assign unev (op operands) (reg exp)) (assign exp (op operator) (reg exp)) (assign continue (label ev-appl-did-operator-no-restore)) (test (op variable?) (reg exp)) (branch (label ev-variable)) (save env) (save unev) (assign continue (label ev-appl-did-operator)) (goto (label eval-dispatch)) ev-appl-did-operator (restore unev) (restore env) ev-appl-did-operator-no-restore (assign argl (op empty-arglist)) (assign proc (reg val)) (test (op no-operands?) (reg unev)) (branch (label apply-dispatch)) (save proc) ) (display "[ok]\n") ; b. Applying all the optimizations make sense, but the compiled code will ; still run faster because the interpreter has to analyze the code every time ; it executes and the analysis itself adds overhead that the compiler can do ; before runtime (display "[answered]\n") (display "\nex-5.33\n") (display "CONTINUE at 5.5.3\n") (display "\nex-5.34\n") ;(display "\nex-5.35\n")