~subsetpark/fugue

f4490022a5ee7badef997b65e869ce9e1317cea2 — Zach Smith 5 months ago 4759dba
Eval default values and prototype allocations at runtime, not comptime
2 files changed, 21 insertions(+), 5 deletions(-)

M fugue.janet
M test/fugue.janet
M fugue.janet => fugue.janet +5 -5
@@ 73,10 73,10 @@
        (array/push (field-definitions :proto-allocated-fields) key-field))
      # Assemble values to be set directly on prototype
      (when-let [proto-value (attrs :allocate-value)]
        (put-in field-definitions [:proto-allocations key-field] (eval proto-value)))
        (put-in field-definitions [:proto-allocations key-field] proto-value))
      # Assemble mapping of fields to default values for instances
      (when-let [default-value (attrs :default)]
        (put-in field-definitions [:instance-defaults key-field] (eval default-value)))
        (put-in field-definitions [:instance-defaults key-field] default-value))
      # Assemble mapping of fields to getters (unless excluded)
      (when-let [getter-name (match attrs
                               {:getter getter} getter


@@ 88,7 88,7 @@
  "Generate the def form for a Prototype."
  [name parent fields defined-fields
   {:proto-allocated-fields proto-allocated-fields
    :proto-allocations proto-allocations
    :proto-allocations to-allocate
    :instance-defaults instance-defaults
    :getters getters}]
  ~(let [object (,bare-proto (,string ',name) ,defined-fields)


@@ 97,9 97,9 @@
        (,table/setproto
           (,table ;(,mapcat |[$0 object] ',proto-allocated-fields))
           (,get-in parent [:_meta :prototype-allocations])))
     (,put-in object [:_meta :instance-defaults] ',instance-defaults)
     (,put-in object [:_meta :instance-defaults] ,instance-defaults)
     (,put-in object [:_meta :getters] ',getters)
     (,merge-into object ',proto-allocations)
     (,merge-into object ,to-allocate)
     (,table/setproto object parent)))

(defn- init-form

M test/fugue.janet => test/fugue.janet +16 -0
@@ 330,6 330,22 @@
  (is (InTestParent? InTestChild))
  (is (InTestChild? (new-InTestChild))))

(deftest value-in-test
  (def some-particular-name "Wonkus")
  (def some-particular-table @{})
  (fugue/defproto ValueInTest nil name {:default some-particular-name})
  (fugue/defproto MutableValueInTest nil tab {:default some-particular-table})
  (is (= "Wonkus" ((new-ValueInTest) :name)))
  (is (= some-particular-table ((new-MutableValueInTest) :tab))))

(deftest allocation-in-test
  (def some-particular-name "Wonkus")
  (def some-particular-table @{})
  (fugue/defproto ValueInTest nil name {:allocate-value some-particular-name})
  (fugue/defproto MutableValueInTest nil tab {:allocate-value some-particular-table})
  (is (= "Wonkus" (ValueInTest :name)))
  (is (= some-particular-table (MutableValueInTest :tab))))

(deftest defgeneric-in-test
  (fugue/defgeneric in-test [x] (string x " ok"))
  (is (= "a ok" (in-test "a"))))