PtcRunner.Lisp.Prelude.Compiler (PtcRunner v0.14.0)

Copy Markdown View Source

Compiles deployment prelude SOURCE into a %PtcRunner.Lisp.Prelude{} artifact.

What this does

  1. Parses the prelude source to raw AST.
  2. Walks the top-level program treating (ns name "doc" {meta}) as a COMPILER-ONLY directive (not a general user-runtime form), and defn/defn- as export/private-helper definitions under the current namespace.
  3. Runs compile-time validation that does NOT depend on a selected runtime: reserved-namespace rejection, missing/invalid namespace, duplicate public refs, invalid visibility, invalid arity/signature metadata. Failures are returned as {:error, %PtcRunner.Lisp.Prelude.ValidationError{}}.
  4. Builds %Export{} records for public definitions and records every transitively referenced tool/<name> as a tool:<name> requirement.
  5. Captures a callable private prelude env by analyzing+evaluating the definition forms (ns directives stripped, defn- rewritten to defn) through the existing PTC-Lisp pipeline. The captured value is the resulting user_ns map (bare symbol => {:closure, ...}). NOTE: the evaluator's lexical closure capture does NOT fold sibling top-level defs into each closure's captured_env — sibling helpers resolve by name through user_ns at CALL time. The whole private_env map IS that namespace, so private_env must be threaded as the user_ns layer when invoking an export for siblings to resolve (the capture seam).
  6. Computes a sha256 source hash.

Attach-time requires validation against granted tools is a separate phase.

Summary

Functions

Compiles prelude source into a %PtcRunner.Lisp.Prelude{}.

Functions

compile(source, opts \\ [])

@spec compile(
  String.t(),
  keyword()
) ::
  {:ok, PtcRunner.Lisp.Prelude.t()}
  | {:error, PtcRunner.Lisp.Prelude.ValidationError.t()}

Compiles prelude source into a %PtcRunner.Lisp.Prelude{}.

Options for declared prelude-to-prelude dependencies:

  • :deps — compiled %Prelude{} artifacts whose PUBLIC exports are visible to namespaces that declare them in :namespace_deps.
  • :namespace_deps%{namespace => [dep_namespace]} declaring which dep namespaces each compiled namespace may reference. A declared dep must be provided by :deps or be a sibling namespace of this compile; siblings are processed in dependency order with progressive scope.

Undeclared cross-namespace references keep failing (unknown namespace), and defn- privates of a dep have no export record so they stay unreachable. Dep references inside def initializers are rejected (:dep_ref_in_def): initializers evaluate at compile time under a no-op tool executor, so a dep call there would silently compute garbage.

Returns {:ok, prelude} or {:error, %ValidationError{}}.