NAME

Muldis::DB::Literal - Abstract syntax tree for the Muldis D language

VERSION

This document describes Muldis::DB::Literal version 0.3.0 for Perl 5.

It also describes the same-number versions for Perl 5 of [...].

SYNOPSIS

This documentation is pending.

use Muldis::DB::Literal;

my $truth_value = Muldis::DB::Literal::Bool->new({ 'v' => (2 + 2 == 4) });
my $direction = Muldis::DB::Literal::Order->new({ 'v' => (5 <=> 7) });
my $answer = Muldis::DB::Literal::Int->new({ 'v' => 42 });
my $package = Muldis::DB::Literal::Blob->new({ 'v' => (pack 'H2', 'P') });
my $planetoid = Muldis::DB::Literal::Text->new({ 'v' => 'Ceres' });

This documentation is pending.

DESCRIPTION

The native command language of a Muldis::DB DBMS (database management system) / virtual machine is called Muldis D; see Language::MuldisD for the language's human readable authoritative design document.

This library, Muldis::DB::Literal ("AST"), provides a few dozen container classes which collectively implement the Abstract representation format of Muldis D; each class is called an AST node type or node type, and an object of one of these classes is called an AST node or node.

These are all of the roles and classes that Muldis::DB::Literal defines (more will be added in the future), which are visually arranged here in their "does" or "isa" hierarchy, children indented under parents:

Muldis::DB::Literal::Node (dummy role)
    Muldis::DB::Literal::Expr (dummy role)
        Muldis::DB::Literal::Lit (dummy role)
            Muldis::DB::Literal::Bool
            Muldis::DB::Literal::Order
            Muldis::DB::Literal::Int
            Muldis::DB::Literal::Blob
            Muldis::DB::Literal::Text
        Muldis::DB::Literal::_Tuple (implementing role)
            Muldis::DB::Literal::Tuple
            Muldis::DB::Literal::QuasiTuple
        Muldis::DB::Literal::_Relation (implementing role)
            Muldis::DB::Literal::Relation
            Muldis::DB::Literal::QuasiRelation
        Muldis::DB::Literal::Default
        Muldis::DB::Literal::Treat
        Muldis::DB::Literal::VarInvo
        Muldis::DB::Literal::FuncInvo
    Muldis::DB::Literal::Stmt (dummy role)
        Muldis::DB::Literal::ProcInvo
        Muldis::DB::Literal::FuncReturn
        Muldis::DB::Literal::ProcReturn
        # more control-flow statement types would go here
    Muldis::DB::Literal::EntityName
    Muldis::DB::Literal::_TypeInvo (implementing role)
        Muldis::DB::Literal::TypeInvo
        Muldis::DB::Literal::QuasiTypeInvo
    Muldis::DB::Literal::_TypeDict (implementing role)
        Muldis::DB::Literal::TypeDict
        Muldis::DB::Literal::QuasiTypeDict
    Muldis::DB::Literal::_ExprDict
    Muldis::DB::Literal::FuncDecl
    Muldis::DB::Literal::ProcDecl
    # more routine declaration types would go here
    Muldis::DB::Literal::HostGateRtn

All Muldis D abstract syntax trees are such in the compositional sense; that is, every AST node is composed primarily of zero or more other AST nodes, and so a node is a child of another iff the former is composed into the latter. All AST nodes are immutable objects; their values are determined at construction time, and they can't be changed afterwards. Therefore, constructing a tree is a bottom-up process, such that all child objects have to be constructed prior to, and be passed in as constructor arguments of, their parents. The process is like declaring an entire multi-dimensional Perl data structure at the time the variable holding it is declared; the data structure is actually built from the inside to the outside. A consequence of the immutability is that it is feasible to reuse AST nodes many times, since they won't change out from under you.

An AST node denotes an arbitrarily complex value, that value being defined by the type of the node and what its attributes are (some of which are themselves nodes, and some of which aren't). A node can denote either a scalar value, or a collection value, or an expression that would evaluate into a value, or a statement or routine definition that could be later executed to either return a value or have some side effect. For all intents and purposes, a node is a program, and can represent anything that program code can represent, both values and actions.

The Muldis::DB framework uses Muldis::DB AST nodes for the dual purpose of defining routines to execute and defining values to use as arguments to and return values from the execution of said routines. The prepare() method of a Muldis::DB::Interface::DBMS object, and by extension the Muldis::DB::Interface::HostGateRtn-new()> constructor function, takes a Muldis::DB::Literal::HostGateRtn node as its primary argument, such that the AST object defines the source code that is compiled to become the Interface object. The fetch_ast() and store_ast() methods of a Muldis::DB::Interface::HostGateVar object will get or set that object's primary value attribute, which is any Muldis::DB::Literal::Node. The Var objects are bound to Rtn objects, and they are the means by which an executed routine accepts input or provides output at execute() time.

AST Node Values Versus Representations

In the general case, Muldis::DB AST nodes do not maintain canonical representations of all Muldis D values, meaning that it is possible and common to have 2 given AST nodes that logically denote the same value, but they have different actual compositions. (Some node types are special cases for which the aforementioned isn't true; see below.)

For example, a node whose value is just the number 5 can have any number of representations, each of which is an expression that evaluates to the number 5 (such as [5, 2+3, 10/2]). Another example is a node whose value is the set {3,5,7}; it can be represented, for example, either by Set(5,3,7,7,7) or Union(Set(3,5),Set(5,7)) or Set(7,5,3). These examples aren't actual Muldis::DB AST syntax.

For various reasons, the Muldis::DB::Literal classes themselves do not do any node refactoring, and their representations differ little if any from the format of their constructor arguments, which can contain extra information that is not logically significant in determining the node value. One reason is that this allows a semblance of maintaining the actual syntax that the user specified, which is useful for their debugging purposes. Another reason is the desire to keep this library as light-weight as possible, such that it just implements the essentials; doing refactoring can require a code size and complexity that is orders of magnitude larger than these essentials, and that work isn't always helpful. It should also be noted that any nodes having references to externally user-defined entities can't be fully refactored as each of those represents a free variable that a static node analysis can't decompose; only nodes consisting of just system-defined or literal entities (meaning zero free variables) can be fully refactored in a static node analysis (though there are a fair number of those in practice, particularly as Var values).

A consequence of this is that the Muldis::DB::Literal classes in general do not include do not include any methods for comparing that 2 nodes denote the same value; to reliably do that, you will have to use means not provided by this library. However, each class does provide a equal_repr method, which compares that 2 nodes have the same representation.

It should be noted that a serialize/unserialize cycle on a node that is done using the as_perl routine to serialize, and having Perl eval that to unserialize, is guaranteed to preserve the representation, so equal_repr will work as expected in that situation.

As an exception to the general case about nodes, the node classes [BoolLit, TextLit, BlobLit, IntLit, EntityName, VarInvo, ProcReturn] are guaranteed to only ever have a single representation per value, and so equal_repr is guaranteed to indicate value equality of 2 nodes of those types. In fact, to assist the consequence this point, these node classes also have the equal_value method which is an alias for equal_repr, so you can use equal_value in your use code to make it better self documenting; equal_repr is still available for all node types to assist automated use code that wants to treat all node types the same. It should also be noted that a BoolLit node can only possibly be of one of 2 values, and ProcReturn is a singleton.

It is expected that multiple third party utility modules will become available over time whose purpose is to refactor a Muldis::DB AST node, either as part of a static analysis that considers only the node in isolation (and any user-defined entity references have to be treated as free variables and not generally be factored out), or as part of an Engine implementation that also considers the current virtual machine environment and what user-defined entities exist there (and depending on the context, user-defined entity references don't have to be free variables).

INTERFACE

The interface of Muldis::DB::Literal is fundamentally object-oriented; you use it by creating objects from its member classes, usually invoking new() on the appropriate class name, and then invoking methods on those objects. All of their attributes are private, so you must use accessor methods.

Muldis::DB::Literal also provides wrapper subroutines for all member class constructors, 1 per each, where each subroutine has identical parameters to the constructor it wraps, and the name of each subroutine is equal to the trailing part of the class name, specifically the Foo of Muldis::DB::Literal::Foo, but with a new prefix (so that Perl doesn't confuse a fully-qualified sub name with a class name). All of these subroutines are exportable, but are not exported by default, and exist solely as syntactic sugar to allow user code to have more brevity. TODO: Reimplement these as lexical aliases or compile-time macros instead, to avoid the overhead of extra routine calls.

The usual way that Muldis::DB::Literal indicates a failure is to throw an exception; most often this is due to invalid input. If an invoked routine simply returns, you can assume that it has succeeded, even if the return value is undefined.

The Muldis::DB::Literal::Bool Class

This documentation is pending.

The Muldis::DB::Literal::Order Class

This documentation is pending.

The Muldis::DB::Literal::Int Class

This documentation is pending.

The Muldis::DB::Literal::Blob Class

This documentation is pending.

The Muldis::DB::Literal::Text Class

This documentation is pending.

The Muldis::DB::Literal::Tuple Class

This documentation is pending.

The Muldis::DB::Literal::QuasiTuple Class

This documentation is pending.

The Muldis::DB::Literal::Relation Class

This documentation is pending.

The Muldis::DB::Literal::QuasiRelation Class

This documentation is pending.

The Muldis::DB::Literal::Default Class

This documentation is pending.

The Muldis::DB::Literal::Treat Class

This documentation is pending.

The Muldis::DB::Literal::VarInvo Class

This documentation is pending.

The Muldis::DB::Literal::FuncInvo Class

This documentation is pending.

The Muldis::DB::Literal::ProcInvo Class

This documentation is pending.

The Muldis::DB::Literal::FuncReturn Class

This documentation is pending.

The Muldis::DB::Literal::ProcReturn Class

This documentation is pending.

The Muldis::DB::Literal::EntityName Class

This documentation is pending.

The Muldis::DB::Literal::TypeInvo Class

This documentation is pending.

The Muldis::DB::Literal::QuasiTypeInvo Class

This documentation is pending.

The Muldis::DB::Literal::TypeDict Class

This documentation is pending.

The Muldis::DB::Literal::QuasiTypeDict Class

This documentation is pending.

The Muldis::DB::Literal::_ExprDict Class

This documentation is pending.

The Muldis::DB::Literal::FuncDecl Class

This documentation is pending.

The Muldis::DB::Literal::ProcDecl Class

This documentation is pending.

The Muldis::DB::Literal::HostGateRtn Class

This documentation is pending.

DIAGNOSTICS

This documentation is pending.

CONFIGURATION AND ENVIRONMENT

This documentation is pending.

DEPENDENCIES

This file requires any version of Perl 5.x.y that is at least 5.8.1.

INCOMPATIBILITIES

None reported.

SEE ALSO

Go to Muldis::DB for the majority of distribution-internal references, and Muldis::DB::SeeAlso for the majority of distribution-external references.

BUGS AND LIMITATIONS

For design simplicity in the short term, all AST arguments that are applicable must be explicitly defined by the user, even if it might be reasonable for Muldis::DB to figure out a default value for them, such as "same as self". This limitation will probably be removed in the future. All that said, a few arguments may be exempted from this limitation.

This documentation is pending.

AUTHOR

Darren Duncan (perl@DarrenDuncan.net)

LICENSE AND COPYRIGHT

This file is part of the Muldis::DB framework.

Muldis::DB is Copyright © 2002-2007, Darren Duncan.

See the LICENSE AND COPYRIGHT of Muldis::DB for details.

ACKNOWLEDGEMENTS

The ACKNOWLEDGEMENTS in Muldis::DB apply to this file too.