Anarres-Mud-Driver
view release on metacpan or search on metacpan
lib/Driver/Compiler/Check.pm view on Meta::CPAN
or push(@errors, "Cannot index on array with " .
$idx->type->name);
return @errors if @errors;
$self->settype($val->type->dereference);
bless $self, __PACKAGE__;
return ();
}
}
{
package Anarres::Mud::Driver::Compiler::Node::MapIndex;
__PACKAGE__->steal("Index", "lvaluep");
sub convert {
my ($self, $program, @rest) = @_;
my ($val, $idx, $endp) = $self->values;
my @errors = ();
$val->check($program, @rest)
or push(@errors, "Failed to check value " . $val->opcode);
$idx->check($program, @rest)
or push(@errors, "Failed to check index " . $idx->opcode);
$val->type->is_mapping
or push(@errors, "Cannot perform mapping dereference on " .
$val->type->name);
# XXX Make this use promotion properly.
$idx->type->equals(T_STRING)
||
$idx->type->equals(T_INTEGER)
or push(@errors, "Cannot index on mapping with " .
$idx->type->name);
return @errors if @errors;
$endp
and $program->error("Cannot index from end of mapping");
$self->settype($val->type->dereference);
bless $self, __PACKAGE__;
return ();
}
}
{
package Anarres::Mud::Driver::Compiler::Node::Member;
sub lvaluep {
if ($_[0]->value(0)->lvaluep) {
$_[0]->setflag(F_LVALUE);
return 1;
}
return undef;
}
sub check {
my ($self, $program, @rest) = @_;
$self->tc_start;
my ($value, $field) = $self->values;
$value->check($program, @rest)
or return $self->tc_fail;
my $type = $value->type;
if (!($type->is_class)) {
$program->error("Cannot get member $field of type " .
$type->name);
# print STDERR "Failed fragment is " . $value->dump, "\n";
return $self->tc_fail;
}
elsif (0) { # XXX Does the field exist?
$program->error("No field called $field in class " .
$type->class);
return $self->tc_fail;
}
my $ftype = $program->class_field_type($type->class, $field);
$self->settype($ftype); # Might be T_FAILED
return $self->tc_end;
}
}
{
package Anarres::Mud::Driver::Compiler::Node::New;
sub check {
my ($self, $program, $flags, @rest) = @_;
my $cname = $self->value(0);
$self->tc_start("class $cname");
my $type = $program->class_type($cname);
$self->settype($type); # Might be T_FAILED
return $self->tc_end;
}
}
# 1. Promote things to blocks.
# 2. Check children
# 3. Check that things are lvalues.
# 4. Check that things are appropriate types.
# 5. Rebless the current node.
# 6. Set the type of the current node.
# 7. Return a success or failure.
{
package Anarres::Mud::Driver::Compiler::Node::Sscanf;
# This should be $_[1], @{$_[2]}
sub check {
my ($self, $program, $flags, @rest) = @_;
my @values = $self->values;
$self->tc_start;
$self->check_children(\@values, $program, @rest)
or return $self->tc_fail(T_INTEGER);
my $exp = shift @values;
my $fmt = shift @values;
my $sexp = $exp->promote(T_STRING);
unless ($sexp) {
$program->error("Input for sscanf must be string, not " .
${ $exp->type });
return $self->tc_fail(T_INTEGER);
}
$self->setvalue(0, $sexp);
my $sfmt = $fmt->promote(T_STRING);
unless ($sfmt) {
$program->error("Format for sscanf must be string, not " .
$fmt->type->dump);
return $self->tc_fail(T_INTEGER);
}
( run in 1.079 second using v1.01-cache-2.11-cpan-b16cb0d3907 )