wrt attached (hopefully inlines for your reading pleasure), I seek 2
things;
1. ideas and clues (who cant use more ?!)
Im cognizant of Stephen McCamants advice to use real ASTs rather
than B::Concise,
but Im getting reasonable mileage going this lower-effort (50 lines)
way.
Im sure the limitations are about to emerge more clearly !
2. advice wrt B::Generate VS OP_seq.
I seek to patch B::Gen well enough that Arthur accepts it.
This could have been a separate msg, but I think the script helps
to motivate it and give context.
On 0, Jim Cromie <jcr...@divsol.com> wrote:
>
> wrt attached (hopefully inlines for your reading pleasure), I seek 2
> things;
I'm working on something not too far off from this. I'm trying to compile
Perl 6 down to Perl 5 "B" bytecode with a modified languages/perl6 suite
from the Parrot distro. Linking things together isn't that hard - atleast
in the simple case. Loops and such make it interesting. I've been documenting
as I go:
http://perldesignpatterns.com/?PerlAssembly
Feel free to comment on that - ask questions, make corrections, etc. It all
goes into CVS so you can't ruin it by editing it.
I saw the post to turn op_seq into 3 bits. Simon says that he doesn't
maintain B::Generate any more. I think Arthur Bergman does. So you'll
want to atleast cc him - aber...@cpan.org. Please keep cc me on the
patches and send me any notes - I'm working on B::Generate as part of
what I'm doing.
I have a copy of B::Generate hacked to allocate pad entries at run-time. I
don't know how well you know B, but many operations use the scratchpad as a
scratchpad rather than merely a closure-friendly symbol table:
perl -MO=Concise -e 'my $bar; my $baz; print "foo $bar $baz";'
g <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v ->3
3 <0> padsv[$bar:1,3] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v ->5
5 <0> padsv[$baz:2,3] vM/LVINTRO ->6
6 <;> nextstate(main 3 -e:1) v ->7
f <@> print vK ->g
7 <0> pushmark s ->8
- <1> ex-stringify sK/1 ->f
- <0> ex-pushmark s ->8
e <2> concat[t5] sKS/2 ->f <-- t5
c <2> concat[t4] sKS/2 ->d <-- t4
a <2> concat[t3] sK/2 ->b <-- t3
8 <$> const(PV "foo ") s ->9
9 <0> padsv[$bar:1,3] s ->a
b <$> const(PV " ") s ->c
d <0> padsv[$baz:2,3] s ->e
t5, t4, and t3 are nameless pad entries. To compile Perl 6, or any
other language with closures, down to Perl 5 B, you need to be able
to allocate those puppies.
I'll also help with getting B::Generate to run on 5.9.2 if you need it
but my projects are keeping me very busy so I can't really take the lead
on that. The only thing that should really cause any grief is:
B::main_root()->linklist();
But you should be able to steal the implementation of that directly
from the patches that made op_seq 3 bits. In other cases, it would
just be a matter of using the new macros to mask off the right bits
of the right op field rather than looking for op_seq. I for one agree
B::Generate shouldn't really need op_seq other than for ->linklist()
and if memory serves, it doesn't use it very heavily.
Hope this helps. Feel free to mail me off the list too.
-scott
>
> 1. ideas and clues (who cant use more ?!)
>
> Im cognizant of Stephen McCamants advice to use real ASTs rather
> than B::Concise,
> but Im getting reasonable mileage going this lower-effort (50 lines)
> way.
> Im sure the limitations are about to emerge more clearly !
>
>
> 2. advice wrt B::Generate VS OP_seq.
>
> I seek to patch B::Gen well enough that Arthur accepts it.
> This could have been a separate msg, but I think the script helps
> to motivate it and give context.
>
>
>
> --------------030205040706060404050303
> Content-Type: text/plain;
> name="bgen.pl"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline;
> filename="bgen.pl"
>
> #!/usr/local/bin/perl5.9.2 -w
>
> =head1 using B::Concise to render B::Generate pseudo-code
>
> this is a strawman attempt to close-the-loop; to traverse the optree
> of a given piece of code, and to produce the B::Generate calls that
> would reconstruct that optree.
>
> Ive completely ignored the difficulty of knitting the ops together
> into a tree, Im hoping you all can sprinkle some magic clues to make
> the next steps obvious.
>
>
> =head1 Running it.
>
> Theres a chicken-egg problem here; you need recent B::Concise patches,
> and thus 'need' blead, but B::Generate wont build on 5.9.2, cuz op_seq
> was replaced by op_opt and op_static.
>
> So I just cut-pasted the output into a separate file, added in the use
> B::Generate, ard it runs on 5.8.3. Theres no crash at least..
>
> $op1 = B::COP -> new ( 1 || 0, "(main 311 bgen.pl:84)", 0 );
> $op2 = B::SVOP -> new ( "const", 2 || 0, sv);
> $op3 = B::PADOP -> new ( "gvsv", 2 || 0, sv);
> $op4 = B::BINOP -> new ( "sassign", 69 || 2, 0, 0 );
> $op5 = B::COP -> new ( 1 || 0, "(main 311 bgen.pl:85)", 0 );
> $op6 = B::OP -> new ( "pushmark", 2 || 0);
> $op7 = B::SVOP -> new ( "const", 2 || 0, sv);
> $op8 = B::LISTOP -> new ( "print", 6 || 0, 0, 0 );
> $op9 = B::UNOP -> new ( "leavesub", 4 || 65, 0 );
>
> =head1 B::Generate VS op_seq
>
> Id welcome advice on how to handle this conflict;
>
> In B/Generate.xs, I #ifd PERL_VERSION to preprocess either OP_seq or
> OP_opt and OP_static, and it compiles on 5.9.2, but test fails.
>
> http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2004-02/msg00559.html
>
> leads me to think that op_seq is 'emulatable' in 5.9.2 at some level,
> but I dont grok whether B::Generate's expectations of seq values is
> realistic any more.
>
> =cut
>
> use B::Concise qw(set_style add_callback);
>
> B::Concise::add_style
> ( "bgen" => (
> "\$op#hyphseq2 = "
> , " (*( )*) goto #seq\n"
> , "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"
> ));
>
> my %bgen = # format-spec templates
> (
> LISTOP => '( "#name", #flagval || #privval, #first, #last )',
> COP => '( #flagval || #privval, "#arg", #first )',
> BINOP => '( "#name", #flagval || #privval, #first, #last )',
> UNOP => '( "#name", #flagval || #privval, #first )',
> LOGOP => '( "#name", #flagval || #privval, #first, #other )',
> SVOP => '( "#name", #flagval || #privval, sv)',
> PADOP => '( "#name", #flagval || #privval, sv)',
> OP => '( "#name", #flagval || #privval)',
> );
>
> add_callback
> ( sub {
> my ($h, $op, $format, $level,$style) = @_;
> $h->{bclass} = 'B::'. $h->{class};
>
> # slather optype-specific format onto format-spec
> if ($style eq 'bgen' and $bgen{$h->{class}} ) {
> $$format .= $h->{bclass};
> # fudge in a padding. 22 accts for '$op#hyphseq2 = '
> $$format .= (length $$format > 22) ? "\t":"\t\t";
> $$format .= "-> new $bgen{$h->{class}};";
> }
> # and populate vars that it may 'call'
> $h->{first} = $h->{last} = $h->{other} = 0;
>
> if ($h->{class} eq 'COP') {
> use Data::Dumper;
> #print Dumper $h;
> }
> });
>
>
> sub foo {
> $DB::single = 1;
> print "in foo\n";
> }
>
> $DB::single = 1;
> B::Concise::set_style_standard('concise');
> B::Concise::compile('-exec', '-banner', 'foo')->();
> B::Concise::compile('-bgen', '-exec', '-banner', \&foo)->();
> #B::Concise::compile(\&foo)->();
>
> __END__
>
>
> --------------030205040706060404050303
> Content-Type: text/plain;
> name="genout.pl"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline;
> filename="genout.pl"
>
>
> use B::Generate;
>
> $op1 = B::COP -> new ( 1 || 0, name, 0 );
> $op2 = B::SVOP -> new ( "const", 2 || 0, sv);
> $op3 = B::PADOP -> new ( "gvsv", 2 || 0);
> $op4 = B::BINOP -> new ( "sassign", 69 || 2, 0, 0 );
> $op5 = B::COP -> new ( 1 || 0, name, 0 );
> $op6 = B::OP -> new ( "pushmark", 2 || 0);
> $op7 = B::SVOP -> new ( "const", 2 || 0, sv);
> $op8 = B::LISTOP -> new ( "print", 6 || 0, 0, 0 );
> $op9 = B::UNOP -> new ( "leavesub", 4 || 65, 0 );
>
> __END__
>
> B::COP->new ( 1 || 0, name, 0 ),
> B::SVOP->new('const', 2 || 0),
> B::PADOP->new('gvsv', 2 || 0),
> new B::BINOP ( "sassign", 69 || 2, 0, 0 ),
> new B::COP ( 1 || 0, name, 0 ),
> B::OP->new('pushmark', 2 || 0),
> #B::SVOP->new('const', 2 || 0),
> new B::LISTOP ( "print", 6 || 0, 0, 0 ),
> new B::UNOP ( "leavesub", 4 || 65, 0 ),
>
> --------------030205040706060404050303--