You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2011/02/07 22:54:34 UTC

[lucy-commits] svn commit: r1068155 - in /incubator/lucy/trunk/clownfish: lib/Clownfish/Parser.pm lib/Clownfish/Type.pm lib/Clownfish/Type/Arbitrary.pm t/107-arbitrary_type.t

Author: marvin
Date: Mon Feb  7 21:54:33 2011
New Revision: 1068155

URL: http://svn.apache.org/viewvc?rev=1068155&view=rev
Log:
Absorb Clownfish::Type::Arbitrary into parent class Clownfish::Type.

Removed:
    incubator/lucy/trunk/clownfish/lib/Clownfish/Type/Arbitrary.pm
Modified:
    incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm
    incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm
    incubator/lucy/trunk/clownfish/t/107-arbitrary_type.t

Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm?rev=1068155&r1=1068154&r2=1068155&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Parser.pm Mon Feb  7 21:54:33 2011
@@ -24,7 +24,6 @@ use Clownfish::Type;
 use Clownfish::Type::Integer;
 use Clownfish::Type::Float;
 use Clownfish::Type::Void;
-use Clownfish::Type::Arbitrary;
 use Clownfish::Variable;
 use Clownfish::DocuComment;
 use Clownfish::Function;
@@ -358,7 +357,7 @@ sub new_void_type {
 
 sub new_arbitrary_type {
     my ( undef, $item ) = @_;
-    return Clownfish::Type::Arbitrary->new(
+    return Clownfish::Type->new_arbitrary(
         specifier => $item->{arbitrary_type_specifier},
         parcel    => $parcel,
     );

Modified: incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm?rev=1068155&r1=1068154&r2=1068155&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm (original)
+++ incubator/lucy/trunk/clownfish/lib/Clownfish/Type.pm Mon Feb  7 21:54:33 2011
@@ -188,6 +188,38 @@ sub new_va_list {
     );
 }
 
+our %new_arbitrary_PARAMS = (
+    parcel    => undef,
+    specifier => undef,
+);
+
+sub new_arbitrary {
+    my $either = shift;
+    verify_args( \%new_arbitrary_PARAMS, @_ ) or confess $@;
+    my $self = $either->new( @_, arbitrary => 1 );
+
+    # Validate specifier.
+    my $specifier = $self->get_specifier;
+    my $parcel    = $self->get_parcel;
+    confess("illegal specifier: '$specifier'")
+        unless $specifier =~ /^\w+$/;
+    if ( $specifier =~ /^[A-Z]/ and $parcel ) {
+        my $prefix = $parcel->get_prefix;
+        # Add $prefix to what appear to be namespaced types.
+        if ( $specifier !~ /^$prefix/ ) {
+            $specifier = $prefix . $specifier;
+            $self->set_specifier($specifier);
+        }
+    }
+
+    # Cache C representation.
+    my $string = $self->const ? 'const ' : '';
+    $string .= $specifier;
+    $self->set_c_string($string);
+
+    return $self;
+}
+
 sub DESTROY {
     my $self = shift;
     delete $array{$self};
@@ -355,8 +387,6 @@ The Parcel's prefix will be prepended to
         specifier => 'va_list',    # default: va_list
     );
 
-=head1 DESCRIPTION
-
 Create a Type representing C's va_list, from stdarg.h.
 
 =over
@@ -365,6 +395,43 @@ Create a Type representing C's va_list, 
 
 =back
 
+=head2 new_arbitrary
+
+    my $type = Clownfish::Type->new_arbitrary(
+        specifier => 'floatint_t',    # required
+        parcel    => 'Crustacean',    # default: undef
+    );
+
+"Arbitrary" types are a hack that spares us from having to support C types
+with complex declaration syntaxes -- such as unions, structs, enums, or
+function pointers -- from within Clownfish itself.
+
+The only constraint is that the C<specifier> must end in "_t".  This allows us
+to create complex types in a C header file...
+
+    typedef union { float f; int i; } floatint_t;
+
+... pound-include the C header, then use the resulting typedef in a Clownfish
+header file and have it parse as an "arbitrary" type.
+
+    floatint_t floatint;
+
+=over
+
+=item * B<specifier> - The name of the type, which must end in "_t".
+
+=item * B<parcel> - A L<Clownfish::Parcel> or a parcel name.
+
+=back
+
+If C<parcel> is supplied and C<specifier> begins with a capital letter, the
+Parcel's prefix will be prepended to the specifier:
+
+    foo_t         -> foo_t                # no prefix prepending
+    Lobster_foo_t -> crust_Lobster_foo_t  # prefix prepended
+
+=cut
+
 =head2 equals
 
     do_stuff() if $type->equals($other);

Modified: incubator/lucy/trunk/clownfish/t/107-arbitrary_type.t
URL: http://svn.apache.org/viewvc/incubator/lucy/trunk/clownfish/t/107-arbitrary_type.t?rev=1068155&r1=1068154&r2=1068155&view=diff
==============================================================================
--- incubator/lucy/trunk/clownfish/t/107-arbitrary_type.t (original)
+++ incubator/lucy/trunk/clownfish/t/107-arbitrary_type.t Mon Feb  7 21:54:33 2011
@@ -17,17 +17,17 @@ use strict;
 use warnings;
 
 use Test::More tests => 12;
-use Clownfish::Type::Arbitrary;
+use Clownfish::Type;
 use Clownfish::Parser;
 
-my $foo_type = Clownfish::Type::Arbitrary->new(
+my $foo_type = Clownfish::Type->new_arbitrary(
     parcel    => 'Neato',
     specifier => "foo_t",
 );
 is( $foo_type->get_specifier, "foo_t", "get_specifier" );
 is( $foo_type->to_c,          "foo_t", "to_c" );
 
-my $compare_t_type = Clownfish::Type::Arbitrary->new(
+my $compare_t_type = Clownfish::Type->new_arbitrary(
     parcel    => 'Neato',
     specifier => "Sort_compare_t",
 );
@@ -35,7 +35,7 @@ is( $compare_t_type->get_specifier,
     "neato_Sort_compare_t", "Prepend prefix to specifier" );
 is( $compare_t_type->to_c, "neato_Sort_compare_t", "to_c" );
 
-my $evil_twin = Clownfish::Type::Arbitrary->new(
+my $evil_twin = Clownfish::Type->new_arbitrary(
     parcel    => 'Neato',
     specifier => "foo_t",
 );
@@ -49,8 +49,8 @@ my $parser = Clownfish::Parser->new;
 for my $specifier (qw( foo_t Sort_compare_t )) {
     is( $parser->arbitrary_type_specifier($specifier),
         $specifier, 'arbitrary_type_specifier' );
-    isa_ok( $parser->arbitrary_type($specifier),
-        "Clownfish::Type::Arbitrary" );
+    my $type = $parser->arbitrary_type($specifier);
+    ok( $type && $type->is_arbitrary, "arbitrary_type '$specifier'" );
     ok( !$parser->arbitrary_type_specifier( $specifier . "_y_p_e" ),
         "arbitrary_type_specifier guards against partial word matches"
     );