lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nwelln...@apache.org
Subject [lucy-commits] [1/4] git commit: refs/heads/cfc-pod - Extract CFC DocuComments from C headers
Date Sat, 20 Jul 2013 16:06:00 GMT
Updated Branches:
  refs/heads/cfc-pod [created] 5d8677be6


Extract CFC DocuComments from C headers

Write a quick and dirty parser that builds CFC classes with DocuComments
from C headers. Then the .pod files for Clownfish::CFC can be generated
using CFC itself.


Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/5d8677be
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/5d8677be
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/5d8677be

Branch: refs/heads/cfc-pod
Commit: 5d8677be6b0a1a04908b2eb3e363de2dc2328990
Parents: d9d1ec1
Author: Nick Wellnhofer <wellnhofer@aevum.de>
Authored: Sat Jul 20 17:47:57 2013 +0200
Committer: Nick Wellnhofer <wellnhofer@aevum.de>
Committed: Sat Jul 20 18:05:22 2013 +0200

----------------------------------------------------------------------
 clownfish/compiler/perl/.gitignore              |   1 +
 .../perl/buildlib/Clownfish/CFC/Build.pm        |  65 +++++++
 .../buildlib/Clownfish/CFC/Build/Binding.pm     | 170 +++++++++++++++++++
 3 files changed, 236 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/.gitignore
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/.gitignore b/clownfish/compiler/perl/.gitignore
index 5517019..36bb0e4 100644
--- a/clownfish/compiler/perl/.gitignore
+++ b/clownfish/compiler/perl/.gitignore
@@ -1,3 +1,4 @@
+*.pod
 /Build
 /Charmony.pm
 /MYMETA.json

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
index 4ba1a6b..2f4cc2a 100644
--- a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
+++ b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build.pm
@@ -146,5 +146,70 @@ sub ACTION_code {
     $self->SUPER::ACTION_code;
 }
 
+sub ACTION_pod {
+    my $self = shift;
+
+    local @INC = ( @INC, qw( blib/lib blib/arch ) );
+    require Clownfish::CFC;
+
+    # Create a dummy hierarchy.
+    my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(
+        dest => 'autogen',
+    );
+
+    # Process all Binding classes in buildlib.
+    my $pm_filepaths = $self->rscan_dir( 'buildlib', qr/\.pm$/ );
+    for my $pm_filepath (@$pm_filepaths) {
+        next unless $pm_filepath =~ /Binding/;
+        require $pm_filepath;
+        my $package_name = $pm_filepath;
+        $package_name =~ s/buildlib\/(.*)\.pm$/$1/;
+        $package_name =~ s/\//::/g;
+        $package_name->bind_all($hierarchy);
+    }
+
+    my $binding = Clownfish::CFC::Binding::Perl->new(
+        hierarchy  => $hierarchy,
+        lib_dir    => 'lib',
+        boot_class => 'Clownfish::CFC',
+        header     => $self->autogen_header,
+        footer     => '',
+    );
+
+    print "Writing POD...\n";
+    my $pod_files = $binding->write_pod;
+    $self->add_to_cleanup($_) for @$pod_files;
+}
+
+sub autogen_header {
+    my $self = shift;
+    return <<"END_AUTOGEN";
+/***********************************************
+
+ !!!! DO NOT EDIT !!!!
+
+ This file was auto-generated by Build.PL.
+
+ ***********************************************/
+
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+END_AUTOGEN
+}
+
 1;
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/5d8677be/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
new file mode 100644
index 0000000..0819b4b
--- /dev/null
+++ b/clownfish/compiler/perl/buildlib/Clownfish/CFC/Build/Binding.pm
@@ -0,0 +1,170 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package Clownfish::CFC::Build::Binding;
+use strict;
+
+sub bind_all {
+    my $class = shift;
+    $class->bind_perlclass;
+}
+
+sub bind_perlclass {
+    class_from_c('CFCPerlClass', 'Clownfish::CFC::Binding::Perl::Class');
+
+    my @exposed = qw(
+        Bind_Constructor
+        Bind_Method
+        Exclude_Constructor
+        Exclude_Method
+        Set_Pod_Spec
+    );
+
+    my $pod_spec = Clownfish::CFC::Binding::Perl::Pod->new;
+    $pod_spec->add_constructor( alias => 'new' );
+    $pod_spec->add_method( method => $_, alias => lc($_) ) for @exposed;
+
+    my $binding = Clownfish::CFC::Binding::Perl::Class->new(
+        class_name => 'Clownfish::CFC::Binding::Perl::Class',
+    );
+    $binding->set_pod_spec($pod_spec);
+
+    Clownfish::CFC::Binding::Perl::Class->register($binding);
+}
+
+# Quick and dirty hack to create a CFC class from a C header.
+sub class_from_c {
+    my ($cfc_class_name, $class_name) = @_;
+
+    $class_name =~ /::(\w+)$/;
+    my $last_component = $1;
+
+    my $h_filename = "../src/$cfc_class_name.h";
+    open(my $h_file, '<', $h_filename)
+        or die("$h_filename: $!");
+
+    my ($class_doc, $function_doc, @functions);
+    my $state = 'before_class_doc';
+
+    while (my $line = <$h_file>) {
+        if ($state eq 'before_class_doc') {
+            if ($line =~ m"^/\*\*") {
+                $class_doc = $line;
+                $state = 'in_class_doc';
+            }
+        }
+        elsif ($state eq 'in_class_doc') {
+            $class_doc .= $line;
+            if ($line =~ m"\*/") {
+                $state = 'before_function_doc';
+            }
+        }
+        elsif ($state eq 'before_function_doc') {
+            if ($line =~ m"^/\*\*") {
+                $function_doc = $line;
+                $state = 'in_function_doc';
+            }
+        }
+        elsif ($state eq 'in_function_doc') {
+            $function_doc .= $line;
+            if ($line =~ m"\*/") {
+                $state = 'after_function_doc';
+            }
+        }
+        elsif ($state eq 'after_function_doc') {
+            if ($line =~ m"^${cfc_class_name}_(\w+)(\(.*)") {
+                my $function_name = $1;
+                my $c_params      = $2;
+
+                while ($c_params !~ /\)/) {
+                    $c_params .= <$h_file>;
+                }
+
+                $c_params =~ s/\).*/\)/;
+
+                push(@functions, {
+                    name     => $function_name,
+                    c_params => $c_params,
+                    doc      => $function_doc,
+                });
+
+                $state = 'before_function_doc';
+            }
+        }
+    }
+
+    close($h_file);
+
+    my $class = Clownfish::CFC::Model::Class->create(
+        class_name  => $class_name,
+        docucomment => Clownfish::CFC::Model::DocuComment->parse($class_doc),
+    );
+
+    my $parser = Clownfish::CFC::Parser->new;
+    my $void_type = Clownfish::CFC::Model::Type->new_void;
+
+    for my $function (@functions) {
+        my $name     = $function->{name};
+        my $c_params = $function->{c_params};
+        my $dc = Clownfish::CFC::Model::DocuComment->parse($function->{doc});
+
+        # "struct" is not allowed in Clownfish types.
+        $c_params =~ s/\bstruct //g;
+        # Clownfish reserved words.
+        $c_params =~ s/\bparcel\b/_$&/g;
+        # Empty param list.
+        $c_params = '()' if $c_params eq '(void)';
+
+        if ($c_params =~ /\($cfc_class_name \*self/) {
+            my $macro_sym = $name;
+            $macro_sym =~ s/(^|_)([a-z])/$1 . uc($2)/ge;
+
+            $c_params =~ s/^\(\w+/($last_component/;
+            my $param_list = $parser->parse($c_params)
+                or die("Invalid param list: $c_params");
+
+            my $method = Clownfish::CFC::Model::Method->new(
+                class_name  => $class_name,
+                exposure    => 'public',
+                macro_sym   => $macro_sym,
+                docucomment => $dc,
+                return_type => $void_type,
+                param_list  => $param_list,
+            );
+            $class->add_method($method);
+        }
+        else {
+            $name = 'init' if $name eq 'new';
+
+            my $param_list = $parser->parse($c_params)
+                or die("Invalid param list: $c_params");
+
+            my $function = Clownfish::CFC::Model::Function->new(
+                class_name  => $class_name,
+                exposure    => 'public',
+                micro_sym   => $name,
+                docucomment => $dc,
+                return_type => $void_type,
+                param_list  => $param_list,
+            );
+            $class->add_function($function);
+        }
+    }
+
+    return $class;
+}
+
+1;
+


Mime
View raw message