From: Mark Wooding Date: Wed, 21 Oct 2015 23:46:28 +0000 (+0100) Subject: src/method-aggregate.lisp: `and' and `or' combinations return decisive value. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/commitdiff_plain/ad303446f43c0029e989a8a3d17c4936965d2c43?ds=inline src/method-aggregate.lisp: `and' and `or' combinations return decisive value. 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. --- 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.