skx / yal

Yet another lisp interpreter
GNU General Public License v2.0
16 stars 0 forks source link

82 struct #93

Closed skx closed 1 year ago

skx commented 1 year ago

This pull-request contains a "struct" implementation, which currently allows structures to be defined - as a list of fields, and objects created assuming all fields are present. One a struct has been created magical methods allow type-checking and field access/updates.

This will close #82, once complete.

Sample usage, which works with this pull-request:


;; define a structure
(struct person name address)
(struct cat    name age)

;; create an instance of a person
(set! self (person "Steve Kemp" "My home address, Helsinki, Finland"))

;; create an instance of a cat
(set! kitty (cat "Meow" (- 2022 2018 )))

;; show the type of our object, and the fields
(print "The person struct.type is %s" (type self))
(print "The person struct.address contains:%s" (get self "address"))
(print "The person struct.name contains:%s" (get self "name"))

;; Type-checking should "just work"
(if (person? self)
    (print "self is a person")
  (print "self is NOT a person - bug"))

(if (cat? self)
    (print "A person cannot be a cat - bug"))

(if (cat? kitty)
    (print "We have a cat, aged %d" (get kitty "age")))

(print (cat.name kitty))
(cat.name kitty (join (list "My " "New" " " "Name")))
(print (cat.name kitty))

Here you'll notice that the struct is actually a hash, and we're merely setting the named fields as key/val pairs.

This is pretty smart, all we've really done is recorded the fields a structure should contain, and hooked into our execution to instantiate a new hash when we see a named structure - before falling back to invoking a command instead.

The bit that's missing?

Adding accessors was a little tricky, but we store the name of the faux method in a map with the appropriate field as the value. This allows accesses to be found and updates to be made.

The biggest issue here is that we're doing extra checks on the "hot path", so the whole eval method is getting deeply complex and slower. I think that needs to be spun out into a different issue.