diff --git a/setup.nqp b/setup.nqp index da4afa2..c771651 100755 --- a/setup.nqp +++ b/setup.nqp @@ -32,6 +32,7 @@ sub MAIN() { 'build/POST/Pattern.pir', 'src/POST/Pattern.nqp', 'build/Tree/Optimizer.pir', 'src/Tree/Optimizer.nqp', 'build/Tree/Optimizer/Pass.pir', 'src/Tree/Optimizer/Pass.nqp', + 'build/Tree/Optimizer/Transformers.pir', 'src/Tree/Optimizer/Transformers.nqp', 'build/Tree/Pattern.pir', 'src/Tree/Pattern.nqp', 'build/Tree/Pattern/Any.pir', 'src/Tree/Pattern/Any.nqp', 'build/Tree/Pattern/Closure.pir', 'src/Tree/Pattern/Closure.nqp', @@ -52,6 +53,7 @@ sub MAIN() { 'build/POST/Pattern.pbc', 'build/POST/Pattern.pir', 'build/Tree/Optimizer.pbc', 'build/Tree/Optimizer.pir', 'build/Tree/Optimizer/Pass.pbc', 'build/Tree/Optimizer/Pass.pir', + 'build/Tree/Optimizer/Transformers.pbc', 'build/Tree/Optimizer/Transformers.pir', 'build/Tree/Pattern.pbc', 'build/Tree/Pattern.pir', 'build/Tree/Pattern/Any.pbc', 'build/Tree/Pattern/Any.pir', 'build/Tree/Pattern/Closure.pbc', 'build/Tree/Pattern/Closure.pir', @@ -79,6 +81,7 @@ sub MAIN() { build/POST/Pattern.pbc build/Tree/Optimizer.pbc build/Tree/Optimizer/Pass.pbc + build/Tree/Optimizer/Transformers.pbc build/Tree/Pattern.pbc build/Tree/Pattern/Any.pbc build/Tree/Pattern/Closure.pbc diff --git a/src/Tree/Optimizer/Pass.nqp b/src/Tree/Optimizer/Pass.nqp index db4677c..e9105e3 100644 --- a/src/Tree/Optimizer/Pass.nqp +++ b/src/Tree/Optimizer/Pass.nqp @@ -1,6 +1,11 @@ class Tree::Optimizer::Pass; +INIT { + pir::load_bytecode('Tree/Optimizer/Transformers.pbc'); +} + has $!name; +has $!recursive; has $!transformation; has $!when; @@ -22,14 +27,17 @@ my $current-gen-name := 0; sub gen-name () { '__unnamed_' ~ $current-gen-name++; } -method BUILD (:$transformation, :$name, :$when, *%ignored) { +method BUILD (:$transformation, :$name, :$recursive, :$when, *%ignored) { $!name := $name || gen-name(); + $!recursive := $recursive || 0; $!transformation := $transformation; $!when := $when; } method run ($tree) { - if pir::defined__IPP($!when) { + if $!recursive { + self.generate-transformer.walk($tree); + } elsif pir::defined__IPP($!when) { my $/ := $tree ~~ $!when; if $/ { $!transformation($/); @@ -40,3 +48,11 @@ method run ($tree) { $!transformation($tree); } } + +method generate-transformer () { + if pir::defined__IP($!when) { + $!when.transformer_class.new($!when, $!transformation); + } else { + Tree::Optimizer::Transformer::Single.new($!transformation); + } +} diff --git a/src/Tree/Optimizer/Transformers.nqp b/src/Tree/Optimizer/Transformers.nqp new file mode 100644 index 0000000..c96b53d --- /dev/null +++ b/src/Tree/Optimizer/Transformers.nqp @@ -0,0 +1,25 @@ +INIT { + pir::load_bytecode('Tree/Transformer.pbc'); +} + +class Tree::Optimizer::Transformer::Single is Tree::Transformer { + has $!transform; + + method new ($transform) { + my $self := pir::new__PP(self.HOW.get_parrotclass(self)); + $self.BUILD($transform); + $self; + } + + method BUILD ($transform) { $!transform := $transform; } + + method transform () { $!transform; } +} + +module Tree::Walker { + our multi walk (Tree::Optimizer::Transformer::Single $walker, $node) { + my $result := $walker.transform()($node); + replaceChildren($result, walkChildren($walker, $result)); + $result; + } +}