(define impc:ti:find-all-vars
(lambda (full-ast syms)
(letrec ((f (lambda (ast)
(cond ((pair? ast)
(cond ((and (symbol? (car ast)) ;; this for generics
(regex:match? (symbol->string (car ast)) "##") ;"\\$\\$\\$")
(impc:ti:genericfunc-exists? (string->symbol (car (regex:split (symbol->string (car ast)) "##")))
(length (cdr ast))))
;; (println 'generics ast (regex:split (symbol->string (car ast)) "(\\$\\$\\$)|(_poly_)"))
(let* ((gname (string->symbol (car (regex:split (symbol->string (car ast)) "(##)|(_poly_)"))))
(gnum (string->number (cadr (regex:split (symbol->string (car ast)) "(##)|(_poly_)"))))
(arity (length (cdr ast)))
(typestrs (cl:remove-duplicates
(impc:ir:get-pretty-closure-arg-strings
(symbol->string (car (impc:ti:genericfunc-types gname arity #f))))))
(types (map (lambda (x) (impc:ir:get-type-from-pretty-str x)) typestrs))
(newsyms (cl:remove-duplicates
(map (lambda (a b)
;(println 'finding: a ': b)
(if (or (impc:ir:type? b)
(not (impc:ir:tuple? b)))
#f
(if (regex:match? a "^[A-Za-z0-9_-]*{")
(string->symbol (string-append a "##" (number->string gnum)))
(if (regex:match? a ":")
(string->symbol (string-append a "##" (number->string gnum)))
(if (not (null? (impc:ir:pretty-print-type b)))
(string->symbol (string-append (impc:ir:get-base-type a)
":"
(impc:ir:pretty-print-type b)
"##" (number->string gnum)))
#f)))))
typestrs types)))
;; (ll (println 'new1: newsyms))
;; (lll (println 'tstrings: typestrs))
;; (llll (println 'types: types))
(gvars
(cl:remove-duplicates
(cl:remove-if-not (lambda (x)
(and (symbol? x) (regex:match? (symbol->string x) "^!")))
(flatten types))))
(newsyms_gvars (map (lambda (k)
(string->symbol (string-append (symbol->string k) "##" (number->string gnum))))
gvars)))
(set! syms (append syms (list (car ast)) (cl:remove #f (cl:remove-duplicates (append newsyms newsyms_gvars)))))
;; (println 'newsyms: syms)
(f (cdr ast))))
((and (symbol? (car ast)) ;; this for polys
(regex:match? (symbol->string (car ast)) "##") ;"\\$\\$\\$")
(impc:ti:get-polyfunc-candidate-types (car (regex:split (symbol->string (car ast)) "##")))) ;"\\$\\$\\$")))))
;(println 'poly!var (car ast))
(set! syms (append (list (car ast)) syms))
(f (cdr ast)))
((member (car ast) '(__make-closure __make-closure-s __make-closure-h __make-closure-z))
(if (not (null? (cl:intersection (cadddr ast) syms)))
(impc:compiler:print-shadow-var-error (car (cl:intersection (cadddr ast) syms)) 'as 'a 'shadow 'variable))
(set! syms (cl:remove-duplicates (append (caddr ast) (cadddr ast) syms)))
(f (car (cddddr ast))))
((member (car ast) '(__make-env __make-env-zone))
(set! syms
(append (map (lambda (p)
(if (member (car p) syms)
(impc:compiler:print-shadow-var-error (car p)))
(car p))
(caddr ast))
syms))
(for-each (lambda (p)
(f (cadr p)))
(caddr ast))
(f (cadddr ast)))
(else (f (car ast))
(f (cdr ast)))))
((atom? ast) '())))))
(f full-ast)
syms)))