1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="AsciiDoc 8.6.8">
<title>AST</title>
<link rel="stylesheet" href="./asciidoc.css" type="text/css">
<link rel="stylesheet" href="./pygments.css" type="text/css">
<script type="text/javascript" src="./asciidoc.js"></script>
<script type="text/javascript">
/*<![CDATA[*/
asciidoc.install();
/*]]>*/
</script>
<link rel="stylesheet" href="./mlton.css" type="text/css"/>
</head>
<body class="article">
<div id="banner">
<div id="banner-home">
<a href="./Home">MLton 20130715</a>
</div>
</div>
<div id="header">
<h1>AST</h1>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph"><p><a href="AST">AST</a> is the <a href="IntermediateLanguage">IntermediateLanguage</a> produced by the <a href="FrontEnd">FrontEnd</a>
and translated by <a href="Elaborate">Elaborate</a> to <a href="CoreML">CoreML</a>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_description">Description</h2>
<div class="sectionbody">
<div class="paragraph"><p>The abstract syntax tree produced by the <a href="FrontEnd">FrontEnd</a>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_implementation">Implementation</h2>
<div class="sectionbody">
<div class="ulist"><ul>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-programs.sig"><span class="monospaced">ast-programs.sig</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-programs.fun"><span class="monospaced">ast-programs.fun</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-modules.sig"><span class="monospaced">ast-modules.sig</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-modules.fun"><span class="monospaced">ast-modules.fun</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-core.sig"><span class="monospaced">ast-core.sig</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/blob/master/mlton/ast/ast-core.fun"><span class="monospaced">ast-core.fun</span></a>
</p>
</li>
<li>
<p>
<a href="https://github.com/MLton/mlton/tree/master/mlton/ast"><span class="monospaced">ast</span></a>
</p>
</li>
</ul></div>
</div>
</div>
<div class="sect1">
<h2 id="_type_checking">Type Checking</h2>
<div class="sectionbody">
<div class="paragraph"><p>The <a href="AST">AST</a> <a href="IntermediateLanguage">IntermediateLanguage</a> has no independent type
checker. Type inference is performed on an AST program as part of
<a href="Elaborate">Elaborate</a>.</p></div>
</div>
</div>
<div class="sect1">
<h2 id="_details_and_notes">Details and Notes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="_source_locations">Source locations</h3>
<div class="paragraph"><p>MLton makes use of a relatively clean method for annotating the
abstract syntax tree with source location information. Every source
program phrase is "wrapped" with the <span class="monospaced">WRAPPED</span> interface:</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="k">signature</span><span class="w"> </span><span class="n">WRAPPED</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w"> </span><span class="k">sig</span><span class="w"></span>
<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">node'</span><span class="w"></span>
<span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">obj</span><span class="w"></span>
<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">dest</span><span class="p">:</span><span class="w"> </span><span class="n">obj</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">node'</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">Region</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">makeRegion'</span><span class="p">:</span><span class="w"> </span><span class="n">node'</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">SourcePos</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">SourcePos</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">obj</span><span class="w"></span>
<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">makeRegion</span><span class="p">:</span><span class="w"> </span><span class="n">node'</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">Region</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">obj</span><span class="w"></span>
<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">node</span><span class="p">:</span><span class="w"> </span><span class="n">obj</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">node'</span><span class="w"></span>
<span class="w"> </span><span class="k">val</span><span class="w"> </span><span class="n">region</span><span class="p">:</span><span class="w"> </span><span class="n">obj</span><span class="w"> </span><span class="p">-></span><span class="w"> </span><span class="n">Region</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
<span class="w"> </span><span class="k">end</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>The key idea is that <span class="monospaced">node'</span> is the type of an unannotated syntax
phrase and <span class="monospaced">obj</span> is the type of its annotated counterpart. In the
implementation, every <span class="monospaced">node'</span> is annotated with a <span class="monospaced">Region.t</span>
(<a href="https://github.com/MLton/mlton/blob/master/mlton/control/region.sig"><span class="monospaced">region.sig</span></a>,
<a href="https://github.com/MLton/mlton/blob/master/mlton/control/region.sml"><span class="monospaced">region.sml</span></a>), which describes the
syntax phrase’s left source position and right source position, where
<span class="monospaced">SourcePos.t</span> (<a href="https://github.com/MLton/mlton/blob/master/mlton/control/source-pos.sig"><span class="monospaced">source-pos.sig</span></a>,
<a href="https://github.com/MLton/mlton/blob/master/mlton/control/source-pos.sml"><span class="monospaced">source-pos.sml</span></a>) denotes a
particular file, line, and column. A typical use of the <span class="monospaced">WRAPPED</span>
interface is illustrated by the following code:</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="w"> </span><span class="k">datatype</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="p">=</span><span class="w"></span>
<span class="w"> </span><span class="n">App</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">Longcon</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">t</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Const</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">Const</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Constraint</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">Type</span><span class="p">.</span><span class="n">t</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">FlatApp</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">vector</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Layered</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="p">{</span><span class="n">constraint</span><span class="p">:</span><span class="w"> </span><span class="n">Type</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="n">option</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">fixop</span><span class="p">:</span><span class="w"> </span><span class="n">Fixop</span><span class="p">.</span><span class="n">t</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">pat</span><span class="p">:</span><span class="w"> </span><span class="n">t</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">var</span><span class="p">:</span><span class="w"> </span><span class="n">Var</span><span class="p">.</span><span class="n">t</span><span class="p">}</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">List</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">vector</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Record</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="p">{</span><span class="n">flexible</span><span class="p">:</span><span class="w"> </span><span class="n">bool</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">items</span><span class="p">:</span><span class="w"> </span><span class="p">(</span><span class="n">Record</span><span class="p">.</span><span class="n">Field</span><span class="p">.</span><span class="n">t</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">Item</span><span class="p">.</span><span class="n">t</span><span class="p">)</span><span class="w"> </span><span class="n">vector</span><span class="p">}</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Tuple</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="n">vector</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Var</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="p">{</span><span class="n">fixop</span><span class="p">:</span><span class="w"> </span><span class="n">Fixop</span><span class="p">.</span><span class="n">t</span><span class="p">,</span><span class="w"></span>
<span class="w"> </span><span class="n">name</span><span class="p">:</span><span class="w"> </span><span class="n">Longvid</span><span class="p">.</span><span class="n">t</span><span class="p">}</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">Wild</span><span class="w"></span>
<span class="w"> </span><span class="k">include</span><span class="w"> </span><span class="n">WRAPPED</span><span class="w"> </span><span class="k">sharing</span><span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">node'</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">node</span><span class="w"></span>
<span class="w"> </span><span class="k">sharing</span><span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="n">obj</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">t</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>Thus, AST nodes are cleanly separated from source locations. By way
of contrast, consider the approach taken by <a href="SMLNJ">SML/NJ</a> (and also
by the <a href="CKitLibrary">CKit Library</a>). Each datatype denoting a syntax
phrase dedicates a special constructor for annotating source
locations:</p></div>
<div class="listingblock">
<div class="content"><div class="highlight"><pre><span class="k">datatype</span><span class="w"> </span><span class="n">pat</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="n">WildPat</span><span class="w"> </span><span class="cm">(* empty pattern *)</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">AppPat</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="p">{</span><span class="n">constr</span><span class="p">:</span><span class="n">pat</span><span class="p">,</span><span class="n">argument</span><span class="p">:</span><span class="n">pat</span><span class="p">}</span><span class="w"> </span><span class="cm">(* application *)</span><span class="w"></span>
<span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="n">MarkPat</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">pat</span><span class="w"> </span><span class="n">*</span><span class="w"> </span><span class="n">region</span><span class="w"> </span><span class="cm">(* mark a pattern *)</span><span class="w"></span>
</pre></div></div></div>
<div class="paragraph"><p>The main drawback of this approach is that static type checking is not
sufficient to guarantee that the AST emitted from the front-end is
properly annotated.</p></div>
</div>
</div>
</div>
</div>
<div id="footnotes"><hr></div>
<div id="footer">
<div id="footer-text">
</div>
<div id="footer-badges">
</div>
</div>
</body>
</html>
|