![]() |
A For-Next bug in 1.2.8-s682 - Printable Version +- Forum (https://www.boriel.com/forum) +-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12) +--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11) +---- Forum: Bug Reports (https://www.boriel.com/forum/forumdisplay.php?fid=15) +---- Thread: A For-Next bug in 1.2.8-s682 (/showthread.php?tid=340) |
A For-Next bug in 1.2.8-s682 - Darkstar - 03-29-2011 This works: Code: For i = AttrAddress to AttrAddress + NumberOfCells - 1 This does not: Code: For AttrAddress = AttrAddress to AttrAddress + NumberOfCells - 1 This would work in other dialects. Thanks, Darkstar Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 Darkstar Wrote:This works:This is related to the ZX Basic to have "Dynamic" evaluation on each pass. In your loop: Code: For i = i to i + N - 1 At the moment, the only way to fix this is: Code: LET z = i + N - 1 Which produces the expected behavior. I'm thinking in fixing this in an more efficient manner, so the user can choose dynamic or static FOR loops with a #pragma directive, and let FOR to be static by default for compatibility's sake. What do you think? Re: A For-Next bug in 1.2.8-s682 - britlion - 03-30-2011 Boriel, I think that's probably the right choice, since most basic dialects use it. You can always do a dynamic expression with a do...until (x) style loop, where it feels more natural to have an expression evaluated each loop, I think. Will static evaluation speed up for loops? Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 britlion Wrote:Boriel,Certainly, if they're complex expressions. Static ones are just like using a temporary variable to store them. The problem is... how to compile them? :roll: Using the stack is a problem if the user jumps out the loop using GOTO. Using a static place is also problematic (and a waste of memory). The most straightforward solution is to use a hidden variable and implement it as shown above. This would imply FOR-NEXT variables will take twice the space of a normal variable, anyway (Sinclair BASIC also makes a distinction between normal variables and FOR-NEXT ones, not only in their length name, but also in their internal implementation). Re: A For-Next bug in 1.2.8-s682 - Darkstar - 03-30-2011 boriel Wrote:At the moment, the only way to fix this is: This would work, no need to check it and it would speed up the current code. I did think that this was it, that is how the loops were evaluated at the beginning. This did produce some "undefined" behaviour that did not make any sense. Is a directive needed? Looks to me that the C style is the poor mans way of doing For-Next loops. What are the benefits? There are already some cons as noted above both in terms of workarounds and speed. If you are thinking about attracting C coders then I think the sacrifice in consistency, even with a pragma directive, is not worth it. A man is nothing if not consistent. Thanks for your(s) reply(s), Darkstar. Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 I also agree with both Britlion and you. I'm going to implement this behaviour by default. If the programmer wants the dynamic behaviour s/he will be able to enable it using something like: Code: #pragma for dynamic Code: #pragma for static Re: A For-Next bug in 1.2.8-s682 - Darkstar - 03-30-2011 boriel Wrote:I also agree with both Britlion and you. I'm going to implement this behaviour by default. If the programmer wants the dynamic behaviour s/he will be able to enable it using something like: Well, static should be a default behaviour yes for consistency but is there any benfits to be derived from dynamic that outweigs the costs? If the answer is no then why go through the work of implementing a directive and it would only add to the confusion amoung coders that expect a language to behave in a certain way in my oppinion. Darkstar. Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 Implementing dynamic is much easier (it's already done) and saves memory comparing to static. Static might be faster sometimes (eg. when using expressions), and take twice the memory for each iterator variable. I think leaving it alone should be ok (since almost no one will be using it). FOR is currently "dynamic" and has not caused much trouble when porting original Sinclair BASIC programs. In fact FOR loops are expensive in much ways (code, speed, etc). While and DO...LOOP are much faster and simpler. Re: A For-Next bug in 1.2.8-s682 - Darkstar - 03-30-2011 boriel Wrote:Implementing dynamic is much easier (it's already done) and saves memory comparing to static. Static might be faster sometimes (eg. when using expressions), and take twice the memory for each iterator variable. I think leaving it alone should be ok (since almost no one will be using it). FOR is currently "dynamic" and has not caused much trouble when porting original Sinclair BASIC programs. If you use expressions then you already have to use an extra variable (double the amount) if speed is the concern and it always is with computers not to mention the ZX at 3.5 MHz. It is the classical speed vs size when it comes to opptimization and you can lay the burden on the programmer or the compiler. This is a compiler's job and it makes for a cleaner code for a programers perspective in the end instead of having an extra variable hanging around that you have to DIM in future versions of this compiler. Dynamic is not in lieu with the BASIC tradition or desing philosophy and For-Next loops are a fact of life. This could lead to pontential trouble in porting, sometimes people have to revise and rewrite instead of preserving the work they have done. Compiler writing is about the whole and not the individual in my humble oppinion. Darkstar. Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 Darkstar Wrote:Not exactly: the code that computes the FOR upper limit expression is the same (regardless its static or dynamic calculated on each iteration). The difference is that once it's used it's discarded (dynamic) or must be stored to be reused later (static). Other than that, there's no difference. I was to implement that anyway (there's another thread in this forum asking for that), but leaving the possibility to use a dynamic for if one wants. I meant: can't see why we must enforce dynamic removal once static is the default behaviour.boriel Wrote:Implementing dynamic is much easier (it's already done) and saves memory comparing to static. Static might be faster sometimes (eg. when using expressions), and take twice the memory for each iterator variable. I think leaving it alone should be ok (since almost no one will be using it). FOR is currently "dynamic" and has not caused much trouble when porting original Sinclair BASIC programs.If you use expressions then you already have to use an extra variable (double the amount) Re: A For-Next bug in 1.2.8-s682 - Darkstar - 03-30-2011 boriel Wrote:Darkstar Wrote:Not exactly: the code that computes the FOR upper limit expression is the same (regardless its static or dynamic calculated on each iteration). The difference is that once it's used it's discarded (dynamic) or must be stored to be reused later (static). Other than that, there's no difference. I was to implement that anyway (there's another thread in this forum asking for that), but leaving the possibility to use a dynamic for if one wants. I meant: can't see why we must enforce dynamic removal once static is the default behaviour.boriel Wrote:Implementing dynamic is much easier (it's already done) and saves memory comparing to static. Static might be faster sometimes (eg. when using expressions), and take twice the memory for each iterator variable. I think leaving it alone should be ok (since almost no one will be using it). FOR is currently "dynamic" and has not caused much trouble when porting original Sinclair BASIC programs.If you use expressions then you already have to use an extra variable (double the amount) Yes, it throws it away and if you want to retain it then you have to set up an extra variable in your code and by logic I assume that if you use the upper limit as an iterator it overwrites the upper limit instead of the case with static where it is kept as a single background variable. No need to enforce a removal but I do not see much sense in keeping a dynamic structure unless you want to shave off a one extra internal variable and the code to manage it meaning certain limitations. If you want to be really smart then the compiler could decide which loops would benefit from a dynamic structure vs a static one, and instead of having two sets of For-Next code in the compiler just do a branch based on a flag but that could eat up the savings made so... If you were going to implement it anyway then that's good, as a default. Thanks, Darkstar. Re: A For-Next bug in 1.2.8-s682 - boriel - 03-30-2011 Darkstar Wrote:No need to enforce a removal but I do not see much sense in keeping aHey, that's a much nicer idea instead:!: But could be difficult. At the moment, only constant expressions are detected as invariant code. There's still much work to do in this area. Please, be patient. Re: A For-Next bug in 1.2.8-s682 - Darkstar - 03-30-2011 boriel Wrote:Not exactly: the code that computes the FOR upper limit expression is the same (regardless its static or dynamic calculated on each iteration). The difference is that once it's used it's discarded (dynamic) or must be stored to be reused later (static). Other than that, there's no difference. I was to implement that anyway (there's another thread in this forum asking for that), but leaving the possibility to use a dynamic for if one wants. I meant: can't see why we must enforce dynamic removal once static is the default behaviour. Found it: <!-- l --><a class="postlink-local" href="http://www.boriel.com/forum/help-support/topic434.html#p1124">help-support/topic434.html#p1124</a><!-- l --> boriel Wrote:Notice also that FOR upper limit is evaluated ON EACH iteration (like C). So if len(a$) changes, the loop will shorten. So better use a temporary var l to store initial LEN(a$). Then how about evaluating the expression once and have internal variables for Lower, Higher and Step limits that do not chance as I assume that that is the traditional way in BASIC, or only the upper limit as the loop is already running. It could make for a speed gain. Re: A For-Next bug in 1.2.8-s682 - britlion - 03-31-2011 You know it occurs to me that it might spot cases where it could keep it on register. Simple loops that don't do much, and live below 256 for B or 65536 for BC.. Remember that code I showed you that made djnz-like speed from a 16 bit counter? Perhaps implementing a push-pop to bc if it calls something that would need that register. But quite a lot of for-next loops are to a static number, or in the next best case from something like 1 to uInteger. Both of which could be stored in registers, assuming that doesn't get too complicated. And of course, it would be blinding fast ![]() |