{"id":111,"date":"2018-09-07T20:53:27","date_gmt":"2018-09-08T04:53:27","guid":{"rendered":"https:\/\/www.viscerallogic.com\/programming\/blog\/?p=111"},"modified":"2018-09-07T20:55:08","modified_gmt":"2018-09-08T04:55:08","slug":"basic-interpreter-part-v","status":"publish","type":"post","link":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-v\/","title":{"rendered":"BASIC Interpreter, Part V"},"content":{"rendered":"<p>This is a continuation of <a href=\"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-iv\/\">Part IV<\/a>. In Part V we will add support for parentheses in mathematical expressions, add the <code>GOTO<\/code> and <code>END<\/code> statements, and implement the remaining program storage statements: <code>CATALOG<\/code>, <code>SCRATCH<\/code>, and <code>RENAME<\/code>.<br \/>\n<!--more--><\/p>\n<p>Now that we have a framework for supporting numerical operations, adding parentheses is not difficult. An expression wrapped in parentheses is equivalent to a literal double or a variable name, so we will put evaluation into the <code>term<\/code> rule in Bison. We need a new subclass of <code>DoubleExpression<\/code>, which we will call <code>ParenExpression<\/code>. It will store a pointer to an inner <code>DoubleExpression<\/code>, and return its value when queried. The only thing this new class adds is in the <code>list()<\/code> function it will print out parentheses so that the program line can be printed out and read back in. Here is the header file, <em>parenexpression.h<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _PARENEXPRESSION_H_\r\n#define _PARENEXPRESSION_H_\r\n\r\n#include &lt;string&gt;\r\n\r\n#include \"doubleexpression.h\"\r\n\r\n\/*\r\nThis class is used to store a parenthesized expression\r\n*\/\r\nclass ParenExpression : public DoubleExpression {\r\npublic:\r\n\tParenExpression(DoubleExpression *exp);\r\n\t~ParenExpression();\r\n\r\n\tconst std::string print() const;\t\t\/\/ return a printable value\r\n\tconst std::string list() const;\t\t\t\/\/ print a listing version\r\n\tdouble value() const;\t\t\t\t\/\/ numerical evaluation\r\n\r\nprivate:\r\n\tDoubleExpression *exp;\r\n};\r\n\r\n#endif<\/pre>\n<p>Here is the implementation, <em>parenexpression.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"parenexpression.h\"\r\n\r\nParenExpression::ParenExpression(DoubleExpression *exp) : DoubleExpression(0){\r\n\tthis-&gt;exp = exp;\r\n}\r\n\r\nParenExpression::~ParenExpression(){\r\n\tdelete exp;\r\n}\r\n\r\n\/\/ return a printable value\r\nconst std::string ParenExpression::print() const{\r\n\treturn std::to_string(value());\r\n}\r\n\r\n\/\/ print a listing version\r\nconst std::string ParenExpression::list() const{\r\n\treturn \"(\" + exp-&gt;list() + \")\";\r\n}\r\n\r\n\/\/ numerical evaluation\r\ndouble ParenExpression::value() const{\r\n\treturn exp-&gt;value();\r\n}<\/pre>\n<p>In the Bison input file, include the new header file, add two new tokens to represent the parenthesis literals, and modify the <code>term<\/code> rule to create the new subclass:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\" data-enlighter-language=\"cpp\">#include \"parenexpression.h\"\r\n\r\n...\r\n\r\n%token OPENPAREN\r\n%token CLOSEPAREN\r\n\r\n...\r\n\r\nterm:\r\n\tDOUBLE\t\t\t{ $$ = new DoubleExpression($1); }\r\n\t| VAR\t\t\t{\r\n\t\t\t\t\t$$ = new VariableExpression($1);\r\n\t\t\t\t\tfree($1);\r\n\t\t\t\t}\r\n\t| OPENPAREN addExpr CLOSEPAREN\t{ $$ = new ParenExpression($2); }\r\n;<\/pre>\n<p>In the flex input file, add scanners for the new parenthesis tokens:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">\\(\t\t{ return OPENPAREN; }\r\n\\)\t\t{ return CLOSEPAREN; }<\/pre>\n<p>Add the new header and source files to your Makefile, and after compiling you will be able to run programs likes the example below:<\/p>\n<pre>Welcome to BASIC!\r\nEnter a program name: new     \r\n&gt;10 print 2*(3+4)\r\n&gt;run\r\n14.000000\r\n&gt;20 print 2*(3+4)^2\r\n&gt;run\r\n14.000000\r\n98.000000\r\n&gt;list\r\n10 PRINT 2.000000*(3.000000+4.000000)\r\n20 PRINT 2.000000*(3.000000+4.000000)^2.000000<\/pre>\n<p>Now we will add the <code>GOTO<\/code> and <code>END<\/code> statements. <code>GOTO<\/code> is used to jump to an arbitrary line number during program execution, allowing lines to be skipped or executed in a different order. <code>END<\/code> terminates the current program. Per the BASIC manual we are following, an <code>END<\/code> statement is <em>required<\/em> in every program, and it must be the highest line number. We have already deviated from that by not requiring an <code>END<\/code> statement, and we will further deviate by allowing it to appear anywhere.<\/p>\n<p>To support these new statements, we need to change how we handle program execution. Right now, we have a <code>for<\/code> loop that steps through every statement in order and executes it. Clearly, this won&#8217;t work. What we need to do instead is have a <em>program counter variable that keeps track of which line to execute next, and have functions that allow this to be modified.<\/em><\/p>\n<p>Let&#8217;s start by updating <em>program.h<\/em>. Add a new private member variable <code>counter<\/code> to keep track of which line to execute next. This variable is an iterator of the same signature as used in our current <code>execute()<\/code> function:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"5\">private:\r\n\r\n...\r\n\r\n\tstd::map&lt;int, const Program*&gt;::iterator counter;\t\/\/ program line to run next<\/pre>\n<p>Next, add the public member functions to manipulate the counter: one to advance to the next line (standard behavior), one to jump to an arbitrary line, and one to go to the end of the program:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"5-7\">public:\r\n\r\n...\r\n\r\n\tvoid gotoLine(int line);\t\/\/ jump to program line\r\n\tvoid nextLine();\t\t\/\/ go to next program line\r\n\tvoid endProgram();\t\t\/\/ end execution\r\n<\/pre>\n<p>Now we can update the class implementation, <em>basic.cpp<\/em>. First, update the <code>execute()<\/code> function to use our new <code>counter<\/code> variable. Instead of a <code>for<\/code> loop, we will reset <code>counter<\/code> to the beginning, and then have a <code>while<\/code> loop that executes each statement until <code>counter<\/code> points to the end. Of course, this requires that each statement execution update <code>counter<\/code> to another line, or we will get stuck execute the same line over and over:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"3-5\">\/\/ run the program\r\nvoid Basic::execute(){\r\n\tcounter = lines.begin();\r\n\twhile( counter != lines.end() )\r\n\t\tcounter-&gt;second-&gt;execute();\r\n}<\/pre>\n<p>Next, add implementations for the three new functions we declared for manipulating <code>counter<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\" data-enlighter-language=\"cpp\">\/\/ jump to program line\r\nvoid Basic::gotoLine(int line){\r\n\tcounter = lines.find(line);\r\n}\r\n\r\n\/\/ go to next program line\r\nvoid Basic::nextLine(){\r\n\t++counter;\r\n}\r\n\r\n\/\/ end program execution\r\nvoid Basic::endProgram(){\r\n\tcounter = lines.end();\r\n}<\/pre>\n<p>Now that we have the control logic implemented, we can create the classes that call these function to support the <code>GOTO<\/code> and <code>END<\/code> statements. We will create two new subclasses of <code>Program<\/code>. <code>Goto<\/code> will take and store a single integer line number; <code>End<\/code> will take no arguments, and simply call <code>Basic::endProgram()<\/code> in its execution. Here is the header file <em>goto.h&lt;\/em:<\/em><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _GOTO_H_\r\n#define _GOTO_H_\r\n\r\n#include \r\n\r\n#include \"program.h\"\r\n\r\n\/*\r\nThis class implements the GOTO statement\r\n*\/\r\nclass Goto : public Program {\r\npublic:\r\n\tGoto(int line);\t\t\t\t\/\/ instantiate goto statement\r\n\t\r\n\tvoid execute() const;\t\t\t\/\/ run this line of the program\r\n\tvoid list(std::ostream&amp; os) const;\t\/\/ list this line\r\n\r\nprivate:\r\n\tint line;\t\t\t\t\/\/ line to goto\r\n};\r\n\r\n#endif<\/pre>\n<p>Here is its implementation, <em>goto.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"goto.h\"\r\n#include \"basic.h\"\r\n\r\n\/\/ instantiate goto statement\r\nGoto::Goto(int line){\r\n\tthis-&gt;line = line;\r\n}\r\n\r\n\/\/ run this line of the program\r\nvoid Goto::execute() const{\r\n\tBasic::instance()-&gt;gotoLine(line);\r\n}\r\n\r\n\/\/ list this line\r\nvoid Goto::list(std::ostream&amp; os) const{\r\n\tos &lt;&lt; \"GOTO \" &lt;&lt; line;\r\n}<\/pre>\n<p>The <code>End<\/code> class is even simpler; all it needs to do is provide implementations of the <em>virtual<\/em> functions defined by <code>Program<\/code>. Here is the header file, <em>end.h<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#ifndef _END_H_\r\n#define _END_H_\r\n\r\n#include \r\n\r\n#include \"program.h\"\r\n\r\nclass End : public Program {\r\npublic:\r\n\tvoid execute() const;\t\t\t\/\/ run this line of the program\r\n\tvoid list(std::ostream&amp; os) const;\t\/\/ list this line\r\n};\r\n\r\n#endif<\/pre>\n<p>And the implementation, <em>end.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include \"end.h\"\r\n#include \"basic.h\"\r\n\r\n\/\/ run this line of the program\r\nvoid End::execute() const{\r\n\tBasic::instance()-&gt;endProgram();\r\n}\r\n\r\n\/\/ list this line\r\nvoid End::list(std::ostream&amp; os) const{\r\n\tos &lt;&lt; \"END\";\r\n}\r\n<\/pre>\n<p>Our new statements will now work, but if we left it like this and tried to run a program, any of the old statements would get stuck in a loop; we need to update them to call <code>Basic::nextLine()<\/code>. We will call this in <code>Program::execute()<\/code>, which previously did nothing, and the subclasses will then call <code>Program::execute()<\/code> after performing their own execution. Here is the new <em>program.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"2,4,6\">#include \"program.h\"\r\n#include \"basic.h\"\r\n\r\n\/\/ advance to next line\r\nvoid Program::execute() const{\r\n\tBasic::instance()-&gt;nextLine();\r\n}\r\n\r\n\/\/ if you ever see this, something is wrong\r\nvoid Program::list(std::ostream&amp; os) const{\r\n\tos &lt;&lt; \"GENERIC PROGRAM (SHOULDN'T SEE THIS)\";\r\n}<\/pre>\n<p>Here is the update to <code>Let::execute()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"4\" data-enlighter-linenumbers=\"false\">\/\/ store the value of the Expression in the Basic vars map\r\nvoid Let::execute() const{\r\n\tBasic::instance()-&gt;assign(var, expression-&gt;value());\r\n\tProgram::execute();\r\n}<\/pre>\n<p>And similarly in <em>print.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-highlight=\"7\" data-enlighter-linenumbers=\"false\">\/\/ 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;print() &lt;&lt; ' ';\r\n\t}\r\n\tcout &lt;&lt; exprList-&gt;at(exprList-&gt;size()-1)-&gt;print() &lt;&lt; endl;\r\n\tProgram::execute();\r\n}<\/pre>\n<p>Next we will update our Bison input file to use our new statements. First, include the new header files:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">#include \"goto.h\"\r\n#include \"end.h\"<\/pre>\n<p>Add two new constant tokens:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">%token GOTO\r\n%token END<\/pre>\n<p>We are going to make some changes to how flex scans for <code>LINE<\/code> tokens. Right now, it recognizes an integer starting at the beginning of a line as a <code>LINE<\/code> token. But since the <code>GOTO<\/code> statement requires a line number to be provided later, we have to recognize an integer anywhere. This will screw up our <code>DOUBLE<\/code> recognition, which scans for any number not at the beginning of a line, so let&#8217;s just rename our <code>LINE<\/code> token to <code>INT<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-linenumbers=\"false\">%token &lt;iVal&gt; INT<\/pre>\n<p>Since we no longer have a <code>LINE<\/code> token, update the <code>stmt<\/code> rule to use the new <code>INT<\/code> token:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"2,3\">stmt:\r\n\tINT\t\t\t{ Basic::instance()-&gt;remove($1); }\r\n\t| INT 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(std::cout); }\r\n\t| NEW\t\t\t{ Basic::instance()-&gt;newProgram(); }\r\n\t| OLD\t\t\t{ Basic::instance()-&gt;oldProgram(); }\r\n\t| SAVE\t\t\t{ Basic::instance()-&gt;saveProgram(); }\r\n\t| UNSAVE\t\t{ Basic::instance()-&gt;unsaveProgram(); }\r\n;<\/pre>\n<p>Now add our two new statements to the <code>program<\/code> rule:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"7,8\">program:\r\n\tPRINT exprList\t\t\t{ $$ = new Print($2); }\r\n\t| LET VAR EQUAL doubleExpr\t{\r\n\t\t\t\t\t\t$$ = new Let($2, $4);\r\n\t\t\t\t\t\tfree($2);\t\/\/ malloced in basic.l\r\n\t\t\t\t\t}\r\n\t| GOTO INT\t\t\t{ $$ = new Goto($2); }\r\n\t| END\t\t\t\t{ $$ = new End(); }\r\n;<\/pre>\n<p>And since flex will now preferentially return an <code>INT<\/code> token rather than a <code>DOUBLE<\/code>, we need to support that in our <code>term<\/code> rule:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"3\">term:\r\n\tDOUBLE\t\t\t{ $$ = new DoubleExpression($1); }\r\n\t| INT\t\t\t{ $$ = new DoubleExpression($1); }\r\n\t| VAR\t\t\t{\r\n\t\t\t\t\t$$ = new VariableExpression($1);\r\n\t\t\t\t\tfree($1);\r\n\t\t\t\t}\r\n\t| OPENPAREN addExpr CLOSEPAREN\t{ $$ = new ParenExpression($2); }\r\n;<\/pre>\n<p>In the flex input file, change the <code>LINE<\/code> scanner to return <code>INT<\/code>, and remove the caret at the beginning so that it will match an <code>INT<\/code> anywhere:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">{DIGIT}+\t{ yylval.iVal = atoi(yytext); return INT; }<\/pre>\n<p>Also, add scanners for the two new constant tokens:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">GOTO\t\t{ return GOTO; }\r\nEND\t\t{ return END; }<\/pre>\n<p>Lastly, add the new header and implementation files to your Makefile. Here is the updated file at this point in time:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-highlight=\"14,15,18,23\">.PHONY: all clean\r\n\r\nall:\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\t\toperatorexpression.h operatorexpression.cpp \\\r\n\t\tlet.h let.cpp \\\r\n\t\tvariableexpression.h variableexpression.cpp \\\r\n\t\tparenexpression.h parenexpression.cpp \\\r\n\t\tgoto.h goto.cpp \\\r\n\t\tend.h end.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 operatorexpression.cpp let.cpp \\\r\n\tvariableexpression.cpp parenexpression.cpp goto.cpp end.cpp \\\r\n\t-o basic\r\n\r\nbasic.tab.c: basic.y basic.h expression.h stringexpression.h doubleexpression.h \\\r\n\t\toperatorexpression.h print.h program.h let.h variableexpression.h parenexpression.h \\\r\n\t\tgoto.h end.h\r\n\tbison -d basic.y\r\n\t\r\nbasic.tab.h: basic.y\r\n\tbison -d basic.y\r\n\r\nlex.yy.c: basic.tab.h basic.l\r\n\tflex basic.l\r\n\r\nclean:\r\n\trm basic.tab.c basic.tab.h lex.yy.c basic *.o<\/pre>\n<p>You can now build and run programs like the following:<\/p>\n<pre>Welcome to BASIC!\r\nEnter a program name: test\r\n&gt;10 print 10\r\n&gt;20 goto 40\r\n&gt;30 end\r\n&gt;40 print 40\r\n&gt;50 goto 25\r\n&gt;25 print 25\r\n&gt;list\r\n10 PRINT 10.000000\r\n20 GOTO 40\r\n25 PRINT 25.000000\r\n30 END\r\n40 PRINT 40.000000\r\n50 GOTO 25\r\n&gt;run\r\n10.000000\r\n40.000000\r\n25.000000<\/pre>\n<p>OK, the last things we want to add this time are the final program storage statements: <code>CATALOG<\/code>, <code>SCRATCH<\/code>, and <code>RENAME<\/code>. <code>CATALOG<\/code> lists the saved BASIC files in the current directory; <code>SCRATCH<\/code> erases the current stored program, but keeps its name; and <code>RENAME<\/code> keeps the stored program but lets the user enter a new name. This will involve changes to the <code>Basic<\/code> class, as well as the Bison and flex input files. Let&#8217;s start with the <code>Basic<\/code> header file. We already have a private function <code>erase()<\/code> that we can repurpose for the <code>SCRATCH<\/code> functionality, so make that a public function. Also, add two new functions: <code>renameProgram()<\/code> and <code>catalogPrograms()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"10-12\">class Basic {\r\npublic:\r\n\r\n...\r\n\r\n\tvoid saveProgram();\t\t\t\t\/\/ save active program to disk\r\n\tvoid unsaveProgram();\t\t\t\t\/\/ delete saved program from disk\r\n\tvoid newProgram();\t\t\t\t\/\/ start a new program\r\n\tvoid oldProgram();\t\t\t\t\/\/ load program from disk\r\n\tvoid erase();\t\t\t\t\t\/\/ clear stored program lines\r\n\tvoid renameProgram();\t\t\t\t\/\/ rename the current program\r\n\tvoid catalogPrograms();\t\t\t\t\/\/ list saved programs\r\n\r\n...<\/pre>\n<p>For the implementation, our existing <code>newProgram()<\/code> function contains what we need for our <code>newProgram()<\/code> function, but first calls <code>erase()<\/code>. So we will move everything after <code>erase()<\/code> into the <code>newProgram()<\/code> and then call <code>newProgram()<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\" data-enlighter-highlight=\"4-8\">\/\/ start a new program\r\nvoid Basic::newProgram(){\r\n\terase();\r\n\trenameProgram();\r\n}\r\n\r\n\/\/ rename the current program\r\nvoid Basic::renameProgram(){\r\n\tstd::cout &lt;&lt; \"Enter a program name: \";\r\n\tstd::cin &gt;&gt; name;\r\n\tstd::cin.ignore();\t\/\/ consume the newline character\r\n}<\/pre>\n<p>Listing the programs that have been saved to disk is a little more complicated. C++ has not included directory access in the standard until very recently. I have used some code that works on Linux and Mac OS X; Windows users will have to find a different solution. First, we need to include a few more headers in <em>basic.cpp<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">#include &lt;cstring&gt;\r\n#include &lt;set&gt;\r\n#include &lt;unistd.h&gt;\r\n#include &lt;sys\/dir.h&gt;<\/pre>\n<p>Now we can add our new <code>catalogPrograms()<\/code> function:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-linenumbers=\"false\">\/\/ list saved programs\r\nvoid Basic::catalogPrograms(){\r\n\tchar cwd[FILENAME_MAX];\r\n\tgetcwd(cwd, FILENAME_MAX);\r\n\r\n\tDIR* dirp = opendir(cwd);\r\n\tstruct dirent * dp;\r\n\tstd::set set;\t\/\/ store in a set to get alphabetical ordering\r\n\twhile ((dp = readdir(dirp)) != NULL) {\r\n\t\tchar *sub = strstr(dp-&gt;d_name, \".bas\");\r\n\t\tif( strstr(dp-&gt;d_name, \".bas\") ){\r\n\t\t\tsub[0] = 0;\t\/\/ end name before .bas\r\n\t\t\tset.insert(dp-&gt;d_name);\r\n\t\t}\r\n\t}\r\n\tclosedir(dirp);\r\n\t\/\/ print them out\r\n\tfor( std::set::iterator it = set.begin(); it != set.end(); ++it ){\r\n\t\tstd::cout &lt;&lt; *it &lt;&lt; std::endl;\r\n\t}\r\n}<\/pre>\n<p>First we create a character buffer (<code>cwd<\/code>) that can store the maximum filename length, and populate it with the current directory. Then we open this directory for reading, and step through it, adding every file that ends in &#8220;.bas&#8221; to a <code>std::set<\/code> (this automatically sorts them alphabetically, which the directory read may not do). Once we have added them all, we iterate through the <code>std::set<\/code> and print the results.<\/p>\n<p>Since we haven&#8217;t added any new files, our existing Makefile does not need to be changed. The complete source files for this part can be found here: <a href=\"https:\/\/github.com\/VisceralLogic\/basic\/tree\/part-5\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/VisceralLogic\/basic\/tree\/part-5<\/a><\/p>\n<p>Continue to\u00a0<a href=\"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vi\/\">Part VI<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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.<\/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-1N","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":90,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-iv\/","url_meta":{"origin":111,"position":0},"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":131,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-vi\/","url_meta":{"origin":111,"position":1},"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":72,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpeter-part-iii\/","url_meta":{"origin":111,"position":2},"title":"BASIC Interpeter, Part III","date":"September 7, 2018","format":false,"excerpt":"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. Let's start with the Basic class header file, basic.h. All we need to do here\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":111,"position":3},"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":3,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/numerical-expression-solver-in-java\/","url_meta":{"origin":111,"position":4},"title":"Numerical Expression Solver in Java","date":"November 12, 2005","format":false,"excerpt":"This tutorial will show you how to write a Java program that takes a string input such as \"3 + 4^2*7.5E-1*sin(22)\" and convert it into a numerical answer, 2.893784 in this case, which you can use for whatever purpose you like. This Java Applet utilizes the Expression class that you\u2026","rel":"","context":"In &quot;Java&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":46,"url":"https:\/\/www.viscerallogic.com\/programming\/blog\/basic-interpreter-part-ii\/","url_meta":{"origin":111,"position":5},"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":[]}],"_links":{"self":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/111"}],"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=111"}],"version-history":[{"count":14,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/111\/revisions"}],"predecessor-version":[{"id":169,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/posts\/111\/revisions\/169"}],"wp:attachment":[{"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/media?parent=111"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/categories?post=111"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.viscerallogic.com\/programming\/blog\/wp-json\/wp\/v2\/tags?post=111"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}