Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add attributes to compile time meta-object for all packages except kn…
…owhow (got a circularity issue to resolve there).
  • Loading branch information
jnthn committed Apr 26, 2011
1 parent 4b81716 commit 0c07f7d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 24 deletions.
32 changes: 32 additions & 0 deletions src/HLL/SerializationContextBuilder.pm
Expand Up @@ -319,6 +319,38 @@ class HLL::Compiler::SerializationContextBuilder {
return $mo;
}

# Constructs a meta-attribute and adds it to a meta-object. Expects to
# be passed the meta-attribute type object, a set of literal named
# arguments to pass and a set of name to object mappings to pass also
# as named arguments, but where these passed objects also live in a
# serialization context. The type would be passed in this way.
method pkg_add_attribute($obj, $meta_attr, %lit_args, %obj_args) {
# Create and add right away.
my $attr := $meta_attr.new(|%lit_args, |%obj_args);
$obj.HOW.add_attribute($obj, $attr);

# Emit code to create and add it when deserializing.
my $create_call := PAST::Op.new(
:pasttype('callmethod'), :name('new'),
self.get_object_sc_ref_past($meta_attr)
);
for %lit_args {
$create_call.push(PAST::Val.new( :value($_.value), :named($_.key) ));
}
for %obj_args {
my $lookup := self.get_object_sc_ref_past($_.value);
$lookup.named($_.key);
$create_call.push($lookup);
}
my $obj_slot_past := self.get_slot_past_for_object($obj);
self.add_event(:deserialize_past(PAST::Op.new(
:pasttype('callmethod'), :name('add_attribute'),
PAST::Op.new( :pirop('get_how PP'), $obj_slot_past ),
$obj_slot_past,
$create_call
)));
}

# Adds a method to the meta-object, and stores an event for the action.
# Note that methods are always subject to fixing up since the actual
# compiled code isn't available until compilation is complete.
Expand Down
59 changes: 40 additions & 19 deletions src/NQP/Actions.pm
Expand Up @@ -596,26 +596,47 @@ class NQP::Actions is HLL::Actions {
}
if $*SCOPE eq 'has' {
# Create and add a meta-attribute.
my $meta-attr-type := %*HOW-METAATTR{$*PKGDECL} || $*DEFAULT-METAATTR;
$*PACKAGE-SETUP.push(PAST::Op.new(
:pasttype('callmethod'), :name('add_attribute'),
PAST::Op.new(
:pirop('get_how PP'),
PAST::Var.new( :name('type_obj'), :scope('register') )
),
PAST::Var.new( :name('type_obj'), :scope('register') ),
(my $meta_args := PAST::Op.new(
:pasttype('callmethod'), :name('new'),
PAST::Var.new( :name($meta-attr-type), :namespace(''), :scope('package') ),
PAST::Val.new( :value($name), :named('name') )
))
));
if $<typename> {
my $type := $<typename>[0].ast;
$type.named('type');
$meta_args.push($type);
if $*PKGDECL ne 'knowhow' {
# Locate the type of meta-attribute we need.
unless pir::exists(%*HOW, $*PKGDECL ~ '-attr') {
$/.CURSOR.panic("$*PKGDECL packages do not support attributes");
}

# Set up arguments for meta-attribute instantiation.
my %lit_args;
my %obj_args;
%lit_args<name> := $name;
if $<typename> {
%obj_args<type> := find_sym(~$<typename>[0], $/);
}

# Add it.
$*SC.pkg_add_attribute($*PACKAGE, %*HOW{$*PKGDECL ~ '-attr'},
%lit_args, %obj_args);
}

else {
# XXX Still need to do it this way for KnowHOW...
my $meta-attr-type := 'KnowHOWAttribute';
$*PACKAGE-SETUP.push(PAST::Op.new(
:pasttype('callmethod'), :name('add_attribute'),
PAST::Op.new(
:pirop('get_how PP'),
PAST::Var.new( :name('type_obj'), :scope('register') )
),
PAST::Var.new( :name('type_obj'), :scope('register') ),
(my $meta_args := PAST::Op.new(
:pasttype('callmethod'), :name('new'),
PAST::Var.new( :name($meta-attr-type), :namespace(''), :scope('package') ),
PAST::Val.new( :value($name), :named('name') )
))
));
if $<typename> {
my $type := $<typename>[0].ast;
$type.named('type');
$meta_args.push($type);
}
}

$BLOCK.symbol($name, :scope('attribute') );
$past := PAST::Stmts.new();
}
Expand Down
5 changes: 0 additions & 5 deletions src/NQP/Grammar.pm
Expand Up @@ -13,11 +13,6 @@ grammar NQP::Grammar is HLL::Grammar {
# one universal KnowHOW from the 6model core.
my %*HOW;
%*HOW<knowhow> := pir::get_knowhow__P();

# What attribute class to use with what HOW, plus a default.
my $*DEFAULT-METAATTR := 'NQPAttribute';
my %*HOW-METAATTR;
%*HOW-METAATTR<knowhow> := 'KnowHOWAttribute';

# Serialization context builder - keeps track of objects that
# cross the compile-time/run-time boundary that are associated
Expand Down

0 comments on commit 0c07f7d

Please sign in to comment.