package Dallycot::AST; our $AUTHORITY = 'cpan:JSMITH'; # ABSTRACT: Abstract type representing a syntax node use strict; use warnings; use utf8; use experimental qw(switch); use Carp qw(croak); use Promises qw(deferred); use Scalar::Util qw(blessed); use Module::Pluggable require => 1, sub_name => '_node_types', search_path => 'Dallycot::AST'; use Dallycot::Value; =head1 DESCRIPTION Dallycot::AST is an abstract class inherited by all of the AST classes: =over 4 =item L<Apply|Dallycot::AST::Apply> =item L<Assign|Dallycot::AST::Assign> =item L<BuildFilter|Dallycot::AST::BuildFilter> =item L<BuildList|Dallycot::AST::BuildList> =item L<BuildMap|Dallycot::AST::BuildMap> =item L<BuildRange|Dallycot::AST::BuildRange> =item L<BuildVector|Dallycot::AST::BuildVector> =item L<Compose|Dallycot::AST::Compose> =item L<Defined|Dallycot::AST::Defined> =item L<Expr|Dallycot::AST::Expr> =item L<Fetch|Dallycot::AST::Fetch> =item L<ForwardWalk|Dallycot::AST::ForwardWalk> =item L<Head|Dallycot::AST::Head> =item L<Identity|Dallycot::AST::Identity> =item L<Index|Dallycot::AST::Index> =item L<Invert|Dallycot::AST::Invert> =item L<Lambda|Dallycot::AST::Lambda> =item L<LibraryFunction|Dallycot::AST::LibraryFunction> =item L<Modulus|Dallycot::AST::Modulus> =item L<Negation|Dallycot::AST::Negation> =item L<Placeholder|Dallycot::AST::Placeholder> =item L<Product|Dallycot::AST::Product> =item L<PropertyLit|Dallycot::AST::PropertyLit> =item L<Reciprocal|Dallycot::AST::Reciprocal> =item L<Reduce|Dallycot::AST::Reduce> =item L<Sequence|Dallycot::AST::Sequence> =item L<Sum|Dallycot::AST::Sum> =item L<Tail|Dallycot::AST::Tail> =item L<TypePromotion|Dallycot::AST::TypePromotion> =item L<Unique|Dallycot::AST::Unique> =item L<Zip|Dallycot::AST::Zip> =back Additional base classes inherit from this abstract class as well: =over 4 =item L<ComparisonBase|Dallycot::AST::ComparisonBase> The base for the various comparison operations. =over 4 =item L<Decreasing|Dallycot::AST::Decreasing> =item L<Equality|Dallycot::AST::Equality> =item L<Increasing|Dallycot::AST::Increasing> =item L<StrictlyDecreasing|Dallycot::AST::StrictlyDecreasing> =item L<StrictlyIncreasing|Dallycot::AST::StrictlyIncreasing> =back =item L<LoopBase|Dallycot::AST::LoopBase> The base for operations that loop through a series of options. =over 4 =item L<All|Dallycot::AST::All> =item L<Any|Dallycot::AST::Any> =item L<Condition|Dallycot::AST::Condition> =item L<PropWalk|Dallycot::AST::PropWalk> =back =back =cut # use overload '""' => sub { # shift->to_string # }; our @NODE_TYPES; =func node_types Returns a list of Perl packages that provide AST nodes. =cut sub is_declarative {return} sub node_types { return @NODE_TYPES if @NODE_TYPES; (@NODE_TYPES) = shift->_node_types; return @NODE_TYPES; } __PACKAGE__->node_types; sub new { my ($class) = @_; $class = ref $class || $class; return bless [] => $class; } =method simplify Simplifies the node and any child nodes. =cut sub simplify { my ($self) = @_; return $self; } =method check_for_common_mistakes Checks for any odd expressions given their context. Returns a list of warnings. =cut sub check_for_common_mistakes { my ($self) = @_; return map { $_->check_for_common_mistakes } $self->child_nodes; } =method to_json Returns a Perl Hash containing the JSON-LD representation of the node and any child nodes. =cut sub to_json { my ($self) = @_; croak "to_json not defined for " . ( blessed($self) || $self ); } =method to_string Returns a Perl string containing a pseudo-code representation of the node and any child nodes. This string may not parse. It's intended for debugging purposes. =cut sub to_string { my ($self) = @_; croak "to_string not defined for " . ( blessed($self) || $self ); } =method execute($engine) Executes the node using the provided engine. Returns a promise. =cut sub execute { my ( $self, $engine ) = @_; my $d = deferred; $d->reject( ( blessed($self) || $self ) . " is not a valid operation" ); return $d->promise; } =method identifiers Returns a list of identifiers referenced in the current environment by this node. =cut sub identifiers { return () } =method child_nodes Returns a list of child nodes. =cut sub child_nodes { my ($self) = @_; return grep { blessed($_) && $_->isa(__PACKAGE__) } @{$self}; } 1;