Quoted Expressions
In this chapter we’ll implement a new type of Lisp Value called a Q-Expression.
This stands for quoted expression, and is a type of Lisp Expression that is not evaluated by the standard Lisp mechanics. When encountered by the evaluation function Q-expressions are left exactly as they are. This makes them ideal for a number of purposes. We can use them to store and manipulate other Lisp values such as numbers, symbols, or other S-Expressions themselves.
After we’ve added Q-Expressions we are going to implement a concise set of operators to manipulate them. Like the arithmetic operators these will prove fundamental in how we think about and play with expressions.
The syntax for Q-Expressions is very similar to that of S-Expressions. The only difference is that instead of parenthesis ()
Q-Expressions are surrounded by curly brackets {}
. We can add this to our grammar as follows.
I’ve never heard of Q-Expressions.
Q-Expressions don’t exist in other Lisps. Other Lisps use Macros to stop evaluation. These look like normal functions, but they do not evaluate their arguments. A special Macro called quote '
exists, which can be used to stop the evaluation of almost anything. This is the inspiration for Q-Expressions, which are unique to our Lisp, and will be used instead of Macros for doing all the same tasks and more.
The way I’ve used S-Expression and Q-Expression in this book is a slight abuse of terminology, but I hope this misdemeanor makes the behaviour of our Lisp clearer.
mpc_parser_t* Number = mpc_new("number");
mpc_parser_t* Symbol = mpc_new("symbol");
mpc_parser_t* Sexpr = mpc_new("sexpr");
mpc_parser_t* Qexpr = mpc_new("qexpr");
mpc_parser_t* Expr = mpc_new("expr");
mpc_parser_t* Lispy = mpc_new("lispy");
mpca_lang(MPCA_LANG_DEFAULT,
" \
number : /-?[0-9]+/ ; \
symbol : '+' | '-' | '*' | '/' ; \
sexpr : '(' <expr>* ')' ; \
qexpr : '{' <expr>* '}' ; \
expr : <number> | <symbol> | <sexpr> | <qexpr> ; \
lispy : /^/ <expr>* /$/ ; \
",
Number, Symbol, Sexpr, Qexpr, Expr, Lispy);
We also must remember to update our cleanup function to deal with the new rule we’ve added.
mpc_cleanup(6, Number, Symbol, Sexpr, Qexpr, Expr, Lispy);