bind-object   macro


Defined in:  https://github.com/digego/extempore/tree/v0.8.9/libs/core/xobject.xtm

Implementation

(define-macro (bind-object name . slots)
  (if (= 0 (xobj_class_exists (symbol->string name)))
      (let* ((obj_type (string-append "xobj_" (symbol->string name) "_t"))
             (obj_name (string-append "xobj_" (symbol->string name)))
             (slots_ (map (lambda (s) (regex:split (symbol->string s) ":")) slots))
             (slots (append (list (list "_xobj_name" "i8*"))
                            (list (list "_xobj_parent" "xobject_t*"))
                            (list (list "_methods" "xlist_t*~<i8*,i8*>*~"))
                            slots_))
             (bindtype (list 'bind-type (string->symbol obj_type)
                             (string->symbol
                              (string-append "<" (cadr (car slots))
                                             (apply string-append
                                                    (map (lambda (k) (string-append "," (cadr k)))
                                                         (cdr slots)))
                                             ">"))))
             (constructor1 (list 'bind-func (string->symbol
                                             (string-append obj_name
                                                            "_1:[" obj_type "*]*"))
                                 `(lambda () (let ((obj (halloc)))
                                          (tset! obj 0 ,(symbol->string name))
                                          obj))))
             (constructor1poly (list 'bind-poly 'xobj_build (string->symbol (string-append obj_name "_1"))))
             (constructor2 (list 'bind-func (string->symbol
                                             (string-append obj_name
                                                            "_2:[" obj_type "*"
                                                            (apply string-append (map (lambda (kk) (string-append "," (cadr kk))) slots_))
                                                            "]*"))
                                 `(lambda ,(map (lambda (s) (string->symbol (car s))) slots_)
                                    (let ((obj (halloc)))
                                      ,(cons 'begin
                                             (cons (list 'tset! 'obj 0 (symbol->string name))
                                                   (map (lambda (s j) (list 'tset! 'obj (+ j 3) (string->symbol (car s))))
                                                        slots_
                                                        (make-list-with-proc (length slots_) (lambda (i) i)))))
                                      obj))))
             (constructor2poly (list 'bind-poly 'xobj_build (string->symbol (string-append obj_name "_2"))))
             (destructor (list 'bind-func (string->symbol
                                           (string-append obj_name "_destroy:[void," obj_type "*]*"))
                               `(lambda (obj) (free obj))))
             (destructorpoly (list 'bind-poly 'xobj_destroy (string->symbol (string-append obj_name "_destroy"))))
             (getters (map (lambda (s idx)
                             (list 'bind-func (string->symbol
                                               (string-append obj_name "_get_" (car s) ":["
                                                              (cadr s) "," obj_type "*]*"))
                                   `(lambda (obj)
                                      (tref obj ,idx))))
                           slots
                           (make-list-with-proc (length slots) (lambda (i) i))))
             (getterpolys (map (lambda (s) (list 'bind-poly
                                            (string->symbol (string-append "xobj_get_" (car s)))
                                            (string->symbol (string-append obj_name "_get_" (car s)))))
                               slots))
             (setters (map (lambda (s idx)
                             (list 'bind-func (string->symbol
                                               (string-append obj_name "_set_" (car s) ":"
                                                              "[void," obj_type "*," (cadr s) "]*"))
                                   `(lambda (obj val)
                                      (tset! obj ,idx val)
                                      void)))
                           slots
                           (make-list-with-proc (length slots) (lambda (i) i))))
             (setterpolys (map (lambda (s) (list 'bind-poly
                                            (string->symbol (string-append "xobj_set_" (car s)))
                                            (string->symbol (string-append obj_name "_set_" (car s)))))
                               slots)))
        (eval bindtype (interaction-environment))
        (eval constructor1 (interaction-environment))
        ;;(println constructor1)
        (eval constructor1poly (interaction-environment))
        (eval constructor2 (interaction-environment))
        ;;(println constructor2)
        (eval constructor2poly (interaction-environment))
        (eval destructor (interaction-environment))
        (eval destructorpoly (interaction-environment))
        (for-each (lambda (e) (eval e (interaction-environment))) getters)
        ;;(println getters)
        (for-each (lambda (e) (eval e (interaction-environment))) getterpolys)
        (for-each (lambda (e) (eval e (interaction-environment))) setters)
        (for-each (lambda (e) (eval e (interaction-environment))) setterpolys)
        ;; (println 'test: (list 'xobj_add_class (symbol->string name)))
        (eval (list 'xobj_add_class (symbol->string name)) (interaction-environment))
        1)))


Back to Index