Parrot has since quite a time the @IMMEDIATE subroutine pragma, which
causes execution of subs during compilation. But these subroutines can't
return a result so it's rather useless now besides testing that printing
something inside thus sub is really done before a print statement in main.
Here is a plan to implement most of the needed bits.
# constant pi = 4 * atan2(1,1);
translates to
.sub anon_1 @IMMEDIATE, @ANON
$N0 = atan 1.0, 1.0
$P0 = new .Float
$P0 = $N0
.return ($P0)
.end
During compilation this subroutine is executed, the resulting PMC gets
frozen and replaces the PMC constant slot of the immediate subroutine.
The constant declaration is then just
.local pmc pi
set_p_pc pi, anon_1
or with a shortcut:
.const pmc pi = anon_1
As PMC constants are already represented as frozen images in PBC this
would work for nested data strucuters, objects, and their classes too.
Comments welcome,
leo
[1] BEGIN {...} and IO
[2] my $pi is constant = 3;
You mean, during PIR compilation?
> As PMC constants are already represented as frozen images in PBC this
> would work for nested data strucuters, objects, and their classes too.
>
> Comments welcome,
I think it's interesting, but as BEGIN blocks may affect subsequent
parsing, as well as trigger compilation of other source files, I wonder
how to address this. Hmm.
Also I wonder about scoping issues:
{
my $a = $a / 2;
BEGIN { $a = 10 };
}
say $a; # this should to print 5
How is @IMMEDIATE going to handle this?
Thanks,
/Autrijus/
Yes.
>>As PMC constants are already represented as frozen images in PBC this
>>would work for nested data strucuters, objects, and their classes too.
>>
>>Comments welcome,
>
>
> I think it's interesting, but as BEGIN blocks may affect subsequent
> parsing, as well as trigger compilation of other source files, I wonder
> how to address this. Hmm.
This shouldn't be a problem (at least when the last few globals from
imcc are gone), i.e. compilation / running code should be fully re-rentrant.
> Also I wonder about scoping issues:
>
> {
> my $a = $a / 2;
> BEGIN { $a = 10 };
> }
> say $a; # this should to print 5
>
> How is @IMMEDIATE going to handle this?
@IMEDIATE subs will execute in the initial interpreter context. This
context gets an initial lexical pad. (Either per default or we mandate
that the first BEGIN{} has to create it).
So subsequenct BEGIN blocks can use this pad to communicate lexical state.
Then when @MAIN is frozen to bytecode and *if* there is a lexical pad,
we consider @MAIN being a closure, which should freeze the pad too.
At runtime thawing the closure makes the pad available as the outermost
pad.
BTW can you explain why the above example prints 5?
> Thanks,
> /Autrijus/
leo
Oooh, that will be much better.
> BTW can you explain why the above example prints 5?
That was a typo. Something like this may illustrate the issue better:
my $a;
{ my $b; BEGIN { $a = { say $b++ } } }
Thanks,
/Autrijus/
>
>>>>>> "LT" == Leopold Toetsch <l...@toetsch.at> writes:
>
> LT> Here is a plan to implement most of the needed bits.
>
> LT> # constant pi = 4 * atan2(1,1);
>
> LT> translates to
>
> LT> .sub anon_1 @IMMEDIATE, @ANON
> LT> $N0 = atan 1.0, 1.0
> LT> $P0 = new .Float
> LT> $P0 = $N0
> LT> .return ($P0)
> LT> .end
>
> did you forget the 4 * part of the init value?
Of course. I just wanted to simplify the example a bit ;-)
> and shouldn't atan2(1,1)
> be (possibly) optimized to a constant or looked up in a table of easy
> trig stuff and that value used?
Yep. The former is already done for unary and binary basic math, but
seems to be missing for trig opcodes still:
$ echo "add N0, 1, 1
end" | ./parrot -t1 -a -
0 set N0, 2 - N0=0.000000,
3 end
The 'times 4' part (and creating pi) is another run through the
optimization loop (after constant propagation).
> then you could just generate the
> constant folded value of pi in the compiler and emit that float for the
> init.
That would yield a constant folded FLOATVAL pi, but not a PMC.
constant num pi = ...
vs
constant pi = ...
(I guess)
> if this gets compiled to bytecode this would really reduce the
> runtime (even in BEGIN) to almost nothing.
Yep. But anyway runtime costs are the same. It's read and thaw (for a
PMC) a constant - and thaw is executed once during PBC loading.
> uri
leo
LT> Here is a plan to implement most of the needed bits.
LT> # constant pi = 4 * atan2(1,1);
LT> translates to
LT> .sub anon_1 @IMMEDIATE, @ANON
LT> $N0 = atan 1.0, 1.0
LT> $P0 = new .Float
LT> $P0 = $N0
LT> .return ($P0)
LT> .end
did you forget the 4 * part of the init value? and shouldn't atan2(1,1)
be (possibly) optimized to a constant or looked up in a table of easy
trig stuff and that value used? then you could just generate the
constant folded value of pi in the compiler and emit that float for the
init. if this gets compiled to bytecode this would really reduce the
runtime (even in BEGIN) to almost nothing.
uri
--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org