summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2023-02-25 13:21:17 -0500
committerDavid Thompson <dthompson2@worcester.edu>2023-06-08 08:14:41 -0400
commit4461d61bb13fbc9ac2ea3a5ecc09c90434653ec3 (patch)
treed605d4b2f6e6d3de9c7028b49cf58e0938e80c12
parenta564307a9473a0a5d3b5413d14595aaead145cd4 (diff)
Implement n-ary comparison operators.
-rw-r--r--chickadee/graphics/seagull.scm44
1 files changed, 41 insertions, 3 deletions
diff --git a/chickadee/graphics/seagull.scm b/chickadee/graphics/seagull.scm
index 0df9b89..8a61367 100644
--- a/chickadee/graphics/seagull.scm
+++ b/chickadee/graphics/seagull.scm
@@ -41,7 +41,6 @@
;; - Loops
;; - User defined structs
;; - Better error messages (especially around type predicate failure)
-;; - n-ary comparison operators
;; - Overloaded functions with multiple arities
;; - Helper function modules
;; - Shader composition
@@ -753,20 +752,59 @@
#:type (-> (type:float) (type:int))
#:proc (compose inexact->exact floor))
+(define (make-comparison-expander name)
+ (lambda (args stage env)
+ (match args
+ (() #t)
+ ((x)
+ (expand `(let ((x* ,x)) (,name x* x*)) stage env))
+ ((x y)
+ `(primcall ,name ,(expand x stage env) ,(expand y stage env)))
+ ((x y . rest)
+ (expand `(let ((y* ,y))
+ (and (,name ,x y*)
+ ,(let loop ((rest rest)
+ (prev 'y*))
+ (match rest
+ ((z)
+ (list name prev z))
+ ((z . rest)
+ `(let ((z* ,z))
+ (and (,name ,prev z*)
+ ,(loop rest 'z*))))))))
+ stage env)))))
+
(define-syntax define-comparison-primitive
(syntax-rules ()
((_ name)
- (define-comparison-primitive name name))
+ (define-comparison-primitive name name
+ (make-comparison-expander 'name)))
((_ name glsl-name)
+ (define-comparison-primitive name glsl-name
+ (make-comparison-expander 'name)))
+ ((_ name glsl-name expand)
(define-seagull-primitive name
#:glsl-name 'glsl-name
#:type
(overload ((a type:int type:float))
(-> (a a) (type:bool)))
#:proc name
+ #:expand expand
#:emit (make-infix-emitter 'glsl-name)))))
-(define-comparison-primitive = ==)
+(define-comparison-primitive = ==
+ (lambda (args stage env)
+ (match args
+ (() #t)
+ ((x)
+ (expand `(let ((x* ,x)) (= x* x*)) stage env))
+ ((x y)
+ `(primcall = ,(expand x stage env) ,(expand y stage env)))
+ ((x . rest)
+ (expand `(let ((x* ,x))
+ (and ,@(map (lambda (y) `(= x* ,y)) rest)))
+ stage env)))))
+
(define-comparison-primitive <)
(define-comparison-primitive <=)
(define-comparison-primitive >)