Am 13.07.2019 um 14:12 schrieb J. Gareth Moreton:
I would like some discussion on this with the administrative team because this does require some careful design if we're going to do this properly.  Building on Florian's suggestion, I would like to propose splitting "pass_1" into "pass_syntax" and a pass that transforms the nodes (I would name it "pass_transform", but this doesn't sound 'important' enough, given it is effectively compiling the nodes).  "pass_syntax" would be a public method declared in tnode as the following "function pass_syntax: Boolean; virtual;" - if it returns True, then everything was fine; if not, it returns False and this can be used to set the error flag.  By being defined this way, this is no ability for the node to transform itself, but it can set private fields based on the syntax it finds (by setting private fields, the "first pass" won't have to repeat some of the work needed to determine how to transform the nodes).

"pass_syntax" is not a good name, because it does *not* do syntax checking (that was done by the parser). Instead it checks the semantic, so "pass_semantic" would be a more correct name.

Also I don't think a Boolean result is needed. Take a look at tgotonode.pass_1 which is after all the one which would need to be moved to pass_semantic: it uses CGMessage*() to write its messages (as all nodes do) which in turn sets the codegenerror flag if it wasn't set already. So after a call to a node's pass_semantic method all that needs to be checked is codegenerror to decide how to proceed further. Thus the semantic pass could simply be "procedure pass_semantic;virtual;".

On the surface, the first implementation suggestion feels like the cleaner option, but I don't know how much of a penalty it will add to the compiler. Personally I would like to attempt a design for the second implementation to keep the number of passes down to a minimum and the compiler reasonably fast (also my motivation behind the x86_64 peephole optimizer overhaul).  But that's just my opinion.

In my opinion a clean, easily maintainable solution is preferrable.

On an additional note, I do wonder if it's possible to merge "pass_1" and "simplify", since they are treated pretty much identically in the "firstpass" routine - if either of them return something other than nil, it is considered to be a node transformation, running this block of code (there are two copies, one for each call):

p.free;
p := hp;
firstpass(p);

(hp contains the return value of whatever method was just called) This may be impractical because "simplify" is called elsewhere for some nodes.


I don't think combining the two passes is necessary. The ideas behind the two passes are after all different.

Regards,
Sven
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to