develooper Front page | perl.moose | Postings from July 2014

From IDL To Moose

From:
Jean-Damien Durand
Date:
July 24, 2014 20:25
Subject:
From IDL To Moose
Message ID:
70316295.xxoqnPuVjZ@jddwww
Hello,

I have been working on an IDL to Moose translator, and would like some advice on the implementation style.

The framework is:
* parse the OMG IDL 3.5 grammar with Marpa
* produce an AST of it
* use Template::Toolkit to generate a Moose version

The project is at https://github.com/jddurand/MarpaX-Languages-IDL-AST .

The first generation is trying to avoid sugars as much as possible. Nothing prevent to have another "style" using e.g. MooseX::Declare.

The prerequesites are:
* IDL makes a clear definition of scoped names, i.e. everything declared in an outer scope is visible, although not necessarily used.
  - That's why current implementation follows the "scoped" style, i.e. perl packages are embedded each other, like in an IDL, and I map an IDL scoped name to a perl scoped variable.
* The goal is NOT to provide a CORBA system. Only to map IDL to Moose style.
* Following Java, constants and IDL's enum are implemented like roles
* All Basic types are mapped to an internal type library MarpaX::Languages::IDL::AST::MooseX::_BaseTypes

The only gotcha is that I use exclusively roles, and this will not permit that roles that are using other roles would not import some methods, unless Moose hacking a-la MooseX::ComposedBehavior (AFAIK).

If some of you experts could have time to tell me what is superfluous, obviously wrong, etc. I would be glad to hear from you, since I claim to be a Moose beginner.

Let's start with a tiny example: Hello World idl

---
module HelloApp
{
  interface Hello
  {
  string sayHello();
  oneway void shutdown();
  };
};
---

The generated Moose is currently:
---
#!env perl
package HelloApp {
    use Moose::Role;
    use MRO::Compat;
    use namespace::sweep;
    use MooseX::Types -declare => [
        qw/
          Hello
          /
    ];
    our $Hello = role_type Hello, { role => 'HelloApp::Hello' };

    package HelloApp::Hello {
        use Moose::Role;
        use MRO::Compat;
        use namespace::sweep;
        use MooseX::Params::Validate qw/pos_validated_list/;
        use MarpaX::Languages::IDL::AST::MooseX::_BaseTypes qw/:all/;
        requires 'sayHello';
        around 'sayHello' => sub {
            my $orig = shift;
            my $self = shift;

            return pos_validated_list( [ $self->$orig() ],
                { isa => _stringType } );
        };
        requires 'shutdown';
        around 'shutdown' => sub {
            my $orig = shift;
            my $self = shift;

            $self->$orig();
            return undef;
        };
    };
};

1;
---

And an example of its use would be:

---
package HelloApp::HelloImpl {
    use Moose::Role;
    use MarpaX::Languages::IDL::AST::MooseX::_BaseTypes qw/:all/;
    sub sayHello() {
	return "\nHello world !!\n";
    };
    
    sub shutdown() {
    };

    with 'HelloApp::Hello';
};

package HelloAppImpl {
    use Moose;
    with 'HelloApp', 'HelloApp::HelloImpl';
};

package main;
use HelloAppImpl;
my $HelloAppImpl = HelloAppImpl->new();
$HelloAppImpl->sayHello;
---

As you can see I make explicit use of things like:
- MRO::Compat
- namespace::sweep
- MooseX::Params::Validate

to perform mro resolution, namespace cleaning and non-MooseX-Declare validation of return type (and of parameters when needed).

A more concrete example is the DOM Level 3 Core Specification, available at http://www.w3.org/TR/DOM-Level-3-Core/idl/dom.idl.
Its Moose generated equivalent is not pasted here, but at this location: https://gist.github.com/jddurand/1a1dc1f148fe6f77dd5c .

Thanks, Jean-Damien.

ps: sorry I first tried to google interface instead of the mail




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About