<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>