Skip to main content

Module annotate

Module annotate 

Source
Expand description

Definition-form annotation (ADR-0019).

A best-effort utility layer over the reader’s Datum tree — not part of the reader-only core (ADR-0001). It recognizes definition forms (defun, defmacro, cl-defun, define-minor-mode, project-local def-macros, …) and tags their parts with Roles (name, arglist, docstring, body) so a consumer can locate a definition’s pieces without hard-coding every macro.

Two pieces:

  • a Registry of FormSpecs keyed by head symbol: start from the bundled per-dialect core (bundled_registry, ADR-0020), extend with the harvester (harvest_source_for, ADR-0032) — which reads a def-macro’s own arglist parameter names across every macro-defining Lisp, plus, for Emacs Lisp, its declare metadata — and layer consumer-authored specs (FormSpec::define) on top;
  • the annotator (annotate_form / annotate_tree), the dialect-agnostic mechanism that applies a spec to a form.

It never expands or evaluates macros; it only interprets declared/structural metadata.

§Examples

Locate a definition’s parts using the bundled per-dialect core:

use lispexp::annotate::{annotate_form, bundled_registry, Category, Role};
use lispexp::{parse, Dialect, Options};

let reg = bundled_registry(Dialect::EmacsLisp);
let parsed = parse("(defun square (x) \"Square X.\" (* x x))", &Options::emacs_lisp());
let def = annotate_form(&parsed.data[0], &reg).unwrap();

assert_eq!(def.category, Some(Category::Function));
assert_eq!(def.first(Role::Name).unwrap().as_symbol(), Some("square"));
assert!(def.first(Role::Docstring).is_some());

Teach the registry a project-local def-macro from its own arglist, then annotate a use of it:

use lispexp::annotate::{annotate_form, bundled_registry, harvest_source_for, Role};
use lispexp::{parse, Dialect, Options};

let mut reg = bundled_registry(Dialect::EmacsLisp);
harvest_source_for("(defmacro defthing (name &rest body) nil)", Dialect::EmacsLisp, &mut reg);

let parsed = parse("(defthing widget (render))", &Options::emacs_lisp());
let def = annotate_form(&parsed.data[0], &reg).unwrap();
assert_eq!(def.first(Role::Name).unwrap().as_symbol(), Some("widget"));

Structs§

Annotated
An annotated definition form.
FormSpec
A description of how to interpret a definition form’s arguments.
Part
One role-tagged child of an annotated form.
Registry
A set of FormSpecs keyed by head symbol.
SpecializedParam
A required parameter of a specialized arglist, split into its variable token and optional specializer (ADR-0021).

Enums§

Category
An optional, normalized classification hint on a FormSpec (ADR-0020).
Confidence
How confidently a FormSpec was determined — also a coarse provenance.
Dispatch
How a dispatch/method form carries its dispatch signature, right after the name (ADR-0021).
Docstring
Where a form’s optional docstring sits, and when a string counts as one.
Role
The role of an argument within a definition form.

Functions§

annotate_form
Annotate a single form if its head is a known definition form.
annotate_tree
Annotate every definition form reachable in code position in data, in source order (outer forms before the inner forms they contain).
bundled_registry
The bundled conservative core Registry for dialect (ADR-0020).
harvest_source
Harvest definition-form specs from Emacs Lisp source into reg.
harvest_source_for
Harvest definition-form specs from dialect source into reg.
split_specialized_arglist
Split a specialized arglist’s required parameters into (variable, specializer) pairs (ADR-0021). Stops at the first lambda-list marker (&optional, &rest, &key, …); those tail parameters are not specialized.