5

I am trying to compile a string of source code and print the parse tree using Poly/ML. The following code compiles, but the parse tree is empty:

fun main () =
    let
        val stream = TextIO.openString "let val a = \"abc\"; val b = \"def\"; val c = a ^ b in print c end";
        val _ = PolyML.compiler (fn () => TextIO.input1 stream, []);
        val (_, parseTree) = !PolyML.IDEInterface.parseTree
    in
        PolyML.print (parseTree);
        PolyML.print (List.length parseTree);
        List.map PolyML.print (parseTree);
        ()
    end

Running this:

$ ./a.out
[...]
0
$

What do I need to do to get the parse tree from the compiler? I also tried a variation using the CPCompilerResultFun compiler parameter. But this did not work either:

fun main () =
    let
        fun useTree (NONE, _) () =
            (PolyML.print "not parsed"; ())
          | useTree (SOME parseTree, _) () =
            (PolyML.print "parsed"; PolyML.print parseTree; ());

        val stream = TextIO.openString "let val a = \"abc\"; val b = \"def\"; val c = a ^ b in print c end";
        val _ = PolyML.compiler (fn () => TextIO.input1 stream, [PolyML.Compiler.CPCompilerResultFun useTree]);
    in
        ()
    end

Running this does not produce any output.

eatonphil
  • 13,115
  • 27
  • 76
  • 133

1 Answers1

3

I was able to obtain it by providing the PolyML.Compiler.CPCompilerResultFun compiler option. It allows you to access and save the parse tree. However, I can't say too much about how the parse tree is actually represented. There's some documentation here (the website is down for me), but I couldn't make too much sense of it yet.

val resultTrees : PolyML.parseTree list ref = ref [];

fun compilerResultFun (parsetree, codeOpt) =
  let
    val _ =
      case parsetree of
        SOME pt => resultTrees := !resultTrees @ [pt]
      | NONE => ()
  in
    fn () => raise Fail "not implemented"
  end;

val stream = TextIO.openString "val a = 1";

val _ = PolyML.compiler (fn () => TextIO.input1 stream, [
  PolyML.Compiler.CPCompilerResultFun compilerResultFun
]);

val [(a, [PolyML.PTfirstChild b])] = !resultTrees;
val (_, [PolyML.PTfirstChild c, PolyML.PTparent d, PolyML.PTprint e]) = b ();
Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • Could you demonstrate the values of the parse tree? I used your code and tried printing (a, b, c, etc.) and it printed "fn" regardless. – eatonphil Feb 24 '16 at 14:07
  • 1
    @eatonphil I couldn't figure out how to traverse the tree. I'll take a deeper look tonight. All I can say is don't `PolyML.print` them, run the script inside the REPL, it provides better pretty-printing. – Ionuț G. Stan Feb 24 '16 at 14:19
  • 1
    Actually, I figured out what I was doing wrong. Those values are functions whose pretty print value is "fn". I called them and was able to inspect what I expected a little clearer. – eatonphil Feb 24 '16 at 14:27