From: Douglas K. <do...@go...> - 2014-04-16 20:43:51
|
I am near ready with the new implementation of backquote, but want to make sure other developers agree that the fasl dumper is worth modifying to get an extremely clean implementation of backq, and a pprinter that is nearly zero code (and very provably correct). The crux of the issue is whether to represent comma "objects" as instances or as conses, i.e. this distinction: (BACKQUOTE (FOO . (COMMA X))) versus (BACKQUOTE (FOO . #<comma-object :form X>)) where BACKQUOTE is a macro that expands at compile-time. It's not hard to see that in the second case above, all you need is one pprint-dispatch entry for (CONS (EQL BACKQUOTE)) to print "`<thing>" and a defstruct printer for a comma, and you're basically done. The pprint hair totally disappears, and everything comes out right no matter how nested. Conversely, representing as conses is harmful to the pretty-printer, not to mention garbage-producing. It makes you either invert the form outside-in, as we do now, which is basically intractable and the reason that Christophe wrote "HATE HATE HATE" in the pp-backq tests; or it requires that the pprinter be doctored up with changes such as CONSP -> BACKQ-EFFECTIVELY-CONSP (hypothetically) so that in a single pass you can detect: should we stop printing the tail of this list L and write-string ". " followed by an atom because it is *effectively* a dotted tail? The latter gets really ugly, requiring a zillion small changes, and probably doesn't admit user-written dispatch code very well. Within the implementation itself, conses are harmful for similar reasons- it begets a list of similarly named functions to paper over the mess: BACKQ-EFFECTIVELY-LAST, BACKQ-EFFECTIVELY-BUTLAST, etc which perform one cell lookahead to see whether (COMMA X) represents an atom. I favor the instance representation, but this must circumvent def!struct because you can't have something be the very-nearly-first file in build-order *and* make use of the convenience of def!struct. A hack on :just-dump-it-normally for a struct that is not a def!struct seems possible. This works because on the xc-host we can use a real make-load-form whereas running the xc we have the xc's layout for a comma as a #<SB!KERNEL:LAYOUT>. Nothing needs that layout sooner than the backq file has been read and digested by the cross-compiler. (This is not just luck - it's the very-near-first file) And we know that a host comma struct is a proxy for a target struct but must not call '%instance-ref' on it. So just hardwire in the dumper to use (compiler-layout-or-lose 'sb!impl::backq-comma) and (backq-comma-form x) to dump it. etc. Probably only for the cross-compiler though. Fair enough? |