bind-type   macro


Defined in:  https://github.com/digego/extempore/tree/v0.8.9/runtime/llvmti.xtm

Implementation

;; bind-type expects: (symbol type [docstring])
(define-macro (bind-type . args)
  ;; (println 'bind-type args)
  (if (null? args)
      (impc:compiler:print-compiler-error "Bind type missing arguments! (symbol type [docstring])"))
  (let* ((symbol (car args))
         (type_1 (cadr args))
         (type (string->symbol
                (string-append "<"
                 (string-join
                  (map (lambda (x)
                         (if (impc:ti:typealias-exists? x)
                             (impc:ir:pretty-print-type (impc:ti:get-typealias-type x))
                             x))
                       (impc:ir:get-pretty-tuple-arg-strings (symbol->string type_1)))
                  ",")
                 ">")))
         (docstring (if (string? (car (reverse args))) (car (reverse args)) ""))
         (extras (cl:remove #f (map (lambda (x) (if (pair? x) x #f)) args)))
         (printer? (if (assoc-strcmp 'printer? extras)
                       (cdr (assoc-strcmp 'printer? extras))
                       #t))
         (copy? (if (assoc-strcmp 'copy? extras)
                       (cdr (assoc-strcmp 'copy? extras))
                       #t))
         (constructor? (if (assoc-strcmp 'constructor? extras)
                           (cdr (assoc-strcmp 'constructor? extras))
                           #t)))
    (if (not (char=? (string-ref (symbol->string type_1) (- (string-length (symbol->string type_1)) 1)) #\>))
        (impc:compiler:print-bad-type-error type_1 "is a malformed tuple type"))
    (if (impc:ti:bang-type? type) ;; send generic named types to aot
        (impc:aot:insert-generic-type `(bind-type ,@args)))
    (if (<> (impc:ir:get-ptr-depth type) 0)
        (impc:compiler:print-bad-type-error type "cannot be a pointer"))
    (if (not (char=? (string-ref (symbol->string type) 0) #\<))
        (impc:compiler:print-bad-type-error type "must be a tuple type"))
    `(begin
       (set! *impc:ir:get-type-callback-off* #t)
       (let* ((ags (impc:ir:get-pretty-tuple-arg-strings ,(symbol->string type)))
              ;; expand all non-explict generic types
              ;; i.e. expand list* into list:<!a,list*>*
              (expand-polys (map (lambda (k)
                                   (if (and (impc:ti:get-generictype-candidate-types (impc:ir:get-base-type k))
                                            (not (equal? (impc:ir:get-base-type k) ,(symbol->string symbol)))) ;; for recursive case!
                                       (impc:ir:pointer++
                                        (string-append (impc:ir:get-base-type k) ":"
                                                       (symbol->string (impc:ti:get-generictype-candidate-types (impc:ir:get-base-type k))))
                                        (impc:ir:get-ptr-depth k))
                                       k))
                                 ags))
              (newtype (string-append "<" (string-join expand-polys ",") ">")))
         ;; (println 'authors_type: ,(symbol->string type))
         ;; (println 'transformed_type: newtype)
         ;; and on with the show!
         (if (impc:ti:bang-type? newtype) ;; then must be poly type
             (begin
               (impc:ti:register-new-generictype ',symbol (string->symbol newtype))
               (impc:compiler:print-binding-details-to-log "GenrType:" ',symbol ',type))
             (let ((typelist (cons *impc:ir:tuple* (impc:ir:get-type-from-pretty-tuple ,(symbol->string type)
                                                                                       ,(symbol->string symbol)))))
               (if (llvm:compile-ir (string-append "%" ,(symbol->string symbol) " = type "
                                                   (impc:ir:get-type-str typelist)))
                   (begin (impc:ti:register-new-namedtype ,(symbol->string symbol) typelist ,docstring)
                          (impc:compiler:print-binding-details-to-log "DataType:" ',symbol ',type))
                   (impc:compiler:print-compiler-error "could not compile IR for type" ',type)))))
       ;; the next line is to help specialize any element types that may not already be specialized!
       (map (lambda (a) (impc:ir:get-type-from-pretty-str a (symbol->string ',(car args)))) (impc:ir:get-pretty-tuple-arg-strings ,(symbol->string type)))
       (set! *impc:ir:get-type-callback-off* #f)
       ;; (sys:wait (now))
       ;; now compile data constructor
       (impc:ti:compile-type-dataconstructors
        ',symbol
        (if (impc:ti:get-generictype-candidate-types ',symbol)
            (symbol->string (impc:ti:get-generictype-candidate-types ',symbol))
            (impc:ir:pretty-print-type (impc:ti:get-namedtype-type ,(symbol->string symbol))))
        (if (impc:ti:get-generictype-candidate-types ',symbol) #t #f)
        ,printer?
        ,copy?
        ,constructor?))))


Back to Index