use strict;
use warnings;
package Clownfish::Type;
use Clownfish::Parcel;
use Clownfish::Util qw( verify_args );
use Scalar::Util qw( blessed );
use Carp;
our %new_PARAMS = (
const => undef,
specifier => undef,
indirection => undef,
parcel => undef,
c_string => undef,
);
sub new {
my $either = shift;
my $package = ref($either) || $either;
confess( __PACKAGE__ . "is an abstract class" )
if $package eq __PACKAGE__;
verify_args( \%new_PARAMS, @_ ) or confess $@;
my $self = bless { %new_PARAMS, @_, }, $package;
if ( defined $self->{parcel} ) {
if ( !blessed( $self->{parcel} ) ) {
$self->{parcel}
= Clownfish::Parcel->singleton( name => $self->{parcel} );
}
confess("Not a Clownfish::Parcel")
unless $self->{parcel}->isa('Clownfish::Parcel');
}
return $self;
}
sub get_specifier { shift->{specifier} }
sub get_parcel { shift->{parcel} }
sub const { shift->{const} }
sub nullable { shift->{nullable} }
sub is_object {0}
sub is_primitive {0}
sub is_integer {0}
sub is_floating {0}
sub is_void {0}
sub is_composite {0}
sub is_string_type {0}
sub equals {
my ( $self, $other ) = @_;
return 0 unless blessed($other);
return 0 unless $other->isa(__PACKAGE__);
return 1;
}
sub to_c { shift->{c_string} }
sub set_c_string { $_[0]->{c_string} = $_[1] }
1;
__END__
__POD__
=head1 NAME
Clownfish::Type - A variable's type.
=head1 METHODS
=head2 new
my $type = MyType->new(
specifier => 'char', # default undef
indirection => undef, # default 0
const => 1, # default undef
parcel => undef, # default undef
c_string => undef, # default undef
);
Abstract constructor.
=over
=item *
B<specifier> - The C name for the type, not including any indirection or array
subscripts.
=item *
B<indirection> - integer indicating level of indirection. Example: the C type
"float**" has a specifier of "float" and indirection 2.
=item *
B<const> - should be true if the type is const.
=item *
B<parcel> - A Clownfish::Parcel or a parcel name.
=item *
B<c_string> - The C representation of the type.
=back
=head2 equals
do_stuff() if $type->equals($other);
Returns true if two Clownfish::Type objects are equivalent. The default
implementation merely checks that C<$other> is a Clownfish::Type object, so
it should be overridden in all subclasses.
=head2 to_c
# Declare variable "foo".
print $type->to_c . " foo;\n";
Return the C representation of the type.
=head2 set_c_string
Set the C representation of the type.
=head2 get_specifier get_parcel const nullable
Accessors.
=head2 is_object is_primitive is_integer is_floating is_composite is_void
do_stuff() if $type->is_object;
Shorthand for various $type->isa($package) calls.
=over
=item * is_object: Clownfish::Type::Object
=item * is_primitive: Clownfish::Type::Primitive
=item * is_integer: Clownfish::Type::Integer
=item * is_floating: Clownfish::Type::Float
=item * is_void: Clownfish::Type::Void
=item * is_composite: Clownfish::Type::Composite
=back
=head2 is_string_type
Returns true if $type represents a Clownfish type which holds unicode
strings.
=head1 COPYRIGHT AND LICENSE
Copyright 2008-2011 Marvin Humphrey
This program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut