<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Interpreter on Werner&#39;s home on the Web</title>
    <link>https://wstoop.co.za/tags/interpreter/</link>
    <description>Recent content in Interpreter on Werner&#39;s home on the Web</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 14 Jan 2016 00:00:00 +0000</lastBuildDate><atom:link href="https://wstoop.co.za/tags/interpreter/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Fiz: A Tcl-like interpreter</title>
      <link>https://wstoop.co.za/posts/fiz/</link>
      <pubDate>Thu, 14 Jan 2016 00:00:00 +0000</pubDate>
      
      <guid>https://wstoop.co.za/posts/fiz/</guid>
      <description>&lt;p&gt;Over the years I&amp;rsquo;ve found myself looking at &lt;a href=&#34;http://en.wikipedia.org/wiki/Tcl&#34;&gt;Tcl&lt;/a&gt;, and wondering what the fuss was about. Then I came across one of John Ousterhout&amp;rsquo;s articles in the Dr Dobb&amp;rsquo;s Journal and as I read through it, I was suddenly enlightened. Tcl is actually a very smart little language.&lt;/p&gt;
&lt;p&gt;I gladly accepted the challenge of writing my own interpreter for a Tcl-like language, and present the result here as Fiz (a name I just sucked out of my thumb). As it stands, Fiz is probably not very useful for production use, but it has some features that I like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is very compact.&lt;/li&gt;
&lt;li&gt;It is easy to extend with new functions written in C.&lt;/li&gt;
&lt;li&gt;It is easy to embed it in another application.&lt;/li&gt;
&lt;li&gt;It can be run interactively. I&amp;rsquo;ve got a couple of ideas in the pipeline where entering commands from a shell may be very useful.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I must add the disclaimer that Fiz is probably very slow (I say probably because I did not bother to benchmark it). All variables are strings, and performing arithmetic involves doing an &lt;code&gt;atoi()&lt;/code&gt; to convert the variable to an integer. It also does a lot of &lt;code&gt;strdup()&lt;/code&gt; internally. I&amp;rsquo;ll add that at the time of this writing (2010) computers are so fast that I&amp;rsquo;m not bothered by it; there are &lt;a href=&#34;http://www.lua.org/&#34;&gt;other interpreters&lt;/a&gt; that fill the &amp;ldquo;fast and embeddable&amp;rdquo; niche.&lt;/p&gt;
&lt;p&gt;I was also found and got inspiration from Salvatore Sanfilippo&amp;rsquo;s &lt;a href=&#34;http://antirez.com/page/picol&#34;&gt;Picol Tcl interpreter&lt;/a&gt;. His is very elegant - he got his interpreter down to about 550 lines of code. You may notice that I borrowed some ideas from him.
Source Code&lt;/p&gt;
&lt;p&gt;Update (2016-01-14): The source code is available on GitHub: &lt;a href=&#34;https://github.com/wernsey/Fiz&#34;&gt;https://github.com/wernsey/Fiz&lt;/a&gt; (and has actually been for some time).&lt;/p&gt;
&lt;p&gt;The code is written in platform independent C, so you should be able to compile it by typing &lt;code&gt;make&lt;/code&gt; on the command prompt if you&amp;rsquo;re using Linux. It also works if you use &lt;a href=&#34;http://www.mingw.org/&#34;&gt;MinGW&lt;/a&gt; on Windows.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>My Unstructured Scripting Language</title>
      <link>https://wstoop.co.za/posts/musl2/</link>
      <pubDate>Sat, 29 Jun 2013 00:00:00 +0000</pubDate>
      
      <guid>https://wstoop.co.za/posts/musl2/</guid>
      <description>&lt;p&gt;Over the past few weeks, I&amp;rsquo;ve spent some time updating my little BASIC dialect, which I called Musl (or MUSL, depending on my mood).&lt;/p&gt;
&lt;p&gt;The name can mean either My Unstructured Scripting Language or Marginally Useful Scripting Language, also depending on my mood. Musl&amp;rsquo;s home official page is &lt;a href=&#34;https://wstoop.co.za/posts/musl/&#34;&gt;on this site&lt;/a&gt; and I have now set up a repository on GitHub at &lt;a href=&#34;http://github.com/wernsey/musl&#34;&gt;http://github.com/wernsey/musl&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If I remember correctly, Musl started out in 2009 when after a couple of beers at a work function I joked that I wanted to create a scripting language that had only &lt;code&gt;IF&lt;/code&gt;s and &lt;code&gt;GOTO&lt;/code&gt;s. The joke started because some of my earliest memories of programming come from writing simple programs in GW-Basic when I was in primary school.&lt;/p&gt;
&lt;p&gt;The goal was to see exactly how little I could get away with. The very first version had a recursive descent parser that created an abstract syntax tree and interpreted it from there. Later, I realised (after seeing this BASIC interpreter&amp;rsquo;s source code) that if you scan the source code for the labels then you don&amp;rsquo;t even need the AST.&lt;/p&gt;
&lt;p&gt;The latest version of Musl scans the input text for labels before interpreting it. It interprets the code with a pointer that runs through the input text and when it encounters a jump (&lt;code&gt;GOTO&lt;/code&gt;, &lt;code&gt;GOSUB&lt;/code&gt; or &lt;code&gt;RETURN&lt;/code&gt;) the pointer is adjusted accordingly. Musl did not have a &lt;code&gt;GOSUB&lt;/code&gt; and &lt;code&gt;RETURN&lt;/code&gt; originally, but they were easy to add (&lt;code&gt;GOSUB&lt;/code&gt; pushes the current value of the pointer to a stack before jumping, and &lt;code&gt;RETURN&lt;/code&gt; then pops that value off the stack again).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been working on a Retro-style game engine lately, for which I thought that having a BASIC interpreter available would be an appropriate homage to the computers and the games we played on them while growing up, hence my renewed interest in Musl.&lt;/p&gt;
&lt;p&gt;From the start I&amp;rsquo;ve written the code in such a way that the interpreter can be embedded within a larger project. It was intended to be a joke: Write something awesome in it, and then take pictures of the horror on my friends&amp;rsquo; faces when I showed them the source code.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t worry, though, I plan to give the engine a proper scripting language, probably Lua, and Musl will only be there for the nostalgia.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Musl - An interpreter for a BASIC language</title>
      <link>https://wstoop.co.za/posts/musl/</link>
      <pubDate>Fri, 06 Apr 2012 00:00:00 +0000</pubDate>
      
      <guid>https://wstoop.co.za/posts/musl/</guid>
      <description>&lt;p&gt;Also known as my Marginally Useful Scripting Language (I still have to pick the name).&lt;/p&gt;
&lt;p&gt;Musl started out as a joke: I stumbled across the atariarchives.org website one evening and browsed through their books on programming games in BASIC. And by BASIC, I really mean old-school style BASIC, not this fancy new style structured language.&lt;/p&gt;
&lt;p&gt;You know, like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-basic&#34; data-lang=&#34;basic&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;PRINT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HELLO WORLD&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&#34;https://wstoop.co.za/images/basicgames.gif&#34; alt=&#34;BASIC Games&#34;&gt;&lt;/p&gt;
&lt;p&gt;Anyways, through my twisted sense of humour, I set out to write my own unstructured language. The original intention was to have a language that had only &lt;code&gt;IF&lt;/code&gt; and &lt;code&gt;GOTO&lt;/code&gt; statements. The joke was going to be to write some awesome application and watch the horror on my friends&amp;rsquo; faces when they see the source code.&lt;/p&gt;
&lt;p&gt;Out of principle, I decided that it should be an embeddable scripting language; that is to say, you can embed the interpreter into another application and have the other application execute custom scripts.&lt;/p&gt;
&lt;p&gt;Here is a sample of what Musl code looks like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-basic&#34; data-lang=&#34;basic&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;LET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;il&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nl&#34;&gt;loop1:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;vg&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;il&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;vg&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;il&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;THEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;GOTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;loop1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you look through the source code, you&amp;rsquo;ll find &lt;code&gt;musl.c&lt;/code&gt; and &lt;code&gt;musl.h&lt;/code&gt; that contains the core of the interpreter. The file &lt;code&gt;main.c&lt;/code&gt; contains a simple driver program that shows you how to run the interpreter from another application, how to add new functions to the interpreter and how to access variables within the interpreter.&lt;/p&gt;
&lt;p&gt;Over time it feature-crept a bit, and now includes these &amp;ldquo;features&amp;rdquo;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dictionaries (or hashes or whatever you want to call them)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FOR&lt;/code&gt; loops&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GOSUB&lt;/code&gt; and &lt;code&gt;RETURN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Regular expression support. It uses the &lt;code&gt;regcomp()&lt;/code&gt; and &lt;code&gt;regexec()&lt;/code&gt; functions that are part of POSIX, but if you want to compile it under Windows, Henry Spencer&amp;rsquo;s &lt;a href=&#34;http://www.arglist.com/regex/&#34;&gt;regex library&lt;/a&gt; compiles quite easily (with MinGW).&lt;/li&gt;
&lt;li&gt;You can declare labels instead of using line numbers. Line numbers are supported, but not required.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Although the syntax may seem BASIC-like, Musl does not strive to be compatible with any known BASIC. The following is an example program:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# This is a test program for &amp;#34;IF x THEN FOR...&amp;#34; type
# situations, which actually took some complexity to get right
x = 0

@start: PRINT(X): IF X THEN PRINT(&amp;#34;STARTING...&amp;#34;)
10 IF X THEN FOR I = 1 TO 10 DO
20 IF I = 4 THEN GOTO lbl
30 PRINT(&amp;#34;X is &amp;#34;, X, &amp;#34;; I is &amp;#34;, I)
40 IF I = 7 THEN NEXT
50 IF I &amp;gt; 2 THEN GOSUB 100
@lbl: NEXT

@foo: IF x = 1 THEN END
x = x+1
GOTO start

#### END ####

100 PRINT(&amp;#34;in sub&amp;#34;)
RETURN
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;source-code&#34;&gt;Source Code &lt;a href=&#34;#source-code&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;The latest version of Musl is available on GitHub at &lt;a href=&#34;https://github.com/wernsey/musl&#34;&gt;https://github.com/wernsey/musl&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;compiling&#34;&gt;Compiling &lt;a href=&#34;#compiling&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;On Linux you can compile it by just typing&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;make
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;at the command prompt.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&#34;http://www.mingw.org/&#34;&gt;MinGW&lt;/a&gt; to compile these things under Windows.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t have the regular expression library, you can comment out the following lines in Makefile.mingw:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# CFLAGS += -DWITH_REGEX -I/c/libs/regex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# LFLAGS += -L/c/libs/regex -lregex
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To compile, just type&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;make -f Makefile.mingw
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;in the MinGW shell.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>
