On 27/08/2013 06:39, Michael Norrish wrote:
On 26/08/13 22:34, David Matthews wrote:

You would have to write your own version of PolyML.prettyPrint and your own REPL
to use it.  Neither of these are very complicated and I can point you at the
existing code as a basis.  PolyML.print and PolyML.makestring, if you actually
use them, would use the original pretty-printer.  You would not need your own
PolyML.addPrettyPrinter. That just adds a function that generates a "pretty"
data structure to a particular type and doesn't care whether the data structure
includes your own ContextProperty values.

Yes, I’d certainly be interested in seeing how to write my own REPL.  I’ve long
meant to try this as it would allow us to use a custom lexer as well.  Please
let me know where to look for the relevant docs/sample code.  I assume that
without an addPrettyPrinter function, this custom REPL would not be extensible
in the same way that the default one is.  I don’t think this would be a big deal
in practice.

The REPL is just a few lines in basis/FinalPolyML.sml . It's the readEvalPrint and handledLoop functions. The core boils down to

let
    val code =
        PolyML.compiler(readin,
           [CPNameSpace nameSpace, CPOutStream printOut])
        handle Fail s =>
        (
            (* Compilation failed *)
            raise Fail s
        )
in
    code ()
    (* Report exceptions in running code. *)
        handle exn =>
        (
            (* Run failed *)
            raise exn
        )
end

The real work is in PolyML.compiler. This takes a function that returns the next character in the input and a list of options. It returns a function that, when called, runs the compiled code and performs any side-effects. That includes printing the results. Actually, nearly everything, including printing can be overridden by adding specific options. The current list is in the code in FinalPolyML.sml with comments explaining what the options do and how they default.

User-defined pretty printing is done at a lower level than the REPL. Whenever a type identifier (a "type name" in the Definition) is created the compiler creates at run-time a ref cell and fills it in with a default function that, when called, builds a pretty tree for a value of that type. Type identifiers are typically created by datatype bindings but can also be created by opaque signature matches and functor applications. What addPrettyPrint does is to set the ref for a particular type to some user-defined function. It has to be treated specially by the compiler because it needs to get the run-time ref from type information that is only present at compile-time. If you need to post-process the output from the compiler there are options such as CPOutStream that is used for all output or CPNameSpace that puts values, types etc into the name-space and deals with printing.

Setting this up to do what you want may be a bit of an effort initially but the idea is that the interface to PolyML.compiler should remain stable with any changes being limited to adding new options to allow for additional features.

I can see the advantage of changing PrettyString to include an explicit length;
it's just that doing that would involve changes to nearly all the existing
pretty-print functions.  That's not just in Poly/ML code but any user code as
well.  It might be simpler to add a new constructor to the pretty datatype.
I'll give it some thought but just at the moment I want to get the current
version released before making any more changes.

I agree that you’d want to keep the existing constructor without the size
information.  With luck, adding a new constructor with explicit size information
would be minimally intrusive.

OK. It's not trivial because there are two versions of the pretty datatype, one inside the compiler and one in user code, and these have to be kept in step. I'll look into this once the current version is released.

David
_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml

Reply via email to