(define impc:ir:compiler:tuple-ref
(lambda (ast types)
;; arg 1 for tuples must be a symbol
;; arg 2 for typles must be a number
;; this should make it easy for us!
(let* ((os (make-string 0))
(index-str (impc:ir:compiler (caddr ast) types))
(idx (impc:ir:gname))
(var-str (impc:ir:compiler (cadr ast) types))
(var (impc:ir:gname))
;(atuple-type (impc:ir:get-type-from-str (cadr var)))
(tuple-type (or (impc:ti:get-namedtype-type (cadr var))
(impc:ir:get-type-from-str (cadr var))))
(ttype (impc:ir:get-type-str tuple-type))
(element-type (list-ref (cdr tuple-type) (caddr ast))))
;; type tests
(if (not (impc:ir:tuple? (impc:ir:get-type-from-str (cadr var))))
(impc:compiler:print-bad-type-error-with-ast (cadr var) "must be a tuple" ast))
(if (not (integer? (caddr ast)))
(impc:compiler:print-bad-type-error (caddr ast) "tref index must be an integer"))
(if (not (impc:ir:fixed-point? (impc:ir:get-type-from-str (cadr idx))))
(impc:compiler:print-bad-type-error-with-ast (cadr idx) "index must be an integer" ast))
;(emit index-str os)
(emit var-str os)
(emit "; tuple ref\n" os)
(define ttstr (impc:ir:get-type-str element-type))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; do a check for recursive type!
;; PROBABLY DON'T NEED THIS NOW WE HAVE NAMED TYPES?
;; (if (and (atom? element-type)
;; (< element-type -1))
;; (let* ((tuples-ptr-depth (floor (/ (car tuple-type) (* 1 *impc:ir:pointer*))))
;; (ptr-depth (- (floor (/ element-type (* -1 *impc:ir:pointer*))) tuples-ptr-depth))
;; (tt tuple-type))
;; (dotimes (i ptr-depth)
;; (set! tt (impc:ir:pointer++ tt)))
;; (set! ttstr (impc:ir:get-type-str tt))))
;; this code here to support basic type recursion (only depth \2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(if (> (impc:ir:get-ptr-depth tuple-type) 1)
(impc:compiler:print-bad-type-error tuple-type "trying to ref from a tuple pointer" ast)
(if (< (impc:ir:get-ptr-depth tuple-type) 1)
(emit (string-append (impc:ir:gname "val" ttstr) " = extractvalue "
(cadr var) " " (car var) ", " (car idx) "\n") os)
(begin (emit (string-append (impc:ir:gname "val" (string-append ttstr "*")) " = getelementptr "
(impc:ir:pointer-- (cadr var)) ", "
(cadr var) " " (car var) ", i64 0, i32 " (car idx) "\n") os)
(emit (string-append (impc:ir:gname "val" ttstr) " = load " ttstr ", " ttstr "* "
(car (impc:ir:gname 1)) "\n") os))))
(impc:ir:strip-space os))))