Skip to content

Conversation

@elegios
Copy link
Contributor

@elegios elegios commented Apr 8, 2025

This PR (finally!) enables mi to replace dprint with essentially (lam x. print (pprintTy x); flushStdout ()), where pprintTy is an auto-generated function based on the inferred type of the dprint. This is based on generate-pprint.mc. I also fix a bug with generating code for user-defined types. There are some important caveats however:

  • When using the old pipeline there's no terribly convenient way of making sure we have the functions we need in scope. If a required function (e.g., int2string or seq2string) isn't in scope, the compiler will insert an unsymbolized variable, which makes the OCaml backend error out later, saying something like "unbound variable nv_int2string. This is the primary reason this feature is behind a flag.
    • This can interact poorly with dead code elimination. For example, when using this in miking-dppl I have to ensure there's a reference somewhere to seq2string, because that function is otherwise not used, even if the file it's defined in (string.mc) is included.
  • The compiler should insert something that can run in all cases, even for things that can't reasonably be inspected. For example, polymorphic values will be printed as <poly varName>, and types that don't have support in generate-pprint.mc will print as <missing case>.

As an example, in code I'm working on right now some DPPL terms aren't removed and instead survive to reach the ocaml backend. Adding a dprint in the wildcard case, then compiling the cppl compiler with mi compile --debug-dprint I can run and get this error message:

(Assume_TmAssume {ty = (FloatTypeAst_TyFloat {info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"})}), info = (Info {col1 = 6, col2 = 12, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"}), dist = (VarAst_TmVar {ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())}), info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"}), ident = ("dist", <missing case for Symbol>), frozen = false}), driftKernel = (Some (LamAst_TmLam {ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())}), info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"}), ident = ("", <missing case for Symbol>), body = (VarAst_TmVar {ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())}), info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"}), ident = ("dist", <missing case for Symbol>), frozen = false}), tyAnnot = (UnknownTypeAst_TyUnknown {info = (NoInfo ())}), tyParam = (UnknownTypeAst_TyUnknown {info = (NoInfo ())})}))})ERROR: infoTm not implemented for OCaml terms!

...or with some extra newlines for readability:

(Assume_TmAssume
  { ty = (FloatTypeAst_TyFloat {info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"})})
  , info = (Info {col1 = 6, col2 = 12, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"})
  , dist = (VarAst_TmVar
    { ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())})
    , info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"})
    , ident = ("dist", <missing case for Symbol>)
    , frozen = false})
  , driftKernel = (Some (LamAst_TmLam
    { ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())})
    , info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"})
    , ident = ("", <missing case for Symbol>)
    , body = (VarAst_TmVar {ty = (UnknownTypeAst_TyUnknown {info = (NoInfo ())}), info = (Info {col1 = 14, col2 = 56, row1 = 57, row2 = 57, filename = "/home/vipa/repositories/miking-dppl/coreppl/models/ssm.mc"}), ident = ("dist", <missing case for Symbol>), frozen = false})
    , tyAnnot = (UnknownTypeAst_TyUnknown {info = (NoInfo ())})
    , tyParam = (UnknownTypeAst_TyUnknown {info = (NoInfo ())})
    }))
  })
ERROR: infoTm not implemented for OCaml terms!

Note <missing case for Symbol>, that's because Symbol is a TyCon even though it's a builtin, and I haven't made the extra effort of adding something that looks for that.

@david-broman david-broman merged commit 17f09c7 into miking-lang:develop Apr 13, 2025
1 of 2 checks passed
@elegios elegios deleted the debug-dprint branch April 16, 2025 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants