(define impc:ti:math-intrinsic-check
(lambda (ast vars kts request?)
(if (equal? request? *impc:ir:notype*) (set! request? #f))
(if (equal? request? (list *impc:ir:notype*)) (set! request? #f))
;; (println 'intrinsic: ast 'r: request?)
(let* ((args (- (length ast) 1))
(a (impc:ti:type-unify (impc:ti:type-check (cadr ast) vars kts request?) vars))
(b (if (> args 1)
(impc:ti:type-unify (impc:ti:type-check (caddr ast) vars kts request?) vars)
#f))
(c (if (> args 2)
(impc:ti:type-unify (impc:ti:type-check (cadddr ast) vars kts request?) vars)
#f)))
(if (null? a) (set! a b))
(if (null? b) (set! b a))
;; (println 'a a 'b b 'c c 'r: request? 'ast ast)
;; if (cadr ast) is a symbol update it
(if (and (symbol? (cadr ast))
(impc:ir:type? a))
(impc:ti:update-var (cadr ast) vars kts a))
(if (and (not (list? a))
(impc:ir:fixed-point? a))
(impc:compiler:print-bad-type-error (impc:ir:pretty-print-type a)
(string-append "Only real numbers are supported for math intrinsics: "
(symbol->string (car ast)))))
(if (and (impc:ir:type? a)
(impc:ir:vector? a)
(impc:ir:pointer? a))
(impc:compiler:print-bad-type-error (impc:ir:pretty-print-type a)
(string-append "\nVector math intrinsics do not support pointers\nTry dereferencing your vector: " (sexpr->string ast))))
(if (and (impc:ir:type? a)
(impc:ir:vector? a))
(if (or (and (= (caddr a) 1)
(not (member (cadr a) '(4 8))))
(and (= (caddr a) 0)
(not (member (cadr a) '(2 4)))))
(impc:compiler:print-bad-type-error (impc:ir:pretty-print-type a)
(string-append "\nVector size not supported by math intrinsics\nFor floats try 4 or 8 - for doubles try 2 or 4\n" (sexpr->string ast)))))
(if (and b
(not (equal? a b))
(not (number? (cadr ast)))
(not (number? (caddr ast))))
(impc:compiler:print-type-conflict-error (impc:ir:pretty-print-type a)
(impc:ir:pretty-print-type b)
ast)
(if (and b
(not (equal? a b))
(number? (cadr ast)))
(list b)
(list a))))))