Logos.StdlibDocs (Logos v0.2.0)

Copy Markdown

Builds the Markdown source for guides/language/stdlib/*.md -- one generated, per-symbol lookup document per file-backed stdlib namespace (Logos.Stdlib.namespaces/0), one for the six special forms Logos.Eval wires in directly, one for every Layer-1 primitive (Logos.Primitives.docs/0, see primitives_document/0), and a table-of-contents OVERVIEW.md linking to every one of them (see overview_document/0) -- ALL of these, OVERVIEW.md included, are generated and written by mix logos.gen_docs; none is hand-edited (OVERVIEW.md's own body is a static template, unlike the others' :doc-metadata-driven content, but it still goes through the exact same generate-and-write path, so hand-editing it would just get silently clobbered on the next regeneration like any other file here). Each namespace/primitives document covers every public Var, pulled live from its own :doc metadata (Logos.Primitives.install!/1 gives every primitive a real one too, sourced from the same Logos.Primitives.docs/0 data -- no more generic "Layer-1 primitive" placeholder), together with a runnable example: @examples/@special_form_examples/ @primitive_examples hold one Logos source snippet per documented item, actually evaluated (fresh Logos.new_runtime/0 inside its own isolated process, starting from namespace "user" -- see evaluate_example/2's own comment) at generation time and rendered alongside its real, freshly-computed printed result -- never a hand-typed "expected output" that could quietly drift from the code. Every stdlib-namespace entry (special forms/primitives are Elixir- implemented, so this doesn't apply to those two pages) also gets its own defining form's exact source, reconstructed from Logos.Reader.tokenize/1's position-preserving token stream rather than re-parsed by hand -- see extract_source_snippets/1's own comment.

guides/language/stdlib/*.md are all generated, checked-in files -- never hand-edit any of them. Regenerate via MIX_ENV=dev mix logos.gen_docs whenever a stdlib docstring or example changes; mix test fails if any checked-in file drifts from what this module would currently produce (see test/logos/stdlib_docs_test.exs). A missing example (no entry in @examples/@special_form_examples/ @primitive_examples for some documented item) or an example that raises when evaluated both fail generation loudly, same as a missing docstring already did -- staleness bugs in the source, not something this generator should silently paper over.

The special-form list below is intentionally hand-maintained data (six forms, essentially never change) rather than derived at runtime -- @eval_source/@special_form_names_in_eval embed Logos.Eval's own source at COMPILE time (same pattern Logos.Stdlib's @sources uses for .logos files) purely so documents/0 can assert the hand-written list hasn't silently drifted from Logos.Eval's real special forms -- it raises instead of quietly generating a stale reference if a special form is ever added/removed there without a matching update here.

Summary

Functions

The guides/language/stdlib/ filename a given stdlib namespace's document is written to, e.g. "logos.core" -> "CORE.md".

Every generated document as {filename, markdown} pairs, filename relative to guides/language/stdlib/: OVERVIEW.md first, then SPECIAL_FORMS.md, then PRIMITIVES.md (built from Logos.Primitives.docs/0), then one file per file-backed stdlib namespace in Logos.Stdlib.namespaces/0 order (doc_filename/1's own naming -- "logos.core" -> "CORE.md", etc.), skipping a namespace that ends up with no public, documented, non-primitive Var (currently none do). Raises if the hand-maintained special forms list (@special_forms) has drifted from Logos.Eval's actual special-form clauses, if any public, non-primitive stdlib Var has no :doc metadata, or if any documented item (special form, primitive, or stdlib Var) has no registered example, or has one that raises when evaluated.

Functions

doc_filename(ns)

@spec doc_filename(String.t()) :: String.t()

The guides/language/stdlib/ filename a given stdlib namespace's document is written to, e.g. "logos.core" -> "CORE.md".

documents()

@spec documents() :: [{String.t(), String.t()}]

Every generated document as {filename, markdown} pairs, filename relative to guides/language/stdlib/: OVERVIEW.md first, then SPECIAL_FORMS.md, then PRIMITIVES.md (built from Logos.Primitives.docs/0), then one file per file-backed stdlib namespace in Logos.Stdlib.namespaces/0 order (doc_filename/1's own naming -- "logos.core" -> "CORE.md", etc.), skipping a namespace that ends up with no public, documented, non-primitive Var (currently none do). Raises if the hand-maintained special forms list (@special_forms) has drifted from Logos.Eval's actual special-form clauses, if any public, non-primitive stdlib Var has no :doc metadata, or if any documented item (special form, primitive, or stdlib Var) has no registered example, or has one that raises when evaluated.