emacs.d/clones/ruslanspivak.com/lsbasi-part8/index.html

536 lines
33 KiB
HTML
Raw Normal View History

2022-10-07 19:32:11 +02:00
<!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 8. - 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="Today well talk about unary operators, namely unary plus (+) and unary minus (-) operators. A lot of todays material is based on the material from the previous article, so if you need a refresher just head back to Part 7 and go over it again. Remember: repetition is the …" />
<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 8."/>
<meta property="og:url" content="https://ruslanspivak.com/lsbasi-part8/"/>
<meta property="og:description" content="Today well talk about unary operators, namely unary plus (+) and unary minus (-) operators. A lot of todays material is based on the material from the previous article, so if you need a refresher just head back to Part 7 and go over it again. Remember: repetition is the …"/>
<meta property="article:published_time" content="2016-01-18" />
<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 8.">
Let&#8217;s Build A Simple Interpreter. Part&nbsp;8.
</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-01-18T06:10:00-05:00"> Mon, January 18, 2016</time>
</span>
</footer><!-- /.post-info --> </div>
</div>
<p>Today we&#8217;ll talk about <strong>unary operators</strong>, namely unary plus (+) and unary minus (-)&nbsp;operators.</p>
<p>A lot of today&#8217;s material is based on the material from the previous article, so if you need a refresher just head back to <a href="../lsbasi-part7/index.html" title="Part 7">Part 7</a> and go over it again. Remember: repetition is the mother of all&nbsp;learning.</p>
<p>Having said that, this is what you are going to do&nbsp;today:</p>
<ul>
<li>extend the grammar to handle unary plus and unary minus&nbsp;operators</li>
<li>add a new <em>UnaryOp</em> <span class="caps">AST</span> node&nbsp;class</li>
<li>extend the parser to generate an <span class="caps">AST</span> with <em>UnaryOp</em>&nbsp;nodes</li>
<li>extend the interpreter and add a new <em>visit_UnaryOp</em> method to interpret unary&nbsp;operators</li>
</ul>
<p>Lets get started, shall&nbsp;we?</p>
<p>So far we&#8217;ve worked with binary operators only (+, -, *, /), that is, the operators that operate on two&nbsp;operands.</p>
<p>What is a unary operator then? A <em>unary operator</em> is an operator that operates on one <em>operand</em>&nbsp;only.</p>
<p>Here are the rules for unary plus and unary minus&nbsp;operators:</p>
<ul>
<li>The unary minus (-) operator produces the negation of its numeric&nbsp;operand</li>
<li>The unary plus (+) operator yields its numeric operand without&nbsp;change</li>
<li>The unary operators have higher precedence than the binary operators +, -, *, and&nbsp;/</li>
</ul>
<p>In the expression &#8220;+ - 3&#8221; the first &#8216;+&#8217; operator represents the unary plus operation and the second &#8216;-&#8216; operator represents the unary minus operation. The expression &#8220;+ - 3&#8221; is equivalent to &#8220;+ (- (3))&#8221; which is equal to -3. One could also say that <strong>-3</strong> in the expression is a negative integer, but in our case we treat it as a unary minus operator with 3 as its positive integer&nbsp;operand:</p>
<p><img alt="" src="lsbasi_part8_exp1.png" width="640"></p>
<p>Lets take a look at another expression, &#8220;5 - -&nbsp;2&#8221;:</p>
<p><img alt="" src="lsbasi_part8_exp2.png" width="640"></p>
<p>In the expression &#8220;5 - - 2&#8221; the first &#8216;-&#8216; represents the <em>binary</em> subtraction operation and the second &#8216;-&#8216; represents the <em>unary</em> minus operation, the&nbsp;negation.</p>
<p>And some more&nbsp;examples:</p>
<p><img alt="" src="lsbasi_part8_exp3.png" width="640"></p>
<p><img alt="" src="lsbasi_part8_exp4.png" width="640"></p>
<p>Now lets update our grammar to include unary plus and unary minus operators. We&#8217;ll modify the <em>factor</em> rule and add unary operators there because unary operators have higher precedence than binary +, -, * and /&nbsp;operators.</p>
<p>This is our current <em>factor</em>&nbsp;rule:</p>
<p><img alt="" src="lsbasi_part8_factor_before.png" width="640"></p>
<p>And this is our updated <em>factor</em> rule to handle unary plus and unary minus&nbsp;operators:</p>
<p><img alt="" src="lsbasi_part8_factor_after.png" width="640"></p>
<p>As you can see, I extended the <em>factor</em> rule to reference itself, which allows us to derive expressions like &#8220;- - - + - 3&#8221;, a legitimate expression with a lot of unary&nbsp;operators.</p>
<p>Here is the full grammar that can now derive expressions with unary plus and unary minus&nbsp;operators:</p>
<p><img alt="" src="lsbasi_part8_grammar.png" width="640"></p>
<p>The next step is to add an <span class="caps">AST</span> node class to represent unary&nbsp;operators.</p>
<p>This one will&nbsp;do:</p>
<div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">UnaryOp</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">op</span><span class="p">,</span> <span class="n">expr</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">op</span> <span class="o">=</span> <span class="n">op</span>
<span class="bp">self</span><span class="o">.</span><span class="n">expr</span> <span class="o">=</span> <span class="n">expr</span>
</pre></div>
<p>The constructor takes two parameters: <em>op</em>, which represents the unary operator token (plus or minus) and <em>expr</em>, which represents an <span class="caps">AST</span>&nbsp;node.</p>
<p>Our updated grammar had changes to the <em>factor</em> rule, so thats what were going to modify in our parser - the <em>factor</em> method. We will add code to the method to handle the &#8220;(<span class="caps">PLUS</span> | <span class="caps">MINUS</span>) factor&#8221;&nbsp;sub-rule:</p>
<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">factor</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;factor : (PLUS | MINUS) factor | INTEGER | LPAREN expr RPAREN&quot;&quot;&quot;</span>
<span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">current_token</span>
<span class="k">if</span> <span class="n">token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">PLUS</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">PLUS</span><span class="p">)</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">UnaryOp</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">factor</span><span class="p">())</span>
<span class="k">return</span> <span class="n">node</span>
<span class="k">elif</span> <span class="n">token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">MINUS</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">MINUS</span><span class="p">)</span>
<span class="n">node</span> <span class="o">=</span> <span class="n">UnaryOp</span><span class="p">(</span><span class="n">token</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">factor</span><span class="p">())</span>
<span class="k">return</span> <span class="n">node</span>
<span class="k">elif</span> <span class="n">token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">INTEGER</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">INTEGER</span><span class="p">)</span>
<span class="k">return</span> <span class="n">Num</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">token</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">LPAREN</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">LPAREN</span><span class="p">)</span>
<span class="n">node</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">expr</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">RPAREN</span><span class="p">)</span>
<span class="k">return</span> <span class="n">node</span>
</pre></div>
<p><br/>
And now we need to extend the <em>Interpreter</em> class and add a <em>visit_UnaryOp</em> method to interpret unary&nbsp;nodes:</p>
<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">visit_UnaryOp</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="n">op</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">op</span><span class="o">.</span><span class="n">type</span>
<span class="k">if</span> <span class="n">op</span> <span class="o">==</span> <span class="n">PLUS</span><span class="p">:</span>
<span class="k">return</span> <span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expr</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">op</span> <span class="o">==</span> <span class="n">MINUS</span><span class="p">:</span>
<span class="k">return</span> <span class="o">-</span><span class="bp">self</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">expr</span><span class="p">)</span>
</pre></div>
<p>Onward!</p>
<p>Let&#8217;s manually build an <span class="caps">AST</span> for the expression &#8220;5 - - - 2&#8221; and pass it to our interpreter to verify that the new <em>visit_UnaryOp</em> method works. Here is how you can do it from the Python&nbsp;shell:</p>
<div class="highlight"><pre><span></span><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">spi</span> <span class="kn">import</span> <span class="n">BinOp</span><span class="p">,</span> <span class="n">UnaryOp</span><span class="p">,</span> <span class="n">Num</span><span class="p">,</span> <span class="n">MINUS</span><span class="p">,</span> <span class="n">INTEGER</span><span class="p">,</span> <span class="n">Token</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">five_tok</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">INTEGER</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">two_tok</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">INTEGER</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">minus_tok</span> <span class="o">=</span> <span class="n">Token</span><span class="p">(</span><span class="n">MINUS</span><span class="p">,</span> <span class="s1">&#39;-&#39;</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">expr_node</span> <span class="o">=</span> <span class="n">BinOp</span><span class="p">(</span>
<span class="o">...</span> <span class="n">Num</span><span class="p">(</span><span class="n">five_tok</span><span class="p">),</span>
<span class="o">...</span> <span class="n">minus_tok</span><span class="p">,</span>
<span class="o">...</span> <span class="n">UnaryOp</span><span class="p">(</span><span class="n">minus_token</span><span class="p">,</span> <span class="n">UnaryOp</span><span class="p">(</span><span class="n">minus_token</span><span class="p">,</span> <span class="n">Num</span><span class="p">(</span><span class="n">two_tok</span><span class="p">)))</span>
<span class="o">...</span> <span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">spi</span> <span class="kn">import</span> <span class="n">Interpreter</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">inter</span> <span class="o">=</span> <span class="n">Interpreter</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">inter</span><span class="o">.</span><span class="n">visit</span><span class="p">(</span><span class="n">expr_node</span><span class="p">)</span>
<span class="mi">3</span>
</pre></div>
<p>Visually the above <span class="caps">AST</span> tree looks like&nbsp;this:</p>
<p><img alt="" src="lsbasi_part8_ast.png" width="420"></p>
<p>Download the full source code of the interpreter for this article directly from <a href="https://github.com/rspivak/lsbasi/blob/master/part8/python/spi.py">GitHub</a>. Try it out and see for yourself that your updated tree-based interpreter properly evaluates arithmetic expressions containing unary&nbsp;operators.</p>
<p>Here is a sample&nbsp;session:</p>
<div class="highlight"><pre><span></span>$ python spi.py
spi&gt; - <span class="m">3</span>
-3
spi&gt; + <span class="m">3</span>
<span class="m">3</span>
spi&gt; <span class="m">5</span> - - - + - <span class="m">3</span>
<span class="m">8</span>
spi&gt; <span class="m">5</span> - - - + - <span class="o">(</span><span class="m">3</span> + <span class="m">4</span><span class="o">)</span> - +2
<span class="m">10</span>
</pre></div>
<p><br/>
I also updated the <a href="https://github.com/rspivak/lsbasi/blob/master/part8/python/genastdot.py">genastdot.py</a> utility to handle unary operators. Here are some of the examples of the generated <span class="caps">AST</span> images for expressions with unary&nbsp;operators:</p>
<div class="highlight"><pre><span></span>$ python genastdot.py <span class="s2">&quot;- 3&quot;</span> &gt; ast.dot <span class="o">&amp;&amp;</span> dot -Tpng -o ast.png ast.dot
</pre></div>
<p><img alt="" src="lsbasi_part8_genastdot_01.png"></p>
<div class="highlight"><pre><span></span>$ python genastdot.py <span class="s2">&quot;+ 3&quot;</span> &gt; ast.dot <span class="o">&amp;&amp;</span> dot -Tpng -o ast.png ast.dot
</pre></div>
<p><img alt="" src="lsbasi_part8_genastdot_02.png"></p>
<div class="highlight"><pre><span></span>$ python genastdot.py <span class="s2">&quot;5 - - - + - 3&quot;</span> &gt; ast.dot <span class="o">&amp;&amp;</span> dot -Tpng -o ast.png ast.dot
</pre></div>
<p><img alt="" src="lsbasi_part8_genastdot_03.png"></p>
<div class="highlight"><pre><span></span>$ python genastdot.py <span class="s2">&quot;5 - - - + - (3 + 4) - +2&quot;</span> <span class="se">\</span>
&gt; ast.dot <span class="o">&amp;&amp;</span> dot -Tpng -o ast.png ast.dot
</pre></div>
<p><img alt="" src="lsbasi_part8_genastdot_04.png"></p>
<p><br/>
<br/>
And here is a new exercise for&nbsp;you:</p>
<p><img alt="" src="lsbasi_part8_exercises.png" width="280"></p>
<ul>
<li>Install <a href="http://www.freepascal.org/">Free Pascal</a>, compile and run <a href="https://github.com/rspivak/lsbasi/blob/master/part8/python/testunary.pas">testunary.pas</a>, and verify that the results are the same as produced with your <a href="https://github.com/rspivak/lsbasi/blob/master/part8/python/spi.py">spi</a>&nbsp;interpreter.</li>
</ul>
<p><br/>
Thats all for today. In the next article, well tackle assignment statements. Stay tuned and see you&nbsp;soon.</p>
<p><br/>
Here is a list of books I recommend that will help you in your study of interpreters and&nbsp;compilers:</p>
<ol>
<li>
<p><a href="http://www.amazon.com/gp/product/193435645X/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=193435645X&linkCode=as2&tag=russblo0b-20&linkId=MP4DCXDV6DJMEJBL">Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages (Pragmatic Programmers)</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=russblo0b-20&l=as2&o=1&a=193435645X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
</li>
<li>
<p><a href="http://www.amazon.com/gp/product/0470177071/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0470177071&linkCode=as2&tag=russblo0b-20&linkId=UCLGQTPIYSWYKRRM">Writing Compilers and Interpreters: A Software Engineering Approach</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=russblo0b-20&l=as2&o=1&a=0470177071" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
</li>
<li>
<p><a href="http://www.amazon.com/gp/product/052182060X/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=052182060X&linkCode=as2&tag=russblo0b-20&linkId=ZSKKZMV7YWR22NMW">Modern Compiler Implementation in Java</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=russblo0b-20&l=as2&o=1&a=052182060X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
</li>
<li>
<p><a href="http://www.amazon.com/gp/product/1461446988/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1461446988&linkCode=as2&tag=russblo0b-20&linkId=PAXWJP5WCPZ7RKRD">Modern Compiler Design</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=russblo0b-20&l=as2&o=1&a=1461446988" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
</li>
<li>
<p><a href="http://www.amazon.com/gp/product/0321486811/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321486811&linkCode=as2&tag=russblo0b-20&linkId=GOEGDQG4HIHU56FQ">Compilers: Principles, Techniques, and Tools (2nd Edition)</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=russblo0b-20&l=as2&o=1&a=0321486811" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
</li>
</ol>
<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="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="../lsbasi-part12/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-8';
var disqus_url = 'https://ruslanspivak.com/lsbasi-part8/';
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>