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

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 linked in at runtime.

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 linked in at runtime.

When false, from_source/2 always returns {:error, :cure_not_available} and callers should skip the Cure source path (or depend on the Cure compiler explicitly).

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()