{"id":72,"date":"2018-09-07T20:50:46","date_gmt":"2018-09-08T04:50:46","guid":{"rendered":"https:\/\/www.viscerallogic.com\/programming\/blog\/?p=72"},"modified":"2018-09-07T20:53:02","modified_gmt":"2018-09-08T04:53:02","slug":"basic-interpeter-part-iii","status":"publish","type":"post","link":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpeter-part-iii\/","title":{"rendered":"BASIC Interpeter, Part III"},"content":{"rendered":"<p>This is a continuation of <a href=\"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-ii\/\">Part II<\/a>. In this part, we will add support for numerical as well as string expressions, support multiple expression in a <em>PRINT<\/em> statement, and add functionality for deleting program lines.<br \/>\n<!--more--><\/p>\n<p>Let&#8217;s start with the <em>Basic<\/em> class header file, <em>basic.h<\/em>. All we need to do here is add a member function for deleting lines from the stored program:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\tvoid remove(int index);\t\/\/ remove program line<\/pre>\n<p>For the class file, <em>basic.cpp<\/em>, since we already have code in in the <em>add<\/em> function to remove a line if it already exists, we will move that into the new <em>remove<\/em> function, and then call <em>remove<\/em> from <em>add<\/em>. Here are the changes:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-lineoffset=\"9\">\/\/ add a program line at index, overwriting if it exists\r\nvoid Basic::add(int index, const Program *program){\r\n\t\/\/ see if index already exists, if so delete it\r\n\tremove(index);\r\n\t\r\n\tlines.insert(std::pair&lt;int, const Program *&gt;(index, program));\r\n}\r\n\r\n\/\/ remove an existing line from the program\r\nvoid Basic::remove(int index){\r\n\tmap&lt;int, const Program*&gt;::iterator it = lines.find(index);\r\n\tif( it != lines.end() ){\r\n\t\tconst Program *old = it-&gt;second;\r\n\t\tdelete old;\r\n\t\tlines.erase(index);\r\n\t}\t\r\n}<\/pre>\n<p>The <em>Program<\/em> base class doesn&#8217;t change at all. The derived <em>Print<\/em> class has a minor change: we will be sub-classing <em>Expression<\/em> to support numerical and string expressions, so we need to make its functions virtual and use pointers in the <em>Print<\/em> class so the derived class member functions will be called. In the header file, <em>print.h<\/em>, change the constructor signature to use <em>Expression *<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\tPrint(const std::vector&lt;Expression*&gt; *exprList);\t\/\/ create with a vector of expressions to print<\/pre>\n<p>Also change the member variable declaration <em>exprList<\/em> to match:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">\tconst std::vector&lt;Expression*&gt; *exprList;\t\/\/ store the expressions here<\/pre>\n<p>In the class file, <em>print.cpp<\/em>, we have to update the method signatures to use pointers, and make a small change to how we access the elements in the vector. Because the elements are now pointers instead of actual objects, instead of using the array subscript method, we have to use the <em>at()<\/em> function. Here is the updated class file:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"9,15-16,18,24-25,27\">#include \r\n\r\n#include \"print.h\"\r\n\r\nusing std::endl;\r\nusing std::cout;\r\n\r\n\/\/ constructor for Print class\r\nPrint::Print(const std::vector&lt;Expression*&gt; *exprList){\r\n\tthis-&gt;exprList = exprList;\r\n}\r\n\r\n\/\/ prints out each expression to std::cout\r\nvoid Print::execute() const{\r\n\tfor( int i = 0; i &lt; exprList-&gt;size()-1; i++ ){\r\n\t\tcout &lt;&lt; exprList-&gt;at(i)-&gt;value() &lt;&lt; ' ';\r\n\t}\r\n\tcout &lt;&lt; exprList-&gt;at(exprList-&gt;size()-1)-&gt;value() &lt;&lt; endl;\r\n}\r\n\r\n\/\/ lists the expressions, as they were originally given\r\nvoid Print::list(ostream&amp; os) const{\r\n\tos &lt;&lt; \"PRINT \";\r\n\tfor( int i = 0; i &lt; exprList-&gt;size()-1; i++ ){\r\n\t\tos &lt;&lt; exprList-&gt;at(i)-&gt;print() &lt;&lt; \", \";\r\n\t}\r\n\tos &lt;&lt; exprList-&gt;at(exprList-&gt;size()-1)-&gt;print();\r\n}<\/pre>\n<p>The <code>Expression<\/code> class has a few changes. Since we will be creating subclasses of it, its member functions need to be virtual. Also, since we will only be using subclasses, we no longer need the member variable <code>text<\/code>. Here is the header file, <em>expression.h<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _EXPRESSION_H_\r\n#define _EXPRESSION_H_\r\n\r\n#include &lt;string&gt;\r\n\r\n\/*\r\nBase class used for storing and evaluating data items\r\n*\/\r\nclass Expression {\r\npublic:\r\n\tvirtual const std::string value() const;\t\t\t\/\/ return the stored value\r\n\tvirtual const std::string print() const;\t\t\t\/\/ printable version\r\n};\r\n\r\n#endif<\/pre>\n<p>The class file, <em>expression.cpp<\/em>, likewise becomes simplified:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"expression.h\"\r\n\r\n\/\/ return the text value\r\nconst std::string Expression::value() const{\r\n\treturn std::string(\"BASE EXPRESSION\");\r\n}\r\n\r\n\/\/ return a string for printing\r\nconst std::string Expression::print() const{\r\n\treturn std::string(\"BASE EXPRESSION\");\r\n}<\/pre>\n<p>Our first subclass of <code>Expression<\/code> is <code>StringExpression<\/code>, which is basically the same as our original implementation of <code>Expression<\/code>. Here is the header file, <em>stringexpression.h<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _STRINGEXPRESSION_H_\r\n#define _STRINGEXPRESSION_H_\r\n\r\n#include \"expression.h\"\r\n\r\n\/*\r\nClass used for storing a text value\r\n*\/\r\nclass StringExpression : public Expression {\r\npublic:\r\n\tStringExpression(const char *text);\t\t\/\/ take a string as input\r\n\t\r\n\tconst std::string value() const;\t\t\/\/ return the stored value\r\n\tconst std::string print() const;\t\t\/\/ printable version\r\n\t\r\nprivate:\r\n\tstd::string text;\t\t\t\t\/\/ data storage\r\n};\r\n\r\n#endif<\/pre>\n<p>Likewise, the implementation in <em>stringexpression.cpp<\/em> duplicates the functionality of the old <code>Expression<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"stringexpression.h\"\r\n\r\n\/\/ create a new StringExpression, storing its text\r\nStringExpression::StringExpression(const char *text){\r\n\tthis-&gt;text = std::string(text);\r\n}\r\n\r\n\/\/ return the text value\r\nconst std::string StringExpression::value() const{\r\n\treturn text;\r\n}\r\n\r\n\/\/ return a string for printing\r\nconst std::string StringExpression::print() const{\r\n\treturn '\"' + text + '\"';\r\n}\r\n<\/pre>\n<p>The class <code>DoubleExpression<\/code> is very similar to <code>StringExpression<\/code>, with the only difference being it stores a numerical value instead of a string value. Here is the header file, <em>doubleexpression.h<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _DOUBLEEXPRESSION_H_\r\n#define _DOUBLEEXPRESSION_H_\r\n\r\n#include \"expression.h\"\r\n\r\n\/*\r\nClass used for storing a numerical value\r\n*\/\r\nclass DoubleExpression : public Expression {\r\npublic:\r\n\tDoubleExpression(double d);\t\t\t\/\/ take a double as input\r\n\t\r\n\tconst std::string value() const;\t\t\/\/ return the stored value\r\n\tconst std::string print() const;\t\t\/\/ printable version\r\n\t\r\nprivate:\r\n\tdouble d;\t\t\t\t\t\/\/ data storage\r\n};\r\n\r\n#endif<\/pre>\n<p>The implementation file, <em>doublexpression.cpp<\/em>, is naturally also very similar. Note that since printable version for calling <code>LIST<\/code> on a numerical expression is the same as its text value, the <code>print<\/code> function simply makes a call to <code>value<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"doubleexpression.h\"\r\n\r\n\/\/ create a new DoubleExpression, storing its value\r\nDoubleExpression::DoubleExpression(double d){\r\n\tthis-&gt;d = d;\r\n}\r\n\r\n\/\/ return the text value\r\nconst std::string DoubleExpression::value() const{\r\n\treturn std::to_string(d);\r\n}\r\n\r\n\/\/ return a string for printing\r\nconst std::string DoubleExpression::print() const{\r\n\treturn value();\r\n}<\/pre>\n<p>OK, now that we&#8217;ve got our classes set up, let&#8217;s update our Bison input file. The first change is to add our two new header files in the C declarations section:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">#include \"stringexpression.h\"\r\n#include \"doubleexpression.h\"<\/pre>\n<p>Next, in the Bison declarations, we need to add some new token types to the <em>%union<\/em>. We need to support reading <code>double<\/code>s, <code>Expression *<\/code>s, and <code>std::vector&lt;Expression*&gt; *<\/code>s:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"3,6,7\">%union {\r\n\tint iVal;\r\n\tdouble dVal;\r\n\tchar *sVal;\r\n\tProgram *progVal;\r\n\tExpression *eVal;\r\n\tstd::vector&lt;Expression*&gt; *eList;\r\n}<\/pre>\n<p>Since we will now be able to enter a comma-separated list of expressions for the <code>PRINT<\/code> statement, we need to add a new constant token:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">%token COMMA<\/pre>\n<p>We also have a new terminal symbol token type for reading doubles:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">%token &lt;dVal&gt; DOUBLE<\/pre>\n<p>And we will round out the Bison declarations with two new non-terminal symbols to use our single expression and expression list types:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">%type &lt;eList&gt; exprList\r\n%type &lt;eVal&gt; expr<\/pre>\n<p>Now that we&#8217;ve got the symbol types defined, we need to update the grammar rules. The <code>input<\/code> and <code>line<\/code> rules remain the same, but we will change the <code>program<\/code> rule and add two new rules for reading expressions: <code>exprList<\/code> and <code>expr<\/code>. Here are the new rules:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-lineoffset=\"63\">stmt:\r\n\tLINE\t\t\t{ Basic::instance()-&gt;remove($1); }\r\n\t| LINE program\t\t{ Basic::instance()-&gt;add($1, $2); }\r\n\t| RUN\t\t\t{ Basic::instance()-&gt;execute(); }\r\n\t| LIST\t\t\t{ Basic::instance()-&gt;list(); }\r\n;\r\n\r\nprogram:\r\n\tPRINT exprList\t\t{ $$ = new Print($2); }\r\n;\r\n\r\nexprList:\r\n\texpr\t\t\t{ $$ = new std::vector&lt;Expression*&gt;(1, $1); }\r\n\t| exprList COMMA expr\t{\r\n\t\t\t\t\t$1-&gt;push_back($3);\r\n\t\t\t\t\t$$ = $1;\r\n\t\t\t\t}\r\n;\r\n\r\nexpr:\r\n\tSTRING\t\t\t{\r\n\t\t\t\t\t$$ = new StringExpression($1);\r\n\t\t\t\t\tfree($1);\t\/\/ malloced in basic.l\r\n\t\t\t\t}\r\n\t| DOUBLE\t\t{ $$ = new DoubleExpression($1); }\r\n;<\/pre>\n<p>We have added one new option to the <code>stmt<\/code> rule: a single <code>LINE<\/code> terminal symbol can be input to delete that line from the stored program. The <code>program<\/code> rule is simpler now: it reads a <code>PRINT<\/code> symbol followed by a new non-terminal symbol <code>exprList<\/code>, which we defined in our Bison declarations section to be of type <code>std::vector&lt;Expression*&gt; *<\/code>. We can pass this symbol to our updated <code>Print<\/code> constructor.<\/p>\n<p>Now we have our new rules. The <code>exprList<\/code> rule is satisfied by either a single <code>expr<\/code>, or by recursion a sequence of <code>expr<\/code>s separated by commas (the terminal symbol <code>COMMA<\/code> we added). When Bison encounters the first matching <code>expr<\/code>, it creates a new <code>std::vector&lt;Expression *&gt;<\/code>, which matches the <code>eList<\/code> symbol type we defined, and populates it with the single <code>Expression<\/code> it read. As additional expression separated by commas are matched, they are pushed onto the end of the vector (the <code>exprList<\/code> symbol in the first matching position), and then that vector is set as the result of the rule.<\/p>\n<p>The <code>expr<\/code> rule matches either a <code>STRING<\/code> or a <code>DOUBLE<\/code> terminal symbol, and builds the appropriate <code>Expression<\/code> derived class, as appropriate. For the case of the string, we again need to free the terminal symbol value, since we explicitly allocated it in the flex scanner.<\/p>\n<p>Something that would be nice is if we had a prompt character at the beginning of each input line when running our BASIC interpreter, to make the input and output lines a little more distinguishable. So, in the <code>main<\/code> function, before the <code>while<\/code> loop, print out a welcome statement (we will change the flex scanner so that it will print out another prompt character every time it reads a new line):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">\tstd::cout &lt;&lt; \"Welcome to BASIC!\\n&gt;\";<\/pre>\n<p>OK, on to the flex scanner! We need to add support for the new terminal symbols we added in Bison, as well as a couple other minor changes. First, it gets annoying having to enter the BASIC commands using capital letters. Fortunately for us, flex provides an option to make the input matching case-insensitive, so we don&#8217;t need to redefine our rules; simply add the <code>case-insensitive<\/code> option to the first line:<\/p>\n<pre class=\"EnlighterJSRAW\">%option noyywrap case-insensitive<\/pre>\n<p>We&#8217;re going to be doing some printing directly from our flex scanner now, so be sure to include <code>iostream<\/code>. We also have defined a token type that uses <code>std::vector<\/code>, so we need to include that header:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">#include &lt;iostream&gt;\r\n#include &lt;vector&gt;<\/pre>\n<p>The next change is to add a declaration of the <code>Expression<\/code> class, since it is used in the symbol type definitions that Bison exports. The flex code never uses this class, so instead of including its header file, we just declare it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"2\">class Program;\r\nclass Expression;<\/pre>\n<p>Since we now need to be able to read in a double-type numerical value, we will be using the pattern <code>[0-9]<\/code> many times, so we will create a flex declaration to use <code>DIGIT<\/code> in its place. While this isn&#8217;t necessary, it can make the patterns a little more clear. Put this line after the end of the C declarations (<code>%}<\/code>) and before the start of the pattern matching (<code>%%<\/code>):<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"3\">%}\r\n\r\nDIGIT    [0-9]\r\n\r\n%%<\/pre>\n<p>Now we can use the pattern <code>{DIGIT}<\/code> wherever we would use <code>[0-9]<\/code>. We will make use of this for both the <code>LINE<\/code> symbol and the <code>DOUBLE<\/code> symbol. Here are the updated rules:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-lineoffset=\"20\" data-enlighter-highlight=\"21,28,32-34\">[ \\t]+\t;\t\/\/ skip white space\r\n^{DIGIT}+\t{ yylval.iVal = atoi(yytext); return LINE; }\r\n\\\"[^\\\"\\n]*\\\"\t{\t\/\/ remove the quote marks from either end\r\n\t\t\tyylval.sVal = (char *)malloc(sizeof(char)*strlen(yytext)-1);\r\n\t\t\tstrncpy(yylval.sVal, yytext+1, strlen(yytext)-2);\r\n\t\t\tyylval.sVal[strlen(yytext)-2] = '\\0';\t\/\/ terminate the string!\r\n\t\t\treturn STRING;\r\n\t\t}\r\n(({DIGIT}+\".\"?)|(\".\"{DIGIT}+)){DIGIT}*(E-?{DIGIT}+)?\t{ yylval.dVal = atof(yytext); return DOUBLE; }\r\nPRINT\t\t{ return PRINT; }\r\nRUN\t\t{ return RUN; }\r\nLIST\t\t{ return LIST; }\r\n,\t\t{ return COMMA; }\r\n\\n\t\t{ std::cout &lt;&lt; \"&gt;\"; return ENDL; }\r\n.\t;\t\/\/ skip any characters that aren't part of a recognized pattern<\/pre>\n<p>The updated rule that matches a <code>LINE<\/code> symbol now requires the sequence of digits to be at the beginning of a line. This ensure that flex won&#8217;t match a numerical expression and return it as a <code>LINE<\/code> symbol.<\/p>\n<p>The new rule for matching a <code>DOUBLE<\/code> is a little bit tricky. There are two ways to start this pattern: either one or more digits followed by an optional dot, or a starting dot followed by one or more digits. After the start, there may be zero or more digits, optionally followed by a literal <em>E<\/em> with an optional minus sign followed by one or more digits. Essentially, this rule requires that there be one or more digits, on either side of an optional<br \/>\ndot, and support for exponential notation followed. Here are some examples of inputs that this will match:<\/p>\n<pre>123\r\n123.\r\n.123\r\n123.123\r\n123E123\r\n123E-123\r\n123.123E-123\r\n.123E-123\r\netc.<\/pre>\n<p>Since we have a new <code>COMMA<\/code> terminal symbol defined in Bison to support comma-separated expression lists, we need to match that here (line 32). Since we want to have a prompt character show up at the beginning of each new input line, we updated the <code>ENDL<\/code> match to print one out every time we read a new line character. Lastly, we have a new rule, <code>.+ ;<\/code>, which silently reads and discards any characters that it can&#8217;t match to previous rules; this prevents some unwanted input for reaching Bison, where it could cause a parsing error.<\/p>\n<p>And of course, we need to update our makefile to include our new header and source files. I&#8217;ve been compiling on macOS, but on Linux we also need to tell g++ to use the C++11 standard, by adding the <code>-std=c++11<\/code> argument. Here is the updated <code>all<\/code> rule:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">all:\tbasic.tab.c lex.yy.c \\\r\n\t\tbasic.h basic.cpp \\\r\n\t\tprogram.h program.cpp \\\r\n\t\tprint.h print.cpp \\\r\n\t\texpression.h expression.cpp \\\r\n\t\tstringexpression.h stringexpression.cpp \\\r\n\t\tdoubleexpression.h doubleexpression.cpp\r\n\tg++ -std=c++11 basic.tab.c lex.yy.c program.cpp basic.cpp print.cpp expression.cpp \\\r\n\tstringexpression.cpp doubleexpression.cpp \\\r\n\t-o basic<\/pre>\n<p>Here is an example session made from this Part III code:<\/p>\n<pre>Welcome to BASIC!\r\n&gt;10 print \"Hello\"\r\n&gt;20 print 123, .123, 123.123E123\r\n&gt;30 print \"Big Number!\"\r\n&gt;list\r\n10 PRINT \"Hello\"\r\n20 PRINT 123.000000, 0.123000, 123122999999999995047514223697997329420208162078904722947470938484432926767618625996126391524302018196895898346062018145943552.000000\r\n30 PRINT \"Big Number!\"\r\n&gt;run\r\nHello\r\n123.000000 0.123000 123122999999999995047514223697997329420208162078904722947470938484432926767618625996126391524302018196895898346062018145943552.000000\r\nBig Number!\r\n&gt;20\r\n&gt;list\r\n10 PRINT \"Hello\"\r\n30 PRINT \"Big Number!\"\r\n&gt;run\r\nHello\r\nBig Number!\r\n&gt;<\/pre>\n<p>As you can see, we&#8217;ll want to clean up the numerical printing a bit, but otherwise, things are looking good! The complete source files from this part are available here: <a href=\"https:\/\/github.com\/VisceralLogic\/basic\/tree\/part-3\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/VisceralLogic\/basic\/tree\/part-3<\/a><\/p>\n<p>Continue to\u00a0<a href=\"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-iv\/\">Part IV<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a continuation of Part II. In this part, we will add support for numerical as well as string expressions, support multiple expression in a PRINT statement, and add functionality for deleting program lines.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[12,16,13,15],"tags":[],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9npkn-1a","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":46,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-ii\/","url_meta":{"origin":72,"position":0},"title":"BASIC Interpreter, Part II","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part I. In Part II, we will add functionality to store and run BASIC programs, although still limited to the PRINT statement. We will also be adding a LIST statement to print out the currently stored program. We will be adding a number of new\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":90,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-iv\/","url_meta":{"origin":72,"position":1},"title":"BASIC Interpreter, Part IV","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part III. This time we will add some mathematical operators, the ability to save and load programs, and support numerical variables. To enable mathematical operations, we will create a subclass of DoubleExpression that takes two DoubleExpressions as inputs, as well as a character code signifying\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":111,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-v\/","url_meta":{"origin":72,"position":2},"title":"BASIC Interpreter, Part V","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part IV. In Part V we will add support for parentheses in mathematical expressions, add the GOTO and END statements, and implement the remaining program storage statements: CATALOG, SCRATCH, and RENAME. Now that we have a framework for supporting numerical operations, adding parentheses is not\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":131,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vi\/","url_meta":{"origin":72,"position":3},"title":"BASIC Interpreter, Part VI","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part V. In the previous section, we added support for the GOTO statement. Since we don't yet have any control logic, that is not very useful, but it does lay the infrastructure for one of the features we will add this time: IF-THEN. We will\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":149,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vii\/","url_meta":{"origin":72,"position":4},"title":"Basic Interpreter, Part VII","date":"September 7, 2018","format":false,"excerpt":"This is a continuation of Part VI. This time, we will be adding the FOR-NEXT loop and unary negation. The FOR-NEXT loop takes a couple forms: FOR <VAR> = <START> TO <STOP> ... NEXT <VAR> or FOR <VAR> = <START> TO <STOP> STEP <STEP> ... NEXT <VAR> In the former\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":39,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-i\/","url_meta":{"origin":72,"position":5},"title":"BASIC Interpreter, Part I","date":"September 7, 2018","format":false,"excerpt":"This is the first of a multi-post tutorial on using flex and Bison to write a programming language interpreter, in this case, BASIC. We'll be using the 1964 BASIC manual from Dartmouth as the starting point language reference. All code is available at this GitHub repository: https:\/\/github.com\/VisceralLogic\/basic. The interpreter will\u2026","rel":"","context":"In &quot;BASIC&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/72"}],"collection":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/comments?post=72"}],"version-history":[{"count":21,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions"}],"predecessor-version":[{"id":165,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/72\/revisions\/165"}],"wp:attachment":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/media?parent=72"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/categories?post=72"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/tags?post=72"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}