emacs.d/clones/ruslanspivak.com/lsbasi-part12/index.html
2022-10-07 19:32:11 +02:00

600 lines
No EOL
34 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en"
xmlns:og="http://ogp.me/ns#"
xmlns:fb="https://www.facebook.com/2008/fbml">
<head>
<title>Lets Build A Simple Interpreter. Part 12. - Ruslan's Blog</title>
<!-- Using the latest rendering mode for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="index.html">
<meta name="author" content="Ruslan Spivak" />
<meta name="description" content="“Be not afraid of going slowly; be afraid only of standing still.” - Chinese proverb. Hello, and welcome back! Today we are going to take a few more baby steps and learn how to parse Pascal procedure declarations. What is a procedure declaration? A procedure declaration is a language construct that …" />
<meta property="og:site_name" content="Ruslan's Blog" />
<meta property="og:type" content="article"/>
<meta property="og:title" content="Lets Build A Simple Interpreter. Part 12."/>
<meta property="og:url" content="https://ruslanspivak.com/lsbasi-part12/"/>
<meta property="og:description" content="“Be not afraid of going slowly; be afraid only of standing still.” - Chinese proverb. Hello, and welcome back! Today we are going to take a few more baby steps and learn how to parse Pascal procedure declarations. What is a procedure declaration? A procedure declaration is a language construct that …"/>
<meta property="article:published_time" content="2016-12-01" />
<meta property="article:section" content="blog" />
<meta property="article:author" content="Ruslan Spivak" />
<meta name="twitter:card" content="summary">
<meta name="twitter:domain" content="https://ruslanspivak.com">
<!-- Bootstrap -->
<link rel="stylesheet" href="../theme/css/bootstrap.min.css" type="text/css"/>
<link href="../theme/css/font-awesome.min.css" rel="stylesheet">
<link href="../theme/css/pygments/tango.css" rel="stylesheet">
<link href="../theme/css/typogrify.css" rel="stylesheet">
<link rel="stylesheet" href="../theme/css/style.css" type="text/css"/>
<link href="../static/custom.css" rel="stylesheet">
<link href="../feeds/all.atom.xml" type="application/atom+xml" rel="alternate"
title="Ruslan's Blog ATOM Feed"/>
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a href="../index.html" class="navbar-brand">
Ruslan's Blog </a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav">
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="../pages/about.html"><i class="fa fa-question"></i><span class="icon-label">About</span></a></li>
<li><a href="../archives.html"><i class="fa fa-th-list"></i><span class="icon-label">Archives</span></a></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
</div> <!-- /.navbar -->
<!-- Banner -->
<!-- End Banner -->
<div class="container">
<div class="row">
<div class="col-sm-9">
<section id="content">
<article>
<header class="page-header">
<h1>
<a href="index.html"
rel="bookmark"
title="Permalink to Lets Build A Simple Interpreter. Part 12.">
Let&#8217;s Build A Simple Interpreter. Part&nbsp;12.
</a>
</h1>
</header>
<div class="entry-content">
<div class="panel">
<div class="panel-body">
<footer class="post-info">
<span class="label label-default">Date</span>
<span class="published">
<i class="fa fa-calendar"></i><time datetime="2016-12-01T16:20:00-05:00"> Thu, December 01, 2016</time>
</span>
</footer><!-- /.post-info --> </div>
</div>
<blockquote>
<p><em><span class="dquo">&#8220;</span>Be not afraid of going slowly; be afraid only of standing still.&#8221; - Chinese&nbsp;proverb.</em></p>
</blockquote>
<p>Hello, and welcome&nbsp;back!</p>
<p>Today we are going to take a few more baby steps and learn how to parse Pascal procedure&nbsp;declarations.</p>
<p><img alt="" src="lsbasi_part12_babysteps.png" width="700"></p>
<p>What is a <em><strong>procedure declaration</strong></em>? A <em><strong>procedure declaration</strong></em> is a language construct that defines an identifier (a procedure name) and associates it with a block of Pascal&nbsp;code.</p>
<p>Before we dive in, a few words about Pascal procedures and their&nbsp;declarations:</p>
<ul>
<li>Pascal procedures dont have return statements. They exit when they reach the end of their corresponding&nbsp;block.</li>
<li>Pascal procedures can be nested within each&nbsp;other.</li>
<li>For simplicity reasons, procedure declarations in this article won&#8217;t have any formal parameters. But, don&#8217;t worry, we&#8217;ll cover that later in the&nbsp;series.</li>
</ul>
<p>This is our test program for&nbsp;today:</p>
<div class="highlight"><pre><span></span><span class="k">PROGRAM</span> <span class="n">Part12</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">PROCEDURE</span> <span class="nf">P1</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span> <span class="o">:</span> <span class="kt">REAL</span><span class="o">;</span>
<span class="n">k</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">PROCEDURE</span> <span class="nf">P2</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span><span class="o">,</span> <span class="n">z</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">BEGIN</span> <span class="cm">{P2}</span>
<span class="n">z</span> <span class="o">:=</span> <span class="mi">777</span><span class="o">;</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P2}</span>
<span class="k">BEGIN</span> <span class="cm">{P1}</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P1}</span>
<span class="k">BEGIN</span> <span class="cm">{Part12}</span>
<span class="n">a</span> <span class="o">:=</span> <span class="mi">10</span><span class="o">;</span>
<span class="k">END</span><span class="o">.</span> <span class="cm">{Part12}</span>
</pre></div>
<p>As you can see above, we have defined two procedures (<em>P1</em> and <em>P2</em>) and <em>P2</em> is nested within <em>P1</em>.
In the code above, I used comments with a procedures name to clearly indicate where the body of every procedure begins and where it&nbsp;ends.</p>
<p>Our objective for today is pretty clear: learn how to parse a code like&nbsp;that.</p>
<p><br/></p>
<p>First, we need to make some changes to our grammar to add procedure declarations. Well, lets just do&nbsp;that!</p>
<p>Here is the updated <em>declarations</em> grammar&nbsp;rule:</p>
<p><img alt="" src="lsbasi_part12_grammar.png" width="640"></p>
<p>The procedure declaration sub-rule consists of the reserved keyword <strong><span class="caps">PROCEDURE</span></strong> followed by an identifier (a procedure name),
followed by a semicolon, which in turn is followed by a <em>block</em> rule, which is terminated by a semicolon.
Whoa! This is a case where I think the picture is actually worth however many words I just put in the previous sentence!&nbsp;:)</p>
<p>Here is the updated syntax diagram for the <em>declarations</em>&nbsp;rule:</p>
<p><img alt="" src="lsbasi_part12_syntaxdiagram.png" width="640"></p>
<p>From the grammar and the diagram above you can see that you can have as many procedure declarations on the same level as you want.
For example, in the code snippet below we define two procedure declarations, <em>P1</em> and <em><span class="caps">P1A</span></em>, on the same&nbsp;level:</p>
<div class="highlight"><pre><span></span><span class="k">PROGRAM</span> <span class="n">Test</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">PROCEDURE</span> <span class="nf">P1</span><span class="o">;</span>
<span class="k">BEGIN</span> <span class="cm">{P1}</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P1}</span>
<span class="k">PROCEDURE</span> <span class="nf">P1A</span><span class="o">;</span>
<span class="k">BEGIN</span> <span class="cm">{P1A}</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P1A}</span>
<span class="k">BEGIN</span> <span class="cm">{Test}</span>
<span class="n">a</span> <span class="o">:=</span> <span class="mi">10</span><span class="o">;</span>
<span class="k">END</span><span class="o">.</span> <span class="cm">{Test}</span>
</pre></div>
<p>The diagram and the grammar rule above also indicate that procedure declarations can be nested because the
<em>procedure declaration</em> sub-rule references the <em>block</em> rule which contains the <em>declarations</em> rule, which in turn
contains the <em>procedure declaration</em> sub-rule. As a reminder, here is the syntax diagram and the grammar
for the block rule from <a href="../lsbasi-part10/index.html">Part10</a>:</p>
<p><img alt="" src="lsbasi_part12_block_rule_from_part10.png" width="800"></p>
<p><br/>
Okay, now let&#8217;s focus on the interpreter components that need to be updated to support procedure&nbsp;declarations:</p>
<p><em><strong>Updating the&nbsp;Lexer</strong></em></p>
<p>All we need to do is add a new token named <strong><span class="caps">PROCEDURE</span></strong>:</p>
<div class="highlight"><pre><span></span><span class="n">PROCEDURE</span> <span class="o">=</span> <span class="s1">&#39;PROCEDURE&#39;</span>
</pre></div>
<p>And add <em>&#8216;<span class="caps">PROCEDURE</span>&#8217;</em> to the reserved keywords. Here is the complete mapping of reserved keywords to&nbsp;tokens:</p>
<div class="highlight"><pre><span></span><span class="n">RESERVED_KEYWORDS</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">&#39;PROGRAM&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;PROGRAM&#39;</span><span class="p">,</span> <span class="s1">&#39;PROGRAM&#39;</span><span class="p">),</span>
<span class="s1">&#39;VAR&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;VAR&#39;</span><span class="p">,</span> <span class="s1">&#39;VAR&#39;</span><span class="p">),</span>
<span class="s1">&#39;DIV&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;INTEGER_DIV&#39;</span><span class="p">,</span> <span class="s1">&#39;DIV&#39;</span><span class="p">),</span>
<span class="s1">&#39;INTEGER&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;INTEGER&#39;</span><span class="p">,</span> <span class="s1">&#39;INTEGER&#39;</span><span class="p">),</span>
<span class="s1">&#39;REAL&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;REAL&#39;</span><span class="p">,</span> <span class="s1">&#39;REAL&#39;</span><span class="p">),</span>
<span class="s1">&#39;BEGIN&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;BEGIN&#39;</span><span class="p">,</span> <span class="s1">&#39;BEGIN&#39;</span><span class="p">),</span>
<span class="s1">&#39;END&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;END&#39;</span><span class="p">,</span> <span class="s1">&#39;END&#39;</span><span class="p">),</span>
<span class="s1">&#39;PROCEDURE&#39;</span><span class="p">:</span> <span class="n">Token</span><span class="p">(</span><span class="s1">&#39;PROCEDURE&#39;</span><span class="p">,</span> <span class="s1">&#39;PROCEDURE&#39;</span><span class="p">),</span>
<span class="p">}</span>
</pre></div>
<p><br/>
<em><strong>Updating the&nbsp;Parser</strong></em></p>
<p>Here is a summary of the parser&nbsp;changes:</p>
<ol>
<li>New <em>ProcedureDecl</em> <span class="caps">AST</span>&nbsp;node</li>
<li>Update to the parsers <em>declarations</em> method to support procedure&nbsp;declarations</li>
</ol>
<p>Lets go over the&nbsp;changes.</p>
<ol>
<li>
<p>The <em>ProcedureDecl</em> <span class="caps">AST</span> node represents a <em>procedure declaration</em>. The class constructor takes as parameters the name of the procedure and the <span class="caps">AST</span> node of the block of code that the procedures name refers&nbsp;to.</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">ProcedureDecl</span><span class="p">(</span><span class="n">AST</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">proc_name</span><span class="p">,</span> <span class="n">block_node</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">proc_name</span> <span class="o">=</span> <span class="n">proc_name</span>
<span class="bp">self</span><span class="o">.</span><span class="n">block_node</span> <span class="o">=</span> <span class="n">block_node</span>
</pre></div>
</li>
<li>
<p>Here is the updated <em>declarations</em> method of the <em>Parser</em>&nbsp;class</p>
<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">declarations</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;declarations : VAR (variable_declaration SEMI)+</span>
<span class="sd"> | (PROCEDURE ID SEMI block SEMI)*</span>
<span class="sd"> | empty</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">declarations</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">VAR</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">VAR</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">ID</span><span class="p">:</span>
<span class="n">var_decl</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">variable_declaration</span><span class="p">()</span>
<span class="n">declarations</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">var_decl</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">SEMI</span><span class="p">)</span>
<span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">PROCEDURE</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">PROCEDURE</span><span class="p">)</span>
<span class="n">proc_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_token</span><span class="o">.</span><span class="n">value</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">ID</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">SEMI</span><span class="p">)</span>
<span class="n">block_node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">block</span><span class="p">()</span>
<span class="n">proc_decl</span> <span class="o">=</span> <span class="n">ProcedureDecl</span><span class="p">(</span><span class="n">proc_name</span><span class="p">,</span> <span class="n">block_node</span><span class="p">)</span>
<span class="n">declarations</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">proc_decl</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">eat</span><span class="p">(</span><span class="n">SEMI</span><span class="p">)</span>
<span class="k">return</span> <span class="n">declarations</span>
</pre></div>
<p>Hopefully, the code above is pretty self-explanatory. It follows the grammar/syntax diagram for procedure declarations that youve seen earlier in the&nbsp;article.</p>
</li>
</ol>
<p><br/>
<em><strong>Updating the SymbolTable&nbsp;builder</strong></em></p>
<p>Because were not ready yet to handle nested procedure scopes, well simply add an empty <em>visit_ProcedureDecl</em> method to the <em>SymbolTreeBuilder</em> <span class="caps">AST</span> visitor class. We&#8217;ll fill it out in the next&nbsp;article.</p>
<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">visit_ProcedureDecl</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node</span><span class="p">):</span>
<span class="k">pass</span>
</pre></div>
<p></br>
<em><strong>Updating the&nbsp;Interpreter</strong></em></p>
<p>We also need to add an empty <em>visit_ProcedureDecl</em> method to the <em>Interpreter</em> class, which will cause our interpreter to silently ignore all our procedure&nbsp;declarations.</p>
<p>So far, so&nbsp;good.</p>
<p></br>
Now that we&#8217;ve made all the necessary changes, let&#8217;s see what the <em>Abstract Syntax Tree</em> looks like with the new <em>ProcedureDecl</em>&nbsp;nodes.</p>
<p>Here is our Pascal program again (you can download it directly from <a href="https://github.com/rspivak/lsbasi/blob/master/part12/python/part12.pas">GitHub</a>):</p>
<div class="highlight"><pre><span></span><span class="k">PROGRAM</span> <span class="n">Part12</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">PROCEDURE</span> <span class="nf">P1</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span> <span class="o">:</span> <span class="kt">REAL</span><span class="o">;</span>
<span class="n">k</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">PROCEDURE</span> <span class="nf">P2</span><span class="o">;</span>
<span class="k">VAR</span>
<span class="n">a</span><span class="o">,</span> <span class="n">z</span> <span class="o">:</span> <span class="kt">INTEGER</span><span class="o">;</span>
<span class="k">BEGIN</span> <span class="cm">{P2}</span>
<span class="n">z</span> <span class="o">:=</span> <span class="mi">777</span><span class="o">;</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P2}</span>
<span class="k">BEGIN</span> <span class="cm">{P1}</span>
<span class="k">END</span><span class="o">;</span> <span class="cm">{P1}</span>
<span class="k">BEGIN</span> <span class="cm">{Part12}</span>
<span class="n">a</span> <span class="o">:=</span> <span class="mi">10</span><span class="o">;</span>
<span class="k">END</span><span class="o">.</span> <span class="cm">{Part12}</span>
</pre></div>
<p><br/>
Let&#8217;s generate an <span class="caps">AST</span> and visualize it with the <a href="https://github.com/rspivak/lsbasi/blob/master/part12/python/genastdot.py">genastdot.py</a>&nbsp;utility:</p>
<div class="highlight"><pre><span></span>$ python genastdot.py part12.pas &gt; ast.dot <span class="o">&amp;&amp;</span> dot -Tpng -o ast.png ast.dot
</pre></div>
<p><img alt="" src="lsbasi_part12_procdecl_ast.png"></p>
<p>In the picture above you can see two <em>ProcedureDecl</em> nodes: <em>ProcDecl:P1</em> and <em>ProcDecl:P2</em> that
correspond to procedures <em>P1</em> and <em>P2</em>. Mission accomplished.&nbsp;:)</p>
<p>As a last item for today, let&#8217;s quickly check that our updated interpreter works as before when
a Pascal program has procedure declarations in it. Download <a href="https://github.com/rspivak/lsbasi/blob/master/part12/python/spi.py">the interpreter</a>
and <a href="https://github.com/rspivak/lsbasi/blob/master/part12/python/part12.pas">the test program</a> if you haven&#8217;t done so yet, and run it on the command line.
Your output should look similar to&nbsp;this:</p>
<div class="highlight"><pre><span></span>$ python spi.py part12.pas
Define: INTEGER
Define: REAL
Lookup: INTEGER
Define: &lt;a:INTEGER&gt;
Lookup: a
Symbol Table contents:
Symbols: <span class="o">[</span>INTEGER, REAL, &lt;a:INTEGER&gt;<span class="o">]</span>
Run-time GLOBAL_MEMORY contents:
<span class="nv">a</span> <span class="o">=</span> <span class="m">10</span>
</pre></div>
<p></br>
Okay, with all that knowledge and experience under our belt, were ready to tackle the topic of nested scopes
that we need to understand in order to be able to analyze nested procedures and prepare ourselves to
handle procedure and function calls. And that&#8217;s exactly what we are going to do in the next article:
dive deep into nested scopes. So don&#8217;t forget to bring your swimming gear next time! Stay tuned and see you&nbsp;soon!</p>
<p><br/>
<p>If you want to get my newest articles in your inbox, then enter your email address below and click "Get Updates!"</p>
<!-- Begin MailChimp Signup Form -->
<link href="https://cdn-images.mailchimp.com/embedcode/classic-081711.css"
rel="stylesheet" type="text/css">
<style type="text/css">
#mc_embed_signup {
background: #f5f5f5;
clear: left;
font: 18px Helvetica,Arial,sans-serif;
}
#mc_embed_signup form {
text-align: center;
padding: 20px 0 10px 3%;
}
#mc_embed_signup .mc-field-group input {
display: inline;
width: 40%;
}
#mc_embed_signup div.response {
width: 100%;
}
</style>
<div id="mc_embed_signup">
<form
action="https://ruslanspivak.us4.list-manage.com/subscribe/post?u=7dde30eedc045f4670430c25f&amp;id=6f69f44e03"
method="post"
id="mc-embedded-subscribe-form"
name="mc-embedded-subscribe-form"
class="validate"
target="_blank" novalidate>
<div id="mc_embed_signup_scroll">
<div class="mc-field-group">
<label for="mce-NAME">Enter Your First Name *</label>
<input type="text" value="" name="NAME" class="required" id="mce-NAME">
</div>
<div class="mc-field-group">
<label for="mce-EMAIL">Enter Your Best Email *</label>
<input type="email" value="" name="EMAIL" class="required email" id="mce-EMAIL">
</div>
<div id="mce-responses" class="clear">
<div class="response" id="mce-error-response" style="display:none"></div>
<div class="response" id="mce-success-response" style="display:none"></div>
</div>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;"><input type="text" name="b_7dde30eedc045f4670430c25f_6f69f44e03" tabindex="-1" value=""></div>
<div class="clear"><input type="submit" value="Get Updates!" name="subscribe" id="mc-embedded-subscribe" class="button" style="background-color: rgb(63, 146, 236);"></div>
</div>
</form>
</div>
<!-- <script type='text/javascript' src='//s3.amazonaws.com/downloads.mailchimp.com/js/mc-validate.js'></script><script type='text/javascript'>(function($) {window.fnames = new Array(); window.ftypes = new Array();fnames[1]='NAME';ftypes[1]='text';fnames[0]='EMAIL';ftypes[0]='email';}(jQuery));var $mcj = jQuery.noConflict(true);</script> -->
<!--End mc_embed_signup-->
</p>
<p><br/>
<strong>All articles in this series:</strong>
<ul>
<li>
<a href="../lsbasi-part1/index.html">Let's Build A Simple Interpreter. Part 1.</a>
</li>
<li>
<a href="../lsbasi-part2/index.html">Let's Build A Simple Interpreter. Part 2.</a>
</li>
<li>
<a href="../lsbasi-part3/index.html">Let's Build A Simple Interpreter. Part 3.</a>
</li>
<li>
<a href="../lsbasi-part4/index.html">Let's Build A Simple Interpreter. Part 4.</a>
</li>
<li>
<a href="../lsbasi-part5/index.html">Let's Build A Simple Interpreter. Part 5.</a>
</li>
<li>
<a href="../lsbasi-part6/index.html">Let's Build A Simple Interpreter. Part 6.</a>
</li>
<li>
<a href="../lsbasi-part7/index.html">Let's Build A Simple Interpreter. Part 7: Abstract Syntax Trees</a>
</li>
<li>
<a href="../lsbasi-part8/index.html">Let's Build A Simple Interpreter. Part 8.</a>
</li>
<li>
<a href="../lsbasi-part9/index.html">Let's Build A Simple Interpreter. Part 9.</a>
</li>
<li>
<a href="../lsbasi-part10/index.html">Let's Build A Simple Interpreter. Part 10.</a>
</li>
<li>
<a href="../lsbasi-part11/index.html">Let's Build A Simple Interpreter. Part 11.</a>
</li>
<li>
<a href="index.html">Let's Build A Simple Interpreter. Part 12.</a>
</li>
<li>
<a href="../lsbasi-part13.html">Let's Build A Simple Interpreter. Part 13: Semantic Analysis</a>
</li>
<li>
<a href="../lsbasi-part14/index.html">Let's Build A Simple Interpreter. Part 14: Nested Scopes and a Source-to-Source Compiler</a>
</li>
<li>
<a href="../lsbasi-part15/index.html">Let's Build A Simple Interpreter. Part 15.</a>
</li>
<li>
<a href="../lsbasi-part16/index.html">Let's Build A Simple Interpreter. Part 16: Recognizing Procedure Calls</a>
</li>
<li>
<a href="../lsbasi-part17.html">Let's Build A Simple Interpreter. Part 17: Call Stack and Activation Records</a>
</li>
<li>
<a href="../lsbasi-part18/index.html">Let's Build A Simple Interpreter. Part 18: Executing Procedure Calls</a>
</li>
<li>
<a href="../lsbasi-part19/index.html">Let's Build A Simple Interpreter. Part 19: Nested Procedure Calls</a>
</li>
</ul>
</p>
</div>
<!-- /.entry-content -->
<hr/>
<section class="comments" id="comments">
<h2>Comments</h2>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'ruslanspivak'; // required: replace example with your forum shortname
var disqus_identifier = 'lets-build-a-simple-interpreter-part-12';
var disqus_url = 'https://ruslanspivak.com/lsbasi-part12/';
var disqus_config = function () {
this.language = "en";
};
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by
Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</section>
</article>
</section>
</div>
<div class="col-sm-3" id="sidebar">
<aside>
<section class="well well-sm">
<ul class="list-group list-group-flush">
<li class="list-group-item"><h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Social</span></h4>
<ul class="list-group" id="social">
<li class="list-group-item"><a href="https://github.com/rspivak/"><i class="fa fa-github-square fa-lg"></i> github</a></li>
<li class="list-group-item"><a href="https://twitter.com/rspivak"><i class="fa fa-twitter-square fa-lg"></i> twitter</a></li>
<li class="list-group-item"><a href="https://linkedin.com/in/ruslanspivak/"><i class="fa fa-linkedin-square fa-lg"></i> linkedin</a></li>
</ul>
</li>
<li class="list-group-item"><h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Popular posts</span></h4>
<ul class="list-group" id="popularposts">
<li class="list-group-item"
style="font-size: 15px; word-break: normal;">
<a href="../lsbaws-part1/index.html">
Let's Build A Web Server. Part 1.
</a>
</li>
<li class="list-group-item"
style="font-size: 15px; word-break: normal;">
<a href="../lsbasi-part1/index.html">
Let's Build A Simple Interpreter. Part 1.
</a>
</li>
<li class="list-group-item"
style="font-size: 15px; word-break: normal;">
<a href="../lsbaws-part2/index.html">
Let's Build A Web Server. Part 2.
</a>
</li>
<li class="list-group-item"
style="font-size: 15px; word-break: normal;">
<a href="../lsbaws-part3/index.html">
Let's Build A Web Server. Part 3.
</a>
</li>
<li class="list-group-item"
style="font-size: 15px; word-break: normal;">
<a href="../lsbasi-part2/index.html">
Let's Build A Simple Interpreter. Part 2.
</a>
</li>
</ul>
</li>
<li class="list-group-item">
<h4>
<span>Disclaimer</span>
</h4>
<p id="disclaimer-text"> Some of the links on this site
have my Amazon referral id, which provides me with a small
commission for each sale. Thank you for your support.
</p>
</li>
</ul>
</section>
</aside>
</div>
</div>
</div>
<footer>
<div class="container">
<hr>
<div class="row">
<div class="col-xs-10">&copy; 2020 Ruslan Spivak
<!-- &middot; Powered by <a href="https://github.com/DandyDev/pelican-bootstrap3" target="_blank">pelican-bootstrap3</a>, -->
<!-- <a href="http://docs.getpelican.com/" target="_blank">Pelican</a>, -->
<!-- <a href="http://getbootstrap.com" target="_blank">Bootstrap</a> -->
<!-- -->
</div>
<div class="col-xs-2"><p class="pull-right"><i class="fa fa-arrow-up"></i> <a href="index.html#">Back to top</a></p></div>
</div>
</div>
</footer>
<script src="../theme/js/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="../theme/js/bootstrap.min.js"></script>
<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->
<script src="../theme/js/respond.min.js"></script>
<!-- Disqus -->
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'ruslanspivak'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function () {
var s = document.createElement('script');
s.async = true;
s.type = 'text/javascript';
s.src = '//' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
<!-- End Disqus Code -->
<!-- Google Analytics Universal -->
<script type="text/javascript">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-2572871-3', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics Universal Code -->
</body>
</html>