Anarres-Mud-Driver
view release on metacpan or search on metacpan
lib/Driver/Compiler/Check.pm view on Meta::CPAN
sub check_children {
my ($self, $vals, @rest) = @_;
my $ok = 1;
foreach (@$vals) {
next unless $_; # We have some 'undef' statements.
$_->check(@rest)
or $ok = undef;
}
return $ok;
}
# A utility function called from various packages at boot time.
# It replaces code similar to the following in various packages.
# my $package = __PACKAGE__;
# $package =~ s/[^:]+$/Index/;
# no strict qw(refs);
# *lvaluep = \&{ "$package\::lvaluep" };
sub steal {
my ($self, $victim, $subname) = @_;
my $target = ref($self) || $self;
my $source = $target;
$source =~ s/[^:]+$/$victim/;
no strict qw(refs);
my $sub = \&{ "$source\::$subname" }
or confess "No such sub $subname in $source";
*{ "$target\::$subname" } = $sub;
}
# Now the node-specific packages.
{
package Anarres::Mud::Driver::Compiler::Node::Nil;
sub check { $_[0]->settype(T_NIL); $_[0]->setflag(F_CONST); 1; }
}
{
package Anarres::Mud::Driver::Compiler::Node::String;
sub check {$_[0]->settype(T_STRING); $_[0]->setflag(F_CONST); 1;}
}
{
package Anarres::Mud::Driver::Compiler::Node::Integer;
# This doesn't start/end since it can't fail.
sub check {$_[0]->settype(T_INTEGER); $_[0]->setflag(F_CONST); 1;}
sub promote {
my ($self, $newtype, @rest) = @_;
# Yes, a special case.
if ($self->value(0) == 0) { # A valid nil
unless ($newtype->equals(T_INTEGER)) {
my $nil = new Anarres::Mud::Driver::Compiler::Node::Nil;
$nil->check;
return $nil;
}
}
return $self->SUPER::promote($newtype, @rest);
}
}
{
package Anarres::Mud::Driver::Compiler::Node::Array;
sub check {
my ($self, $program, @rest) = @_;
$self->tc_start;
my @values = $self->values;
$self->check_children(\@values, $program, @rest)
or return $self->tc_fail(T_ARRAY);
my $flag = F_CONST;
my $type = T_NIL;
foreach (@values) {
# Search the types to find a good type.
$type = $_->type->unify($type);
$flag &= $_->flags;
}
$self->settype($type->array);
$self->setflag($flag) if $flag;
return $self->tc_end;
}
}
{
package Anarres::Mud::Driver::Compiler::Node::Mapping;
sub check {
my ($self, $program, @rest) = @_;
$self->tc_start;
my @values = $self->values;
$self->check_children(\@values, $program, @rest)
or return $self->tc_fail(T_MAPPING);
my $ret = 1;
my $flag = F_CONST;
my $type = T_NIL;
my $idx = 0;
foreach (@values) {
# Search the types to find a good type.
if ($idx & 1) {
$type = $_->type->unify($type);
}
else {
my $key = $_->promote(T_STRING);
if ($key) {
$self->setvalue($idx, $key);
}
else {
$program->error("Map keys must be strings, not " .
$_->dump);
$ret = undef;
}
( run in 1.083 second using v1.01-cache-2.11-cpan-ceb78f64989 )