Skip to main content

Examining large ASTs as JSON

Sometimes the ASTs you wish to examine are too large for the various --debug-* flags to be viable, or you want the ability to programmatically explore it outside the compiler.

This can be achieved using mexpr/json-debug.mc, which is a small library in the standard library. Usage centers around a few functions like exprToJson, typeToJson, etc., To use these functions you need include mexpr/json-debug.mc and use the MExprToJson language fragment:

-- Add this include to the file
include "mexpr/json-debug.mc"

-- Later:
let ast = /- Some code producing an AST to examine -/ in
printLn (json2string (use MExprToJson in exprToJson ast));
-- ... more code that keeps processing the AST ...
note

If you are working with an extended language, e.g., in miking-dppl, then you will need to create a new language fragment that implements the corresponding sems (exprToJson for constructors in Expr, etc.). See stdlib/mexpr/json-debug.mc for examples.

When run, this code will typically print a very large json object, thus it's typically useful to redirect the output to a file for later processing:

# Assuming the above code has been added somewhere in the main `mi` compiler:
mi compile test.mc > debug.json

Some useful tools to explore this data are jless and jq.

tip

When looking at data from a program that prints both json-encoded data and arbitrary strings (e.g., an edited mi compiler) it might be useful to pre-process the output first:

# Filter out non-json lines
jq -R 'try fromjson' < debug.json | jless

# Reformat all non-json lines as strings with `-> ` added at the start
jq -R '. as $line | try fromjson catch ("-> " + $line)' < debug.json | jless