Announcements
Final Exam
Johnson Athletic Center (not what the Registrar said!), Wed.
May 21, 1:30pm to 4:30pm.
Compiling linkage
(define (compile-linkage linkage)
(cond ((eq? linkage 'return)
(make-instruction-sequence
'((goto (reg continue)))))
((eq? linkage 'next)
(empty-instruction-sequence))
(else
(make-instruction-sequence
`((goto (label ,linkage)))))))
Saving and Restoring Registers
(define (preserving regs seq1 seq2)
(if (null? regs)
(append-instruction-sequences seq1 seq2)
(let ((first-reg (car regs)))
(preserving (cdr regs)
(make-instruction-sequence
(append `((save ,first-reg))
(statements seq1)
`((restore ,first-reg))))
seq2))))
(define (end-with-linkage linkage instruction-sequence)
(preserving '(continue)
instruction-sequence
(compile-linkage linkage)))
Compiling Expressions, Part 1
(define (compile-self-evaluating exp target linkage)
(end-with-linkage linkage
(make-instruction-sequence
`((assign ,target (const ,exp))))))
(define (compile-application exp target linkage)
(let ((proc-code (compile (operator exp) 'proc 'next))
(operand-codes
(map (lambda (operand) (compile operand 'val 'next))
(operands exp))))
(preserving '(env continue)
proc-code
(preserving '(proc continue)
(construct-arglist operand-codes)
(compile-procedure-call target linkage)))))
Compiling Expressions, Part 2
(define (construct-arglist operand-codes)
(let ((operand-codes (reverse operand-codes)))
(if (null? operand-codes)
(make-instruction-sequence
'((assign argl (const ()))))
(let ((code-to-get-last-arg
(append-instruction-sequences
(car operand-codes)
(make-instruction-sequence
'((assign argl (op list) (reg val)))))))
(if (null? (cdr operand-codes))
code-to-get-last-arg
(preserving '(env)
code-to-get-last-arg
(code-to-get-rest-args
(cdr operand-codes))))))))
Compiling Expressions, Part 3
(define (code-to-get-rest-args operand-codes)
(let ((code-for-next-arg
(preserving '(argl)
(car operand-codes)
(make-instruction-sequence
'((assign argl
(op cons) (reg val) (reg argl)))))))
(if (null? (cdr operand-codes))
code-for-next-arg
(preserving '(env)
code-for-next-arg
(code-to-get-rest-args (cdr operand-codes))))))
"Clever" PRESERVING
(define (preserving regs seq1 seq2)
(if (null? regs)
(append-instruction-sequences seq1 seq2)
(let ((first-reg (car regs)))
(if (and (needs-register? seq2 first-reg) ; **
(modifies-register? seq1 first-reg)) ; **
(preserving (cdr regs)
(make-instruction-sequence
(list-union (list first-reg) ; ** needs
(registers-needed seq1)) ; **
(list-difference (registers-modified seq1) ; ** modifies
(list first-reg)) ; **
(append `((save ,first-reg))
(statements seq1)
`((restore ,first-reg))))
seq2)
(preserving (cdr regs) seq1 seq2)))))