class Mildew::Frontend::STD::Cached {
has
cache
=> (
is
=>
'ro'
,
default
=>
sub
{CHI->new(
driver
=>
'File'
,
root_dir
=>
'parser_cache'
,
serializer
=>
'YAML'
)});
has
parser
=> (
is
=>
'ro'
,
default
=>
sub
{
require
STD;
require
Mildew::Frontend::STD;Mildew::Frontend::STD->new()},
lazy
=>1);
method parse(
$source
) {
my
$checksum
= md4(
$source
);
if
(
my
$parse
=
$self
->cache->get(
$checksum
)) {
{
local
$INC
{
"STD.pm"
} =
"do-not-load"
;
do
'viv'
;
}
warn
"using cached ast"
;
for
(@{
$parse
->{gen_class}}) {
Actions::gen_class(@{
$_
})
}
$::ORIG =
$parse
->{ORIG};
return
$parse
->{VAST};
}
my
$gen_class
= \
&Actions::gen_class
;
my
@gen_class
;
{
no
warnings
'redefine'
;
*Actions::gen_class
=
sub
{
say
"generating class $_[0]"
;
push
(
@gen_class
,[
@_
]);
$gen_class
->(
@_
);
};
}
my
$vast
=
$self
->parser->parse(
$source
);
$self
->cache->set(
$checksum
,{
ORIG
=>$::ORIG,
VAST
=>
$vast
,
gen_class
=>\
@gen_class
});
$vast
->emit_m0ld;
}
}