{"id":11229,"date":"2025-07-21T01:01:00","date_gmt":"2025-07-21T05:01:00","guid":{"rendered":"https:\/\/www.both.org\/?p=11229"},"modified":"2025-07-17T09:39:02","modified_gmt":"2025-07-17T13:39:02","slug":"an-algol-68-pretty-printer","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=11229","title":{"rendered":"An Algol 68 Pretty Printer"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"11229\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">1    <\/span>\r\n<\/div><\/div>\n<p><br> <em>For Marcel van der Veer<\/em>, <em>with many thanks for Algol 68 Genie<\/em><\/p>\n\n\n\n<p>If you pick up a textbook on Algol 68 from the 1970s, such as Andrew McGettrick\u2019s wonderful primer, <em>Algol 68 \u2013 a first and second course<\/em><a href=\"#sdfootnote1sym\" id=\"sdfootnote1anc\"><sup>1<\/sup><\/a>, you will see code examples represented as follows:<a href=\"#sdfootnote2sym\" id=\"sdfootnote2anc\"><sup>2<\/sup><\/a><\/p>\n\n\n\n<p><strong>begin real<\/strong> <em>e<\/em> = 2.7182818284; <strong>real<\/strong> <em>circum<\/em>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;<em>circum<\/em> := 2 \u00d7 <em>pi<\/em> \u00d7 <em>e<\/em>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em> ((\u201c<em>circumference of a cricle of radius e is<\/em>\u201d, <em>circum<\/em>))<\/p>\n\n\n\n<p><strong>end <\/strong><\/p>\n\n\n\n<p>Professor McGettrick soon explains:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>When a program has to be run on a computer it will have to be prepared in some suitable manner&#8230; Unfortunately, however, these and similar devices do not permit the printing in bold type of words such as <\/em><em><strong>begin<\/strong><\/em><em>. Indeed, often small leters are also unavailable&#8230; <\/em><em>Typically <\/em><em><strong>begin<\/strong><\/em><em> might appear in one of the forms<\/em><\/p>\n\n\n\n<p><em>.BEGIN. \u2018BEGIN\u2019 \u2018BEGIN BEGIN<\/em><\/p>\n\n\n\n<p><em>&#8230; Moreover the multiplication sign has been replaced by an asterisk.<\/em><a href=\"#sdfootnote3sym\"><sup>3<\/sup><\/a><\/p>\n<\/blockquote>\n\n\n\n<p>This convention of using boldfaced words for symbols comes from the Revised Report,<a href=\"#sdfootnote4sym\" id=\"sdfootnote4anc\"><sup>4<\/sup><\/a> which states:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>The manner in which symbols for newly defined <\/em><em><strong>mode-indications<\/strong><\/em><em> and <\/em><em><strong>operators<\/strong><\/em><em> are to be represented is now more closely defined. Thus it is clear that the implementer is to provide a special alphabet of bold-faced, or &#8220;&#8216;stropped&#8221;&#8216;, marks from which <\/em><em><strong>symbols<\/strong><\/em><em> such as <\/em><em><strong>person<\/strong><\/em><em> may be made, and it is also clear that <\/em><em><strong>operators<\/strong><\/em><em> such as \u00bb are to be allowed<\/em>.<a href=\"#sdfootnote5sym\"><sup>5<\/sup><\/a><\/p>\n<\/blockquote>\n\n\n\n<p>Worthwhile mentioning at this point is that the members of the Working Group defining Algol 68 were developing a whole new framework for describing the programming language, and even for describing the description, with new concepts such as stropping mentioned above.<\/p>\n\n\n\n<p>Most of us have had some experience with programming languages whose designers have adopted a standard for styling code in that language. Think of the arguments between C programmers as to whether to write <code>} else {<\/code> or have one or more of the braces appear on separate lines.<\/p>\n\n\n\n<p>And yes, one of the little things that challenges Algol 68 implementations is how to deal with the difference between <strong>begin<\/strong>, which is a symbol, and <em>begin<\/em>, which is an identity.<\/p>\n\n\n\n<p>In the articles I have written to date about Algol 68 on <a href=\"https:\/\/both.org\/\">both.org<\/a>, I have used the Algol 68 Genie compiler \u2013 interpreter, which prefers <em>UPPER stropping<\/em> \u2013 symbols are written all in capital letters and identities are written all in lower case letters and numbers. Moreover, symbols cannot contain blanks, but identifiers can.<\/p>\n\n\n\n<p>This UPPER stropping makes it pretty straightforward to write a simple pretty printer, in order to convert bold-stropped Algol 68 code into the more decorated version, in HTML format, for inclusion in web pages or elsewhere.<\/p>\n\n\n\n<p>Enough background, let\u2019s get to work on the code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The pretty printer<\/h2>\n\n\n\n<p>Here it is. It\u2019s pretty long, but not super-complicated, and because of the length I\u2019ve added quite a few comments. Discussion follows:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">     1\t#\n     2\t    Library-preludes\n     3\t    \n     4\t    \/Nothing, however, prevents you from subjoining to this standard-prelude a\n     5\t     set of home made declarations. Of course you are free to declare such new\n     6\t     things in your own particular-program; but, as soon as you want to apply\n     7\t     them in several programs,or you want to enable others to use them, or you\n     8\t     have reason to expect that more efficiency may be acquired, then you can go\n     9\t     to your implementor and ask him to make the whole set an as efficient as\n    10\t     possible extension of the standard-prelude, i.e. 'it 'library-prelude'. In\n    11\t     that way an arbitrary number of problem oriented dialects may be defined.\/\n       \n    12\t     Lindsey, C.H., &amp; van der Meulen, S.G. (1973).\n    13\t     \/Informal Introduction to Algol 68\/ (Revised Edition, Ch. 0.10.7, p. 52).\n    14\t     North Holland Publishing Company.\n    15\t#\n       \n    16\tPR read \"each_line.a68\" PR\n       \n    17\t#\n    18\t    Particular-program\n       \n    19\t    Algol 68 pretty printer.\n    20\t    Depends on UPPER stropping.\n    21\t    Lowercases and bolds reserved words.\n    22\t    Italicizes variable names.\n    23\t    Generates HTML output.\n    24\t#\n       \n    25\tBEGIN\n       \n    26\t    #\n    27\t        Using a68g, we can get at Linux command line arguments.\n       \n    28\t        In order to pass arguments to the program, we terminate arguments to a68g\n    29\t        itself using the command line option \"--\".\n       \n    30\t        Therefore, there are three arguments to be skipped before the program can\n    31\t        find its own arguments:\n       \n    32\t        argv(1) - \"a68g\"\n    33\t        argv(2) - name of the program being interpreted\n    34\t        argv(3) - \"--\" which is necessary to get a68g to leave off interpreting args\n       \n    35\t        Following those, we can provide a list of one or more Algol 68 files,\n    36\t        which appear in argv(4) and onward.\n       \n    37\t    #\n       \n    38\t    IF argc &lt; 4 THEN\n       \n    39\t        print(\"Usage: a68g pp.a68 -- [source files for pretty printing]\")\n       \n    40\t    ELSE\n       \n    41\t        #\n    42\t            Embed our pretty-printed code in a minimal HTML head-body section\n    43\t        #\n       \n    44\t        print((\"&lt;html&gt;\",new line));\n    45\t        print((\"&lt;head&gt;\",new line));\n    46\t        print((\"&lt;title&gt; Algol 68 Pretty Print&lt;\/title&gt;\",new line));\n    47\t        print((\"&lt;body&gt;\",new line));\n       \n    48\t        #\n    49\t            Loop over source files.\n    50\t            There is no sophisticated parsing nor error checking here\n    51\t        #\n       \n    52\t        FOR an FROM 4 TO argc DO\n       \n    53\t            STRING file name = argv(an);\n       \n    54\t            #\n    55\t                If the file is a readable regular file, we attempt to pretty print it\n    56\t            #\n       \n    57\t            IF file is regular(file name) THEN\n       \n    58\t                print((new line, new line,\"&lt;p&gt;&lt;strong&gt;&lt;em&gt;{ **** \",file name,\" **** }&lt;\/em&gt;&lt;\/strong&gt;&lt;\/p&gt;\",new line,new line));\n       \n    59\t                #\n    60\t                    There are six \"states\" that the pretty printer can be in:\n       \n    61\t                    - commenting (between opening sharp and closing sharp):\n    62\t                        do no pretty printing\n    63\t                    - stringing (between opening doublequote and closing doublequote):\n    64\t                          do no pretty printing\n    65\t                    - leadering (processing leading blanks on a line):\n    66\t                        replace blanks with &amp;nbsp;, tabs with &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\n    67\t                    - reserved wording (processing upper case words):\n    68\t                        lowercase and wrap in &amp;lt;strong&amp;gt;&amp;lt;\/strong&amp;gt;\n    69\t                    - identitying (processing lower case variable names possibly\n    70\t                      including spaces or numerals): \n    71\t                          wrap in &amp;lt;em&amp;gt;&amp;lt;\/em&amp;gt;\n    72\t                    - other (for example processing numerals, punctuation):\n    73\t                        just let the characters through\n       \n    74\t                    Commenting can be active over more than one line, but other states reset at the beginning of each line.\n    75\t                    Each file appears as one HTML paragraph, with line breaks after each line.\n    76\t                #\n       \n    77\t                print(\"&lt;p&gt;\");\n       \n    78\t                # multiline state resets #\n       \n    79\t                BOOL commenting := FALSE;\n       \n    80\t                #\n    81\t                    Loop over the lines in the file\n    82\t                #\n       \n    83\t                each line(file name, (STRING line, INT linecount) VOID: BEGIN\n       \n    84\t                    # individual line state resets #\n       \n    85\t                    BOOL reserved wording := FALSE;\n    86\t                    BOOL identitying := FALSE;\n    87\t                    BOOL stringing := FALSE;\n    88\t                    BOOL leadering := TRUE;\n       \n    89\t                    # process the line character-by-character #\n       \n    90\t                    FOR cn FROM LWB line TO UPB line DO\n    91\t                        CHAR c := line[cn];\n       \n    92\t                        # analyze the current character and change states where necessary #\n       \n    93\t                        IF c = \"\"\"\" AND NOT commenting THEN\n       \n    94\t                            # start or end of a string - flip stringing; off reserved wording, identifying, leadering #\n       \n    95\t                            stringing := NOT stringing;\n       \n    96\t                            IF reserved wording THEN reserved wording := FALSE; print(\"&lt;\/strong&gt;\") FI;\n    97\t                            IF identitying THEN identitying := FALSE; print(\"&lt;\/em&gt;\") FI;\n    98\t                            leadering := FALSE\n       \n    99\t                        ELIF c = \"#\" AND NOT stringing THEN\n       \n   100\t                            # start or end of a comment - flip commenting; off reserved wording, identifying, leadering #\n       \n   101\t                            commenting := NOT commenting;\n       \n   102\t                            IF reserved wording THEN reserved wording := FALSE; print(\"&lt;\/strong&gt;\") FI;\n   103\t                            IF identitying THEN identitying := FALSE; print(\"&lt;\/em&gt;\") FI;\n   104\t                            leadering := FALSE\n       \n   105\t                        ELIF NOT (commenting OR stringing) THEN\n       \n   106\t                            IF \"A\" &lt;= c AND c &lt;= \"Z\" THEN\n       \n   107\t                                # reserved wording #\n       \n   108\t                                IF NOT reserved wording THEN\n       \n   109\t                                    # start of reserved wording - on reserved wording; off identifying, stringing, commenting, leadering #\n       \n   110\t                                    reserved wording := TRUE; print(\"&lt;strong&gt;\");\n       \n   111\t                                    IF identitying THEN identitying := FALSE; print(\"&lt;\/em&gt;\") FI;\n   112\t                                    leadering := FALSE\n   113\t                                FI;\n       \n   114\t                                # translate to lower case #\n       \n   115\t                                c := REPR (ABS c - ABS \"A\" + ABS \"a\")\n       \n   116\t                            ELIF \"a\" &lt;= c AND c &lt;= \"z\" THEN\n       \n   117\t                                # identifying #\n       \n   118\t                                IF NOT identitying THEN\n       \n   119\t                                    # start of identifying - on identifying; off reserved wording, stringing, commenting, leadering #\n       \n   120\t                                    identitying := TRUE; print(\"&lt;em&gt;\");\n       \n   121\t                                    IF reserved wording THEN reserved wording := FALSE; print(\"&lt;\/strong&gt;\") FI;\n   122\t                                    leadering := FALSE\n   123\t                                FI\n       \n   124\t                                # don't mess with the character #\n       \n   125\t                            ELIF ABS c = 9 OR c = \" \" THEN\n       \n   126\t                                # leadering, space within an identity or just a space - off reserved wording #\n       \n   127\t                                IF reserved wording THEN reserved wording := FALSE; print(\"&lt;\/strong&gt;\") FI\n       \n   128\t                            ELIF \"0\" &lt;= c AND c &lt;= \"9\" THEN\n       \n   129\t                                # continuation of an identity or just a numeral - off reserved wording, leadering #\n       \n   130\t                                IF reserved wording THEN reserved wording := FALSE; print(\"&lt;\/strong&gt;\") FI;\n   131\t                                leadering := FALSE\n       \n   132\t                            ELSE\n       \n   133\t                                # something else, e.g. punctuation - off reserved wording, identitying and leadering #\n       \n   134\t                                IF reserved wording THEN print(\"&lt;\/strong&gt;\"); reserved wording := FALSE FI;\n   135\t                                IF identitying THEN print(\"&lt;\/em&gt;\"); identitying := FALSE FI;\n   136\t                                leadering := FALSE\n       \n   137\t                            FI\n   138\t                        FI;\n       \n   139\t                        # emit the current character (or its surrogate) #\n       \n   140\t                        IF leadering AND c = \" \" THEN\n   141\t                            print(\"&amp;nbsp;\")\n   142\t                        ELIF leadering AND ABS c = 9 THEN\n   143\t                            print(\"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\")\n   144\t                        ELIF c = \"&lt;\" THEN\n   145\t                            print(\"&amp;lt;\")\n   146\t                        ELIF c = \"&gt;\" THEN\n   147\t                            print(\"&amp;gt;\")\n   148\t                        ELSE\n   149\t                            print(c)\n   150\t                        FI\n   151\t                    OD;\n       \n   152\t                    # end of line - off reserved wording, identifying; print line break #\n       \n   153\t                    IF reserved wording THEN print(\"&lt;\/strong&gt;\"); reserved wording := FALSE FI;\n   154\t                    IF identitying THEN print(\"&lt;\/em&gt;\"); identitying := FALSE FI;\n   155\t                    print((\"&lt;br \/&gt;\",new line))\n       \n   156\t                END);\n       \n   157\t                #\n   158\t                    That's it for this file, close off the HTML paragraph\n   159\t                #\n       \n   160\t                print((\"&lt;\/p&gt;\",new line))\n       \n   161\t            ELSE\n       \n   162\t                #\n   163\t                    Oops - not a regular file\n   164\t                #\n       \n   165\t                print((new line, new line,\"&lt;p&gt;&lt;strong&gt;&lt;em&gt;{ **** \",file name,\" **** is not a regular file - skipping }&lt;\/em&gt;&lt;\/strong&gt;&lt;\/p&gt;\",new line,new line))\n       \n   166\t            FI\n   167\t        OD;\n       \n   168\t        #\n   169\t            Emit HTML postamble\n   170\t        #\n       \n   171\t        print((\"&lt;\/body&gt;\",new line));\n   172\t        print((\"&lt;\/html&gt;\",new line))\n   173\t    FI\n       \n   174\tEND<\/pre>\n\n\n\n<p>On line 16, we use the Algol 68 Genie <strong>pragmat<\/strong> <em>read<\/em> to include the source code for our each line() procedure that lets us process a text file without worrying about the \u201chow\u201d details.<\/p>\n\n\n\n<p>The particular-program, that is the main program, runs from the <code>BEGIN<\/code> on line 25 through to the <code>END<\/code> on line 174.<\/p>\n\n\n\n<p>Lines 26 \u2013 40 use Algol 68 Genie extensions to get at the Linux command line arguments, allowing the user of our program to pass in one or more source code files for pretty printing. The comments explain this in more detail.<\/p>\n\n\n\n<p>Lines 41 \u2013 47 emit the HTML the opening \u201chtml\u201d, the \u201chead\u201d block and the opening \u201cbody\u201d elements; lines 168 \u2013 173 emit the closing \u201cbody\u201d and \u201chtml\u201d elements. This lets us have a standalone HTML page; or we can take the output lines between these two HTML segments if we just want the pretty printed code.<\/p>\n\n\n\n<p>Lines 52 \u2013 167 are a loop over each file supplied by the user. As the comments note, the pretty printed code is placed in a single HTML paragraph with HTML line breaks at the end of each line.<\/p>\n\n\n\n<p>Line 53 sets the file name from the relevant <code>argv()<\/code> call.<\/p>\n\n\n\n<p>Lines 54 \u2013 161 process the file if it is \u201cregular\u201d; lines 162 \u2013 166 print a warning and skip the file otherwise.<\/p>\n\n\n\n<p>Lines 58 \u2013 77 print an HTML header for the file being processed, describe the interpretation process as a set of states established by what is read and used for the pretty printing and print the HTML opening \u201cp\u201d element, indicating the start of the pretty printed code. Lines 157 \u2013 160 print the closing \u201cp\u201d element.<\/p>\n\n\n\n<p>Lines 78 \u2013 156 initialize the <code>commenting<\/code> state to <code>FALSE<\/code> \u2013 that is, the pretty printing starts knowing that it is not within a comment &#8211; and use the <code>each line()<\/code> procedure to process the lines in the text file. This then is where the work is done. Comments in Algol 68 are potentially multline and therefore cannot be reset to \u201cnot commenting\u201d at the end of each line.<\/p>\n\n\n\n<p>Lines 84 \u2013 88 reset the remaining states \u2013 <code>stringing<\/code>, <code>reserved wording<\/code>, <code>identifying<\/code> and <code>leadering<\/code> at the beginning of each line. These states are not multiline, so this is appropriate. The <code>leadering<\/code> state might confuse \u2013 this refers to the zero or more blanks or tabs that begin each line of code. All of these states are mutually exclusive, as is the \u201cnot any of these\u201d state, at least as far as pretty printing goes. There is no adjustment to text within comments or strings. Symbols (reserved words) are converted to HTML \u201cstrong\u201d text and lower-cased; identifiers are converted to HTML \u201cem\u201d text.<\/p>\n\n\n\n<p>Lines 90 \u2013 151 loop over the characters in a line, looking for state changes and wrapping symbols and identifiers as required.<\/p>\n\n\n\n<p>Lines 93 \u2013 98 detect the beginning or end of a string, flip the <code>stringing<\/code> state and turn off <code>reserved wording<\/code>, <code>identifying<\/code> and <code>leadering<\/code> states.<\/p>\n\n\n\n<p>Lines 98 \u2013 104 detect the beginning or end of a comment, flip the <code>commenting<\/code> state and turn off <code>reserved wording<\/code>, <code>identifying<\/code> and <code>leadering<\/code> states.<\/p>\n\n\n\n<p>Lines 105 \u2013 138 deal with the rest of the states provided that the pretty printing process is in neither the <code>stringing<\/code> nor <code>commenting<\/code> state.<\/p>\n\n\n\n<p>Lines 106 \u2013 115 deal with symbols, turning on the <code>reserved wording<\/code> state at the beginning of a symbol (upper case letter) and turning off <code>identifying<\/code> and <code>leadering<\/code> states. Uppercase characters are translated to lower case in line 115 using a rule that works with ASCII upper- and lowercase characters.<\/p>\n\n\n\n<p>Lines 116 \u2013 124 deal with identifiers, turning on the <code>identifying<\/code> state at the beginning of an identifier (lower case letter) and turning off <code>reserved wording<\/code> and <code>leadering<\/code> states. No adjustments are made to the characters themselves.<\/p>\n\n\n\n<p>Lines 125 \u2013 127 deal with spaces that terminate symbols, can be embedded in identifiers or can be \u201csignificant\u201d white space (from a pretty printing perspective) at the beginning of a line, turning off the <code>reserved wording<\/code> state.<\/p>\n\n\n\n<p>Lines 128 \u2013 131 deal with numerical digits that terminate symbols and leading white space but can be a second or subsequent character in an identifier, turning off the <code>reserved wording<\/code> and <code>leadering<\/code> states.<\/p>\n\n\n\n<p>Lines 132 \u2013 136 deal with any other characters which terminate symbols, identifiers and leading white space, turning off <code>reserved wording<\/code>, <code>identifying<\/code> and <code>leadering<\/code> states.<\/p>\n\n\n\n<p>Phew, done with tracking all the state changes and bits of HTML markup!<\/p>\n\n\n\n<p>Lines 140 \u2013 150 convert the character to one or four HTML non-breaking spaces if it\u2019s a space ot tab and the leadering state is on; to HTML lt and gt symbols if it\u2019s the less-than or greater-than symbol respectively; or just output it otherwise.<\/p>\n\n\n\n<p>Finally lines 152 \u2013 155 handle the end of line.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running the code and looking at the results<\/h2>\n\n\n\n<p>Let\u2019s test the program out on the regress.a68 program we wrote in the previous article:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ a68g pp.a68 -- regress.a68 &gt; regress.html\n$<\/pre>\n\n\n\n<p>And here\u2019s the output:<\/p>\n\n\n\n<p><strong><em>{ **** regress.a68 **** }<\/em><\/strong><\/p>\n\n\n\n<p>#<br> &nbsp;&nbsp;&nbsp;&nbsp;Utility&nbsp;routines<br> #<br> <br> <strong>pr<\/strong> <em>read <\/em>&#8220;str_to_real.a68&#8221; <strong>pr<\/strong><br> <strong>pr<\/strong> <em>read <\/em>&#8220;split.a68&#8221; <strong>pr<\/strong><br> <strong>pr<\/strong> <em>read <\/em>&#8220;each_delimited_line.a68&#8221; <strong>pr<\/strong><br> <br> #<br> &nbsp;&nbsp;&nbsp;&nbsp;Perform&nbsp;a&nbsp;least-squares&nbsp;fit&nbsp;of&nbsp;a&nbsp;line&nbsp;to&nbsp;a&nbsp;data&nbsp;file&nbsp;containing&nbsp;(x,y)&nbsp;values<br> #<br> <br> <strong>begin<\/strong><br> <br> &nbsp;&nbsp;&nbsp;&nbsp;[1:2,1:2] <strong>real<\/strong> <em>xtx <\/em>:= ((0.0, 0.0),(0.0,0.0));<br> &nbsp;&nbsp;&nbsp;&nbsp;[1:2] <strong>real<\/strong> <em>xty <\/em>:= (0.0, 0.0);<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# Accumulate XTX and XTy #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<em>each delimited line<\/em>(&#8220;test_data.txt&#8221;, &#8220;,&#8221;, (<strong>string<\/strong> <em>line<\/em>, []<strong>string<\/strong> <em>fields<\/em>, <strong>int<\/strong> <em>line count<\/em>) <strong>void<\/strong>: <strong>begin<\/strong><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# skip the header line #<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong> <em>line count <\/em>&gt; 1 <strong>then<\/strong><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>real<\/strong> <em>xi <\/em>= <em>str to real<\/em>(<em>fields<\/em>[1]), <em>yi <\/em>= <em>str to real<\/em>(<em>fields<\/em>[2]);<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[1,1] +:= <em>xi <\/em>* <em>xi<\/em>;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[1,2] +:= <em>xi<\/em>;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[2,2] +:= 1.0;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>xty<\/em>[1] +:= <em>xi <\/em>* <em>yi<\/em>;<br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em>xty<\/em>[2] +:= <em>yi<\/em><br> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>fi<\/strong><br> &nbsp;&nbsp;&nbsp;&nbsp;<strong>end<\/strong>);<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[2,1] := <em>xtx<\/em>[1,2];<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# let&#8217;s see the matrix and vector before Gauss #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;before Gauss:&#8221;,<em>new line<\/em>));<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;\u23a1&#8221;,<em>xtx<\/em>[1,1],&#8221; &#8220;,<em>xtx<\/em>[1,2],&#8221;\u23a4 = \u23a1&#8221;,<em>xty<\/em>[1],&#8221;\u23a4&#8221;,<em>new line<\/em>));<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;\u23a3&#8221;,<em>xtx<\/em>[2,1],&#8221; &#8220;,<em>xtx<\/em>[2,2],&#8221;\u23a6 \u23a3&#8221;,<em>xty<\/em>[2],&#8221;\u23a6&#8221;,<em>new line<\/em>));<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# Gaussian elimination #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<strong>real<\/strong> <em>a <\/em>= &#8211;<em>xtx<\/em>[2,1] \/ <em>xtx<\/em>[1,1];<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[2,1] +:= <em>a <\/em>* <em>xtx<\/em>[1,1];<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>xtx<\/em>[2,2] +:= <em>a <\/em>* <em>xtx<\/em>[1,2];<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>xty<\/em>[2] +:= <em>a <\/em>* <em>xty<\/em>[1];<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# let&#8217;s see the matrix and vector after Gauss #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;after Gauss:&#8221;,<em>new line<\/em>));<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;\u23a1&#8221;,<em>xtx<\/em>[1,1],&#8221; &#8220;,<em>xtx<\/em>[1,2],&#8221;\u23a4 = \u23a1&#8221;,<em>xty<\/em>[1],&#8221;\u23a4&#8221;,<em>new line<\/em>));<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;\u23a3&#8221;,<em>xtx<\/em>[2,1],&#8221; &#8220;,<em>xtx<\/em>[2,2],&#8221;\u23a6 \u23a3&#8221;,<em>xty<\/em>[2],&#8221;\u23a6&#8221;,<em>new line<\/em>));<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# back substitution #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<strong>real<\/strong> <em>b <\/em>= <em>xty<\/em>[2] \/ <em>xtx<\/em>[2,2];<br> &nbsp;&nbsp;&nbsp;&nbsp;<strong>real<\/strong> <em>m <\/em>= (<em>xty<\/em>[1] &#8211; <em>xtx<\/em>[1,2] * <em>b<\/em>) \/ <em>xtx<\/em>[1,1];<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;# let&#8217;s see the equation #<br> <br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;equation:&#8221;,<em>new line<\/em>));<br> &nbsp;&nbsp;&nbsp;&nbsp;<em>print<\/em>((&#8220;y = &#8220;,<em>fixed<\/em>(<em>m<\/em>,0,7),&#8221; * x + &#8220;,<em>fixed<\/em>(<em>b<\/em>,0,7),<em>new line<\/em>))<br> <br> <strong>end<\/strong><a href=\"https:\/\/www.both.org\/?p=11217\">https:\/\/www.both.org\/?p=11217<\/a><\/p>\n\n\n\n<p>Not bad! I like to have string constants like &#8220;equation:&#8221; stand out from identifiers so I don&#8217;t italicize them. But other than that, I think it looks pretty close to the beautifully typeset examples from the 1970s.<\/p>\n\n\n\n<p>What did we learn here? Two things come to mind:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>we gained some familiarity with processing text in Algol 68, which is cool because we now know it&#8217;s not just a &#8220;numerical algorithms language&#8221;;<\/li>\n\n\n\n<li>we saw that we can parse an Algol 68 program that is UPPER stropped with a very simple state-machine approach.<\/li>\n<\/ul>\n\n\n\n<p>I\u2019ll be back with more Algol 68 in the not-too-distant future, when we\u2019ll take a look at the exciting new <a href=\"https:\/\/gcc.gnu.org\/wiki\/Algol68FrontEnd\" data-type=\"link\" data-id=\"https:\/\/gcc.gnu.org\/wiki\/Algol68FrontEnd\">GNU Algol 68 compiler<\/a>, built with the GNU Compiler Collection.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><a href=\"#sdfootnote1anc\" id=\"sdfootnote1sym\">1<\/a> McGettrick, A.D. (1978). <em>Algol 68 \u2013 a first and second course<\/em>. Cambridge University Press.<\/p>\n\n\n\n<p><a href=\"#sdfootnote2anc\" id=\"sdfootnote2sym\">2<\/a><em> Ibid<\/em>, p. 6<\/p>\n\n\n\n<p><a href=\"#sdfootnote3anc\" id=\"sdfootnote3sym\">3<\/a> <em>Ibid<\/em>, p. 7-8<\/p>\n\n\n\n<p><a href=\"#sdfootnote4anc\" id=\"sdfootnote4sym\">4<\/a> van Wijngaarden, A., Mailloux, B.J., Peck, J.E.L., Koster, C.H.A., Sintzoff, M., Lindsey, C.H., Meertens, L.G.L.T., &amp; Fisker, R.G. (1978). <em>Revised Report on the Algorithmic Language Algol 68<\/em>. IFIP Working Group 2.1.<\/p>\n\n\n\n<p><a href=\"#sdfootnote5anc\" id=\"sdfootnote5sym\">5<\/a> <em>Ibid<\/em>, \u00a7 0.3.6, p. 14<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 For Marcel van der Veer, with many thanks for Algol 68 Genie If you pick up a<\/p>\n","protected":false},"author":430,"featured_media":5771,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[794,98,5,150],"tags":[],"class_list":["post-11229","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-algol-68","category-code","category-linux","category-programming"],"modified_by":"David Both","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/430"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11229"}],"version-history":[{"count":4,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11229\/revisions"}],"predecessor-version":[{"id":11234,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/11229\/revisions\/11234"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/5771"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}