Lisp mode

The syntax in Lisp mode is generally what you would expect from a Lisp language, though it's not nearly as complex as Common Lisp.

Both round and square parens can be used with the same semantic (reading a list). The reader is case-sensitive (better said, it doesn't upper-case symbol names, like Common Lisp does by default).

The start/end token characters are special in Lisp mode too (the brackets { and } but may be modified with the .SYNTAX directive). Note that the brackets are only special when a new Lisp token starts. For example in a string, or in a Lisp comment, the brackets are read literally:

{(define foo "check {this} out")}
{foo} <!-- outputs: check {this} out -->

When the open bracket is encountered, the raw parser is entered recursively and its result is put in the place of the current Lisp token as a “strcat” expression. Therefore you can say for example:

{(define (headline text)
   {<h1>{text}</h1>})}

{(headline "Foo bar")}
; or
{(headline {Foo bar})}

Literals

Strings, numbers, keywords and other literal values are parsed into their Common Lisp representation and can be shared with the host Lisp system. Particularly, the Sytes parser supports literal regexps (they are parsed into a scanner as returned by ppcre:create-scanner) using the #/.../ syntax:

{[define rx #/foo|bar/i]}
{(regexp-replace rx "1bAR2foo3" "x")}
;; ==>  "1x2x3"

A symbol whose name starts with a colon will be interned into the CL “KEYWORD” package, making it possible to call Common Lisp functions which expect keyword arguments:

{(member 5 '(1 2 3 4 5 6 7) :test <)}  ==>  (6 7)

Except as the first character of a symbol, the colon is otherwise not special. We have no notion of packages like Common Lisp does, so foo:bar is simply an ordinary symbol named “foo:bar”.

The “dot notation”

The dot notation is ubiquitous these days for accessing properties of an object, or values of a hash table, etc. Therefore I decided to bite the bullet and implement it in the parser, sacrificing the nice fact in Lisp that the dot character could be a part of symbol names.

Therefore when the parser encounters the the dot in symbols, it will actually return an expression which fetches the named property from the object. For example parsing {foo.bar.baz} returns:

(strcat (&dot-lookup foo (quote bar) (quote baz)))

&dot-lookup is an internal function (it is not meant to be called manually, hence the funny name) which receives a “bag” object (in the above case, “foo”) and one or more properties that it needs to dig in that object. The “bag” could be an association list, a hash table or a context object, in which case it will dig through the global variables defined in that context.

Welcome! (login)
Fork me on Github