Skip to content
This repository has been archived by the owner on Feb 3, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Start to stub out role meta-objects. All roles are implicitly paramet…
…ric because a mention of $?CLASS is generic. The base here could be built up to do parametric roles in NQP, but that's not on the cards at the momnet; of course, Rakudo's meta-objects will carry a full implementation of those.
  • Loading branch information
jnthn committed Feb 5, 2011
1 parent 0b5765d commit 594f186
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
1 change: 1 addition & 0 deletions build/Makefile.in
Expand Up @@ -164,6 +164,7 @@ METAMODEL_OBJS = ../metamodel/rakudoobject$(O) ../metamodel/repr_registry$(O)

HOW_SOURCES = src/metamodel/how/KnowHOWAttribute.pm src/metamodel/how/NQPClassHOW.pm \
src/metamodel/how/NQPNativeHOW.pm src/metamodel/how/NQPAttribute.pm \
src/metamodel/how/NQPConcreteRoleHOW.pm src/metamodel/how/NQPParametricRoleHOW.pm \
src/metamodel/how/NQPMu.pm src/metamodel/how/NativeTypes.pm

HOW_COMBINED = src/gen/how.pm
Expand Down
75 changes: 75 additions & 0 deletions src/metamodel/how/NQPConcreteRoleHOW.pm
@@ -0,0 +1,75 @@
# This implements a concrete, parameterized instance of a role that
# can be composed into a class or mixed into an object.
knowhow NQPConcreteRoleHOW {
##
## Attributes
##

# Name of the concrete role.
has $!name;

# Attributes and methods.
has %!attributes;
has %!methods;

# Have we been composed?
has $!composed;


##
## Declarative
##

# Creates a new instance of this meta-class.
method new(:$name!) {
my $obj := pir::repr_instance_of__PP(self);
$obj.BUILD(:name($name));
$obj
}

method BUILD(:$name!) {
$!name := $name;
}

# Create a new meta-object instance, and then a new type object
# to go with it, and return that.
method new_type(:$name = '<anon>', :$repr = 'P6opaque') {
my $metarole := self.new(:name($name));
pir::repr_type_object_for__PPS($metarole, $repr);
}

# Compose the role. Beyond this point, no changes are allowed.
method compose($obj) {
$!composed := 1;
$obj
}


##
## Introspecty
##

method methods($obj, :$local!) {
my @meths;
for %!methods {
@meths.push($_.value);
}
@meths
}

method method_table($obj) {
%!methods
}

method name($obj) {
$!name
}

method attributes($obj, :$local!) {
my @attrs;
for %!attributes {
@attrs.push($_.value);
}
@attrs
}
}
110 changes: 110 additions & 0 deletions src/metamodel/how/NQPParametricRoleHOW.pm
@@ -0,0 +1,110 @@
# This implements a parametric role (that is, one that has yet to be
# parameterized to get a concrete role that we can actually compose
# into a class or mix into an object). It also contains the logic to
# reify it into an actual role.
knowhow NQPParametricRoleHOW {
##
## Attributes
##

# Name of the parametric role.
has $!name;

# Attributes and methods.
has %!attributes;
has %!methods;

# Have we been composed?
has $!composed;

# The body block of the role. (If we were to support multiple role
# variants with the same name, this would be a multi. However, we
# don't do that in NQP.)
has $!body_block;


##
## Declarative
##

# Creates a new instance of this meta-class.
method new(:$name!, :$body_block!) {
my $obj := pir::repr_instance_of__PP(self);
$obj.BUILD(:name($name), :body_block($body_block));
$obj
}

method BUILD(:$name!, :$body_block!) {
$!name := $name;
$!body_block := $body_block;
}

# Create a new meta-class instance, and then a new type object
# to go with it, and return that.
method new_type(:$body_block!, :$name = '<anon>', :$repr = 'P6opaque') {
my $metarole := self.new(:name($name), :body_block($body_block));
pir::repr_type_object_for__PPS($metarole, $repr);
}

# Compose the role. Beyond this point, no changes are allowed.
method compose($obj) {
$!composed := 1;
$obj
}


##
## Parametricity
##

# Method to indicate that this type is parametric.
method parametric($obj) {
1
}

# This instantiates the role with arguments and builds a concrete
# role.
method instantiate($obj, *@pos_args, *%named_args) {
# Run the body block to capture the arguments into the correct
# type argument context.
$!body_block();

# Construct a new concrete role.
my $irole := NQPConcreteRoleHOW.new_type(:name($!name));

# XXX Much comes here

# Compose and return produced role.
$irole.HOW.compose($irole);
return $irole;
}


##
## Introspecty
##

method methods($obj, :$local!) {
my @meths;
for %!methods {
@meths.push($_.value);
}
@meths
}

method method_table($obj) {
%!methods
}

method name($obj) {
$!name
}

method attributes($obj, :$local!) {
my @attrs;
for %!attributes {
@attrs.push($_.value);
}
@attrs
}
}

0 comments on commit 594f186

Please sign in to comment.