Add --dump-corefn command line option#2275
Conversation
|
Would it be easier to use the macros to generate Aeson instances? I don't know if that's bad or generates unhelpful JSON or whatever as I only have peripheral contact with it, but just wondered if it would make things simpler. |
|
Do you mean the Template Haskell facilities? The current JSON output isn't particularly nice either, but it's very systematic too, which means it's predictable if you're familiar with the ADTs. |
|
Yeah exactly. We already use it in a few places, like purescript/src/Language/PureScript/Types.hs Lines 102 to 104 in 9b34d87 externs.json.
|
|
That's probably easier then, yes xD |
|
Alright, did that. Much better. Thanks! 👍 |
|
I'm just a little apprehensive about using derived instances here, unless the expectation is that people will only be consuming this JSON in other Haskell programs which are using the compiler as a library, i.e. not using the json itself as an interface. For example, with derived instances, is it likely that we might want to change the internal ADT and not be able to do so without breaking third party programs? |
|
That's a good point, I hadn't really considered that aspect of it. |
|
That's a good point. At least I gained more experience with Aeson 😺 |
This reverts commit 96bbd1f.
|
Alright, reversed that, I'll now work on |
|
All the conversions are now implemented. |
CONTRIBUTORS.md
Outdated
| - [@philopon](https://github.com/philopon) (Hirotomo Moriwaki) - My existing contributions and all future contributions until further notice are Copyright Hirotomo Moriwaki, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT). | ||
| - [@pseudonom](https://github.com/pseudonom) (Eric Easley) My existing contributions and all future contributions until further notice are Copyright Eric Easley, and are licensed to the owners and users of the PureScript compiler project under the terms of the [MIT license](http://opensource.org/licenses/MIT). | ||
| - [@puffnfresh](https://github.com/puffnfresh) (Brian McKenna) All contributions I made during June 2015 were during employment at [SlamData, Inc.](#companies) who owns the copyright. I assign copyright of all my personal contributions before June 2015 to the owners of the PureScript compiler. | ||
| - [@rightfold](https://github.com/rightfold) (rightfold) My existing contributions and all future contributions until further notice are Copyright rightfold, and are licensed to the owners and users of the PureScript compiler project under the terms of the [BSD 3-Clause license](https://opensource.org/licenses/BSD-3-Clause). |
There was a problem hiding this comment.
I think we need to figure out how this will work, since I don't think BSD3 code can be redistributed under MIT, due to the additional clause about no advertising. I'd be fine to switch to BSD3 personally, which would be fine since MIT code can definitely be redistributed under BSD3. But we should discuss it.
There was a problem hiding this comment.
I'm fine with MIT if BSD causes too many issues
|
@paf31 I switched to MIT. The relicensing of the old commits isn't an issue because I plan to squash everything before merging anyway (commit history is a bit of a mess) |
src/Language/PureScript/Make.hs
Outdated
| let coreFnFile = outputDir </> filePath </> "corefn.json" | ||
| let jsonPayload = CFJ.moduleToJSON CFJ.annToJSON m | ||
| let json = Aeson.object [ ("version", Aeson.toJSON $ showVersion Paths.version) | ||
| , ("payload", jsonPayload) |
There was a problem hiding this comment.
Is this json inside json now?
There was a problem hiding this comment.
Aeson.toJSON returns Value, not String.
Aeson.encode returns String.
|
@rightfold Could you please paste an example of the generated JSON here for something small like |
|
@paf31 JSON doesn't distinguish between floats and ints so you need the discriminator. Also I'm not sure about object literals and updates, because turning them into JSON objects discards their evaluation order. |
| import Language.PureScript.Types | ||
|
|
||
| literalToJSON :: (a -> Value) -> Literal a -> Value | ||
| literalToJSON _ (NumericLiteral (Left n)) = toJSON ("NumericLiteral", "Int", n) |
There was a problem hiding this comment.
These could just be called IntLiteral and NumberLiteral. The fact that they're represented using the same constructor in the compiler is just a historical detail, really.
|
@garyb @andyarvanitis Would you like to review the output format here at all, before this gets merged? Edit: Here's a little example: {"Main":{"imports":["Prim","Main"],"builtWith":"0.9.2","exports":["X","test"],"decls":{"test":["Abs","f",["Abs","g",["Abs","v",["Abs","x",["Case",[["Var","f"],["Var","g"],["Var","v"],["Var","x"]],[[[["VarBinder","f1"],["VarBinder","g1"],["ConstructorBinder","Main.Y","Main.X",[]],["VarBinder","x1"]],["Literal",["ObjectLiteral",{"z":["Var","Main.X"],"result":["App",["Var","f1"],["App",["Var","g1"],["Accessor","foo",["Var","x1"]]]]}]]]]]]]]],"X":["Constructor","Y","X",[]]},"foreign":[]}}and prettified: {
"Main": {
"imports": [
"Prim",
"Main"
],
"builtWith": "0.9.2",
"exports": [
"X",
"test"
],
"decls": {
"test": [
"Abs",
"f",
[
"Abs",
"g",
[
"Abs",
"v",
[
"Abs",
"x",
[
"Case",
[
[
"Var",
"f"
],
[
"Var",
"g"
],
[
"Var",
"v"
],
[
"Var",
"x"
]
],
[
[
[
[
"VarBinder",
"f1"
],
[
"VarBinder",
"g1"
],
[
"ConstructorBinder",
"Main.Y",
"Main.X",
[
]
],
[
"VarBinder",
"x1"
]
],
[
"Literal",
[
"ObjectLiteral",
{
"z": [
"Var",
"Main.X"
],
"result": [
"App",
[
"Var",
"f1"
],
[
"App",
[
"Var",
"g1"
],
[
"Accessor",
"foo",
[
"Var",
"x1"
]
]
]
]
}
]
]
]
]
]
]
]
]
],
"X": [
"Constructor",
"Y",
"X",
[
]
]
},
"foreign": [
]
}
} |
|
Hmm. It looks like the distinction between top-level let and letrec is gone? |
|
Yes, but we could add it back. I'd probably like to change the syntax a bit though. |
|
It'd be nice if non-recursive things appeared like they do now, and we added a |
|
Or: "decls": {
"let": {...},
"letrec": [
{...},
{...}
]
} |
|
Do we need to distinguish self-recursive declarations from non-recursive ones? If not, I'd rather do something like: where the top level is a list of binding groups, each of which is a list of function declarations. |
|
@paf31 Sorry, I was on an overseas flight (with no wifi). I'm still jet lagged right now, but it looks good. I also just looked at the sample posted by @rightfold earlier which included type information -- which is good, since the C++ backend is back to using type information (for optimizations now). One question, though: are all imported values available? The C++ backend also uses those for some optimations (basically grabbing things from |
That looks good to me. It works for data binding groups too. I don't think it should be the responsibility of the AST format to indicate when a function is self-recursive, since that's not something we even track in the AST, so in doing that we're kinda making the JSON representation a different thing. It should be easy enough to figure out by anything that does need that distinction too. |
I thought we did track self-recursive functions in the core AST, as a |
|
Core has Let/LetRec distinction for both top-level declarations and let-expressions |
Oh right. I should probably know that since I contributed |
|
I think the question should be: do we need this for the first version, bearing in mind that it might be tricky to implement it in a non-breaking way if we decide to use it later? For that reason, I think we should add it, but I'm happy to spend some time figuring out the syntax. |
|
@andyarvanitis Actually, there are no type annotations in this version. The reason is that I would like to discuss move towards something a bit more like GHC core, where only binders get type annotations. With that approach, the type checker would elaborate directly to functional core, rather than decorating the initial AST.
The core JSON will include a list of imports, but you would have to pull the definitions of the imports from the appropriate core JSON/externs file. Does that work? |
|
@garyb @andyarvanitis Binding group information has now been added back to the JSON output. |
|
Ok, thanks, I've gone back through the comments and see now what's there for the first version. I probably won't switch the C++ backend over to it just yet, then, but it's looks good for some other things I've been thinking about doing. |
WORK IN PROGRESS. I'd like some feedback on these changes.
A few things are still left to do:
Annto JSON.Typeto JSON.JSON is dumped to
corefn.jsonin the module's output directory (i.e. alongsideindex.js).Addresses #876.