<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"><base href="x-msg://5543/"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Sorry, I should have read more closely. You are right.<div>Yes, I do believe that when generating C code you will need multiple passes to accumulate stuff to be dumped out together.</div><div>For example, I assume that to handle nested functions that you will construct a local "frame" struct for the function, containing a pointer to it’s outer scope frame struct plus all the local variables having "up_level==true". There is no other way to do static chains portably in C. A pointer to this frame struct will serve as the static link to inner-scope functions.</div><div><br>
<br><div><div>On Sep 6, 2012, at 10:23 PM, Jay K <<a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="hmmessage" style="font-size: 12pt; font-family: Calibri; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div dir="ltr">I'm not really suggesting any change to any existing code..<br> <br><br>Though, the frontend, I gather, is already multi-pass,<br>so it might be nice if it did things in an order more<br>convenient for backends.<br>e.g. it'd be nice if all the import_procedure calls came in before any begin_procedure;<br>as it stands, many come in early, and then more come in in the middle of code.<br> <br><br>I'm motivating that my C/C++ generating backend could<br>benefit from internally having multiple passes.<br> <br><br>Which might be convenient to implement via a general<br>mechanism for combining multiple "partial" passes.<br> <br> <br>Such mechanism would naturally "temporarily persist"<br>a faithful m3cg representation in memory.<br>Very similar to the existing temporary binary files<br>we feed to parse.c, but without all the encoding for<br>compactness. i.e. an array of records<br> <br> <br>I guess I'll still try to ignore this matter for now.<br>I'm getting by with one pass that generates invalid C++ but valid C.<br> <br> <br>Possibly I can provide a "nicely reordering m3cg"<br>that buffers it all up and then plays it back<br>in a slightly better order, that is more amenable<br>to a simple implementation, e.g. again getting<br>all the import_procedure calls in before any begin_procedure.<br> <br><br>Moving all the init_* calls to near the start instead of near the end.<br>etc.<br> <br> <br>i.e. I'm not really sure multiple passes are needed, it's just that<br>the current ordering is kind of surprising sometimes.<br> <br> <br><br> - Jay<br><div><div id="SkyDrivePlaceholder"></div><hr id="stopSpelling">Subject: Re: [M3devel] a "need" for multi-pass m3cg (or different order of calls)<br>From: <a href="mailto:hosking@cs.purdue.edu">hosking@cs.purdue.edu</a><br>Date: Thu, 6 Sep 2012 17:13:14 -0400<br>CC: <a href="mailto:m3devel@elegosoft.com">m3devel@elegosoft.com</a><br>To: <a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a><br><br>I’ll respond to this in more detail, but briefly, I object strongly to a multipass m3cg. If you need multiple passes then you probably need a different internal representation (just like m3cg has a different internal representation). M3CG is a simple single-pass linear representation of a program. If you need multiple passes to understand it then that is your problem. I imagine that any backend will itself need to be multipass anyway (if it is to do something useful). I think your C backend should be multipass too. It certainly will need to read M3CG IR and import it into some reasonable internal representation. This is exactly the strategy I am taking with M3CG to LLVM IR. I will have some minor tweaks to M3CG just to lift its level of abstraction slightly (to better communicate typed indexing of arrays and fields, for example). But I see no need to make M3CG do any more heavy lifting.<br><br><div><div>On Sep 6, 2012, at 4:40 AM, Jay K <<a href="mailto:jay.krell@cornell.edu">jay.krell@cornell.edu</a>> wrote:</div><br class="ecxApple-interchange-newline"><blockquote><div class="ecxhmmessage" style="font-style: normal; font-variant: normal; font-weight: normal; font-size: 12pt; line-height: normal; font-family: Calibri; text-transform: none; text-indent: 0px; letter-spacing: normal; word-spacing: 0px; white-space: normal; orphans: 2; widows: 2; "><div dir="ltr"><div><font face="Calibri">/* The following is legal C but not C++: */</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">struct Foo_t;</font></div><div><font face="Calibri">typedef struct Foo_t Foo_t;</font></div><div><font face="Calibri">static struct Foo_t Foo; /* illegal C++; C forward/tentative definition */</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">int F1(void) { return *(int*)&Foo; }</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">struct Foo_t { int i; };</font></div><div><font face="Calibri">static Foo_t Foo = { 123 };</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">This is a reason that either</font></div><div><font face="Calibri">1) I "need" to make M3C.m3 "multi pass"</font></div><div><font face="Calibri">2) or at least buffer everything in memory</font></div><div><font face="Calibri">in multiple pieces and then concat at the end</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"> I could also make it less efficient: </font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"> struct Foo_t; /* segment */ </font></div><div><font face="Calibri"> typedef struct Foo_t Foo_t; </font></div><div><font face="Calibri"> static struct Foo_t * /*const*/ Foo; </font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"> int F1(void) { return *(int*)&Foo; } </font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"> struct Foo_t { int i; };</font></div><div><font face="Calibri"> static Foo_t _Foo = { 123 }; </font></div><div><font face="Calibri"> static Foo_t* /*const*/ Foo = &_Foo;</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">But that seems unfortunate.</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">I will want to generate C++ at some point, for efficient portable exception</font></div><div><font face="Calibri">handling. But that comes later.</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri">Also later, the C code needs a reordering in order to refer to fields in "segments".</font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"><br></font></div><div><font face="Calibri"> - Jay</font></div></div></div></blockquote></div></div></div></div></blockquote></div><br></div></body></html>