Metastatic.Adapters.Cure.ToMeta (Metastatic v0.30.0)

View Source

Transform Cure source / Cure AST (M1) into MetaAST (M2).

This is the abstraction function α_Cure that lifts a Cure program to the meta-level. Unlike the Python / Ruby / Haskell adapters -- which marshal a foreign-language AST through a subprocess -- the Cure compiler already emits 3-tuples in the MetaAST shape because MetaAST was designed as Cure's primary AST. This module therefore does only two jobs:

  1. invoke the Cure compiler's lexer + parser (when it is linked in at runtime);
  2. normalise any lingering adapter-specific metadata so the result round-trips cleanly through Metastatic.AST.conforms?/1.

When the Cure.Compiler.Lexer / Cure.Compiler.Parser modules are not available at runtime (e.g. Metastatic is used as a library in a host project that does not depend on Cure) the from_source/2 entry point returns {:error, :cure_not_available}. The normalize/1 entry point -- which accepts an already-parsed AST -- works unconditionally.

Entry Points

v0.20.0 Notes

Cure v0.20.0 added :bin_segment and :comment node types plus the segment-list payload for {:literal, [subtype: :bytes], ...}. All three are part of the MetaAST M2.1 core layer, so this adapter does not need to rewrite them -- it only walks the tree to ensure every 3-tuple has a keyword-list metadata in the second position (the Cure parser emits [] when no metadata applies, which is already canonical).

Summary

Types

The MetaAST produced by this adapter.

M1 metadata preserved for round-tripping (currently empty).

Opaque Cure source code.

Functions

Return true if the Cure compiler is available at runtime.

Ensure Cure compiler modules are loaded into the VM. Attempts dynamic discovery of Cure ebin directories or escript/executable if Cure is not already loaded.

Normalise an already-parsed Cure AST into canonical MetaAST.

Parse a Cure source fragment into a canonical MetaAST.

Types

meta_ast()

@type meta_ast() :: Metastatic.AST.meta_ast()

The MetaAST produced by this adapter.

metadata()

@type metadata() :: map()

M1 metadata preserved for round-tripping (currently empty).

source()

@type source() :: String.t()

Opaque Cure source code.

Functions

available?()

@spec available?() :: boolean()

Return true if the Cure compiler is available at runtime.

ensure_cure_compiler()

@spec ensure_cure_compiler() :: :ok | {:error, :cure_not_available}

Ensure Cure compiler modules are loaded into the VM. Attempts dynamic discovery of Cure ebin directories or escript/executable if Cure is not already loaded.

from_ast(ast)

@spec from_ast(meta_ast()) :: meta_ast()

Normalise an already-parsed Cure AST into canonical MetaAST.

The Cure parser already emits 3-tuples with keyword metadata, so this is effectively a structure-preserving pass that ensures:

  • the metadata list is always a keyword list (even when empty);
  • :literal nodes with subtype: :bytes keep either their raw binary payload or their :bin_segment children (v0.20.0+);
  • :comment nodes carry a :comment_kind metadata key (defaults to :line when the parser did not set one);
  • :param lists stored in :function_def / :lambda metadata are recursively normalised.

Nodes unknown to MetaAST are passed through unchanged so analyzers can use Metastatic.AST.conforms?/1 to surface them.

from_source(source, opts \\ [])

@spec from_source(source(), keyword()) ::
  {:ok, meta_ast(), metadata()} | {:error, term()}

Parse a Cure source fragment into a canonical MetaAST.

Returns {:ok, meta_ast, metadata} on success, {:error, reason} otherwise. metadata is a map reserved for future M1-specific round-trip hints; it is currently %{language: :cure}.

When the Cure compiler's Cure.Compiler.Lexer / Cure.Compiler.Parser modules are not linked in at runtime the function returns {:error, :cure_not_available} instead of attempting to parse. Call available?/0 to probe ahead of time.

normalize(other)

@spec normalize(meta_ast() | term()) :: meta_ast() | term()