We will define some additional syntax to facilitate entry of some common expressions. Recall that we already allow the user to enter
(A B C)instead of
(A . (B . (C . NIL)))
In order to include a literal symbol or list in an expression, we need
to use the QUOTE operator. As a shortcut, we will
define
'EXPRto be equivalent to
(QUOTE EXPR)
So for example the following forms are equivalent:
| Abbreviation | Canonical form | Evaluates to | 
|---|---|---|
| 'FOO | (QUOTE FOO) | FOO | 
| '(+ 1 2) | (QUOTE (+ 1 2)) | (+ 1 2) | 
| '(A . B) | (QUOTE (A . B)) | (A . B) | 
The lexer needs to know that the quote mark is a prefix (i.e., it can appear immediately before another token but is not necessarily a delimeter).
int lex(const char *str, const char **start, const char **end)
{
	const char *ws = " \t\n";
	const char *delim = "() \t\n";
	const char *prefix = "()\'";
	.
	.
	.
}
Also read_expr must convert it to the correct list
expresssion.
int read_expr(const char *input, const char **end, Atom *result)
{
	const char *token;
	Error err;
	err = lex(input, &token, end);
	if (err)
		return err;
	if (token[0] == '(') {
		return read_list(*end, end, result);
	} else if (token[0] == ')') {
		return Error_Syntax;
	} else if (token[0] == '\'') {
		*result = cons(make_sym("QUOTE"), cons(nil, nil));
		return read_expr(*end, end, &car(cdr(*result)));
	} else {
		return parse_simple(token, *end, result);
	}
}
> (define x '(a b c)) X > x (A B C) > 'x X > (define foo 'bar) FOO > foo BAR > ''() (QUOTE NIL)
It is cumbersome to have to type a lambda expression every time we wish
to define a function, so we will modify the DEFINE operator
to avoid this.
(DEFINE (name args...) body...)is equivalent to
(DEFINE name (LAMBDA (args...) body...))
Here's how:
int eval_expr(Atom expr, Atom env, Atom *result)
{
	.
	.
	.
	if (op.type == AtomType_Symbol) {
		if (strcmp(op.value.symbol, "QUOTE") == 0) {
		.
		.
		.
		} else if (strcmp(op.value.symbol, "DEFINE") == 0) {
			Atom sym, val;
			if (nilp(args) || nilp(cdr(args)))
				return Error_Args;
			sym = car(args);
			if (sym.type == AtomType_Pair) {
				err = make_closure(env, cdr(sym), cdr(args), &val);
				sym = car(sym);
				if (sym.type != AtomType_Symbol)
					return Error_Type;
			} else if (sym.type == AtomType_Symbol) {
				if (!nilp(cdr(cdr(args))))
					return Error_Args;
				err = eval_expr(car(cdr(args)), env, &val);
			} else {
				return Error_Type;
			}
			if (err)
				return err;
			*result = sym;
			return env_set(env, sym, val);
		} else if (strcmp(op.value.symbol, "LAMBDA") == 0) {
		.
		.
		.
		}
	}
	.
	.
	.
}
> (define (square x) (* x x)) SQUARE > (square 3) 9
Sweet!