(lambda ()
(integrate/name-if-safe expression expression
environment operations
+ '(INTEGRATE INTEGRATE-SAFELY)
integration-success
integration-failure))))
(operations/lookup operations variable
(integration-failure))))))))
\f
(define (integrate/name-if-safe expr reference environment
- operations if-win if-fail)
+ operations safe-operations if-win if-fail)
(let ((variable (reference/variable reference)))
(if (or (variable/side-effected variable)
(not (block/safe? (variable/block variable))))
(if-fail)
(let ((finish
(lambda (value)
- (if (constant-value? value environment operations)
+ (if (safely-integrable-value? value environment operations
+ safe-operations)
(if-win
(reassign
expr
(with-new-scode (object/scode expr) object)
object))
-(define (constant-value? value environment operations)
+(define (safely-integrable-value? value environment operations safe-operations)
(let check ((value value) (top? #t))
(or (constant? value)
(and (reference? value)
(or (not top?)
- (let ((var (reference/variable value)))
- (and (not (variable/side-effected var))
- (block/safe? (variable/block var))
- (environment/lookup environment var
- (lambda (value*)
- (check value* #f))
- (lambda ()
- ;; unknown value
- (operations/lookup operations var
- (lambda (operation info)
- operation info
- #f)
+ (let ((variable (reference/variable value)))
+ (or (operations/lookup operations variable
+ (lambda (operation info)
+ info ;ignore
+ (memq operation safe-operations))
+ (lambda () #f))
+ (and (not (variable/side-effected variable))
+ (block/safe? (variable/block variable))
+ (environment/lookup environment variable
+ (lambda (value*)
+ (check value* #f))
(lambda ()
- ;; No operations
- #t)))
- (lambda ()
- ;; not found variable
- #t)))))))))
+ ;; unknown value
+ (operations/lookup operations variable
+ (lambda (operation info)
+ operation info
+ #f)
+ (lambda ()
+ ;; No operations
+ #t)))
+ (lambda ()
+ ;; not found variable
+ #t))))))))))
\f
(define (integrate/reference-operator expression operations environment
block operator operands)
(lambda ()
(integrate/name-if-safe expression operator
environment operations
+ '(EXPAND INTEGRATE INTEGRATE-OPERATOR
+ INTEGRATE-SAFELY)
integration-success
integration-failure))))
(operations/lookup operations variable
(define (integrate/compound-operator operator operands)
(define (scan-body body encloser)
(if (procedure? body)
- (procedure-with-body body (encloser (procedure/body body)))
+ (and (not (open-block? (procedure/body body)))
+ (procedure-with-body body (encloser (procedure/body body))))
(scan-operator body encloser)))
(define (scan-operator operator encloser)
(cond ((sequence? operator)
((combination? operator)
(let ((descend
(lambda (operator*)
- (scan-body (procedure/body operator*)
- (lambda (body*)
- (encloser
- (combination-with-operator
- operator
- (procedure-with-body operator* body*)))))))
+ (and (not (open-block? (procedure/body operator*)))
+ (scan-body
+ (procedure/body operator*)
+ (lambda (body*)
+ (encloser
+ (combination-with-operator
+ operator
+ (procedure-with-body operator* body*))))))))
(operator* (combination/operator operator)))
(cond ((procedure? operator*) (descend operator*))
((integrate/compound-operator
(cons (loop (car actions))
(cdr actions))))))
((and (combination? predicate)
- (procedure? (combination/operator predicate)))
+ (procedure? (combination/operator predicate))
+ (not
+ (open-block?
+ (procedure/body (combination/operator predicate)))))
(combination-with-operator
predicate
(procedure-with-body