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/expressioncall- Array of method calls to applyind- Array of index operationsarg- Arguments for operationsblock- 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
Sidef::Parser - The Sidef parser that generates ASTs
Sidef - The main Sidef language module
https://github.com/trizen/sidef - Sidef language repository
AUTHOR
Daniel "trizen" Șuteu
LICENSE
This module is part of the Sidef programming language and is licensed under the same terms as Sidef itself.