Page 1 of 1

FOR...NEXT with negative STEP semantic

Posted: Wed Jul 10, 2024 1:49 pm
by clovepower
Hi

The below code, when executed in the Dragon or C128 (so I suspect it is a general behavior), doesn't print anything.

Code: Select all

 i = 0
 FOR i = 10 TO 1 STEP -1
    PRINT i
 NEXT
From my past BASIC memories, this should count down from 10 to 1, extremes included.

Is this a bug or intended behavior?

Regards
Maxi

Re: FOR...NEXT with negative STEP semantic

Posted: Wed Jul 10, 2024 7:30 pm
by spotlessmind1975
Hi clovepower!
clovepower wrote: ↑Wed Jul 10, 2024 1:49 pm Is this a bug or intended behavior?
This is a bug without any doubt. And I also know how it was introduced. Before I tell you that I have already fixed it and you can download the compilers' COLDFIX, I would like to explain how it was born.

Let me start by saying that being the only structured programming construct of standard BASIC, it had very flexible semantics. In fact, it had the ability to perform dynamic loops, unlike most languages ​​in the same era.

Example:

Code: Select all

f = 1: t = 10: s = 2
FOR i = f TO t STEP s
   t = t - 1
   s = s + 1
   PRINT i
NEXT i
This program will produce 1, 4 and 8 (or other sequences, it depends by implementation).

The first implementation of ugBASIC did not meet this criterion, and therefore only allowed static loops to be executed, i.e. where the endpoints and step do not change (in the previous case, we will obtain 1,3,5,7,9). After an exchange with other BASIC programmers, I worked to make the three terms of the FOR completely dynamic. In doing this, I forgot about the retrograde semantics that the previous implementation had - hence the bug you encountered.

Anyway, the bug is fixed. :D

Re: FOR...NEXT with negative STEP semantic

Posted: Thu Jul 11, 2024 5:49 am
by clovepower
Hi spotlessmind1975

Verified fixed!

Thanks for the super fast fix, as usual :) ...and for the tory, always nice to know what happens "behind the scene".

Regards
Max

...btw, I do appreciate FOR...NEXT to be dynamic, I am using this continuously and using a WHILE instead would just be longer and more difficult to read.

Re: FOR...NEXT with negative STEP semantic

Posted: Thu Jul 11, 2024 6:38 am
by clovepower
Hi spotlessmind1975

Unfortunately, I think the fix introduced another issue :(

"OPTION TYPE NARROW" produces strange effects now, depending on the program and platform using it.

The below program for example prints 5 forever on the dragon, prints noting between "UP" and "DOWN" for the C128, VIC20, ATARI.

Other programs with same option just crash (maybe because there is a POKE in the loop).

This started with COLDFIX 9bf166708.

To be honest, I am not even sure "OPTION TYPE NARROW" is the cause, since I now have weird behaviors in programs without the clause, but the below program will run fine without "OPTION TYPE NARROW".

Code: Select all

OPTION TYPE NARROW

CLS
i = 0

PRINT "UP"
FOR i = 1 TO 10 STEP 2
	PRINT i
NEXT

PRINT "DOWN"
FOR i = 5 TO 1 STEP -1
	PRINT i
NEXT

PRINT "DONE"

Re: FOR...NEXT with negative STEP semantic

Posted: Thu Jul 11, 2024 3:44 pm
by spotlessmind1975
Hi clovepower!
clovepower wrote: ↑Thu Jul 11, 2024 6:38 am Unfortunately, I think the fix introduced another issue
For that matter I fear he has introduced more than one. But I think that, in the end, this is a good thing: because it allowed me to see that there was one basic thing that wasn't right. :)

In order to better explain the complexity of the fix I must introduce a brief explanation, that is, how ugBASIC manages calculations without using the stack. In a nutshell: the compiler translates every calculation that can be understood as dynamic into a static calculation, as much as possible. A dynamic calculation is a calculation in which, at the time of compilation, the result is not known. A static calculation is just the opposite. The advantage of static calculations is that it is not necessary to have a stack (i.e. a "dynamic" structure) and, furthermore, that all instructions are inherent to the calculation itself. There are, so to speak, no "service" instructions. Another advantage, in the end, is that it is possible to optimize the generated code, removing useless instructions (even if sometimes a little too much, as happened with one of the latest bugs).

Now, given an instruction:

Code: Select all

FOR var = bottom TO top STEP step
The bottom, top and step variables must be calculated dynamically and valued when compared with the var variable. To do this you would need to have a stack, where you can manipulate the value of those variables. This in 8-bit processors is very slow, and it would force us not to allow entering the middle of a FOR or exiting it, which standard BASIC allows.

To avoid this, I fixed ugBASIC so that it statically generates the code that calculates these variables and which will therefore be recalled (recalculated) at every cycle. Previously this was not done and the value was calculated at the input of FOR...NEXT was therefore used. Hence the further bug. Obviously I had to implement this mechanism also for a possible FOR within a PARALLEL PROCEDURE, with the bottom, top and step variables are declined independently for each thread.

In this evening's COLDFIX the problem has been fixed, and the program you wrote works correctly, both with OPTION TYPE NARROW and without. ;)

Re: FOR...NEXT with negative STEP semantic

Posted: Thu Jul 11, 2024 4:34 pm
by clovepower
Hi

I am not sure if it is more fun to spot a bug, write the bug report, or read your explanation of the fix :)

Anyway, the fix has been tested and works. And I do like your explanations since, as I mentioned, I love computer languages and compilers, so always interesting to get to know some detail an technique.

Regards