thx Vincent/Trebint/Vampier i will look at this material soon. I think would be fine to have a basic to 'c' converter also.
Actually i'm faced with the for next basic loops, because of it's implementation in msxbasic i cannot easily directly translate them into 'c' for loop. Most probably i need a more run-time management of for next.
aND a question: anyone think is too much limitative the requirement of having explicitly declared the variable in the next part?
NEXT : REM WRONG! does not compile
NEXT MYVAR% : OK, because of the MYVAR% declaration.
allowing the latter will improve performaces...
Funny that then it will behave the opposite of the MSX BASIC itself. When the NEXT variable is not declared is faster that declaring it, in this case I guess that it must check against all the FOR variables if it's the right one and without declaring, it must be poping out the first found in the stack.
Haven't worked with MSXBasic for a long time, but shouldn't for next loops always be nested? I don't think it would work correctly if you did something like
for a=1 to 3 step 2 for b=3 to 1 step -1 next a next b
Funny that then it will behave the opposite of the MSX BASIC itself. When the NEXT variable is not declared is faster that declaring it, in this case I guess that it must check against all the FOR variables if it's the right one and without declaring, it must be poping out the first found in the stack.
the problem is thanks to the crappy implementation of basic for loops
take this for example:
10 FOR T%=0 to 10
20 IF INKEY$="" THEN NEXT : REM ORRIBLE!
30 NEXT T% : REM TWO NEXT FOR EACH 'FOR'
---
10 FORT%=0TO10
20 ...
30 NEXT
15 REM FOR K%=0 TO 1120
or
15 FOR K1%=0 TO 1120
in this case then next in 30 refer to k% or k1% depending of comment in line 15.
this is a run-time management of for loops, that cannot be replicated if we directly translate basic costruct to 'c' ones.
we need a sort of run-time management of for loops, may be converting them into goto and if then clauses.
I think you need to use a stack for the FOR statements. Then when you call NEXT you'll go from the top of the stack to the bottom and search for a match to the argument of the NEXT statement.
When you find a match you'll just discard any more recent entries in the stack.
For example if you do:
10 FORI=1TO5
20 FORJ=1TO10
30 PRINTJ;
40 IFJ=2THENNEXTIELSENEXT
50 NEXTJ
This program will (I think) print:
1212121212
and get a NEXT without FOR error on line 50 because the FORJ is removed from the FOR stack by the NEXTI call
Same program a bit clearer:
10 FOR I=1 TO 5
20 FOR J=1 TO 10
30 PRINT J;
40 IF J=2 THEN NEXT I
50 NEXT J
So when the condition J=2 then NEXT I is invoked which will pop the FOR stack and see that the top for loop is a FOR J, which doesn't match NEXT I. So the FOR J is thrown away from the stack and the next one is popped, which is the FOR I.
dvik: nothing personal, but this way of BASIC coding stinks. Breaking from [nested] loops is considered a sin in computer science . But you probably know that already. Should anyone write a compiler, I'd opt it would only parse 100% legal code. Bit like XML, where you must have proper closing of elements.
The problem is that the example above is a perfectly valid MSX Basic program and I strongly think a compiler should be 100% compatible with the language it tries to compile.
But I definitely agree that these constructions stink and should be avoided.
Here is another example that makes it a bit more tricky:
10 FOR I=1 TO 5
20 PRINT I
30 GOSUB 100
40 END
100 NEXT I
In this case you'll get a "NEXT without FOR in 100" error so the NEXT I will not be matched with the FOR I statement.
The reason is that the GOSUB call is also placed on the stack and the NEXT I search goes back only to the GOSUB entry on the stack.
And the RETURN statement of a GOSUB routine will remove any active FOR loops within the sub routine. So in the example below the NEXT statement on line 30 will not match to the FOR J statement because the FOR J is removed from the stack by the RETURN call:
10 FOR I=0 TO 5
20 GOSUB 100
30 NEXT
40 END
100 FOR J=0 TO 10
110 PRINT J;
120 RETURN
Outputs: 11111
But one thing is funny though. Since all variables are global the following program:
10 FOR I=1 TO 5
20 GOSUB 100
30 NEXT I
100 FOR I=1 TO 2
110 PRINT I;
120 NEXT I
130 RETURN
will output: 1212121212121212121212121212121212......
obfuscated MSX BASIC coding contest all the way... Hey, are you and NYYRIKKI still going to 'finish' that obfuscated car racing program? (It really rocked!)