<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
        {mso-style-priority:99;
        mso-style-link:"Nur Text Zchn";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
span.NurTextZchn
        {mso-style-name:"Nur Text Zchn";
        mso-style-priority:99;
        mso-style-link:"Nur Text";
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=DE-CH link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoPlainText><span lang=EN-US>With a multi-pass compiler this IF optimization is much simpler as you can look for constant IF-branches and prune the tree before code generation.<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=EN-US>With a single-pass compiler where parsing and code generation is interleaved, there are principally two different approaches:<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=EN-US>A) add code to only parse. Something like a clever SkipUntilMatchingEnd(). It has to handle nesting...<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US> <o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>B) influence code generation if the IF-condition is constant. Not very elegant code but something like this should do:<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=EN-US>      <span style='background:aqua;mso-highlight:aqua'>ELSIF sym = ORS.if THEN ORS.Get(sym);</span>     (* optimize: 0 = don’t optimize / 1 = all FALSE / 2 = first TRUE / 3 = subsequent TRUE *)<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>expression(x); CheckBool(x);</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        IF x.mode # ORB.Const THEN optimize :=0; <span style='background:aqua;mso-highlight:aqua'>ORG.CFJump(x);</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        ELSIF x.a = 0 THEN optimize := 1; <span style='background:yellow;mso-highlight:yellow'>ORG.DisableCode</span> ELSE optimize := 2 END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>Check(ORS.then, "no THEN"); StatSequence;</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        IF optimize = 1 THEN <span style='background:yellow;mso-highlight:yellow'>ORG.EnableCode</span> ELSIF optimize = 2 THEN <span style='background:lime;mso-highlight:lime'>ORG.DisableCode</span> END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>L0 := 0;</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>WHILE sym = ORS.elsif DO ORS.Get(sym);</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           IF optimize = 0 THEN <span style='background:aqua;mso-highlight:aqua'>ORG.FJump(L0); ORG.Fixup(x)</span> END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           <span style='background:aqua;mso-highlight:aqua'>expression(x); CheckBool(x);</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           IF optimize = 1 THEN<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>              IF x.mode # ORB.Const THEN optimize := 0 ELSIF x.a = 0 THEN <span style='background:yellow;mso-highlight:yellow'>ORG.DisableCode</span> ELSE optimize := 2 END<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           ELSIF (optimize = 2) & (x.mode = ORB.Const) & (x.a = 1) THEN optimize := 3<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           IF optimize = 0 THEN <span style='background:aqua;mso-highlight:aqua'>ORG.CFJump(x)</span> END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           <span style='background:aqua;mso-highlight:aqua'>Check(ORS.then, "no THEN"); StatSequence</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           IF optimize = 1 THEN <span style='background:yellow;mso-highlight:yellow'>ORG.EnableCode</span> ELSIF optimize = 2 THEN <span style='background:lime;mso-highlight:lime'>ORG.DisableCode</span> END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>END;<o:p></o:p></span></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>IF sym = ORS.else THEN ORS.Get(sym);</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           IF optimize = 0 THEN <span style='background:aqua;mso-highlight:aqua'>ORG.FJump(L0); ORG.Fixup(x)</span> END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>           <span style='background:aqua;mso-highlight:aqua'>StatSequence;</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        ELSIF optimize = 0 THEN <span style='background:aqua;mso-highlight:aqua'>ORG.Fixup(x)</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>END ;</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        IF optimize = 0 THEN  <span style='background:aqua;mso-highlight:aqua'>ORG.FixLink(L0)</span> <o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        ELSIF optimize >=  2 DO <span style='background:lime;mso-highlight:lime'>ORG.EnableCode</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>        <span style='background:aqua;mso-highlight:aqua'>Check(ORS.end, "no END")</span><o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=EN-US>In ORG Enable and Disable have to decrement/increment a code generation status, and all Put / Fix procedures only generate code if status = 0.<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=EN-US>br<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US>Jörg<o:p></o:p></span></p><p class=MsoPlainText><span lang=EN-US><o:p> </o:p></span></p><p class=MsoPlainText><span lang=DE>Am 11.08.18, 09:37 schrieb "Oberon im Auftrag von Andreas Pirklbauer" <oberon-bounces@lists.inf.ethz.ch im Auftrag von andreas_pirklbauer@yahoo.com>:<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE><o:p> </o:p></span></p><p class=MsoPlainText><span lang=DE>       > I have tried to work out how the authors of ETH-M2 and GPCP<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       > achieved this but have been unsuccessful so far.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    First, note that the ETH Modula-2 compilers has seen multiple<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    re-implementations over the years. As hardware with more and<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    more RAM became available, the number of passes was reduced.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    That’s a topic in and by itself, but only of historic interest.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    A. Here is an excerpt of Pass3 of the ETH Modula-2 Multi-Pass<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    Compiler in the Lilith implementation Version C18 of 10.02.82:<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>        PROCEDURE IfStatement;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>           ...<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>        BEGIN (*IfStatement*)<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>          jumpList := NIL;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>          LOOP Expression(lat);<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            IF lat.mode=constantMod THEN<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              IF BOOLEAN(lat.value) THEN           (*<-------*)<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>                StatSeq3(endsy, elsifsy, elsesy);<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>                IF sy<>endsy THEN Skip(endsy, endsy) END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>                EXIT<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              ELSE Skip(elsesy, elsifsy);<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>                IF sy <> elsifsy THEN EXIT END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>                GetSymbol<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              END<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    I have no way to check this today (no access to Lilith ;-),<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    but I “believe* this is what is happening.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    To replicate that on Project Oberon on RISC you’d need<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    to adjust ORP.StatSequence accordingly and check the<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    x after Expression(x) whether it is a boolean constant.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    a) BOOLEAN converts lat.value<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       (in M2 on Lilith the field ‘lat’ is an attribute and a<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       descriptor of the operand in an expression,<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       in Project Oberon it would correspond to x.a)<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    b) The IF BOOLEAN(lat.value) THEN expression<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       then becomes either IF TRUE or IF FALSE<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    c) If it is FALSE, then Skip(elsesy, elsifsy) is<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       executed (see above code), i.e. NO code is generated.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    Again, I have no way to check, but I believe that this<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    *may* be the way it was done.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    B. And here is an excerpt of MacMETH compiler in MC68000<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    which I was most familiar with at the time (and which was based<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    on one of the Lilith implementations if I remember correctly):<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>       PROCEDURE StatSe;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>         ELSIF sym = if THEN<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            GetSym; RefPoint; Expression(x); GenCFJ(x, L0);<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            CheckSym(then, 27); StatSeq; L1 := 0;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            WHILE (sym = elsif) DO<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              GetSym; GenFJ(L1); FixLink(L0); RefPoint; Expression(x);<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              GenCFJ(x, L0); CheckSym(then, 27); StatSeq<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            IF sym = else THEN<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>              GetSym; GenFJ(L1); FixLink(L0); StatSeq<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            ELSE FixLink(L0)<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            END;<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>            FixLink(L1); CheckSym(end, 20)<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    So there it is not done. It already looks at lot like Oberon on RISC.<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    HTH,<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    -ap<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    --<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    https://lists.inf.ethz.ch/mailman/listinfo/oberon<o:p></o:p></span></p><p class=MsoPlainText><span lang=DE>    <o:p></o:p></span></p></div></body></html>