system. First define some error classes that you can signal when
Now you can implement
Now you can do something like this:
and you'll get dropped into the debugger with this message:
If you invoke the
Then, as a convenience, you can provide restart functions—functions that invoke the
Now you can use
Finally, you can define a macro to provide a nicer syntax for binding handlers for the two kinds of errors.
With this macro defined, you can write this:
|
Now to connect the FOO language to the processor interface, all you need is a function that takes an object and processes it, invoking the appropriate processor functions to generate HTML. For instance, when given a simple form like this:
(:p 'Foo')
this function might execute this sequence of calls on the processor:
(freshline processor)
(raw-string processor '<p' nil)
(raw-string processor '>' nil)
(raw-string processor 'Foo' nil)
(raw-string processor '</p>' nil)
(freshline processor)
For now you can define a simple function that just checks whether a form is, in fact, a legal FOO form and, if it is, hands it off to the function process-sexp-html
for processing. In the next chapter, you'll add some bells and whistles to this function to allow it to handle macros and special operators. But for now it looks like this:
(defun process (processor form)
(if (sexp-html-p form)
(process-sexp-html processor form)
(error 'Malformed FOO form: ~s' form)))
The function sexp-html-p
determines whether the given object is a legal FOO expression, either a self-evaluating form or a properly formatted cons.
(defun sexp-html-p (form)
(or (self-evaluating-p form) (cons-form-p form)))
Self-evaluating forms are easily handled: just convert to a string with PRINC-TO-