{"id":5453,"date":"2018-04-22T13:00:00","date_gmt":"2018-04-22T13:00:00","guid":{"rendered":"http:\/\/writeasync.net\/?p=5453"},"modified":"2018-04-20T03:23:41","modified_gmt":"2018-04-20T03:23:41","slug":"basic-solutions-statements","status":"publish","type":"post","link":"http:\/\/writeasync.net\/?p=5453","title":{"rendered":"BASIC solutions: statements"},"content":{"rendered":"<p>My <a href=\"http:\/\/writeasync.net\/?p=5448\">last post<\/a> showcased what I thought was a complete GW-BASIC expression parsing solution. Hence, I pushed forward with a <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/7a4422bb46ed022151fe9d724c7c61dc1f5a15e1#diff-c28f4e057de8f074fb00a87ab678c17b\">new project<\/a> to implement statement parsing.<\/p>\n<p>This went fine for a bit, but I quickly encountered <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/460c53bab4c416a951b471811b7f06e3a8943337#diff-c28f4e057de8f074fb00a87ab678c17b\">overly complicated situations<\/a>. Without access to the <a href=\"https:\/\/github.com\/sprache\/Sprache\">Sprache<\/a> parser implementations, I was left parsing string values to extract expressions used within statements. This was less than ideal, so I pivoted and <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/e279c89f2bd29740514ba79e8e73bf329037c204#diff-c28f4e057de8f074fb00a87ab678c17b\">merged the separate projects<\/a> back into a single one. <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/07b70621212bf0abcf5758fbf971dc8facbfff39#diff-c28f4e057de8f074fb00a87ab678c17b\">Almost immediately<\/a> the job became much simpler.<\/p>\n<p><a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/a40868f0bd6e9fff4cbe3a3e2a029329d494c148#diff-c28f4e057de8f074fb00a87ab678c17b\">Commit<\/a> <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/7067cb3c3402f9d3b5d51eb786e02b736f385255#diff-c28f4e057de8f074fb00a87ab678c17b\">after<\/a> <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/cccef25ae9d68a8ac4ff92938af50208719d6c23#diff-c28f4e057de8f074fb00a87ab678c17b\">commit<\/a>, I kept implementing support for more and more statements. It was almost too easy! (In general though <a href=\"http:\/\/www.engr.mun.ca\/~theo\/Misc\/exp_parsing.htm\">expression parsing<\/a> really is the hardest part of a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Compiler#Front_end\">compiler front end<\/a>.)<\/p>\n<p>Of course, these adventures never proceed without at least one critical issue. Just when I thought I was done, I pointed my glorious new line\/statement parser at <a href=\"http:\/\/writeasync.net\/?p=5408\">adventure.bas<\/a>. It blew up on an input that I thought I had handled but slipped through the cracks, an expression like <code>(X AND Y)=Z<\/code>. I put in <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/e8f14f1255d4b90191c19b023fce32faf2f2f6b8#diff-c28f4e057de8f074fb00a87ab678c17b\">a quick fix<\/a> but it was not sufficient to handle the general situation. Basically, due to the way that I implemented AND\/OR expressions &#8212; having them in the upper level with separate forks for string and numeric expressions &#8212; I kept running into examples beyond the reach of my parser. Seeing that I was on the verge of a major refactor, I <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/7c5a6ca77f03eba982b43f9d5c4855f78c6f3f3d#diff-c28f4e057de8f074fb00a87ab678c17b\">added several new tests<\/a>. Then I set out to eliminate the string\/number parser dichotomy and instead lean on <a href=\"http:\/\/www.semware.com\/html\/04-parse.html\">semantic analysis<\/a> to ensure valid results.<\/p>\n<p>I started small by just <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/e5df3f286c8392c97ac0532fb5def95713f70bd6#diff-c28f4e057de8f074fb00a87ab678c17b\">adding the type information<\/a>. With the groundwork laid, I could then <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/694ffe958d384d38cf12bd02bdcca485491272b4#diff-c28f4e057de8f074fb00a87ab678c17b\">add operator type checking<\/a>. From there, it wasn&#8217;t a big leap to <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/2d60a95f5c4dcd1398bb8a7de2f55547e52e8486#diff-c28f4e057de8f074fb00a87ab678c17b\">finalize the simplified grammar with proper type checking<\/a>.<\/p>\n<p>With the path now fully unblocked, I could complete the final set of statements needed to parse <code>adventure.bas<\/code>! A finishing touch to <a href=\"https:\/\/github.com\/brian-dot-net\/writeasync\/commit\/2e83ae0a9f05b74b8e5275f9d54743d6c56e3b02#diff-c28f4e057de8f074fb00a87ab678c17b\">add the visitor pattern<\/a>, similar to what I had done for expressions, and it was complete.<\/p>\n<p>The code can now produce a valid <a href=\"https:\/\/en.wikipedia.org\/wiki\/Abstract_syntax_tree\">AST<\/a> of a sort for some subset of GW-BASIC programs.<\/p>\n<p>Here is an example program, followed by a textual output of how my GWParse library interprets it:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n10 CLS\r\n20 INPUT &quot;WHAT IS YOUR NAME&quot;;A$\r\n30 IF A$=&quot;&quot; THEN PRINT &quot;TRY AGAIN.&quot; : GOTO 20\r\n40 PRINT &quot;HELLO, &quot;;A$;&quot;!&quot;\r\n\r\nLine(10, Cls())\r\nLine(20, Input(&quot;WHAT IS YOUR NAME&quot;, StrV(A)))\r\nLine(30, If(Eq(StrV(A), StrL(&quot;&quot;)), Print(StrL(&quot;TRY AGAIN.&quot;))), Goto(20))\r\nLine(40, Print(StrL(&quot;HELLO, &quot;), StrV(A), StrL(&quot;!&quot;)))\r\n<\/pre>\n<p>Next time, we will see if I can finally complete the trifecta &#8212; C# code generation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My last post showcased what I thought was a complete GW-BASIC expression parsing solution. Hence, I pushed forward with a new project to implement statement parsing. This went fine for a bit, but I quickly encountered overly complicated situations. Without&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[91,41],"tags":[],"class_list":["post-5453","post","type-post","status-publish","format-standard","hentry","category-design","category-tdd"],"_links":{"self":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5453"}],"version-history":[{"count":1,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5453\/revisions"}],"predecessor-version":[{"id":5454,"href":"http:\/\/writeasync.net\/index.php?rest_route=\/wp\/v2\/posts\/5453\/revisions\/5454"}],"wp:attachment":[{"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5453"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/writeasync.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}