<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

    <title>Sergi Mansilla</title>
    <subtitle>Sergi Mansilla. Experiments about functional programming and monkey brains programming.</subtitle>
    <link href="http://sergimansilla.com/blog/atom.xml" rel="self" type="application/atom+xml" />
    <link href="http://sergimansilla.com" rel="alternate" type="text/html" />
    <id>http://sergimansilla.com</id>
    <updated>2013-05-14T14:52:54+02:00</updated>
    <author>
        <name>Sergi Mansilla</name>
    </author>

    
        <entry>
            <title>Virtual list in vanilla JavaScript</title>
            <link href="http://sergimansilla.com/blog/virtual-scrolling/" rel="alternate" type="text/html" />
            <updated>2013-05-12T00:00:00+02:00</updated>
            <id>http://sergimansilla.com/blog/virtual-scrolling</id>
            <content type="html">&lt;p&gt;Let's say you need to show a scrolling list with millions of rows, or even
a reasonably big list with visually complex rows, each one composed by several
DOM elements or CSS3 effects.&lt;/p&gt;

&lt;p&gt;If you try to render this the naive way,
for example by appending rows into a DOM container with the CSS  &lt;code&gt;overflow&lt;/code&gt; property set
to &lt;code&gt;scroll&lt;/code&gt; (or &lt;code&gt;auto&lt;/code&gt;), you will most likely run into performance issues. This is because all the items in the list are cached, thus your memory
consumption will certainly go up, and since all the DOM nodes composing the rows of
the list are appended in the document, the browser is trying to properly render them all making your CPU pretty busy as you scroll. If these rows change any style say, on hover, you will trigger a &lt;a href=&quot;http://www-archive.mozilla.org/newlayout/doc/reflow.html&quot;&gt;reflow&lt;/a&gt; and the experience will be even more sluggish.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Many websites and apps have run into this issue before and solved it using &lt;em&gt;virtual renderers&lt;/em&gt;, which trick the viewer into thinking that she is looking at a massive list, when in reality only the items that are currently in the viewport are being loaded and rendered. A popular application that does that is the &lt;a href=&quot;http://ace.ajax.org/&quot;&gt;ACE editor&lt;/a&gt;, which can load a massively big source code file while keeping scrolling snappy using this technique.&lt;/p&gt;

&lt;p&gt;Anyway, I needed a virtually rendered list and I couldn't find readily available components in simple JavaScript that I could use (and that I liked), so I created my own: &lt;a href=&quot;https://github.com/sergi/virtual-list&quot;&gt;virtual-list&lt;/a&gt;. Virtual list is a short and simple piece of code that doesn't depend on anything else, so you can drop it into any website and use it right away.&lt;/p&gt;

&lt;p&gt;For example, here you have a 1 million row list:&lt;/p&gt;

&lt;div id=&quot;placeholder&quot; style=&quot;text-align: center;&quot;&gt;&lt;/div&gt;


&lt;script&gt;

function VirtualList(config) {
  var width = (config &amp;&amp; config.w + 'px') || '100%';
  var height = this.height = (config &amp;&amp; config.h + 'px') || '100%';
  var itemHeight = this.itemHeight = config.itemHeight;

  this.items = config.items;
  this.generatorFn = config.generatorFn;
  console.log(config.totalRows)
  this.totalRows = config.totalRows || (config.items &amp;&amp; config.items.length);

  var totalHeight = itemHeight * this.totalRows;
  this.scroller = VirtualList.createScroller(totalHeight);
  this.container = VirtualList.createContainer(width, height);

  var screenItemsLen = Math.ceil(config.h / itemHeight);
  // Cache 4 times the number of items that fit in the container viewport
  var cachedItemsLen = screenItemsLen * 3;
  this._renderChunk(this.container, 0, cachedItemsLen / 2);

  var self = this;
  var lastRepaintY;
  var maxBuffer = screenItemsLen * itemHeight;

  function onScroll(e) {
    var scrollTop = e.target.scrollTop;
    var first = parseInt(scrollTop / itemHeight) - screenItemsLen;
    first = first &lt; 0 ? 0 : first;
    if (!lastRepaintY || Math.abs(scrollTop - lastRepaintY) &gt; maxBuffer) {
      self._renderChunk(self.container, first, cachedItemsLen);
      lastRepaintY = scrollTop;
    }

    e.preventDefault &amp;&amp; e.preventDefault();
  }

  this.container.addEventListener('scroll', onScroll);
}

VirtualList.prototype._renderChunk = function(node, fromPos, howMany) {
  var fragment = document.createDocumentFragment();
  fragment.appendChild(this.scroller);

  var finalItem = fromPos + howMany;
  if (finalItem &gt; this.totalRows)
    finalItem = this.totalRows;

  for (var i = fromPos; i &lt; finalItem; i++) {
    var item;
    if (this.generatorFn)
      item = this.generatorFn(i);
    else {
      if (typeof this.items[i] === 'string') {
        var itemText = document.createTextNode(this.items[i]);
        item = document.createElement('div');
        item.style.height = this.height;
        item.appendChild(itemText);
      } else {
        item = this.items[i];
      }
    }

    item.classList.add('vrow');
    item.style.position = 'absolute';
    item.style.top = (i * this.itemHeight) + 'px';
    fragment.appendChild(item);
  }

  node.innerHTML = '';
  node.appendChild(fragment);
};

VirtualList.createContainer = function(w, h) {
  var c = document.createElement('div');
  c.style.width = w;
  c.style.height = h;
  c.style.overflow = 'auto';
  c.style.position = 'relative';
  c.style.padding = 0;
  c.style.border = '1px solid black';
  return c;
};

VirtualList.createScroller = function(h) {
  var scroller = document.createElement('div');
  scroller.style.opacity = 0;
  scroller.style.position = 'absolute';
  scroller.style.top = 0;
  scroller.style.left = 0;
  scroller.style.width = '1px';
  scroller.style.height = h + 'px';
  return scroller;
};

var list = new VirtualList({
w: 300,
h: 300,
itemHeight: 31,
totalRows: 1000000,
generatorFn: function(row) {
  var el = document.createElement(&quot;div&quot;);
  el.innerHTML = &quot;I am row number &quot; + row;
  el.style.backgroundColor = &quot;red&quot;;
  el.style.background = &quot;linear-gradient(to bottom, #fefefd 0%,#dce3c4 42%,#aebf76 100%)&quot;;
  el.style.textAlign = &quot;center&quot;;
  el.style.width = &quot;300px&quot;;
  return el;
}
});

list.container.style.marginLeft = &quot;auto&quot;;
list.container.style.marginRight = &quot;auto&quot;;
document.getElementById(&quot;placeholder&quot;)
.appendChild(list.container);
&lt;/script&gt;


&lt;p&gt;Each of these rows is generated on demand, not wasting any memory, and the list
never has to manage more than ~30 rows at a time, no matter how long the list
is in reality.&lt;/p&gt;

&lt;p&gt;Please read more about how to use it in the project's &lt;a href=&quot;https://github.com/sergi/virtual-list#virtual-dom-list&quot;&gt;README&lt;/a&gt;
and report any bugs or improvements you may find if you happen to start using it in your projects.&lt;/p&gt;
</content>
        </entry>
    
        <entry>
            <title>Implement cursor-swiping in half an afternoon</title>
            <link href="http://sergimansilla.com/blog/swipeselection-in-an-afternoon/" rel="alternate" type="text/html" />
            <updated>2013-02-21T00:00:00+01:00</updated>
            <id>http://sergimansilla.com/blog/swipeselection-in-an-afternoon</id>
            <content type="html">&lt;p&gt;If you haven't seen it yet, I suggest that you take a look at this concept video that made the rounds on the internet some months ago:&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/RGQTaHGQ04Q?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/p&gt;


&lt;p&gt;I would pay to have this in my phone. Only, money wouldn’t help since I own an
iPhone, and a developer has simply no way to access an internal component like
the phone keyboard.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Well, it only took a small part of an afternoon to implement a proof of concept of cursor-swiping in Firefox OS. And even if this swipe-selection implementation is only a prototype, it’s perfectly functional
and I've already gotten used to its convenience. See a rough video I made here:&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe style=&quot;text-align: center&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/uDzb7HZY2mE?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/p&gt;


&lt;p&gt;You can check out the code for it in &lt;a href=&quot;https://github.com/comoyo/gaia/compare/master...swipe_selection&quot;&gt;Comoyo's Gaia branch on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I can't even express how amazing it is to hack the OS of the phone
you use and adapt it to your needs in such an easy way and with such a fast
development cycle. It makes me excited to think about what will happen once all these
JavaScript developers discover that they can hack their phone and contribute to
it using their favorite language.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: This implementation is in the Gaia fork that I use and I have no idea of whether it
will make it into the actual OS eventually, since there are obvious UX implications that might be uncomfortable for some.&lt;/em&gt;&lt;/p&gt;
</content>
        </entry>
    
        <entry>
            <title>The promise of Firefox OS</title>
            <link href="http://sergimansilla.com/blog/promise-of-ffos/" rel="alternate" type="text/html" />
            <updated>2013-02-09T00:00:00+01:00</updated>
            <id>http://sergimansilla.com/blog/promise-of-ffos</id>
            <content type="html">&lt;p&gt;&quot;But &lt;em&gt;how&lt;/em&gt; is it going to beat Android or iOS?”&lt;/p&gt;

&lt;p&gt;That’s the reaction many people have when I tell them that I am working on &lt;a href=&quot;http://www.mozilla.org/en-US/firefoxos/&quot;&gt;Firefox OS&lt;/a&gt;, the new mobile operating system from &lt;a href=&quot;http://www.mozilla.org/en-US/&quot;&gt;Mozilla&lt;/a&gt;. It is a logical reaction. After all, we live in times where every major software company and its mother is releasing a mobile platform, struggling to lure developers into their new proprietary environment, APIs, libraries, etc. And indeed, many of these companies &lt;a href=&quot;http://global.blackberry.com/sites.html&quot;&gt;barely make it&lt;/a&gt; or &lt;a href=&quot;http://www.hpwebos.com/us/&quot;&gt;don’t make it at all&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But Firefox OS will not be directly battling against other mobile platforms. Its main objective is to change the way the world develops mobile apps, and even in the unlikely event that Firefox OS itself disappears in the process, if web-apps become mainstream, it will have succeeded.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;The fact that any website is a potential app can’t be underestimated. By tapping into extremely popular and flexible technologies such as HTML5, CSS3 and JavaScript, Firefox OS instantly promoted millions of web and JavaScript developers into app developers. All they have to do is download a &lt;a href=&quot;https://hacks.mozilla.org/2012/12/firefox-os-simulator-1-0-is-here/&quot;&gt;free simulator addon&lt;/a&gt; (and not even that is strictly necessary if your app is not going to use phone APIs). Developers already know the browser environment and the tools, and there’s no need to learn any new language or framework.&lt;/p&gt;

&lt;p&gt;I hear some of you, already. Just when you were over with that mess that it is to manipulate the DOM and that &lt;a href=&quot;http://wtfjs.com/&quot;&gt;sneaky&lt;/a&gt; JavaScript language. Just when you learned to love the highly architected &lt;a href=&quot;http://developer.android.com/reference/classes.html&quot;&gt;Android classes and managers&lt;/a&gt; or iOS’s beautiful &lt;a href=&quot;https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/stringByReplacingPercentEscapesUsingEncoding:&quot;&gt;method naming&lt;/a&gt;, why would we be back to that mayhem that is writing web applications? Didn’t we agree that HTML was not, after all, good enough for making &lt;a href=&quot;http://www.zdnet.com/facebooks-mark-zuckerberg-knocks-html5-in-favor-of-native-apps-7000004082/&quot;&gt;real and performing apps&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Well, that might have been true some time ago, but we live in a brave new world now. Several approaches exist for developers to develop solid and real-world web applications, in the form of high-quality frameworks. At &lt;a href=&quot;http://www.telenor.com/&quot;&gt;Telenor/Comoyo&lt;/a&gt;, where I work, we are leaning towards using &lt;a href=&quot;http://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; for building our apps, but there are multiple &lt;a href=&quot;http://emberjs.com/&quot;&gt;well-thought&lt;/a&gt;, &lt;a href=&quot;http://knockoutjs.com/&quot;&gt;reliable&lt;/a&gt; frameworks that build on years of existing knowledge of modern application development. And if your problem is with JavaScript as a language, you can already use a myriad of languages that reliably compile to it. Do you come from a Java background? You’ll probably like &lt;a href=&quot;http://www.dartlang.org/&quot;&gt;Dart&lt;/a&gt;, from Google. More of a functional kind of developer? Try &lt;a href=&quot;http://clojurescriptone.com/&quot;&gt;ClojureScript&lt;/a&gt;, which is an impressive, well-maintained and well-performing implementation of Clojure on top of JavaScript. Coming from Ruby? You’ll be almost at home with &lt;a href=&quot;http://coffeescript.org/&quot;&gt;CoffeeScript&lt;/a&gt;. You get the picture.*&lt;/p&gt;

&lt;p&gt;While some other mobile vendors such as Blackberry also provide ways to develop apps for their systems using HTML5, Mozilla is going one step further by pushing hard to standardize the &lt;a href=&quot;https://wiki.mozilla.org/WebAPI&quot;&gt;WebAPI&lt;/a&gt; through the W3C, guaranteeing that your app will work in any device that follows the WebAPI standard.&lt;/p&gt;

&lt;p&gt;In my humble opinion, this puts some sense into the madness that developing for mobile devices has become, in which the developer has to know several languages, frameworks and APIs, not to mention pay a developer fee in order to build apps in some cases. It really feels like a step from the open web philosophy right back into the 90s, ridden with vendor lock-ins but without the good music.&lt;/p&gt;

&lt;p&gt;Mozilla has a good track record of looking after the web, and it &lt;a href=&quot;http://blog.mozilla.org/theden/2013/02/06/mozilla-is-most-trusted-internet-company-in-privacy/&quot;&gt;is a trusted company by its users&lt;/a&gt;. In the past they played a big role in freeing us from browser monopolies and pushing for better web standards, a movement that browsers like Chrome hooked onto, contributing to a better, faster and more accessible web for everybody. We should strive to do the same with our mobile environments. Fewer walled gardens, more standards and openness.&lt;/p&gt;

&lt;p&gt;That is the promise of Firefox OS.&lt;/p&gt;

&lt;p&gt;* &lt;em&gt;Although hey, it wouldn’t hurt to learn a bit of JS to know what’s going on under the hood, after all, it is a powerful language that will only get better with the upcoming &lt;a href=&quot;https://wiki.mozilla.org/ES6_plans&quot;&gt;ES6&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</content>
        </entry>
    
        <entry>
            <title>Moving on</title>
            <link href="http://sergimansilla.com/blog/moving-on/" rel="alternate" type="text/html" />
            <updated>2013-01-29T00:00:00+01:00</updated>
            <id>http://sergimansilla.com/blog/moving-on</id>
            <content type="html">&lt;p&gt;A little bit more than two years ago I was sitting on a meeting room, listening to Ruben Daniels and Rik Arends, the two founders of the company I was considering to join, &lt;a href=&quot;http://c9.io&quot;&gt;Cloud9 &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;&lt;/a&gt;. These were two of the smartest, most inspiring people I&amp;#8217;ve met, and they were working hard on a ground-breaking concept: a full-fledged development environment that run in the browser, and in the cloud. At the time, that sounded wildly adventurous, to say the least. But the challenges were so many, the concept so revolutionary and the people so inspiring that I joined the company two weeks after that conversation.&lt;/p&gt;
&lt;p&gt;What followed were two exhilarating years in which we got funding, surpassed almost every technical limitation that got on our way, got a huge user base and learned (many times the hard way) about software development, startup world and companionship.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
Today Cloud9 &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; is by far the most advanced online &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; in the world, and what many told us that would not be possible (the &lt;span class=&quot;caps&quot;&gt;DOM&lt;/span&gt; will never be fast enough for an editor, you won&amp;#8217;t be able to implement real-time code analysis/refactor, developers won&amp;#8217;t move their code to the cloud, etc.) is now a reality.&lt;/p&gt;
&lt;p&gt;I am extremely proud to have been part of this great adventure, which has definitely made me a better developer and human being. I have no doubt that Cloud9 will continue improving and taking the development wold by storm, because they have the most talented, visionary and experienced team I&amp;#8217;ve worked with behind.&lt;/p&gt;
&lt;p&gt;But the time has come for me to move on. I have officially accepted a position at Telenor to work on core &lt;a href=&quot;http://www.mozilla.org/en-US/firefoxos/&quot;&gt;Firefox OS&lt;/a&gt; development, Mozilla&amp;#8217;s new mobile operating system based on the open web. It is a very exciting project, and extremely different in technological challenges and userbase demographics compared to Cloud9.&lt;/p&gt;
&lt;p&gt;Whatever the future may bring, Cloud9 will always have a special place in my heart, and I will keep using and evangelizing it on my day-to-day work.&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>Nodejsconf in Italy</title>
            <link href="http://sergimansilla.com/blog/nodejs-conference-italy-2012/" rel="alternate" type="text/html" />
            <updated>2012-11-12T00:00:00+01:00</updated>
            <id>http://sergimansilla.com/blog/nodejs-conference-italy-2012</id>
            <content type="html">&lt;p&gt;Last weekend I was at the &lt;a href=&quot;http://nodejsconf.it&quot;&gt;Node.js conference&lt;/a&gt; in Brescia, Italy. Like every year the organizers managed to stage a great conference with really good talks. Even if I was there only for a lightning visit (less than 24 hours between leaving Amsterdam and being back), I had tons of fun and the talks I saw were really top-notch.&lt;/p&gt;
&lt;p&gt;As a side note, I&amp;#8217;m continually impressed by how much hacker spirit there is in Italy. There was lots of Arduino, BeagleBone boards and the real excitement of building stuff in Node.js that nobody has built before. Check out the talks from Simone Chiaretta or Matteo Collina to see an example of what I mean, when you have some time.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
I was a speaker in the conference too, and my talk was about dependency handling and modularization in our codebase. Perhaps not as exciting as &lt;a href=&quot;http://en.wikipedia.org/wiki/Remotely_operated_underwater_vehicle&quot;&gt;ROVs&lt;/a&gt; controlled by Node.js but this is one of the important parts of the architecture of &lt;a href=&quot;http://c9.io&quot;&gt;Cloud9 &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;&lt;/a&gt;, where the ever-growing amount of code and functionality has to be extendable while keeping the dependency graph complexity low.&lt;/p&gt;
&lt;p&gt;During my talk I recorded the slides with voice over, and you can see the video below. Unfortunately, the image and the sound of it are in a very low quality, but I think it is enough to get a rough impression of the talk.&lt;/p&gt;
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;iframe src=&quot;http://player.vimeo.com/video/53268844?badge=0&quot; width=&quot;500&quot; height=&quot;375&quot; frameborder=&quot;0&quot; webkitAllowFullScreen mozallowfullscreen allowFullScreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;Hopefully there will be videos of all the conference talks soon!&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>My talk at DynCon 2011</title>
            <link href="http://sergimansilla.com/blog/my-talk-at-dyncon/" rel="alternate" type="text/html" />
            <updated>2011-04-04T00:00:00+02:00</updated>
            <id>http://sergimansilla.com/blog/my-talk-at-dyncon</id>
            <content type="html">&lt;p&gt;The video with my talk about &lt;a href=&quot;http://c9.io&quot;&gt;Cloud9 &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;&lt;/a&gt; at &lt;a href=&quot;http://swdc-central.com/dyncon2011/&quot;&gt;DynCon 2011&lt;/a&gt; is already out! It’s quite long, but definitely worth it if you are interested in the future of the &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;, since I had the chance to answer many questions about it during the talk. About half of the video contains demo and questions from the audience, as it was quite interactive.&lt;/p&gt;
&lt;p&gt;Also, I want to thank &lt;a href=&quot;http://twitter.com/psvensson&quot;&gt;Peter Svensson&lt;/a&gt; for creating such a wildly interesting conference and being a really great host and organizer. It is a very, very hard job that he pulled off amazingly well.&lt;/p&gt;
&lt;p&gt;This talk was especially interesting to me because although the audience included mainly professional developers, most of them weren’t using JavaScript as their main language (as is often the case in our talks). It was fun to show them the power of JavaScript. And as always when you add people with different backgrounds to a discussion, ideas and good questions quickly started popping up. It was great. We’re also working hard at getting more languages incorporated, so hopefully we can have more of these types of discussions in the future, hang in there!&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
The best part was to see how programmers from all kinds of backgrounds were equally interested in having the advantages of a development platform like Cloud9 on the Cloud. It is incredibly motivating to get approval and excitement from the very audience that we are targeting with Cloud9.&lt;/p&gt;
&lt;p&gt;As a side note, it is amazing how much our own perception of past events diverges from the real thing. I thought the talk was quite fluent, but I can (painfully) see that I could have used more practice (&lt;span class=&quot;caps&quot;&gt;LOTS&lt;/span&gt; of “ums”, especially at the beginning!). Ah well…it was my first big public talk, so I guess this is to be expected :)&lt;/p&gt;
&lt;p&gt;Still, it’s a talk I’m proud of about a product that I’m proud of. Check it out if you want to see a glimpse of the future of development!!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Find the slides for the talk &lt;a href=&quot;http://www.slideshare.net/sergimansilla/introducing-cloud9-at-dyncon-2011&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align:center;&quot;&gt;&lt;iframe src=&quot;http://player.vimeo.com/video/21912872?byline=0&amp;amp;portrait=0&quot; width=&quot;400&quot; height=&quot;295&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>Dynamically generating MIDI in JavaScript</title>
            <link href="http://sergimansilla.com/blog/dinamically-generating-midi-in-javascript/" rel="alternate" type="text/html" />
            <updated>2010-11-08T00:00:00+01:00</updated>
            <id>http://sergimansilla.com/blog/dinamically-generating-midi-in-javascript</id>
            <content type="html">&lt;p&gt;Last weekend I open-sourced a &lt;a href=&quot;https://github.com/sergi/jsmidi&quot;&gt;small side project&lt;/a&gt; consisting of a JavaScript library that generates &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; in a simple manner. As an example, the code to generate a &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; file that plays 3 notes (C, E and G) would look like the following:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// We pass some notes to |MidiWriter.createNote| to create the MIDI&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// events that define the notes that will be in the final MIDI stream. If&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// no other parameters are specified to |createNote|, a NoteOff event&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// will be inserted automatically, instead of letting the note ring forever.&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Disregard the |push.apply|, it is used here simply to flatten the&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// resulting array, since |createNote| returns an array of events.&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noteEvents&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;C4&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;E4&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;G4&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;note&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;noteEvents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MidiEvent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createNote&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;note&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Create a track that contains the events to play the notes above&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MidiTrack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noteEvents&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Creates an object that contains the final MIDI track in base64 and some&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// useful methods.&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;song&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MidiWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;tracks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Alert the base64 representation of the MIDI file&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;alert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;song&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;b64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Play the song&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;song&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Play/save the song (depending of MIDI plugins in the browser). It opens&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// a new window and loads the generated MIDI file with the proper MIME type&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;song&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The library is work in progress, but it already outputs standard &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; files (&lt;a href=&quot;http://www.midi.org/aboutmidi/tut_midifiles.php&quot;&gt;&lt;span class=&quot;caps&quot;&gt;SMF&lt;/span&gt;&lt;/a&gt;) encoded in &lt;a href=&quot;http://en.wikipedia.org/wiki/Base64&quot;&gt;base64&lt;/a&gt;, and can play them in any browser that has a plugin that can reproduce &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; installed. It is usually Quicktime in most machines. And now, please allow me to rant a little bit&amp;#8230;&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
h2. The surprisingly bad state of &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; in the browser&lt;/p&gt;
&lt;p&gt;While developing this small library I was shocked at how inconsistent the state of &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; reproducibility is in the browser. I might have been very naive, but I expected that a &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; file would just sound right away inside a browser. Boy was I wrong.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: Any time I talk about reproducing &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt;, I am trying to do so using a data &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; encoded in base64. Although all the browsers mentioned should be compatible with it, there are some bugs related to how data &lt;span class=&quot;caps&quot;&gt;URI&lt;/span&gt; is supported when using it along with external plugins.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The new and shiny HTML5 &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; element doesn’t support &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; in any browser, so I had to revert to the good ol’ &lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; element, which supports it &lt;span class=&quot;caps&quot;&gt;ONLY&lt;/span&gt; if the user has a proper plugin installed. All the browsers are using the Quicktime 7 plugin (I was very surprised to see that the mighty &lt;a href=&quot;http://www.videolan.org&quot;&gt;&lt;span class=&quot;caps&quot;&gt;VLC&lt;/span&gt;&lt;/a&gt; can’t reproduce &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; out of the box).&lt;/p&gt;
&lt;p&gt;In some cases, even with the plugin installed, things didn’t work. That is the case for Webkit in Mac, which can’t reproduce the &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; file generated by the library, while Webkit on Windows and Firefox 4b6 (Mac/Win) have no problems with it. I suspect this is due to bad interaction of the plugins with data URIs.&lt;/p&gt;
&lt;p&gt;Of course you can always try to force a file download, but that’s not the point. It would be very nice if something as basic as cross-browser &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; reproducibility would exist, and it is surprising that it is not possible.&lt;/p&gt;
&lt;p&gt;But its inconsistent behavior isn’t actually the worse part. The worse part is that the user has to manually install a plug-in if she wants to be able to reproduce &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; inside the browser. Of course iTunes and Media Player can play &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt;, but that’s not the experience I am aiming for. &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; is still a strong standard nowadays (apparently the new iOS 4.2 is &lt;a href=&quot;http://www.engadget.com/2010/11/04/apple-introduces-midi-to-ios-4-2-ipads-the-world-oer-get-ready&quot;&gt;betting hard&lt;/a&gt; for it), specially in the world of professional musicians. For some reason this format has been ditched from HTML5 audio, or was never considered for it, leaving &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; reproduction in the browser in the hands of mediocre plugins and careless browser vendors.&lt;/p&gt;
&lt;h2&gt;Try it!&lt;/h2&gt;
&lt;p&gt;Go and try it! Find bugs, suggest improvements to the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; or features you would like to see there. And if you find solutions or have ideas on how to improve &lt;span class=&quot;caps&quot;&gt;MIDI&lt;/span&gt; reproducibility in the browser, please don&amp;#8217;t hesitate to tell me!&lt;/p&gt;
&lt;p&gt;You can find the library &lt;a href=&quot;https://github.com/sergi/jsmidi&quot;&gt;here&lt;/a&gt;. Remember that it is not complete and there is heavy work in progress going on, so expect that new versions will break compatibility (certainly) and keep updating it because I will improve it during the following weeks.&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>Writing a JavaScript interpreter for DBN using PEG.js and canvas (Part II)</title>
            <link href="http://sergimansilla.com/blog/writing-a-javascript-interpreter-for-dbn-using-canvas-II/" rel="alternate" type="text/html" />
            <updated>2010-08-20T00:00:00+02:00</updated>
            <id>http://sergimansilla.com/blog/writing-a-javascript-interpreter-for-dbn-using-canvas-II</id>
            <content type="html">&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this article I build an interpreter for the &lt;acronym title=&quot;Design By Language&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;&lt;/acronym&gt; language from the parsed &lt;acronym title=&quot;Abstract Syntax Tree&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt;&lt;/acronym&gt; generated by the grammar we defined &lt;a href=&quot;/blog/writing-a-javascript-interpreter-for-dbn-using-canvas-I&quot;&gt;in the previous article&lt;/a&gt; in &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js. If you haven&amp;#8217;t read the first part, I strongly reccomend to do so, otherwise this will make little sense to you.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It should be quite easy to follow by just looking at the code and its comments. Still, I will be explaining how the interpreter works as I put the code examples in.&lt;/p&gt;
&lt;h2&gt;Choices and assumptions&lt;/h2&gt;
&lt;p&gt;Due to little time and given the lack of any reference of the language, I made some assumptions and I left out some advanced features of the language. I hope I can include them soon into the &lt;a href=&quot;http://github.com/sergi/Design-By-Canvas&quot;&gt;project&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Scope&lt;/h4&gt;
&lt;p&gt;Since I don&amp;#8217;t know how scope works in &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;, I assumed &lt;a href=&quot;http://en.wikipedia.org/wiki/Scope_%28programming%29#Lexical_scoping&quot;&gt;Lexical scoping&lt;/a&gt;, given that it is the most common among modern programming languages (JavaScript has lexical scoping as well, for example).&lt;/p&gt;
&lt;h2&gt;The interpreter&lt;/h2&gt;
&lt;p&gt;The interpreter takes care of evaluating the arguments for each statement and then execute the statement with its parsed arguments and the given scope, if any:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;evalType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;typeTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;evalExpression&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ast&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Parse the arguments real value&lt;/span&gt;
            &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;reset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Resets all cnavas state and properties&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cmds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The global variables will reside in the &lt;code&gt;vars&lt;/code&gt; property, and the most important methods here are obviously &lt;code&gt;evalType&lt;/code&gt; and &lt;code&gt;evalExpression&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;!--more--&gt;&lt;br /&gt;
h3. Evaluating types&lt;/p&gt;
&lt;p&gt;&lt;code&gt;evalType&lt;/code&gt; receives the type object and its scope and calls the proper static method in &lt;code&gt;Interpreter.typeTable&lt;/code&gt; with the same parameters. &lt;code&gt;Interpreter.typeTable&lt;/code&gt; holds the functions that interpret the different types in &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// In DBN, everything is an integer or a set of integers, and the developer has&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// the possibility to put the values directly in the code or store them in&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// variables.&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;typeTable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cmdTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasOwnProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasOwnProperty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;vars&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;point&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;point&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
            &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The types are the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Command&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;padding-left:1em;&quot;&gt;A user-defined function in &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; jargon. The user can define custom commands with parameters that execute a block of code when called.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;String&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;padding-left:1em;&quot;&gt;Used mainly for variable names. Given a string from a generated &lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt;, I check whether the variable is defined in its local scope (in case there is one) or in the global scope. In case it is in neither of them, I assume that it is the name of a parameter and doesn&amp;#8217;t have an associated value.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Integer&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;padding-left:1em;&quot;&gt;The basic type. Its value is returned right away.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Point&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;padding-left:1em;&quot;&gt;A point refers to a coordinate in the canvas. It contains &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; values that can be integers, variables or arithmetic expressions. Returns an object with the evaluated &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; values.&lt;/p&gt;
&lt;h3&gt;Evaluating expressions&lt;/h3&gt;
&lt;p&gt;Expressions are &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; functions. In this interpreter, everything that computes is considered a function, including the arithmetic operators.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;evalExpression&lt;/code&gt; takes an &lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt; (or a portion of one, as it is done for code blocks) and loops through every statement, resolving the types of its arguments using &lt;code&gt;evalType&lt;/code&gt; and calling the proper static method in &lt;code&gt;Interpreter.expTable&lt;/code&gt; with them. &lt;code&gt;Interpreter.expTable&lt;/code&gt; is a dictionary that stores the supported &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; expressions&amp;#8217; equivalents in JavaScript (same as with types).&lt;/p&gt;
&lt;p&gt;Inside the &lt;code&gt;Interpreter.expTable&lt;/code&gt; we can find the following kinds of expressions:&lt;/p&gt;
&lt;h4&gt;Arithmetic expressions&lt;/h4&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;+&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&amp;quot;-&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Arithmetic expressions are always used inside other expressions parameters, never by themselves. The functions are called always with 2 arguments that have been already resolved by &lt;code&gt;evalType&lt;/code&gt;, so they are integers when they get to the expression.&lt;/p&gt;
&lt;h4&gt;Drawing expressions&lt;/h4&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; * paper will fill up the canvas with the specified color (the only argument&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; * of the expression)&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;paper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clientWidth&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clientHeight&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fillStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gray2rgb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fillRect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;pen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;strokeStyle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gray2rgb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;canvas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clientHeight&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;moveTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;closePath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The main difference between the &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; &amp;#8216;canvas&amp;#8217; and HTML5 canvas is that the Y coordinate is inverted; in &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; the Y coordinate starts at the bottom whereas in HTML5 canvas it starts at the top. The other important difference is that DBN&amp;#8217;s pixels color can only be a gray value from 0 (black) to 100 (white), so we have to use the very simple &lt;code&gt;gray2rgb&lt;/code&gt; method to translate them to canvas rgb syntax:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;cm&quot;&gt;/*&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; * gray2rgb transforms a 0 to 100 gray value into a rgb&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; * string compatible with canvas&lt;/span&gt;
&lt;span class=&quot;cm&quot;&gt; */&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gray2rgb&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;gray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rgb(&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;  &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;,&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;)&amp;quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With these two changes in place it is quite straightforward to translate drawing functions using the basic HTML5 canvas functions and passing the arguments properly.&lt;/p&gt;
&lt;h4&gt;Block expressions&lt;/h4&gt;
&lt;p&gt;A block expression is a statement that contains a block of nested expressions. DBN&amp;#8217;s &lt;code&gt;repeat&lt;/code&gt; and &lt;code&gt;command&lt;/code&gt; statements are the ones implemented here that belong to this kind. The peculiarity of block expressions is that they have a local scope:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Cloning context object because otherwise we will change&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// properties of the parent context, messing up everything&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Update the &amp;#39;counter&amp;#39; variable to reflect the current loop number&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalExpression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;rest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;Interpreter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;expTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Cloning context object because otherwise we will change&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// properties of the parent context, messing up everything&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Associate every argument name with the given argument&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// value of the command call&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;evalExpression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;scopeObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The local scope here is implemented in a naïve (and a bit inefficient) way. Basically and if it exists, the parent scope of the block expression is cloned and then the local variables of the block are copied on it. After that, the block of nested expressions is executed with the cloned context.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;repeat&lt;/code&gt; is a &amp;#8216;for&amp;#8217; loop that gets as arguments the &amp;#8216;counter&amp;#8217; variable, the lower bound of the range and the higher bound of the range. From that it creates a loop that assigns the counter variable to the local scope and executes the block with this scope.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;command&lt;/code&gt; builds a function from the given name and arguments and the block expression that forms the body of the function. In that case I create a function and store it in &lt;code&gt;Interpreter.expTable&lt;/code&gt; so it can be called anywhere in the code. I do the same trick with the scope as in &lt;code&gt;repeat&lt;/code&gt;, with the difference that in this case I asociate the name of the &lt;code&gt;command&lt;/code&gt; arguments with the value passed to the call of the function.&lt;/p&gt;
&lt;h2&gt;Demo&lt;/h2&gt;
&lt;p&gt;That&amp;#8217;s it, you can try a quick demo &lt;a href=&quot;/projects/dbn/dbn.html&quot;&gt;here&lt;/a&gt;. In the demo page you can find some examples and you can play around to better understand how &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; works and what its powers and limitations are.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As you can see this is a very simple implmentation, but it is enough to run most of the &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; programs around. Some things like arrays, timers and mouse position and events were left out and will be implemented at some point when I have time, but the actual &amp;#8216;meat&amp;#8217; of the intepreter won&amp;#8217;t change much anyway.&lt;/p&gt;
&lt;p&gt;You can find the complete code for this interpreter &lt;a href=&quot;http://github.com/sergi/Design-By-Canvas/blob/master/interpreter.js&quot;&gt;here&lt;/a&gt; and the complete repository &lt;a href=&quot;http://github.com/sergi/Design-By-Canvas&quot;&gt;here&lt;/a&gt;. If I missed something or yo have some suggestions of how to better implement &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; drop me a line, or even better: fork it!&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>Writing a JavaScript interpreter for DBN using PEG.js and canvas (Part I)</title>
            <link href="http://sergimansilla.com/blog/writing-a-javascript-interpreter-for-dbn-using-canvas-I/" rel="alternate" type="text/html" />
            <updated>2010-08-03T00:00:00+02:00</updated>
            <id>http://sergimansilla.com/blog/writing-a-javascript-interpreter-for-dbn-using-canvas-I</id>
            <content type="html">&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this first part of the article, I will define a grammar for &lt;acronym title=&quot;Design By Numbers&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;&lt;/acronym&gt; and generate a parser for it that outputs an &lt;acronym title=&quot;Abstract Syntax Tree&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt;&lt;/acronym&gt;, so I can interpret the syntax tree it later on with JavaScript and draw it into an HTML5 Canvas.&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br/&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/John_Maeda&quot;&gt;John Maeda&lt;/a&gt; created the &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; language as a tool to teach programming to non-developers. It was quite an influential language; in fact it was the precursor of the popular &lt;a href=&quot;http://en.wikipedia.org/wiki/Processing_%28programming_language%29&quot;&gt;processing&lt;/a&gt; language, developed by Maeda’s students &lt;a href=&quot;http://en.wikipedia.org/wiki/Casey_Reas&quot;&gt;Casey Reas&lt;/a&gt; and Ben Fry, taking many ideas from &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Unfortunately, &lt;acronym title=&quot;Design By Numbers&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt;&lt;/acronym&gt; hasn’t been open-sourced and the documentation of it is almost nonexisting, let alone any official specification of the language. There is only &lt;a href=&quot;http://www.amazon.com/Design-Numbers-John-Maeda/dp/0262632446&quot;&gt;one book&lt;/a&gt; written about it (although a &lt;a href=&quot;http://books.google.com/books?id=cptXSf5kS_IC&amp;amp;printsec=frontcover&amp;amp;dq=design+by+numbers&amp;amp;hl=en&amp;amp;ei=9ShZTIDxLsu6OO6D1bAJ&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=1&amp;amp;ved=0CCoQ6AEwAA#v=onepage&amp;amp;q&amp;amp;f=false&quot;&gt;blurry copy&lt;/a&gt; exists in google books, censored enough to miss very important parts), and the &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; software amounts to a &lt;a href=&quot;http://dbn.media.mit.edu/dbn/applet.html&quot;&gt;Java applet&lt;/a&gt; in the official website and a Java program that you can run on your own computer.&lt;/p&gt;
&lt;p&gt;All this lack of proper information was a challenge enough to get me interested on building a JavaScript interpreter for it (this, and my deep hatred for Java applets) and a good excuse to play with some cool JavaScript technologies.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
h2. Crash course in &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js grammar definitions&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://pegjs.majda.cz/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js&lt;/a&gt; is a parser generator for JavaScript. Given a proper grammar definition of the language, it will generate a parser for it that you can use wherever.&lt;/p&gt;
&lt;p&gt;If you want to quickly test the grammar output as you go, use &lt;a href=&quot;http://pegjs.majda.cz/online&quot;&gt;&lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js online version&lt;/a&gt;, it is immensely useful on the early stages of grammar definition.&lt;/p&gt;
&lt;p&gt;Also, keep in mind that what I explain here is a 10.000 foot overview of &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js and it is by no means a tutorial; if you want to learn real language grammar definition with &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js you &lt;strong&gt;must&lt;/strong&gt; read the &lt;a href=&quot;http://pegjs.majda.cz/documentation&quot;&gt;real documentation&lt;/a&gt; for it, and have some idea about parsers, lexers, tokens and their friends.&lt;/p&gt;
&lt;h3&gt;1. Defining the basics&lt;/h3&gt;
&lt;p&gt;Before we start, one thing worth oting is that &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js doesn&amp;#8217;t have a separate stage for &amp;#8220;lexing&amp;#8221;. The lexer is integrated seamlessly in the generated parser, so we don&amp;#8217;t have to worry about it.&lt;/p&gt;
&lt;p&gt;Ok, so the first thing to do is to define the building bocks for the language. Note that the parser doesn’t take anything for granted, so we will have to define how our language handles whitespace as well.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Z_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;zA&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Z0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// The first character must not be a number&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;integer&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;integer&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;digits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Matches expressions of the form [value1 value2]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[&amp;quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;point&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;special&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Matches expressions of the form &amp;lt;command value1 value2 ...&amp;gt;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;special&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})]&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;muldiv&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+-&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;muldiv&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;muldiv&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;primary&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;/] _ right:muldiv {&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;primary&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;primary&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;special&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;(&amp;quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;)&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;special&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Matches single-line comments&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;//&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;lb&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Matches any number of whitespace/comments in a row&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see, the language is very clear and takes inspiration from regular expressions. The above peg grammar defines strings, integers (&lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; has no decimals), points in a 2D canvas, and basic arithmetic (the latter adapted from the arithmetic grammar given at the &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js site as example).&lt;/p&gt;
&lt;p&gt;A rule is composed of several parts: its name, the matching expression and the optional &lt;em&gt;parser action&lt;/em&gt;, which is enclosed between brackets and transforms the output of the rule.&lt;/p&gt;
&lt;p&gt;For example, for the &lt;code&gt;point&lt;/code&gt; rule:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;point&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[&amp;quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;]&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// &amp;lt;-- This is the matching expression&lt;/span&gt;
   &lt;span class=&quot;c1&quot;&gt;// The following code is the parser action&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;point&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;right&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This rule checks for a &amp;#8220;[&amp;#8221; character followed by a &lt;code&gt;value&lt;/code&gt; rule (which is defined separately), followed by a whitespace rule (also defined separately), followed by another &lt;code&gt;value&lt;/code&gt; rule and a closing &amp;#8220;]&amp;#8221;.&lt;/p&gt;
&lt;p&gt;In most non-trivial rules we include a &lt;em&gt;parser action&lt;/em&gt;, which is the JavaScript code inside the brackets. The parser action can access the matched values of the rule and modify them using JavaScript before the output is returned. Here I return an object that contains the two values inside a point, which were labeled &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; in the matching expression so they can be accessed from the parser action. Without a parser action the output would be a JavaScript array with all the matches in the matching expression, so with the input &lt;code&gt;[4 2]&lt;/code&gt; we would get the output &lt;code&gt;[&quot;[&quot;, &quot;a&quot;, &quot; &quot;, &quot;b&quot;, &quot;]&quot;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;point&lt;/code&gt; rule references two other rules, &lt;code&gt;value&lt;/code&gt; and &lt;code&gt;ws&lt;/code&gt;, which look like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// matches any of the standard values in DBN&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;variable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;additive&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;point&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;special&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Matches space and tab characters&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;value&lt;/code&gt; will try to sequentially match any of the expressions separated by &amp;#8220;/&amp;#8221;, and it will return the first sucessful match. The whitespace &lt;code&gt;ws&lt;/code&gt; rule uses a RegExp construct to match any single space or tab character.&lt;/p&gt;
&lt;h3&gt;2. &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; Commands&lt;/h3&gt;
&lt;p&gt;Now we will define the &amp;#8220;meat&amp;#8221; of our grammar. Fortunately enough, &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; is a language with a rather simple syntax. A basic program could look like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;paper&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;repeat&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;pen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;pen&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;paper&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This program runs the instructions inside the &lt;code&gt;repeat&lt;/code&gt; loop, which is equivalent to a classical &lt;code&gt;for&lt;/code&gt; loop. It loops from 0 to 300 while assigning the current iteration value to the variable A and drawing different lines on the canvas.&lt;/p&gt;
&lt;p&gt;As we see above, a basic command in &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; takes the following form:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;command_name value_1 value_2 value_n&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;And a rule &lt;code&gt;command&lt;/code&gt; to parse it:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Za&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;z0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
       &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let&amp;#8217;s break the matching expresion down:&lt;/p&gt;
&lt;dl&gt;
	&lt;dt&gt;&lt;code&gt;_&lt;/code&gt;&lt;/dt&gt;
	&lt;dd&gt;Match 0 or more whitespace characters.&lt;/dd&gt;
	&lt;dt&gt;&lt;code&gt;cmd:[A-Za-z0-9?]+&lt;/code&gt;&lt;/dt&gt;
	&lt;dd&gt;Match an alphanumeric word that might include the &amp;#8216;?&amp;#8217; char, and label it as &amp;#8220;cmd&amp;#8221;.&lt;/dd&gt;
	&lt;dt&gt;&lt;code&gt;args:((ws+ value)+)?&lt;/code&gt;&lt;/dt&gt;
	&lt;dd&gt;Match 0 or more &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; &lt;code&gt;value&lt;/code&gt; expressions preceded by a whitespace and label them as &amp;#8220;args&amp;#8221;.&lt;/dd&gt;
	&lt;dt&gt;&lt;code&gt;lb+&lt;/code&gt;&lt;/dt&gt;
	&lt;dd&gt;Match at least one linebreak.&lt;br /&gt;
&amp;nbsp;&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;In case an expression &lt;code&gt;command&lt;/code&gt; is matched, we will pass the &lt;code&gt;cmd&lt;/code&gt; and the &lt;code&gt;args&lt;/code&gt; results to the parsing expression, who will return an object with some particular properties that manipulate the values in the way we want. In that case we just do some basic filtering to the arrays resulting from the matches.&lt;/p&gt;
&lt;p&gt;An important thing to note down is that any match gotten using the operators &lt;code&gt;[]&lt;/code&gt; &lt;code&gt;*&lt;/code&gt; or &lt;code&gt;+&lt;/code&gt; will return an array with as many coincidences as there are in the matching expression. That means that we will have to take care of filtering these arrays so we obtain the results we want. A clear example is the &lt;code&gt;cmd&lt;/code&gt; variable, which returns an array with all the characters of the command name matched, so in the parsing expression we have to join it to form a real string.&lt;/p&gt;
&lt;h3&gt;3. &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; Blocks&lt;/h3&gt;
&lt;p&gt;Our grammar can already process &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; commands, but this is pretty limited functionality. Any interesting program will at least have loops and block commands, and we still can&amp;#8217;t parse these.&lt;/p&gt;
&lt;p&gt;In order to process block commands we will create the new rules &lt;code&gt;block&lt;/code&gt; and &lt;code&gt;block_command&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;{&amp;quot;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block_command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;}&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;block_command&lt;/span&gt;
 &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;lb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;block&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In &lt;code&gt;block&lt;/code&gt; we match any group of &lt;code&gt;commands&lt;/code&gt; or nested &lt;code&gt;block_commands&lt;/code&gt; that are inside braces, taking into account the possible whitespaces that we might find.&lt;/p&gt;
&lt;p&gt;In &lt;code&gt;block_command&lt;/code&gt; the matching expression is very straightforward, but there is an interesting bit in the parsing expression, where we attach &lt;code&gt;b&lt;/code&gt; to &lt;code&gt;c&lt;/code&gt; as a property, and we return &lt;code&gt;c&lt;/code&gt; after that, so the result is a JavaScript object with the properties &lt;code&gt;type&lt;/code&gt;: &amp;#8220;command&amp;#8221;, array of parameters &lt;code&gt;args&lt;/code&gt; and that &lt;code&gt;block&lt;/code&gt; property we just added, which contains the commands inside the block.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;And we&amp;#8217;re finished! Our grammar can now parse &lt;span class=&quot;caps&quot;&gt;DBN&lt;/span&gt; programs and generate its &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; &lt;acronym title=&quot;Abstract Syntax Tree&quot;&gt;&lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt;&lt;/acronym&gt;. Parsing the basic program that I wrote above as an example generates &lt;a href=&quot;http://gist.github.com/508528#file_ast.js&quot;&gt;this tree&lt;/a&gt;. You can find the complete grammar file &lt;a href=&quot;http://github.com/sergi/Design-By-Canvas/blob/master/grammar.pegjs&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As you can see, using &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js is a very clean and concise way to define language grammars. And best of all, we can use JavaScript for doing it which is pretty awesome. Moreover, the generated parser for it is pure JavaScript and thus independent from the &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js library itself. In fact, using the &lt;a href=&quot;http://pegjs.majda.cz/online&quot;&gt;online version&lt;/a&gt; of it, you can just download the generated parser without even having to download the library itself.&lt;/p&gt;
&lt;p&gt;I am sure very soon we will hear of apps that use &lt;span class=&quot;caps&quot;&gt;PEG&lt;/span&gt;.js in very creative ways, surely involving &lt;a href=&quot;http://nodejs.org&quot;&gt;node&lt;/a&gt; (as it seems to be the trend now) or some other cool technologies. JavaScript is definitely ready for prime time.&lt;/p&gt;
&lt;p&gt;In the second part of this article I will create the interpreter that turns the &lt;span class=&quot;caps&quot;&gt;AST&lt;/span&gt; into JavaScript code that paints directly into canvas. Stay tuned!&lt;/p&gt;</content>
        </entry>
    
        <entry>
            <title>GitHub in Catalan</title>
            <link href="http://sergimansilla.com/blog/github-in-catalan/" rel="alternate" type="text/html" />
            <updated>2010-07-28T00:00:00+02:00</updated>
            <id>http://sergimansilla.com/blog/github-in-catalan</id>
            <content type="html">&lt;p&gt;This is awesome. From now on, Catalan users of GitHub can use the website in their native language. Thanks to the Github team initiative and the brilliant approach of crowd-sourcing the translations (along with some very convenient tooling to do so), I could translate almost all the strings of the website in a record time two weeks ago.&lt;/p&gt;
&lt;p lang=&quot;ca&quot;&gt;What I found out today is that the website is already making use of it and available to everyone! Just point your browser to &lt;a href=&quot;http://github.com/blog?locale=ca&quot;&gt;http://github.com/blog?locale=ca&lt;/a&gt; and the page will be offered to you in Catalan already. The translation is currently 87% complete, so there is still some work to be done, which I expect to finish between today and tomorrow.&lt;/p&gt;
&lt;p&gt;Anyway, if Catalan is your native language and the lack of it in Github was stopping you from using it, now you have the chance!&lt;/p&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;h2 lang=&quot;ca&quot;&gt;&lt;em&gt;GitHub en Català&lt;/em&gt;&lt;/h2&gt;
&lt;p lang=&quot;ca&quot;&gt;&lt;em&gt;Des d’ara mateix, els usuaris Catalans de Github poden utilitzar la web en el seu propi llenguatge. Gràcies a la iniciativa de l’equip GitHub i a la manera brillant d’utilitzar crowd-sourcing per a traduïr la web a multitud de llenguatges (i a unes eines de traducció molt útils), he pogut traduïr quasi totes les cadenes de la web fa dues setmanes en un temps récord.&lt;/em&gt;&lt;/p&gt;
&lt;p lang=&quot;ca&quot;&gt;&lt;em&gt;El que no m’esperava i he descobert avui és que GitHub ja està disponible online en Català! Només cal que introduïu la següent direcció al vostre navegador: &lt;a href=&quot;http://github.com/blog?locale=ca&quot;&gt;http://github.com/blog?locale=ca&lt;/a&gt; i la pàgina us preguntarà si voleu establir Català com a llenguatge del lloc per defecte. La traducció està 87% complerta, així que encara hi ha una mica de feina per fer, que espero finalitzar entre avui i demà.&lt;/em&gt;&lt;/p&gt;
&lt;p lang=&quot;ca&quot;&gt;&lt;em&gt;Així doncs, si la teva llengua és el Català i el fet que GitHub estigués només en anglès t’impedia utilitzar-lo, ara ja no tens excuses!&lt;/em&gt;&lt;/p&gt;</content>
        </entry>
    

</feed>
