Each example defines an Eclector client that in some way extends the behaviour of the standard Common Lisp reader. Since the clients are accessed through the readtable, all examples require that the client is “enabled” at the beginning of a lisp file (i.e. change to the readtable that provides access to client).
This is a general client that can replace symbols in a file-local fashion with something else whenever a symbol satisfies a test. Kind of like a symbol macro for a set of symbols that applies to the entire file.
For instance, symbols ending with a “^” could expand into a call to
GETHASH
, like so:
(incf foo^) => (incf (gethash 'foo *my-counters* 0))
This client defines a reader that is able to understand SBCL’s extended package prefix syntax, i.e.:
'FOO::(BAR QUUX ZOT) == '(FOO::BAR FOO::QUUX FOO::ZOT)
Package locks will still work, so CL::(A B C)
will signal an error on
implementations that lock the CL package.
See extended-package-prefix-syntax-test.lisp for a demonstration.
http://www.sbcl.org/manual/index.html#Extended-Package-Prefix-Syntax
This reader is initialized with mapping from nicknames to packages and will simply replace symbols having one of the nicknames as package designator with the corresponding real package name.
Example:
(eclector-access:enable
(make-instance 'package-nicknames:reader
:nicknames '("E" "ECLECTOR-ACCESS"
"P" "PACKAGE-NICKNAMES"
"C" "CL")))
(print 'e:client)
(print 'p:reader)
(print (c:list 1 2))
This example defines a bare-bones reader that mimics the hierarchical packages mechanism as implemented by Allegro CL.
(defpackage #:foo (:use #:cl))
(defpackage #:foo.bar (:use #:cl))
(in-package #:foo)
(print '.bar::a)
; => FOO.BAR::A
See hierarchical-packages-test.lisp for a demonstration.
https://franz.com/support/documentation/current/doc/packages.htm#resolving-relative-2
This reader will recognize symbol patterns like FOO.A
or FOO/ID
and replace them with calls to (SLOT-VALUE FOO 'A)
or (ID FOO)
respectively. This provides an always-on alternative to WITH-SLOTS
and
WITH-ACCESSORS
.
Example:
(eclector-access:enable
(make-instance 'slots-and-accessors:reader
:accessor-separator #\/
:slot-separator #\.))
(print '(setf foo/c (+ foo.a foo.b)))
; => (SETF (C FOO) (+ (SLOT-VALUE FOO 'A) (SLOT-VALUE FOO 'B)))
See slots-and-accessors-test.lisp for a demonstration.
This example defines a reader that recognizes capitalized symbols
and translates them into MAKE-INSTANCE
forms.
Example:
(Foo :a 1 :b 2)
becomes
(MAKE-INSTANCE 'FOO :A 1 :B 2).
This reader could make code that uses many different classes and
that relies heavily on MAKE-INSTANCE
a bit easier to write, and
possibly to read.
See instance-creation-test.lisp for a demonstration.
This reader understands (when-packages PACKAGES &body BODY) forms,
whose BODY
may contain symbols that reference packages that do not
exist. The body of a WHEN-PACKAGES
form will be evaluated if
PACKAGES
exist when the form is read. The body of a
WHEN-PACKAGES-DYNAMIC
form will be evaluated if PACKAGES
exist at
runtime.
Example:
(when-packages (:when-packages-test.foo)
(print 'when-packages-test.foo::a))
See when-packages-test.lisp for a demonstration.
This example defines a (pretty adventurous) reader that recognizes
“keyword messages” similar to those found in Smalltalk. In a message
form, the first element is the recipient of the message and the rest
is any number of alternating keywords and arguments. The keywords are
of the form foo:
(which would normally be illegal in Common Lisp).
This is, of course, purely an exercise in syntax. No other aspects of
Smalltalk message passing are implemented.
An example message looks like this:
(1 to: 5 do: #'print)
and by default, it is simply translated into:
(TO=DO= 1 5 #'PRINT)
If a message consists solely of keywords, then it is interpreted as a unary message chain. For example:
(1.5 floor: 1+: prin1-to-string:)
becomes:
(PRIN1-TO-STRING (1+ (FLOOR 1.5)))
A recipient can itself be a message form. This means that the following is also valid:
((1 to: 5) third: 1+:)
this becomes:
(1+ (THIRD (TO= 1 5)))
See keyword-messages-test.lisp for a demonstration.