NAME

Sidef::Deparse::Sidef - Deparse Sidef abstract syntax trees back into Sidef source code

SYNOPSIS

use Sidef::Deparse::Sidef;

# Create a new deparser instance
my $deparser = Sidef::Deparse::Sidef->new(
    before       => '',
    between      => ";\n",
    after        => ";\n",
    class        => 'main',
    extra_parens => 0,
);

# Deparse an AST structure
my $code = $deparser->deparse($ast);

# Deparse individual expressions
my $expr_code = $deparser->deparse_expr({self => $expression});

# Deparse with arguments
my $args_code = $deparser->deparse_args(@arguments);

DESCRIPTION

Sidef::Deparse::Sidef is the deparsing component of the Sidef programming language. It takes abstract syntax tree (AST) structures generated by the Sidef parser and reconstructs them into valid Sidef source code. This is useful for code analysis, transformation, pretty-printing, and metaprogramming tasks.

The deparser maintains information about data types, handles complex nested structures, and preserves semantic meaning while generating readable code output.

CONSTRUCTOR

new

my $deparser = Sidef::Deparse::Sidef->new(%options);

Creates a new deparser instance with the specified options.

Options:

  • before - String to prepend before the deparsed output (default: '')

  • between - String to insert between statements (default: ";\n")

  • after - String to append after the deparsed output (default: ";\n")

  • class - Current class context for deparsing (default: 'main')

  • extra_parens - Whether to add extra parentheses for clarity (default: 0)

  • opt - Hash reference for additional options (default: {})

  • data_types - Hash reference mapping internal types to Sidef type names

The constructor also initializes a comprehensive mapping of Sidef data types, including:

  • Basic types (Bool, String, Number, Array, Hash, etc.)

  • Numeric types (Complex, Fraction, Polynomial, Quaternion, etc.)

  • Range types (Range, RangeNum, RangeStr)

  • File and I/O types (File, Dir, FileHandle, Socket, etc.)

  • Control flow types (Block, next, break, continue)

  • Special types (nil, null, Lazy, Enumerator, etc.)

METHODS

Core Deparsing Methods

deparse

my $code = $deparser->deparse($struct);

Main entry point for deparsing a complete AST structure. Takes a hash reference representing the AST and returns the complete deparsed Sidef source code.

The method processes all statements in the structure, joins them with the configured separator, and adds before/after strings.

deparse_script

my @statements = $deparser->deparse_script($struct);
my $last_statement = $deparser->deparse_script($struct);

Deparses a script structure (hash of class-keyed expression arrays). In list context, returns an array of deparsed statements. In scalar context, returns only the last statement.

deparse_expr

my $code = $deparser->deparse_expr($expr);

Deparses a single expression. The $expr parameter is typically a hash reference with a self key containing the object to deparse, and optional call, ind, or other keys for method calls and indexing operations.

This is the most complex method in the deparser, handling numerous Sidef language constructs including:

  • Variables (var, static, const, has, global)

  • Functions and methods

  • Classes, structs, and subsets

  • Control structures (if, while, for, given, when, etc.)

  • Blocks and closures

  • Operators and method calls

  • Literals (numbers, strings, arrays, hashes)

  • Special constructs (try/catch, gather/take, etc.)

Generic Deparsing Utilities

deparse_generic

my $code = $deparser->deparse_generic($before, $sep, $after, @args);

Generic method for deparsing a list of arguments with configurable delimiters. Used internally by other deparsing methods.

  • $before - String to prepend

  • $sep - Separator between elements

  • $after - String to append

  • @args - List of arguments to deparse (can be strings, hash refs, or objects)

deparse_args

my $code = $deparser->deparse_args(@args);

Deparses a list of arguments enclosed in parentheses with comma separation. Equivalent to deparse_generic('(', ', ', ')', @args).

deparse_bare_block

my $code = $deparser->deparse_bare_block(@args);

Deparses a bare block structure with proper indentation. Used for blocks that don't have the standard block syntax (like in loops or conditionals).

Variable and Type Handling

_dump_vars

my $code = $deparser->_dump_vars(@vars);

Internal method that deparses variable declarations. Handles:

  • Variable sigils (*, : for arrays and hashes)

  • Class qualification (Class::var)

  • Type constraints

  • Subsets

  • Where clauses (conditions)

  • Default values

_dump_init_vars

my $code = $deparser->_dump_init_vars($init_obj);

Deparses variable initialization constructs (var, has, const, etc.) with optional assignment from arguments.

_dump_reftype

my $type_name = $deparser->_dump_reftype($obj);

Returns the Sidef type name for a given object reference. Handles special cases like ClassInit, Struct, and Subset types.

_dump_class_name

my $name = $deparser->_dump_class_name($obj);

Extracts and formats the fully qualified class name from a class-related object.

Literal Deparsing

_dump_string

my $code = $deparser->_dump_string($str);

Deparses a string literal, properly escaping special characters and wrapping in quotes.

_dump_number

my $code = $deparser->_dump_number($num);

Deparses a number literal. Handles:

  • Special values (Inf, NaN)

  • Floating point numbers (with 'f' suffix)

  • Complex numbers (using Complex constructor)

  • Rational numbers (fractions)

  • Regular integers and decimals

_dump_array

my $code = $deparser->_dump_array($array);

Deparses an array literal with square bracket notation [elem1, elem2, ...].

SUPPORTED LANGUAGE CONSTRUCTS

The deparser handles the complete Sidef language syntax, including:

Variable Declarations

var x = 42
const PI = 3.14159
static counter = 0
has @items
global $config

Functions and Methods

func fibonacci(n) {
    # ...
}

method calculate(x, y) -> Number {
    # ...
}

func cached_result() is cached {
    # ...
}

Classes and Objects

class Point(x, y) {
    method distance(other) {
        # ...
    }
}

class Circle < Shape {
    # ...
}

Structs and Subsets

struct Person {
    String name,
    Number age
}

subset PositiveInt < Number {
    .is_pos && .is_int
}

Control Flow

if (condition) {
    # ...
} elsif (other) {
    # ...
} else {
    # ...
}

while (running) {
    # ...
}

for i in (1..10) {
    # ...
}

foreach item in array {
    # ...
}

Pattern Matching

given value {
    when (1) { "one" }
    when (2) { "two" }
    default  { "other" }
}

case (x) {
    # ...
}

Exception Handling

try {
    # risky operation
} catch {
    warn "Error occurred"
}

Operators and Expressions

x + y * z
array[index]
hash{key}
obj->method(args)
condition ? true_val : false_val

Special Constructs

gather {
    take(1)
    take(2)
}

do {
    # ...
}

loop {
    # ...
}

eval { ... }

local(x)

INDENTATION AND FORMATTING

The deparser uses the global variables $Sidef::SPACES and $Sidef::SPACES_INCR to manage indentation:

  • $Sidef::SPACES - Current indentation level (in spaces)

  • $Sidef::SPACES_INCR - Indentation increment per nesting level

The deparser automatically adjusts indentation when entering and exiting blocks, creating readable, properly formatted output.

CIRCULAR REFERENCE HANDLING

The deparser maintains an internal %addr hash (using refaddr) to track already-deparsed objects and prevent infinite recursion when dealing with:

  • Recursive function definitions

  • Mutually referencing classes

  • Self-referential data structures

  • Circular class inheritance

When an object is encountered for the second time, the deparser outputs a reference or placeholder (like __FUNC__ or __BLOCK__) instead of recursing infinitely.

DATA AFTER __DATA__

The deparser handles the special __DATA__ marker. When a DATA section is encountered, it appends the data content to the after field to ensure it's included in the final output.

EXAMPLES

Basic Usage

use Sidef::Deparse::Sidef;

my $deparser = Sidef::Deparse::Sidef->new();

# Assuming $ast is a parsed Sidef AST
my $source_code = $deparser->deparse($ast);
print $source_code;

Custom Formatting

my $deparser = Sidef::Deparse::Sidef->new(
    between => ";\n\n",  # Double space between statements
    after   => ";\n\n",
);

Deparsing with Extra Parentheses

my $deparser = Sidef::Deparse::Sidef->new(
    extra_parens => 1,  # Add extra parens for clarity
);

INTERNAL STRUCTURE

The deparser works with AST structures that are typically hash references with specific keys:

  • self - The primary object/expression

  • call - Array of method calls to apply

  • ind - Array of index operations

  • arg - Arguments for operations

  • block - Block/closure code

Different Sidef object types (Variable, Block, Class, etc.) have their own internal structures that the deparser knows how to handle.

LIMITATIONS

  • The deparser assumes well-formed AST input

  • Some internal optimizations in the AST may not be perfectly preserved

  • Comments are not preserved (as they're typically not part of the AST)

  • The exact original formatting/whitespace is not preserved

SEE ALSO

AUTHOR

Daniel "trizen" Șuteu

LICENSE

This module is part of the Sidef programming language and is licensed under the same terms as Sidef itself.