https://github.com/tmccombs/mexpr.git
git clone 'https://github.com/tmccombs/mexpr.git'
(ql:quickload :mexpr)
Macro for Common Lisp to allow infix syntax for mathematical expressions.
The mexpr package contains the infix
macro which converts infix expressions into Lisp S-Expressions.
The easiest way to install mexpr is with quicklisp.
(ql:quickload :mexpr)
The following are examples of how the infix
macro can be used:
CL-USER> (infix 3 + 4)
7
CL-USER> (infix [ 3 + 4 ] * 5)
35
CL-USER (infix 3 + 4 * 5)
23
CL-USER> (let ((x 0))
(infix [ 4 + (1+ x) ] / (sqrt 4)))
2.5
CL-USER> (infix 4 + 4 < 7 or 2 > 6 / 16)
T
CL-USER> (infix 5 = 6)
NIL
CL-USER> (infix 5 = 5)
T
CL-USER> (infix 2 expt 5)
32
You can use defop
to add new operators:
CL-USER> (defop union 10) ; use function name and precedence
CL-USER> (infix '(1 2) union '(2 3))
(2 1 3 4)
CL-USER> (defop ++ 100 append) ; use operator symbol, precedence, and defition symbol
CL-USER> (infix '(1 2) ++ '(3 4))
(1 2 3 4)
CL-USER> (defop p 110 (lambda (a b) (+ (* a a) (* b b)))) ; use lambda for definition
CL-USER> (infix 3 p 4)
25
You can use a reader macro to make it a little simpler:
CL-USER> (enable-infix-syntax) ; equivalent to (cl-syntax:use-syntax :mexpr)
CL-USER> #n(3 + 4 ** 2)
19
The mexpr
(or more verbose bytecurry.mexpr
) package contains two main macros.
The infix
macro parses it's arguments as an infix expression and produces the corresponding s-expression. Each argument
is evaluated as one of the following forms:
[
and ]
are used for grouping expressions. (Parentheses were already taken.)defop
macro. It represents a binary operation.The infix
macro can detect some syntax errors, in which case it will create a syntax-error
condition. The type of the
syntax error can be obtained with syntax-error-type
. Unfortunately, at the moment some invalid forms simply produce strange results, such as a transposition of a operator and operand.
The defop
macro can be used to define new operators. It takes two parameters, the first is the unquoted symbol of the
operator, the second is the desired precedence of the operator (see below for precedence table). The symbol
should correspond to a function or macro which can accept exactly two arguments (although it may have more optional arguments).
The function infix-reader
is macro dispatch function which is available to the user to use in
any reader macro he/she desires. The package also registers the “#n” dispatch with cl-syntax, so
you can enable syntax of the form #n(<expr>)
with (cl-syntax:use-syntax :mexpr)
. Alternatively,
enable-infix-syntax
is a wrapper around cl-syntax:use-syntax
.
Unlike prefix and postfix notations, infix notation uses operator precedence to determine the order of evaluation.
mexpr
uses a numeric precedence system, where the precedence of an operator is a positive integer. A higher number
corresponds to a higher precedence. The precedence of the default operators is given below:
| Operator | Precedence | Translation of a <op> b
|:———-:|———–:|:————————–
| ** | 110 | (expt a b)
| expt | 110 | (expt a b)
| * | 100 | (* a b)
| / | 100 | (/ a b)
| % | 100 | (mod a b)
| mod | 100 | (mod a b)
| rem | 100 | (rem a b)
| + | 90 | (+ a b)
| - | 90 | (- a b)
| ash | 80 | (ash a b)
| << | 80 | (ash a b)
| >> | 80 | (ash a (- b))
| < | 70 | (< a b)
| > | 70 | (> a b)
| ⇐ | 70 | (<= a b)
| >= | 70 | (>= a b)
| = | 60 | (= a b)
| /= | 60 | (/= a b)
| logand | 50 | (logand a b)
| & | 50 | (logand a b)
| logxor | 40 | (logxor a b)
| ^ | 40 | (logxor a b)
| logior | 30 | (logior a b)
| \|| 30 | (logior a b)
| and | 20 | (and a b)
| or | 10 | (or a b)