SubX - Common Lisp Sub-eXpressions







SubX Summary

Common Lisp extension that facilitates the use of infix notation for unary and binary operators. Includes arithmetic, logic, binary functions, assignment, sequencing. Allows the incorporation of s-expressions in an infix expression and vice versa.


ispbuilder-lexer => sublexer
lispbuilder-yacc, sublexer => subx

Download lispbuilder-yacc and lispbuilder-lexer here



The initial intent was to create a lisp extension that allows to easily write arithmetic expressions that can be understood by someone unfamiliar with lisp. Because function evaluation is a strongly desired feature in an expression, s-expressions are permitted in the context of an infix expression. Binary functions can also be used as operators with highest precedence. Variable scopes are implicitly set to the local infix expression if the variables don't exist otherwise the external context of the variables is used. Local scope can be forced by the local statement. Sequencing is done by the ',' operator.
The extension is created using Common Lisp read-time macros and standard macros. The '[' ']' characters are used as delimiters for the infix expression. The available operators are: + - * / = == >= <= > < += *= && || or any binary function.

Example 1:
[ x = 11, y = x mod 2, "x is " ++ (if [y == 0] "even" "odd") ]
Returns: "x is odd"

Here ++ is:
(defmethod ++((a list) (b list))
(concatenate 'list a b))
(defmethod ++((a string) (b string))
(concatenate 'string a b))

Obviously operators can be redefined because all of them are translated to function calls:
(defmacro __(x y)
`(range ,x ,y))
(defmacro ==(x y)
`(= ,x ,y))
(defmacro +=(x incval)
`(incf ,x ,incval))
(defmacro *=(x mulval)
`(setf ,x (* ,x ,mulval)))

[ h = (make-hash-table), 'a gethash h = "a", 'a gethash h]
Returns: “a”

(defparameter x 1)
[ local (x) ( x = 2) ]
Returns: 1

(mapcar (lambda (x) [x + 1]) [1 __ 5])
Returns: (2 3 4 5 6)


Because lisp atoms can contain -/+* and these are frequently used in global vars : *global*, function names : make-hash-table subx requires spacing between each atom. This is not strictly required but there will be some inconsistencies if it is not supplied.
So just to be sure to separate everything with spaces (except the parens).

Future extensions

Subx - Infix Expression Macro