Patrick R. Michaud wrote:
Now implemented in r15882 as shown above, sans the helper 'init'
method (which I'll add later tonight). Examples are in
languages/perl6/ and languages/abc/ .
Definitely an improvement. Hmm... okay, I see what you're going for.
Creating subclass of HLLCompiler for every stage of compilation is
heavyweight, but it's definitely nice to be able to say "give me a
compiler for this tree".
So, with a thumbs up on that modification, I've attached a patch that
does two things: a) keeps strict functionality boundaries so the
controller object does the controlling, and the compiler objects for
PAST and POST do only compiling; and b) makes it possible to override
the grammar used for the PAST-to-POST transformation. ABC passes all its
tests, and Perl6 doesn't fail any more tests than it was failing before.
(I made it a patch because it's a refactor that's easy to show but
convoluted to explain.)
chromatic's suggestion is to replace the series of manual calls in
HLLCompiler's 'compile' method with an iterator over an array of
compiler tasks. Then, a compiler-writer can insert another task (perhaps
a tree-based optimizer between the PAST and POST stages), by calling a
method to specify that the new task is 'before' or 'after' another task
(much like the precedence levels of PGE rules). His idea is a good next
step, but I wanted to keep the change set small, so didn't implement it
here.
Allison
Index: runtime/parrot/library/Parrot/HLLCompiler.pir
===================================================================
--- runtime/parrot/library/Parrot/HLLCompiler.pir (revision 15893)
+++ runtime/parrot/library/Parrot/HLLCompiler.pir (working copy)
@@ -17,6 +17,7 @@
$P0 = newclass [ 'HLLCompiler' ]
addattribute $P0, '$parsegrammar'
addattribute $P0, '$astgrammar'
+ addattribute $P0, '$ostgrammar'
addattribute $P0, '$!compsub'
.end
@@ -71,6 +72,10 @@
Accessor for the 'astgrammar' attribute.
+=item ostgrammar([string grammar])
+
+Accessor for the 'ostgrammar' attribute.
+
=cut
.sub 'parsegrammar' :method
@@ -86,7 +91,13 @@
.return self.'attr'('$astgrammar', value, has_value)
.end
+.sub 'ostgrammar' :method
+ .param string value :optional
+ .param int has_value :opt_flag
+ .return self.'attr'('$ostgrammar', value, has_value)
+.end
+
=item compile(pmc code [, adverbs :slurpy :named])
Compile C<source> according to any options given by
@@ -113,10 +124,13 @@
.local pmc result
result = self.'parse'(source, adverbs :flat :named)
if target == 'parse' goto have_result
- result = self.'ast'(result, adverbs :flat :named)
+ result = self.'astcompile'(result, adverbs :flat :named)
if target == 'past' goto have_result
- $P0 = compreg 'PAST'
- result = $P0.'compile'(result, adverbs :flat :named)
+ result = self.'ostcompile'(result, adverbs :flat :named)
+ if target == 'post' goto have_result
+ result = self.'pircompile'(result, adverbs :flat :named)
+ if target == 'pir' goto have_result
+ result = self.'pirrun'(result, adverbs :flat :named)
have_result:
.return (result)
.end
@@ -147,7 +161,7 @@
.end
-=item ast(source [, adverbs :slurpy :named])
+=item astcompile(source [, adverbs :slurpy :named])
Transform C<source> using the compiler's C<astgrammar>
according to any options given by C<adverbs>, and return the
@@ -155,7 +169,7 @@
=cut
-.sub 'ast' :method
+.sub 'astcompile' :method
.param pmc source
.param pmc adverbs :slurpy :named
.local string astgrammar_name
@@ -173,7 +187,50 @@
throw $P0
.end
+=item ostcompile(source [, adverbs :slurpy :named])
+Transform C<source> using the compiler's C<ostgrammar>
+according to any options given by C<adverbs>, and return the
+resulting ost.
+
+=cut
+
+.sub 'ostcompile' :method
+ .param pmc source
+ .param pmc adverbs :slurpy :named
+ .local string ostgrammar_name
+ .local pmc ostgrammar, ostbuilder
+ ostgrammar_name = self.'ostgrammar'()
+ unless ostgrammar_name goto default_ostgrammar
+ $I0 = find_type ostgrammar_name
+ ostgrammar = new $I0
+ ostbuilder = ostgrammar.'apply'(source)
+ .return ostbuilder.'get'('post')
+
+ default_ostgrammar:
+ $P0 = compreg 'PAST'
+ .return $P0.'compile'(source, adverbs :flat :named)
+.end
+
+.sub 'pircompile' :method
+ .param pmc source
+ .param pmc adverbs :slurpy :named
+
+ $P0 = compreg 'POST'
+ $P1 = $P0.'compile'(source, adverbs :flat :named)
+ .return ($P1)
+.end
+
+.sub 'pirrun' :method
+ .param pmc source
+ .param pmc adverbs :slurpy :named
+
+ $P0 = compreg 'PIR'
+ $P1 = $P0(source)
+ .return ($P1)
+.end
+
+
=item register(string name, pmc compsub) # DEPRECATED
(Deprecated.) Registers this compiler object as C<name> and
Index: compilers/past-pm/POST/Compiler.pir
===================================================================
--- compilers/past-pm/POST/Compiler.pir (revision 15893)
+++ compilers/past-pm/POST/Compiler.pir (working copy)
@@ -27,13 +27,6 @@
.param pmc post
.param pmc adverbs :slurpy :named
- .local string target
- target = adverbs['target']
- target = downcase target
- if target != 'post' goto compile_post
- .return (post)
-
- compile_post:
$I0 = isa post, 'POST::Sub'
if $I0 goto with_sub
post = post.'new'('POST::Sub', post, 'name'=>'anon')
@@ -44,13 +37,7 @@
post.'pir'()
code = get_hll_global ['POST'], '$!subpir'
- if target != 'pir' goto compile_pir
.return (code)
-
- compile_pir:
- $P0 = compreg 'PIR'
- $P0 = $P0(code)
- .return ($P0)
.end
Index: compilers/past-pm/PAST/Compiler.pir
===================================================================
--- compilers/past-pm/PAST/Compiler.pir (revision 15893)
+++ compilers/past-pm/PAST/Compiler.pir (working copy)
@@ -37,21 +37,12 @@
.param pmc past
.param pmc adverbs :slurpy :named
- .local string target
- target = adverbs['target']
- target = downcase target
- if target == 'past' goto return_past
- if target == 'parse' goto return_past
-
.local pmc postgrammar, postbuilder, post
postgrammar = new 'POST::Grammar'
postbuilder = postgrammar.'apply'(past)
post = postbuilder.'get'('root')
- $P0 = compreg 'POST'
- .return $P0.'compile'(post, adverbs :flat :named)
+ .return (post)
- return_past:
- .return (past)
.end
=back