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

Reply via email to