Search documentation of Metastatic

# Metastatic.Adapters.Python.ToMeta (Metastatic v0.13.2)

View Source

Transform Python AST (M1) to MetaAST (M2).

Implements the abstraction function α_Python that lifts Python-specific AST structures to the meta-level representation.

## Transformation Strategy

Python's AST is represented as nested maps with "_type" keys. We pattern match on these structures and transform them to MetaAST tuples.

### M2.1 (Core Layer)

- Literals: Constant nodes → {:literal, type, value}
- Variables: Name nodes → {:variable, name}
- Binary operators: BinOp → {:binary_op, category, op, left, right}
- Unary operators: UnaryOp → {:unary_op, category, op, operand}
- Function calls: Call → {:function_call, name, args}
- Conditionals: If, IfExp → {:conditional, condition, then, else}
- Blocks: Module, multiple statements → {:block, statements}
- Early returns: Return, Break, Continue → {:early_return, kind, value}

### M2.2 (Extended Layer)

- Loops: While → {:loop, :while, condition, body}
- Loops: For → {:loop, :for_each, iterator, collection, body}
- Lambdas: Lambda → {:lambda, params, captures, body}
- Collection ops: Simple ListComp → {:collection_op, :map, lambda, collection}
- Exception handling: Try → {:exception_handling, try_block, rescue_clauses, finally_block}

## Metadata Preservation

The transformation preserves Python-specific information:

- `:lineno` - line number
- `:col_offset` - column offset
- `:python_node_type` - original Python AST node type

This enables high-fidelity round-trips (M1 → M2 → M1).

## Summary

### Functions

transform(node)

Transform Python AST to MetaAST.

## Functions

# transform(node)

    @spec transform(map()) :: {:ok, term(), map()} | {:error, String.t()}

Transform Python AST to MetaAST.

Returns `{:ok, meta_ast, metadata}` on success or `{:error, reason}` on failure.

## New 3-Tuple Format

All MetaAST nodes are uniform 3-element tuples:

    {type_atom, keyword_meta, children_or_value}

## Examples

    iex> transform(%{"_type" => "Constant", "value" => 42})
    {:ok, {:literal, [subtype: :integer], 42}, %{}}

    iex> transform(%{"_type" => "Name", "id" => "x"})
    {:ok, {:variable, [scope: :local], "x"}, %{}}

    iex> transform(%{"_type" => "BinOp", "op" => %{"_type" => "Add"}, ...})
    {:ok, {:binary_op, [category: :arithmetic, operator: :+], [left, right]}, %{}}