Search documentation of Metastatic

# Metastatic (Metastatic v0.13.2)

View Source

Metastatic - Cross-language code analysis via unified MetaAST.

## Main API

The primary entry points for working with Metastatic:

- `quote/2` - Convert source code to MetaAST
- `unquote/2` - Convert MetaAST back to source code

## Examples

    # Parse Python code to MetaAST
    iex> {:ok, {:binary_op, meta, _}} = Metastatic.quote("x + 5", :python)
    iex> Keyword.get(meta, :category) == :arithmetic and Keyword.get(meta, :operator) == :+
    true

    # Convert MetaAST back to Python source
    iex> ast = {:binary_op, [category: :arithmetic, operator: :+], [{:variable, [], "x"}, {:literal, [subtype: :integer], 5}]}
    iex> Metastatic.unquote(ast, :python)
    {:ok, "x + 5"}

    # Round-trip demonstration
    iex> {:ok, my_ast} = Metastatic.quote("x + 5", :python)
    iex> {:ok, source} = Metastatic.unquote(my_ast, :python)
    iex> source
    "x + 5"

## Cross-Language Translation

Since MetaAST is language-independent, you can parse in one language and generate in another:

    # Parse from Python, generate Elixir code (same MetaAST!)
    iex> {:ok, py_ast} = Metastatic.quote("x + 5", :python)
    iex> {:ok, _source} = Metastatic.unquote(py_ast, :elixir)
    iex> true
    true

## Summary

### Types

language()
meta_ast()

### Functions

quote(code, language)

Convert source code to MetaAST.

unquote(ast, language)

Convert MetaAST to source code.

## Types

# language()

    @type language() :: :elixir | :erlang | :ruby | :haskell | :python

# meta_ast()

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

## Functions

# quote(code, language)

    @spec quote(String.t(), language()) :: {:ok, meta_ast()} | {:error, term()}

Convert source code to MetaAST.

Performs Source → M1 → M2 transformation, returning just the MetaAST without the Document wrapper.

## Parameters

- `code` - Source code string
- `language` - Language atom (`:python`, `:elixir`, `:ruby`, `:erlang`, `:haskell`)

## Returns

- `{:ok, meta_ast}` - Successfully parsed and abstracted to M2
- `{:error, reason}` - Parsing or abstraction failed

## Examples

    iex> {:ok, {:binary_op, meta, _}} = Metastatic.quote("x + 5", :python)
    iex> Keyword.get(meta, :category) == :arithmetic and Keyword.get(meta, :operator) == :+
    true

    iex> {:ok, {:binary_op, meta, _}} = Metastatic.quote("x + 5", :elixir)
    iex> Keyword.get(meta, :category) == :arithmetic and Keyword.get(meta, :operator) == :+
    true

    iex> {:ok, {:list, _, items}} = Metastatic.quote("[1, 2, 3]", :python)
    iex> length(items) == 3
    true

# unquote(ast, language)

    @spec unquote(meta_ast(), language()) :: {:ok, String.t()} | {:error, term()}

Convert MetaAST to source code.

Performs M2 → M1 → Source transformation, generating source code in the specified target language.

## Parameters

- `ast` - MetaAST structure (M2 level)
- `language` - Target language atom (`:python`, `:elixir`, `:ruby`, `:erlang`, `:haskell`)

## Returns

- `{:ok, source}` - Successfully generated source code
- `{:error, reason}` - Generation failed

## Examples

    iex> ast = {:binary_op, [category: :arithmetic, operator: :+], [{:variable, [], "x"}, {:literal, [subtype: :integer], 5}]}
    iex> Metastatic.unquote(ast, :python)
    {:ok, "x + 5"}

    iex> ast = {:binary_op, [category: :arithmetic, operator: :+], [{:variable, [], "x"}, {:literal, [subtype: :integer], 5}]}
    iex> Metastatic.unquote(ast, :elixir)
    {:ok, "x + 5"}

    iex> ast = {:literal, [subtype: :integer], 42}
    iex> Metastatic.unquote(ast, :python)
    {:ok, "42"}

    iex> ast = {:list, [], [{:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]}
    iex> Metastatic.unquote(ast, :python)
    {:ok, "[1, 2]"}

## Cross-Language Translation

Since MetaAST is language-independent, you can parse from one language and generate in another:

    iex> {:ok, ast} = Metastatic.quote("x + 5", :python)
    iex> {:ok, source} = Metastatic.unquote(ast, :elixir)
    iex> source
    "x + 5"

    iex> {:ok, ast} = Metastatic.quote("42", :ruby)
    iex> {:ok, source} = Metastatic.unquote(ast, :python)
    iex> source
    "42"