Anarres-Mud-Driver

 view release on metacpan or  search on metacpan

lib/Driver/Compiler/Check.pm  view on Meta::CPAN

		# These are choice targets.
		(map { $_ => 'NOCHECK' } qw(
			MapAdd MapSub
				)),

	ObjEq		=> [ T_OBJECT, T_OBJECT,				T_BOOL ],
	ObjNe		=> [ T_OBJECT, T_OBJECT,				T_BOOL ],

		# These actually have custom choose routines.
		(map { $_ => 'CHOOSE' } qw(
			Index Range
				)),

	StrIndex	=> [ T_STRING, T_INTEGER, undef,		T_INTEGER ],
	StrRange	=> [ T_STRING, T_INTEGER, T_INTEGER, undef, undef,
														T_INTEGER ],
		# These are choice targets with nonstatic types
		(map { $_ => 'NOCHECK' } qw(
			ArrIndex ArrRange
			MapIndex
				)),
		# These have nonstatic types
		(map { $_ => 'CODE' } qw(
			Member New
				)),

	Catch		=> [ T_UNKNOWN,							T_STRING ],

	Assign		=> 'CODE',		# Output type is input type

	ExpCond		=> 'CODE',		# Output type is unification of input

	Block		=> 'CODE',		# Iterate over statements

	StmtExp		=> [ T_UNKNOWN,							T_VOID ],
	StmtRlimits => [ T_INTEGER, T_INTEGER, 'BLOCK',		T_VOID ],
	StmtTry		=> 'CODE',
	StmtCatch	=> [ 'BLOCK',							T_VOID ],

		# XXX These have to set up break and continue targets.
	StmtDo		=> [ T_BOOL, 'BLOCK',					T_VOID ],
	StmtWhile	=> [ T_BOOL, 'BLOCK',					T_VOID ],
	StmtFor		=> [ T_VOID, T_BOOL, T_VOID, 'BLOCK',	T_VOID ],
		(map { $_ => 'CODE' } qw(
			StmtForeach StmtForeachArr StmtForeachMap
				)),

		# StmtBreak also needs code to get the label.
		# Most of the flow control statements probably need code.
	StmtSwitch	=> 'CODE',		# Open a new switch context
	StmtCase	=> 'CODE',		# Generate a label
	StmtDefault	=> 'CODE',		# Sort out the labels
	StmtIf		=> 'CODE',		# Handle the 'else' clause!
	StmtBreak	=> 'CODE',		# Get the break target
	StmtContinue=> 'CODE',		# Get the continue target
	StmtReturn	=> 'CODE',		# Output type must match function

	Sscanf		=> 'CODE',		# Urgh!
);

	# This looks like a fast way of generating the choice table for
	# promotable operators, but does depend a little on the naming
	# of opcodes! If there are any special cases, they need to be put
	# into %OPCHOICES as literals. I'm going to get lynched for this.
{
	%OPCHOICES = ();
	no strict qw(refs);
	my $package = __PACKAGE__;
	$package =~ s/[^:]+$/Node/;
	foreach my $op (keys %OPTYPES) {
		next unless $OPTYPES{$op} eq 'CHOOSE';
		foreach my $tp (qw(Int Str Obj Arr Map)) {
			push(@{ $OPCHOICES{$op} }, "$tp$op") if $OPTYPES{"$tp$op"};
		}
	}
}
# We can't do this because we then don't pass the new opcode type
# in the case that we're calling the superclass method! Furthermore,
# the subclass method we actually try to call won't exist.
#			my $sub = \&{ "$package\::$tp$op::convert" }
#					or die "No 'convert' in package $package\::$tp$op";


# A lot of superclass methods. These are found in ::Check via @ISA.

sub lvaluep { undef; }
sub constp { undef; }

sub assert {	# This sucks somewhat
	my ($self, $type) = @_;
	if (!$self->type->equals(T_UNKNOWN)) {	# DEBUGGING
		confess "Asserting something of known type.";
	}
	print "Asserting " . $self->opcode . " into " . ${$type} . "\n";
	return new Anarres::Mud::Driver::Compiler::Node::IntAssert($self)
					if $type->equals(T_INTEGER);
	return new Anarres::Mud::Driver::Compiler::Node::StrAssert($self)
					if $type->equals(T_STRING);
	return new Anarres::Mud::Driver::Compiler::Node::ArrAssert($self)
					if $type->is_array;
	return new Anarres::Mud::Driver::Compiler::Node::MapAssert($self)
					if $type->is_mapping;
	return new Anarres::Mud::Driver::Compiler::Node::ClsAssert($self)
					if $type->equals(T_CLOSURE);
	return new Anarres::Mud::Driver::Compiler::Node::ObjAssert($self)
					if $type->equals(T_OBJECT);
	confess "Cannot assert node into type " . $$type . "!\n";
	return undef;
}

sub promote_to_block {
	my ($self, $stmt) = @_;

	return $stmt if ref($stmt) =~ /::Block$/;
	confess "Can only promote statements into blocks, not " .
			$stmt->opcode
					unless ref($stmt) =~ /::Stmt[^:]+$/;

	# It's a statement. This code is partially duplicated below.
	return new Anarres::Mud::Driver::Compiler::Node::Block(
					[],	# locals



( run in 1.933 second using v1.01-cache-2.11-cpan-6aa56a78535 )