Peter Siebel - Practical Common Lisp
Здесь есть возможность читать онлайн «Peter Siebel - Practical Common Lisp» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2005, ISBN: 2005, Издательство: Apress, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.
- Название:Practical Common Lisp
- Автор:
- Издательство:Apress
- Жанр:
- Год:2005
- ISBN:1-59059-239-5
- Рейтинг книги:4 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 80
- 1
- 2
- 3
- 4
- 5
Practical Common Lisp: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Practical Common Lisp»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Practical Common Lisp — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Practical Common Lisp», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
(defun emit-open-tag (processor tag body-p attributes)
(when (or (paragraph-element-p tag) (block-element-p tag))
(freshline processor))
(raw-string processor (format nil "<~(~a~)" tag))
(emit-attributes processor attributes)
(raw-string processor (if (and *xhtml* (not body-p)) "/>" ">")))
In emit-attributes
the attribute names aren't evaluated since they must be keyword symbols, but you should invoke the top-level process
function to evaluate the attribute values, binding *escapes*
to *attribute-escapes*
. As a convenience for specifying boolean attributes, whose value should be the name of the attribute, if the value is T
—not just any true value but actually T
—then you replace the value with the name of the attribute. [317] While XHTML requires boolean attributes to be notated with their name as the value to indicate a true value, in HTML it's also legal to simply include the name of the attribute with no value, for example,
(defun emit-attributes (processor attributes)
(loop for (k v) on attributes by #'cddr do
(raw-string processor (format nil " ~(~a~)='" k))
(let ((*escapes* *attribute-escapes*))
(process processor (if (eql v t) (string-downcase k) v)))
(raw-string processor "'")))
Emitting the element's body is similar to emitting the attribute values: you can loop through the body calling
process
to evaluate each form. The rest of the code is dedicated to emitting fresh lines and adjusting the indentation as appropriate for the type of element.
(defun emit-element-body (processor tag body)
(when (block-element-p tag)
(freshline processor)
(indent processor))
(when (preserve-whitespace-p tag) (toggle-indenting processor))
(dolist (item body) (process processor item))
(when (preserve-whitespace-p tag) (toggle-indenting processor))
(when (block-element-p tag)
(unindent processor)
(freshline processor)))
Finally,
emit-close-tag
, as you'd probably expect, emits the closing tag (unless no closing tag is necessary, such as when the body is empty and you're either emitting XHTML or the element is one of the special empty elements). Regardless of whether you actually emit a close tag, you need to emit a final fresh line for block and paragraph elements.
(defun emit-close-tag (processor tag body-p)
(unless (and (or *xhtml* (empty-element-p tag)) (not body-p))
(raw-string processor (format nil "</~(~a~)>" tag)))
(when (or (paragraph-element-p tag) (block-element-p tag))
(freshline processor)))
The function
process
is the basic FOO interpreter. To make it a bit easier to use, you can define a function, emit-html
, that invokes process
, passing it an html-pretty-printer
and a form to evaluate. You can define and use a helper function, get-pretty-printer
, to get the pretty printer, which returns the current value of *html-pretty-printer*
if it's bound; otherwise, it makes a new instance of html-pretty-printer
with *html-output*
as its output stream.
(defun emit-html (sexp) (process (get-pretty-printer) sexp))
(defun get-pretty-printer ()
(or *html-pretty-printer*
(make-instance
'html-pretty-printer
:printer (make-instance 'indenting-printer :out *html-output*))))
With this function, you can emit HTML to
*html-output*
. Rather than expose the variable *html-output*
as part of FOO's public API, you should define a macro, with-html-output
, that takes care of binding the stream for you. It also lets you specify whether you want pretty HTML output, defaulting to the value of the variable *pretty*
.
(defmacro with-html-output ((stream &key (pretty *pretty*)) &body body)
`(let* ((*html-output* ,stream)
(*pretty* ,pretty))
,@body))
So, if you wanted to use
emit-html
to generate HTML to a file, you could write the following:
(with-open-file (out "foo.html" :direction output)
(with-html-output (out :pretty t)
(emit-html *some-foo-expression*)))
What's Next?
In the next chapter, you'll look at how to implement a macro that compiles FOO expressions into Common Lisp so you can embed HTML generation code directly into your Lisp programs. You'll also extend the FOO language to make it a bit more expressive by adding its own flavor of special operators and macros.
31. Practical: An HTML Generation Library, the Compiler
Now you're ready to look at how the FOO compiler works. The main difference between a compiler and an interpreter is that an interpreter processes a program and directly generates some behavior—generating HTML in the case of a FOO interpreter—but a compiler processes the same program and generates code in some other language that will exhibit the same behavior. In FOO, the compiler is a Common Lisp macro that translates FOO into Common Lisp so it can be embedded in a Common Lisp program. Compilers, in general, have the advantage over interpreters that, because compilation happens in advance, they can spend a bit of time optimizing the code they generate to make it more efficient. The FOO compiler does that, merging literal text as much as possible in order to emit the same HTML with a smaller number of writes than the interpreter uses. When the compiler is a Common Lisp macro, you also have the advantage that it's easy for the language understood by the compiler to contain embedded Common Lisp—the compiler just has to recognize it and embed it in the right place in the generated code. The FOO compiler will take advantage of this capability.
The Compiler
The basic architecture of the compiler consists of three layers. First you'll implement a class
html-compiler
that has one slot that holds an adjustable vector that's used to accumulate ops representing the calls made to the generic functions in the backend interface during the execution of process
.
Интервал:
Закладка:
Похожие книги на «Practical Common Lisp»
Представляем Вашему вниманию похожие книги на «Practical Common Lisp» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Practical Common Lisp» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.