From ad303446f43c0029e989a8a3d17c4936965d2c43 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Thu, 22 Oct 2015 00:46:28 +0100 Subject: [PATCH] src/method-aggregate.lisp: `and' and `or' combinations return decisive value. Organization: Straylight/Edgeware From: Mark Wooding Rather than canonifying to an integer result, effective methods with `and' and `or' method combination now return the decisive value -- which means that they can be used with any scalar return type (so the type restriction has been removed). Most significantly, the `or' combination is very useful with pointer returns: it returns the result of the most specific direct method which returns a non-null value. --- src/method-aggregate.lisp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/method-aggregate.lisp b/src/method-aggregate.lisp index 9446820..c8791af 100644 --- a/src/method-aggregate.lisp +++ b/src/method-aggregate.lisp @@ -390,32 +390,26 @@ (define-aggregating-method-combination :max ((acc val) :codegen codegen) (emit-inst codegen (make-if-inst (format nil "~A < ~A" acc val) (make-set-inst acc val) nil)))) -(define-aggregating-method-combination :and ((ret val) :codegen codegen) - :return-type int +(define-aggregating-method-combination :and ((ret) :codegen codegen) :around (lambda (body) (codegen-push codegen) - (deliver-expr codegen ret 0) (funcall body) - (deliver-expr codegen ret 1) (emit-inst codegen (make-do-while-inst (codegen-pop-block codegen) 0))) :methods (lambda (invoke) - (funcall invoke val) - (emit-inst codegen (make-if-inst (format nil "!~A" val) + (funcall invoke ret) + (emit-inst codegen (make-if-inst (format nil "!~A" ret) (make-break-inst) nil)))) -(define-aggregating-method-combination :or ((ret val) :codegen codegen) - :return-type int +(define-aggregating-method-combination :or ((ret) :codegen codegen) :around (lambda (body) (codegen-push codegen) - (deliver-expr codegen ret 1) (funcall body) - (deliver-expr codegen ret 0) (emit-inst codegen (make-do-while-inst (codegen-pop-block codegen) 0))) :methods (lambda (invoke) - (funcall invoke val) - (emit-inst codegen (make-if-inst val (make-break-inst) nil)))) + (funcall invoke ret) + (emit-inst codegen (make-if-inst ret (make-break-inst) nil)))) ;;;-------------------------------------------------------------------------- ;;; A customizable aggregating method combination. -- [mdw]