Синтаксис Лиспекс: Атомы мысли

Здесь нет сложных правил. Исследуйте чистый мир токенов, литералов и S-выражений — мельчайших единиц, из которых строится вся логика Лиспекс.

Это справочник по входной грамматике S‑выражений и детерминированным правилам нормализации в Core AST. Семантика выполнения и поведение стандартной библиотеки — вне области.

Область: только входная грамматика + нормализация. Пользовательские макросы/расширения чтения запрещены. Переключатель R5RS-compat корректирует некоторые детали (см. полную спецификацию).

0) Заголовок файла (необязательно)

;! lispex 1.1
;! compat: r5rs   ; включить режим совместимости R5RS

1) Кодировка / пробелы / комментарии

  • Кодировка: UTF‑8
  • Пробелы: space, tab, CR, LF
  • Комментарии: строка ; ..., блок #| ... |# (вложенные)

2) Токены и литералы

Символы (идентификаторы)

С учётом регистра, Unicode. Идея регулярного выражения: [^()\[\]{}\s"';,]+`. Зарезервированные слова нельзя связывать (см. ниже).

Логические значения

#t   #f

Числа (вводные формы)

  • Целые (десятичные): 0 | -?[1-9][0-9]*
  • Рациональные: p/q (q ≠ 0)
  • Вещественные: -?[0-9]+(\.[0-9]+)?([eE][-+]?[0-9]+)?

Символы‑литеры (Characters) / Строки

  • Символы‑литеры: #\a, #\space, #\x03B1
  • Строки: "..." с экранированием \" \\ \n \t \r \xHH;

Списки / точечные списки / векторы / байтовые векторы

  • Списки: (a b c); точечные: (a b . c)
  • Векторы: #(a b c)
  • Байтовые векторы: #u8(0 255 ...)

Семейство quote (сокращения чтения)

'x      ⇒ (quote x)
`x      ⇒ (quasiquote x)
,x      ⇒ (unquote x)
,@xs    ⇒ (unquote-splicing xs)

3) Заголовок модуля (необязательно)

(module <name>
  (export id ...)
  (import <name> ...)
  body ...)

<name> — символ или точечный путь (util.string). В этом заголовке нет rename/only/except. Файлы без модуля допустимы.

Примечание: этот заголовок — опциональный и в Руководствах не используется. Lispex — трансформер; примеры в руководствах оставлены минимальными на верхнем уровне. Инструменты могут сплющивать или игнорировать этот заголовок при трансформации.

4) Зарезервированные слова — связывать нельзя

quote quasiquote unquote unquote-splicing
lambda if begin set! define let let* letrec
cond case and or when unless do
values call-with-values
call/cc dynamic-wind
module export import

Использование пользовательских макросов/расширений чтения приводит к ошибке: define-syntax syntax-rules syntax-case let-syntax letrec-syntax #lang #;.

5) Core‑формы — остаются после нормализации

(lambda (formals) body+)
(if test then else)
(begin e1 ... en)
(set! id expr)
(define id expr)
(define (f params) body+)
(let ((id expr) ...) body+)
(letrec ((id expr) ...) body+)
(quote datum)
(quasiquote template)
(values expr*) (call-with-values producer consumer)
(call/cc proc) (dynamic-wind before thunk after)

6) Производные формы — правила нормализации

(define (f a b) body...) ⇒ (define f (lambda (a b) body...))
(let* ((x e1) (y e2) ...) body)
  ⇒ (let ((x e1)) (let* ((y e2) ...) body))
(cond (t1 b1...) ... (else e...))
  ⇒ (if t1 (begin b1...) (if t2 (begin b2...) ... (begin e...)))
(case key ((k11 k12 ...) b1...) ... (else e...))
  ⇒ (let ((t key)) (if (equal? t k11) (begin b1...) ... (begin e...)))
(and) ⇒ #t, (and e1) ⇒ e1, (and e1 e2 ... en) ⇒ (if e1 (and e2 ... en) #f)
(or)  ⇒ #f, (or e1)  ⇒ e1, (or e1 e2 ... en) ⇒ (let ((t e1)) (if t t (or e2 ... en)))

R5RS‑compat: при включении корректирует синтаксис байтовых векторов и некоторые детали предикатов/портов. Примечание: в описании нормализации case использовано equal? для простоты; реализация может следовать стандартной семантике сравнения eqv? (см. полную спецификацию).