[M3devel] Modula-2 parsing

Jay jay.krell at cornell.edu
Tue Aug 4 21:47:16 CEST 2015


Agreed the recovery might be worthwhile. Maybe the code can be refactored -- I'll look later.


"Counting TRY" is in m3front. No full IR -- though I agree that isn't a bad idea..


This change is for all backends.

No front end or backend will need to know the size of a jmp_buf and a chunk of target-specific code will be gone.

 If a backend wants to know about jmp_buf, that ability will be added soon thereafter.


I have it "almost working" and might send diffs soon. Specifically, "upgrade", which does raise exceptions, e.g. file not found, works. Compilation fails though in jvideo. I have to debug that and write more tests, esp. for TRY in finally and module main -- the cases of "procedures" I had originally missed (and still wish were modeled using Procedure.T).


So..indeed...what about this idea: form up the entire IR in memory in m3front, allow some passes over it, and then onto backend?


There are obvious counter points but most seem moot these days.


Yes, it means a larger working set and more likely-traced allocations.


Ignoring the tracing though, this is how cm3cg has always worked.


And much of the world has moved past even this -- attempting "whole program compilation" -- with imho mixed results -- the resulting compilation speed and scaling and memory use and loss of inceementality have been problems. But the results are also good. My favorite example is cross-module inlining. 


At least one of the transforms M3C does could be moved to m3front -- removing unused locals.


And maybe unused imports -- that is an extremely small problem though -- OpenBSD C compiler warns/errors for strcpy/strcat being declared.


Heck -- there is also an implied better in-memory IR that could be used -- i.e. the whole thing per module instead of just a function call at a time.


Given the M3C code, this is easy at this point.

Isn't BlockStmt introducable almost anywhere? How do I know start of a procedure? Well, by looking for cg.begin_procedure.

I'll send diffs later. I think I'm quite close.

Thoughts?

 - Jay

On Aug 4, 2015, at 11:30 AM, "Rodney M. Bates" <rodney_bates at lcwb.coop> wrote:

> On 08/04/2015 02:36 AM, Jay K wrote:
>> Procedure.m3:
>> 
>> Do we need this?
>> I know it isn't much, but remove it?
> 
> It looks to me like the comment "accepting" is misleading, since it produces
> an error message.  My guess is that this is a specialized syntax error recovery
> technique, designed to do a better job of continuing when this particular
> error occurs, probably based on experience.  Modula-3 evolved from Modula-2+,
> which evolved from Modula-2, and I'll bet there was a lot of code converted
> from one language to another.  This would have been a common leftover from
> that process.
> 
> I'd change the comment, but otherwise leave it.
> 
>> 
>>     ELSIF (cur.token = TK.tSEMI) THEN
>>       t.body := NEW (Body, self := t);
>>       ProcBody.Push (t.body);
>>       (* try accepting the Modula-2 syntax *)
>>       Error.ID (id, "expecting \'=\' before procedure body");
>>       GetToken (); (* ; *)
>>       t.syms  := Scope.PushNew (TRUE, id);
>>       t.block := BlockStmt.Parse (FALSE);
>>       t.fails := BlockStmt.ExtractFails (t.block);
>>       t.end_origin := Scanner.offset;
>>       final_id := MatchID ();
>>       IF (final_id # id) THEN
>>         Error.ID (id, "Initial name doesn\'t match final name");
>>       END;
>>       Scope.PopNew ();
>>       ProcBody.Pop ();
>>     ELSE
>> 
>> 
>> It always errors?
>> 
>> But I guess it errors and checks nicer than it might otherwise?
>> 
>> Why am I looking here?
>> 
>> Tangential:
>> 
>> I'm looking for where/how to model counting TRYs per "procedure"
>> and doing the alloca at the start of a "procedure".
> 
> Are you counting TRYs in the front end, or on the back side of the
> cm3 IR?  If the former, try looking at the way "fails" is collected
> from Decl.Parse, to BlockStmt.ExtractFails, to Procedure.ParseDecl,
> to a field of Procedure.T.  But it has to come out of TryStmt.Parse,
> to Stmt.Parse, to BlockStmt.Parse.  And you only need a count, not
> a list?
> 
> If the latter, aren't you already doing two passes over the IR?
> 
>> 
>> "procedure"'s definition for my context is being worked on.
>>  It appears to be three things:
>>   1) Things called "PROCEDURE".
>>   2) FINALLY blocks, sometimes
>>   3) "Module main"
>> 
>>  I was looking for what they have in common already,
>>  and it looks like maybe "ProcBody.Push".
>> 
>>  So I was looking all of them.
>> 
>>  - Jay
>> 
>> 
>> 
>> 
>> _______________________________________________
>> M3devel mailing list
>> M3devel at elegosoft.com
>> https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
> 
> -- 
> Rodney Bates
> rodney.m.bates at acm.org



More information about the M3devel mailing list