├── .gitignore
├── Setup.hs
├── ui
├── fonts
│ ├── FiraMono-Bold.ttf
│ ├── FiraMono-Regular.ttf
│ └── OFL.txt
├── see.html
├── see.css
├── see.js
└── jquery.js
├── ChangeLog.md
├── LICENSE
├── dump-core.cabal
├── README.md
└── DumpCore.hs
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | dist-newstyle
3 |
--------------------------------------------------------------------------------
/Setup.hs:
--------------------------------------------------------------------------------
1 | import Distribution.Simple
2 | main = defaultMain
3 |
--------------------------------------------------------------------------------
/ui/fonts/FiraMono-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yav/dump-core/HEAD/ui/fonts/FiraMono-Bold.ttf
--------------------------------------------------------------------------------
/ui/fonts/FiraMono-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yav/dump-core/HEAD/ui/fonts/FiraMono-Regular.ttf
--------------------------------------------------------------------------------
/ChangeLog.md:
--------------------------------------------------------------------------------
1 | # Revision history for dump-core
2 |
3 | ## 0.1.4
4 | * Changes to work with various GHCs
5 |
6 | ## 0.1.3.2
7 | * Changes to work with more recent GHC
8 |
9 | ## 0.1.3.0
10 |
11 | * First version. Released on an unsuspecting world.
12 |
--------------------------------------------------------------------------------
/ui/see.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Iavor S. Diatchki
2 |
3 | Permission to use, copy, modify, and/or distribute this software for any purpose
4 | with or without fee is hereby granted, provided that the above copyright notice
5 | and this permission notice appear in all copies.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9 | FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
11 | OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
12 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
13 | THIS SOFTWARE.
14 |
--------------------------------------------------------------------------------
/dump-core.cabal:
--------------------------------------------------------------------------------
1 | name: dump-core
2 | version: 0.1.4
3 | synopsis: A plug-in for rendering GHC core
4 | description: This is a GHC plugin that renders the Core generated by
5 | GHC into JSON and also HTML, for easy inspection.
6 | The JSON is machine readable so it could be used by
7 | other tools, although at present the format is not
8 | documented and unstable.
9 |
10 |
11 | license: ISC
12 | license-file: LICENSE
13 | author: Iavor S. Diatchki
14 | maintainer: iavor.diatchki@gmail.com
15 | category: Development
16 | build-type: Simple
17 | extra-source-files: ChangeLog.md
18 | cabal-version: >=1.10
19 |
20 | data-files: ui/see.js,
21 | ui/see.css,
22 | ui/jquery.js,
23 | ui/fonts/OFL.txt,
24 | ui/fonts/FiraMono-Regular.ttf,
25 | ui/fonts/FiraMono-Bold.ttf
26 | library
27 | exposed-modules: DumpCore
28 | other-modules: Paths_dump_core
29 | build-depends: base >=4.9 && <4.15, ghc, text, aeson, bytestring,
30 | containers, monadLib, directory, filepath
31 | default-language: Haskell2010
32 |
33 | source-repository head
34 | type: git
35 | location: git://github.com/yav/dump-core
36 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a GHC plugin that renders the Core generated by GHC
2 | into JSON and also HTML, for easy inspection. The JSON is machine
3 | readable so it could be used by other tools, although at present the
4 | format is not documented and unstable.
5 |
6 | An easy way to use the plugin is to add a flag to your Cabal file. For
7 | example, add the following to top-level of the Cabal file:
8 |
9 | flag dump-core
10 | description: Dump HTML for the core generated by GHC during compilation
11 | default: False
12 |
13 | Then, you can add something like this to your library or executable section:
14 |
15 | if flag(dump-core)
16 | build-depends: dump-core
17 | ghc-options: -fplugin=DumpCore -fplugin-opt DumpCore:core-html
18 |
19 | The option to the plugin specifies the directory where files should be saved---
20 | in this example, it is set to `core-html`. The default is `dump-core`.
21 |
22 | After compilation, directory `dump-core` (or whatever was specified in the
23 | options) will contain HTML files that you can open with a web browser.
24 | I've only tried Chrome but most browsers ought to work. Please
25 | let me know if you encounter problems.
26 |
27 | While browsing, you can hover over variables to get information about them:
28 | hovering over a use site of a variable will highlight all other uses of it,
29 | as well as its binder. Hovering over a binder will give information about
30 | the type of the variable, as well as some of the information GHC inferred,
31 | such as strictness, uses, etc. You may also click on a binder to "hold on"
32 | to its information---the information won't disappear when you move the mouse.
33 | Click again to "let go" of the binder.
34 |
35 | Hovering over identifiers from other modules will show you where they are
36 | defined. You may click on them to go to that module (if you have the HTML
37 | for it), although---due to a bug---you'll have to scroll to the definition
38 | manually.
39 |
40 | You may also expand and collapse (some of the) definitions to make things more
41 | manageable.
42 |
43 | Here a sample of the output for a single module:
44 |
45 | http://yav.github.io/dump-core/example-output/Galua.OpcodeInterpreter.html
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ui/see.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: 'Fira Mono', monospace;
3 | }
4 |
5 | .dots {
6 | display: inline-block;
7 | }
8 |
9 |
10 | a.var {
11 | color: #339;
12 | text-decoration: none;
13 | }
14 |
15 | a.var:hover {
16 | text-decoration: underline;
17 | }
18 |
19 |
20 | .clickable {
21 | cursor: pointer;
22 | }
23 |
24 |
25 | .active { background-color: orange; }
26 | .active-long { background-color: green; }
27 |
28 | .var {
29 | display: inline-block;
30 | }
31 |
32 | .top.bind {
33 | margin-bottom: 2em;
34 | }
35 |
36 |
37 | .app {
38 | vertical-align: top;
39 | }
40 |
41 | .title {
42 | font-size: large;
43 | font-weight: bold;
44 | }
45 |
46 | .nested { padding-left: 1em; }
47 |
48 |
49 |
50 | .paren {
51 | border: 1px solid black !important;
52 | padding: 3px;
53 | vertical-align: middle;
54 | }
55 |
56 | .arg {
57 | display: inline-block;
58 | margin-right: 0.5em;
59 | white-space: nowrap;
60 | }
61 |
62 | .app-arg {
63 | margin-left: 0.2em;
64 | }
65 |
66 |
67 | .lit {
68 | color: purple;
69 | display: inline-block;
70 | }
71 |
72 | .kw.lam {
73 | margin-right: 0.1em;
74 | }
75 |
76 | .kw {
77 | display: inline-block;
78 | font-weight: bold;
79 | margin-right: 0.5em;
80 | }
81 |
82 | .expr:hover {
83 | border-left: 1px dashed #999;
84 | }
85 |
86 | .expr {
87 | border-left: 1px solid transparent;
88 | margin-right: 0.5em;
89 | vertical-align: middle;
90 | }
91 |
92 | .small.expr {
93 | display: inline-block;
94 | }
95 |
96 | table.details {
97 | border-collapse: collapse;
98 | }
99 |
100 | table.details td {
101 | border-left: 1px solid white;
102 | padding-left: 0.5em;
103 | padding-right: 0.5em;
104 | white-space: nowrap;
105 | }
106 |
107 | table.details th {
108 | border-left: 1px solid white;
109 | padding-left: 0.5em;
110 | padding-right: 0.5em;
111 | white-space: nowrap;
112 | }
113 |
114 |
115 |
116 |
117 | #all-details {
118 | z-index: 5;
119 | position: fixed;
120 | right: 1em;
121 | top: 1em;
122 | max-width: 50%;
123 | }
124 |
125 | #details-long {
126 | border: 2px solid green;
127 | background-color: rgba(0,0,0,0.8);
128 | color: white;
129 | padding: 0.5em;
130 | overflow: auto;
131 | }
132 |
133 | #details-short {
134 | border: 2px solid orange;
135 | background-color: rgba(0,0,0,0.8);
136 | color: white;
137 | padding: 0.5em;
138 | margin-bottom: 0.5em;
139 | overflow: auto;
140 | }
141 |
142 | @font-face {
143 | font-family: 'Fira Mono';
144 | font-style: normal;
145 | font-weight: 400;
146 | src: local('Fira Mono');
147 | }
148 |
149 |
--------------------------------------------------------------------------------
/ui/fonts/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012-2013, The Mozilla Corporation and Telefonica S.A.
2 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
3 | This license is copied below, and is also available with a FAQ at:
4 | http://scripts.sil.org/OFL
5 |
6 |
7 | -----------------------------------------------------------
8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9 | -----------------------------------------------------------
10 |
11 | PREAMBLE
12 | The goals of the Open Font License (OFL) are to stimulate worldwide
13 | development of collaborative font projects, to support the font creation
14 | efforts of academic and linguistic communities, and to provide a free and
15 | open framework in which fonts may be shared and improved in partnership
16 | with others.
17 |
18 | The OFL allows the licensed fonts to be used, studied, modified and
19 | redistributed freely as long as they are not sold by themselves. The
20 | fonts, including any derivative works, can be bundled, embedded,
21 | redistributed and/or sold with any software provided that any reserved
22 | names are not used by derivative works. The fonts and derivatives,
23 | however, cannot be released under any other type of license. The
24 | requirement for fonts to remain under this license does not apply
25 | to any document created using the fonts or their derivatives.
26 |
27 | DEFINITIONS
28 | "Font Software" refers to the set of files released by the Copyright
29 | Holder(s) under this license and clearly marked as such. This may
30 | include source files, build scripts and documentation.
31 |
32 | "Reserved Font Name" refers to any names specified as such after the
33 | copyright statement(s).
34 |
35 | "Original Version" refers to the collection of Font Software components as
36 | distributed by the Copyright Holder(s).
37 |
38 | "Modified Version" refers to any derivative made by adding to, deleting,
39 | or substituting -- in part or in whole -- any of the components of the
40 | Original Version, by changing formats or by porting the Font Software to a
41 | new environment.
42 |
43 | "Author" refers to any designer, engineer, programmer, technical
44 | writer or other person who contributed to the Font Software.
45 |
46 | PERMISSION & CONDITIONS
47 | Permission is hereby granted, free of charge, to any person obtaining
48 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
49 | redistribute, and sell modified and unmodified copies of the Font
50 | Software, subject to the following conditions:
51 |
52 | 1) Neither the Font Software nor any of its individual components,
53 | in Original or Modified Versions, may be sold by itself.
54 |
55 | 2) Original or Modified Versions of the Font Software may be bundled,
56 | redistributed and/or sold with any software, provided that each copy
57 | contains the above copyright notice and this license. These can be
58 | included either as stand-alone text files, human-readable headers or
59 | in the appropriate machine-readable metadata fields within text or
60 | binary files as long as those fields can be easily viewed by the user.
61 |
62 | 3) No Modified Version of the Font Software may use the Reserved Font
63 | Name(s) unless explicit written permission is granted by the corresponding
64 | Copyright Holder. This restriction only applies to the primary font name as
65 | presented to the users.
66 |
67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68 | Software shall not be used to promote, endorse or advertise any
69 | Modified Version, except to acknowledge the contribution(s) of the
70 | Copyright Holder(s) and the Author(s) or with their explicit written
71 | permission.
72 |
73 | 5) The Font Software, modified or unmodified, in part or in whole,
74 | must be distributed entirely under this license, and must not be
75 | distributed under any other license. The requirement for fonts to
76 | remain under this license does not apply to any document created
77 | using the Font Software.
78 |
79 | TERMINATION
80 | This license becomes null and void if any of the above conditions are
81 | not met.
82 |
83 | DISCLAIMER
84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92 | OTHER DEALINGS IN THE FONT SOFTWARE.
93 |
--------------------------------------------------------------------------------
/ui/see.js:
--------------------------------------------------------------------------------
1 | function seeMod(m) {
2 |
3 | var heading = $('').addClass('title').text(m.mod)
4 |
5 | var binds = $('')
6 | jQuery.each(m.binds, function(ix,b) { binds.append(seeBinds(b,true)) })
7 |
8 | return $('').append(heading,binds)
9 |
10 |
11 | /* ------------------------------------------------------------ */
12 |
13 | function seeBinds(b,atTop) {
14 | var binds = $('').addClass('binding-group')
15 |
16 | jQuery.each(b.binds, function(ix,b) {
17 | var bind = $('').addClass('bind')
18 | if (atTop) {
19 | bind.addClass('top').append($('').attr('name',b.var.id))
20 | }
21 |
22 | if (b.terms) bind.append(kw('(' + b.terms + ')'))
23 | bind.append(seeBindVar(b.var))
24 |
25 | var eq = kw('=')
26 | var ex = nested(seeExpr(b.def))
27 | var dots = switcher(eq,ex,atTop)
28 | bind.append(eq,ex,dots)
29 |
30 | binds.append(bind)
31 | })
32 |
33 | return b.rec ? $('').append(kw('rec'), nested(binds))
34 | : binds
35 | }
36 |
37 | /* ------------------------------------------------------------ */
38 |
39 | function seeBindVar(x) {
40 |
41 | var d = $('')
42 | .addClass('var clickable')
43 | .addClass(x.id)
44 | .hover(entry,exit)
45 |
46 | if (x.join) { d.append(kw('join '), $('').text(x.name)) }
47 | else d.text(x.name)
48 |
49 | var infoBox = null
50 |
51 | d.click(function() {
52 | var c = 'active-long'
53 | var nowOn = d.hasClass(c)
54 | $('.' + c).removeClass(c)
55 |
56 | if (nowOn) {
57 | $('#details-long').empty()
58 | } else {
59 | findAll().addClass(c)
60 | if (infoBox) $('#details-long').empty().append(infoBox.clone())
61 | }
62 | })
63 |
64 | if (x.info) { d.addClass('arg').attr('id',x.id)
65 | infoBox = seeDetails(x.info) }
66 |
67 |
68 | function findAll() {
69 | var c = '.' + x.id
70 | return $(c + ',div:has(' + c + ')+.dots')
71 | }
72 |
73 | function entry() {
74 | if (infoBox) $('#details-short').append(infoBox)
75 | findAll().addClass('active')
76 | }
77 | function exit () {
78 | findAll().removeClass('active')
79 | $('#details-short').empty()
80 | }
81 |
82 | return d
83 | }
84 |
85 | /* ------------------------------------------------------------ */
86 |
87 | function seeDetails(info) {
88 | var d = $('
').addClass('details')
89 |
90 | if (info.poly.length !== 0) {
91 | var vars = $('