Skip to content

Instantly share code, notes, and snippets.

@cbaggers
Last active August 29, 2015 14:15
Show Gist options
  • Save cbaggers/dec902b72818f52318d1 to your computer and use it in GitHub Desktop.
Save cbaggers/dec902b72818f52318d1 to your computer and use it in GitHub Desktop.
readmacro magic
;; Playing with reader macros over the weekend.
;; Example of reader and writer being mirroring each other beautifully
;;So we need a class for IP addresses
CL-USER> (defclass ip () ((address :initarg :address) (port :initarg :port)))
#<STANDARD-CLASS IP>
;; def-hashslash-reader is a macro I wrote to create reader macros.
;; In short this code:
CL-USER> (def-hashslash-reader (ip :space)
(destructuring-bind (adr &optional port) (split-sequence #\: this)
(make-instance 'ip :address adr :port port)))
;; will take this pattern:
#/ip/somestuff:someotherstuff
;;and rewrites it as
(make-instance 'ip :address somestuff :port someotherstuff)
;;So now the reader writes the code to make new instances of ip
CL-USER> #/ip/192.168.0.1:4005
#<IP 0x3445> ;;<- this is an object
;; Only bummer is the writer doesn't know about this so it doesnt feel
;; like a language primitive.
;; So we specialize print-method for the 'ip' class
CL-USER> (defmethod print-object ((object ip) stream)
(with-slots (address port) object
(format stream "#/ip/~a~@[:~a~]" address port)))
;; and then..
CL-USER> #/ip/192.168.0.1:4005
#/ip/192.168.0.1:4005
;; Bingo :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment