Skip to content

Commit

Permalink
[pmcc] finish code to emit class_init, now for cleanup
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.parrot.org/parrot/branches/pmc_pct@39785 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
Christoph Otto committed Jun 25, 2009
1 parent 2d4e10a commit de12884
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 46 deletions.
4 changes: 4 additions & 0 deletions compilers/pmcc/src/builtins.pir
Expand Up @@ -147,7 +147,11 @@ is not intended to be a general-use sub.
frozen = pio.'readall'(filename)
$P0 = thaw frozen
.return ($P0)
.end
.sub 'die'
.param string msg
die msg
.end
# Extend various Parrot's PMCs to play nicely with NQP.
Expand Down
2 changes: 0 additions & 2 deletions compilers/pmcc/src/emitter/c.pir
Expand Up @@ -45,10 +45,8 @@ TODO: Parse c_body properly and implement all other functions.
.param pmc pmclass
.param pmc past
.local string res
res = "{\n"
$S0 = self.'!generate_children_body_part'(pmclass, past)
concat res, $S0
concat res, "}\n"
.return (res)
.end
Expand Down
58 changes: 39 additions & 19 deletions compilers/pmcc/src/emitter/pmc.pm
Expand Up @@ -311,6 +311,18 @@ Generate C file's contents for this PMC.
=cut

method generate_c_code($past) {

my %vtables := thaw('../../vtable.frozen');
#make sure there aren't any misnamed VTABLE functions
for self.past.vtables{'default'} {
if !%vtables{$_} {
#XXX: check that the return type and parameter types are good too
#XXX: show a nicer message that points to the failure
die("Found an invalid vtable function '"~$_~"'. Perhaps you misnamed it?");
}
}


self.pre_method_gen();
my $res :=
self.past<c_header> ~ "\n\n"
Expand Down Expand Up @@ -385,12 +397,6 @@ method generate_class_init_func() {
@res.push( self.generate_multis() );
@res.push( self.generate_passes() );

my $past := self.past;
if ($past<class_init>) {
@res.push("/* class_init */\n");
@res.push(PMC::Emitter::C.new().emit($past, $past<class_init>));
}

@res.push("\n}\n");
join('', @res);
}
Expand Down Expand Up @@ -521,16 +527,16 @@ method generate_passes() {
@res.push(' } /* pass 2 */');
@res.push(' else {');

my $hll := self.past.hll();
my $hll := self.past.traits{'hll'};

if $hll ne '' && elements(self.past.maps()) {
if $hll ne '' && elements(self.past.maps) {

@res.push(' {');
@res.push(' /* Register this PMC as a HLL mapping */');
@res.push(' const INTVAL pmc_id = Parrot_get_HLL_id( interp, CONST_STRING_GEN(interp, "'~$hll~'"));');
@res.push(' if (pmc_id > 0) {');

for self.past.maps() {
for self.past.maps {
@res.push(' Parrot_register_HLL_type( interp, pmc_id, enum_class_'~$_~', entry);');
}

Expand All @@ -539,18 +545,33 @@ method generate_passes() {
@res.push('');
}

@res.push(' /* set up MRO and _namespace */');
@res.push(' {');
@res.push(' VTABLE * const vt = interp->vtables[entry];');
@res.push(' vt->mro = Parrot_'~self.name~'_get_mro(interp, PMCNULL);');
@res.push(' if (vt->ro_variant_vtable)');
@res.push(' vt->ro_variant_vtable->mro = vt->mro;');
@res.push(' }');
@res.push(' /* set up MRO and _namespace */');
@res.push(' {');
@res.push(' VTABLE * const vt = interp->vtables[entry];');
@res.push(' vt->mro = Parrot_'~self.name~'_get_mro(interp, PMCNULL);');
@res.push(' if (vt->ro_variant_vtable)');
@res.push(' vt->ro_variant_vtable->mro = vt->mro;');
@res.push(' }');
@res.push('');
@res.push(' Parrot_create_mro(interp, entry);');
@res.push(' Parrot_create_mro(interp, entry);');

for self.past.methods {
@res.push(' register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_'~self.name~'_nci_'~$_~'), CONST_STRING_GEN(interp, "'~$_~'"));');
if self.past.methods{$_}{'attrs'}{'write'} {
@res.push(' Parrot_mark_method_writes(interp, entry, "nci_'~$_~'");');
}
}
@res.push('');

@res.push('}');
if self.past.class_init {
@res.push(' /* class_init */');
@res.push(' {');
@res.push(PMC::Emitter::C.new().emit(self.past, self.past.class_init));
#@res.push(self.past.class_init);
@res.push(' }');
}

@res.push(' }');
join("\n", @res);
}

Expand All @@ -575,7 +596,6 @@ method generate_get_vtable_func() {
else {
$first_parent := @other_parents.shift;
}
say("first parent is "~$first_parent);

@res.push('PARROT_EXPORT');
@res.push('PARROT_CANNOT_RETURN_NULL');
Expand Down
30 changes: 13 additions & 17 deletions compilers/pmcc/src/nodes.pir
Expand Up @@ -41,6 +41,9 @@ PMC class by it self.
res.'init'(children :flat, adverbs :flat :named)
# Initialize various attributes
$P1 = new ['ResizableStringArray']
res.'attr'('does', $P1, 1)
$P1 = new ['ResizableStringArray']
res.'attr'('parents', $P1, 1)
Expand All @@ -66,15 +69,22 @@ PMC class by it self.
$P1 = new ['Hash']
res.'attr'('traits', $P1, 1)
$P1 = new ['String']
res.'attr'('hll', $P1, 1)
$P1 = new ['ResizableStringArray']
res.'attr'('maps', $P1, 1)
.return (res)
.end
=item C<does>
How does this PMC act?.
=cut
.sub 'does' :method
.tailcall self.'attr'('does',0,0)
.end
=item C<parents>
Get PMC parents.
Expand Down Expand Up @@ -165,20 +175,6 @@ Get PMC traits.
.tailcall self.'attr'('traits',0,0)
.end
=item hll
Get PMC hll name.
=cut
.sub 'hll' :method
.tailcall self.'attr'('hll',0,0)
.end
.sub 'set_hll' :method
.param pmc name
.tailcall self.'attr'('hll',name,1)
.end
.sub 'maps' :method
.tailcall self.'attr'('maps',0,0)
Expand Down
40 changes: 35 additions & 5 deletions compilers/pmcc/src/parser/actions.pm
Expand Up @@ -44,23 +44,30 @@ method traits($/, $key) {
our $?PMC;

if $key eq 'does' {
$?PMC.does.push(~$<identifier>);
}
elsif $key eq 'group' {
#XXX: only one group is possible
#XXX: only valid for dynpmcs
$?PMC.traits{'group'} := ~$<identifier>;
}
elsif $key eq 'hll' {
$?PMC.set_hll(~$<identifier>);
#XXX: only one HLL is possible
$?PMC.traits{'hll'} := ~$<identifier>;
}
elsif $key eq 'provides' {
$?PMC.provides().push(~$<identifier>);
$?PMC.provides.push(~$<identifier>);
}
elsif $key eq 'extends' {
$?PMC.parents().push(~$<identifier>);
#XXX: some sanity checking here would probably be advisable
$?PMC.parents.push(~$<identifier>);
$?PMC.thaw_pmc_attrs(~$<identifier>);
}
elsif $key eq 'maps' {
$?PMC.maps().push(~$<identifier>);
$?PMC.maps.push(~$<identifier>);
}
elsif $key eq 'lib' {
$?PMC.traits{'lib'} := ~$<identifier>;
}
else {
$?PMC.traits{$key} := 1;
Expand Down Expand Up @@ -137,25 +144,42 @@ method vtable($/) {
$<c_body>.ast
);
$past<parameters> := $<c_signature><c_arguments>.ast;

my %attrs;
for $<method_attr> {
%attrs{~$_<identifier>} := 1;
}
$past<attrs> := %attrs;

make $past;
}

method method($/) {
#say('METHOD ' ~$<identifier>);
my $method_body := $<c_body>.ast;

my $past := PAST::Block.new(
:name(~$<identifier>),
:blocktype('declaration'),
:returns('void'), # PCC METHODS returns void
:node($/),

$<c_body>.ast
$method_body
);
#$past<parameters> := $<c_signature><c_arguments>.ast;

my %attrs;
for $<method_attr> {
%attrs{~$_<identifier>} := 1;
}
$past<attrs> := %attrs;

make $past;
}

method multi($/) {
#say('MULTI ' ~$<identifier>);

my $past := PAST::Block.new(
:name(~$<c_signature><identifier>),
:blocktype('method'),
Expand Down Expand Up @@ -201,6 +225,12 @@ method multi($/) {
$past<long_signature> := join(',', @long_sig);
$past<full_name> := "multi_" ~ $past.name ~ "_" ~ join('_', @long_sig);

my %attrs;
for $<method_attr> {
%attrs{~$_<identifier>} := 1;
}
$past<attrs> := %attrs;

make $past;
}

Expand Down
10 changes: 7 additions & 3 deletions compilers/pmcc/src/parser/grammar.pg
Expand Up @@ -118,22 +118,26 @@ rule class_init {

rule method {
'METHOD' :: [
[ <identifier> '(' <parrot_c_arguments> ')' <c_body> ]
[ <identifier> '(' <parrot_c_arguments> ')' <method_attr>* <c_body> ]
| <.panic: "Unexpected METHOD content">
]
{*}
}

rule vtable {
'VTABLE' :: <c_signature> <c_body>
'VTABLE' :: <c_signature> <method_attr>* <c_body>
{*}
}

rule multi {
'MULTI' :: <c_signature> <c_body>
'MULTI' :: <c_signature> <method_attr>* <c_body>
{*}
}

rule method_attr {
':' <identifier>
}

# Nested list of something
rule c_body {
'{' <c_body_statement>* '}' {*}
Expand Down

0 comments on commit de12884

Please sign in to comment.