On Mon, Nov 27, 2006 at 09:20:08PM -0800, Allison Randal wrote: > 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/ . > > 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.
I very much agree with chromatic -- indeed, this is mainly why I didn't go with putting "ostgrammar" methods into the HLLCompiler object before. Having HLLCompiler effectively hardcode a sequence of parser-astgrammar-ostgrammar feels a bit heavy-handed to me, almost saying that "we really expect you to always have exactly the sequence source->parse->ast->ost->pir->bytecode, and you're definitely using TGE for the intermediate steps". I guess if we expect a lot of compilers to be making language-specific derivations or replacements of the ast->ost stage then putting the ost specifications into HLLCompiler makes some sense, but I totally agree with chromatic that a more generic approach is needed here. And what I had been aiming for in terms of "array of compiler tasks" was something like "array of compiler stages", where each compiler stage is itself a "compiler" (in the compreg and HLL compiler sense) that does the transformation to the next item in the list. And each compiler stage knows the details of how it performs its transformation, whether that's using TGE or some other method. Putting transformation details like the ostbuilder and apply steps into HLLCompiler still feels wrong to me somehow, although I did come around to agreeing with the idea that the commonly repeated details for source->parse and parse->ast belong in the default 'compile' method for compiler objects. Part of me really wishes that each compiler task would end up being a standardized 'apply' or 'compile' subroutine or method of each stage. In other words, to have compilation effectively become a sequence like: .local pmc code # source to parse tree $P0 = get_hll_global ['Perl6::Grammar'], 'apply' code = $P0(code, adverbs :flat :named) # parse tree to ast $P0 = get_hll_global ['Perl6::PAST::Grammar'], 'apply' code = $P0(code, adverbs :flat :named) # ast to ost $P0 = get_hll_global ['POST::Grammar'], 'apply' code = $P0(code, adverbs :flat :named) # ost to result $P0 = get_hll_global ['POST::Compiler'], 'apply' code = $P0(code, adverbs :flat :named) Here the 'apply' functions in Perl6::PAST::Grammar and POST::Grammar are simply imported from TGE and do the steps of creating the builder object and then applying the grammar. The 'apply' function in Perl6::Grammar would just be a standardized start rule for the parser grammar (and can be directly specified as such in the .pg file). If we could standardize at this level, then a compiler simply specifies the sequence of things to be applied, and the above instructions could be implemented with a simple iterator over the sequence. This is _really_ what I was attempting to get at by having separate compiler objects for PAST, POST, and friends, except that instead of calling the standard function 'apply' I was using 'compile'. Part of me thinks that 'apply' and 'compile' are pretty much the same thing, in the sense that both refer to using some sort of transformer "thing" to change from a source representation into an equivalent target. ----- At any rate, even if we go with the approach outlined in the patch, I have to say that I'm not at all keen on the method names 'astcompile', 'ostcompile', etc. in the patch. When I read 'astcompile' it sounds to me like it's a method to compile an ast into something else, when in fact the method in the patch is compiling some source into an ast. (By analogy, we speak of "Perl 6 compiler" and "PIR compiler" as being things that consume Perl 6 and PIR, not the things that that produce Perl 6 or PIR.) So at the very least I'd prefer to have those methods called 'get_ast' or 'make_ast' or something much less likely to cause confusion. Indeed, the reason why I went with simple 'parse' and 'ast' method names in the original is because the method name tells me what it is that I'm getting back, much like an accessor. Pm