Decl
view release on metacpan or search on metacpan
lib/Decl/Node.pm view on Meta::CPAN
next unless ref $_;
$_ = $new if $_ == $old;
}
}
=head2 Setting parts of a node: set_name($name), set_label($label), set_parmlist (@list), set_parameter($key, $value), set_optionlist (@list), set_option($key, $value)
These are handy for building a node from scratch.
=cut
sub set_name {
my $self = shift;
$self->{name} = $_[0];
$self->{namelist} = [@_]; # Make a copy!
}
sub set_label {
my $self = shift;
$self->{label} = $_[0];
}
sub set_parmlist {
my $self = shift;
$self->{parmlist} = [@_];
}
sub set_parameter {
my ($self, $key, $value) = @_;
$self->{parameters}->{$key} = $value;
}
sub set_optionlist {
my $self = shift;
$self->{optionlist} = [@_];
}
sub set_option {
my ($self, $key, $value) = @_;
$self->{options}->{$key} = $value;
}
=head2 The build process: build(), preprocess(), preprocess_line(), decode_line(), parse_body(), build_payload(), build_children(), add_to_parent(), post_build()
The C<build> function parses the body of the tag, then builds the payload it defines, then calls build on each child if appropriate, then adds itself
to its parent. It provides the hooks C<preprocess> (checks for macro nature and expresses if so), C<parse_body> (asks the application to call the appropriate
parser for the tag), C<build_payload> (does nothing by default), C<build_children> (calls C<build> on each element), and C<add_to_parent>
(does nothing by default).
If this tag corresponds to a macro, then substitution takes place before parsing, in the preprocess step.
=cut
sub build {
my $self = shift;
return $self->{replaced}->build if $self->{replaced};
if ($self->{state} ne 'built') {
if ($self->root()->{macro_definitions}->{$self->tag}) { # This is required because in some cases, the macro definition may have been
# registered *after* the class was already assigned to the macro instance.
# E.g.:
# define my_macro
# ...
# my_macro
# (On the same level with the same parent, my_macro has already been split out.)
bless $self, 'Decl::Semantics::Macro';
}
$self->{force_text} = 0;
$self->preprocess_line;
$self->decode_line;
$self->preprocess;
$self->parse_body unless $self->{force_text};
$self->build_payload;
$self->build_children unless $self->{force_text};
$self->add_to_parent;
$self->post_build;
$self->{state} = 'built';
}
return $self->payload;
}
sub preprocess_line {}
sub decode_line { # Was called parse_line, but there was an unfortunate and brain-bending collision with Text::ParseWords. Oy.
my $self = shift;
my $root = $self->root;
$root->parse_line ($self);
}
sub preprocess {}
sub parse_body {
my $self = shift;
if ($self->tag =~ /^!/) {
$self->{tag} =~ s/^!//;
} else {
my $root = $self->root;
if (ref $self->body eq 'ARRAY') {
# If we have an arrayref input, we don't need to parse it! (2010-12-05)
#print "parse_body: body is an arrayref\n";
my $list = $self->{body};
$self->{body} = '';
foreach (@$list) {
$self->load ($_);
}
} else {
my @results = $root->parse ($self, $self->body) if $self->body and not $self->{bracket};
$self->{body} = '' if @results;
}
}
}
sub build_payload {}
sub build_children {
my $self = shift;
foreach ($self->nodes) {
$_->build if $_->can('build');
}
}
sub add_to_parent {}
sub post_build {}
( run in 1.008 second using v1.01-cache-2.11-cpan-39bf76dae61 )