BASIC without line numbers?

BruceMcF

Active Member
May 19, 2019
100
30
28
I know how that works, I just wanted to point out the other direction, there are some constructs which cannot be (fully) utilized in direct mode.
Yes, there are those that cannot be fully utilized for reasons of how they are implemented and others, like defining subroutines, where there is not enough benefit in being able to do them in direct mode to make it worthwhile to offer them.

The whole point of direct mode is that it is a program that is written, executed, and then overwritten by the next direct mode program.

If you define a subroutine in direct mode, the next direct mode entry you write can't use the subroutine, because it's over-written the subroutine. Given 16K or 32K or 64K, there's no particular reason to try to create a direct mode subroutine definition ability when you can interactively define the subroutine as the current program and THEN call it in direct mode.

WHILE...WEND on the other hand could be used in direct mode like a FOR...NEXT loop. So the argument of BASIC being interactive and therefore omitting some of the structured blocks don't fit.
But "Basic is interactive and therefore omits some of the structured blocks" is a specious argument, since the interactivity of Basic is not limited to direct mode.

And the DO/LEAVE/LOOP construct can also be used as a conditional loop in direct mode, as can full fledged QBasic DO/LOOPs.

The worst omission cause of space constraints is the lack of ELSE which leads to a lot of unnecessary complicated constructs with IF...THEN and GOTOS so simulate the ELSE case.
But as noted, the most direct ELSE implementation in BASIC results in a non-nesting IF-THEN-ELSE construct. So without additional block capabilities or alternative Block versions of THEN and ELSE, some of those GOTOs would still be there. But at the very least a single-line, non-nesting ELSE is needed to let the DO/LEAVE/LOOP work as a conditional loop in direct mode.
 
Last edited:

Schlowski

Member
Sep 24, 2019
45
22
8
I would be happy with a single line IF-THEN-ELSE and DO/LEAVE/LOOP for the more complicated cases. This would bring BASIC a giant step forward and eliminate a lot of GOTOs.

I'm a little bit worried about feature creep for BASIC - it was so easy to learn in the days because it had only so much commands and functions. If we "overload" it with everything nowadays a BASIC "must have" I fear we lose that simplicity. Not to say that some of these features aren't badly missed on BASIC V2, but there should be a thorough discussion about those extensions.

What's not totally clear for me is the implementation of the new BASIC commands: Will they be implemented as a direct extension to BASIC V2 or will they be implemented as sort of macros for an extended editor? Or are we talking about both here without a clear distinction between them?
 

BruceMcF

Active Member
May 19, 2019
100
30
28
I would be happy with a single line IF-THEN-ELSE and DO/LEAVE/LOOP for the more complicated cases. This would bring BASIC a giant step forward and eliminate a lot of GOTOs.

I'm a little bit worried about feature creep for BASIC - it was so easy to learn in the days because it had only so much commands and functions. If we "overload" it with everything nowadays a BASIC "must have" I fear we lose that simplicity. Not to say that some of these features aren't badly missed on BASIC V2, but there should be a thorough discussion about those extensions.
Feature creep is an issue ... indeed, after reading the CX16 PRG, I see that my hopes for a single byte DO and LOOP are in vain, as they want to retain V3.5 and V7 compatibility ... not IMPLEMENT all of 3.5 & 7 as such, but not to re-use 3.5 or 7 tokens either. And Version 7 uses all of the 126 primary tokens available (they are high bit set, I forget what $FF is for), but luckily including $FE for extension tokens. SO Commodore "feature creep" killed my hope of a single byte token DO & LOOP.

Worry about feature creep is one reason why I switched to DO/LEAVE/LOOP, which in its DO/LEAVE/DONE form fixes a substantial flaw in V2 Basic For/Next. Single line, non-nested ELSE is a worthwhile add in its own right (and doesn't take up any token space, if that's compatible with the V7 ELSE and so can use its token).

Then I get the rest of the package by adding LOOP, which offers a substantial operating efficiency for building loops in the Screen Basic based on ROM Basic keywords.

What's not totally clear for me is the implementation of the new BASIC commands: Will they be implemented as a direct extension to BASIC V2 or will they be implemented as sort of macros for an extended editor? Or are we talking about both here without a clear distinction between them?
In my proposal (which is now submitted to GitHub), I am explicitly talking about the direct extension to Basic V2 that is currently taking place. In my discussion, when I am referring to the "macros for the extended editor", that is what I call Screen Editor Basic.
 
  • Like
Reactions: Schlowski

BruceMcF

Active Member
May 19, 2019
100
30
28
I'll also note that DO/LOOP might be doable as an "anonymous variable" extension to FOR/NEXT, since NEXT already supports omitting the variable, so it would be a hack of FOR where it created an entry with a null variable when the variable and "TO" part was left out ... but I'm inclined against that, because the error for a poorly formed FOR/NEXT when you INTENDED it to have a variable and TO part would be lost in the wash.
 
May 22, 2019
409
211
43
Interestingly enough... Python interpreters DO support the use of immediate mode subroutines. ("Immediate" mode is the term you mean when you say "direct.")

When you create a subroutine or function in immediate mode, the Python interpreter stores that subroutine as an object in memory. If that subroutine gets defined again, the new definition replaces the old one.

NodeMCU works the same way with Lua. Subroutines can be entered in immediate mode by simply entering the text of the subroutine, and when the END keyword is parsed, the object is created and added to the relevant table.
 
  • Like
Reactions: BruceMcF

BruceMcF

Active Member
May 19, 2019
100
30
28
Interestingly enough... Python interpreters DO support the use of immediate mode subroutines. ("Immediate" mode is the term you mean when you say "direct.")

When you create a subroutine or function in immediate mode, the Python interpreter stores that subroutine as an object in memory. If that subroutine gets defined again, the new definition replaces the old one.

NodeMCU works the same way with Lua. Subroutines can be entered in immediate mode by simply entering the text of the subroutine, and when the END keyword is parsed, the object is created and added to the relevant table.
Yes ... interpreted languages designed in an environment of much more memory than was assumed when Basic was first designed can (and it seems do) design their direct mode to be more sophisticated than a language designed for 1960's era minicomputer timesharing.
 

Wertyloo

Member
Sep 15, 2019
62
4
8
a small input-rutin for 10 chars:
a$=""
for i=0 to 10
for j=0 to 1 step 0
get b$
if b$="" then next
if b$<>chr$(13) then a$=a$+b$ : print b$; : next i
print a$
 

BruceMcF

Active Member
May 19, 2019
100
30
28
do-loop:
for i=0 to 1 step 0
...
if ... then i=1
...
next
Except this doesn't accomplish the task of cleaning up early-terminated for/next loops in cases where the existing for/next loops do not, since you build a loop where the outer loop does clean up of an un-terminated inner loop.

IOW, you don't have DO/LEAVE/DONE, you can use this to get the equivalent of a do while or do until loop (do until being easier):

10 REM DO UNTIL K>10 ... LOOP
20 FOR I=1 TO 0 STEP 0
30 IF K>10 THEN 100
40 ...
...
90 NEXT I
100 ...

... and everytime you do you have left a mess on the stack to clean up with a single step outer loop that cleans up the abandoned "FOR I" structure:
10 REM DO UNTIL K>10 ... LOOP
20 FOR J=1 TO 1
20 FOR I=1 TO 0 STEP 0
30 IF K>10 THEN 100
40 ...
...
90 NEXT I
100 NEXT J

And that unwieldy, error prone mess is the argument for:
10 REM: DO UNTIL K>10 ... LOOP
20 DO IF K>10 THEN LEAVE
30 ...
...
90 LOOP
 
May 22, 2019
409
211
43
Just a note... QBASIC and VB uses the syntax "EXIT DO" to bail out of a loop. There is similar syntax for other loops, as well as EXIT SUB and EXIT FUNCTION. If proposing new syntax for Commander BASIC, we should probably be mindful of established patterns to make it easier for coders on other platforms to transfer their skills and knowledge.

 
Last edited:

Wertyloo

Member
Sep 15, 2019
62
4
8
Except this doesn't accomplish the task of cleaning up early-terminated...
it depends on the in-situ, or what you want to accompl. in that case
different needs,diff. solutions
i just wanted to prove, not needed to implement all other basic capabilities/tokens/commands just because they do use that command formulate to accomplish a certain task
we need to add flexibly useable ones,as we want to reserve backward compat.ty with the tokens too[we got not enough free single-byte tokens]
 

millenniumtree

New Member
Oct 2, 2019
24
16
3
Has anyone considered implementing FastBasic?

I just found it, and it looks promising.

It's a complete rewrite of ATARI basic, that actually compiles to machine code on the device. It does an intermediate tokenization as you write code, similar to how MSBasic works, but compiles to machine language as you run the program. It's supposed to take a little bit more RAM, but it's way faster and appears to have more loop constructs.

 
Last edited:

BruceMcF

Active Member
May 19, 2019
100
30
28
Just a note... QBASIC and VB uses the syntax "EXIT DO" to bail out of a loop. There is similar syntax for other loops, as well as EXIT SUB and EXIT FUNCTION. If proposing new syntax for Commander BASIC, we should probably be mindful of established patterns to make it easier for coders on other platforms to transfer their skills and knowledge.
I double checked, and it is indeed EXIT not LEAVE in Commodore V7 Basic ... LEAVE is Forth (where EXIT means something dramatically different).

No "EXIT DO" ... the V7 syntax for leaving a DO/LOOP is EXIT. So DO/EXIT/LOOP are already allocated tokens. So is ELSE ... under C7 syntax, ELSE must start a STATEMENT in a line, so it is IF cond THEN action1 : ELSE action2. The only new token would be DONE, which deliberately AVOIDS being BEGIN/BEND to avoid requiring the upgrading the ROM Basic IF/THEN to handle BEGIN/BEND blocks, and to re-use EXIT for single run blocks wrapping FOR/NEXT loops, in addition to being the EXIT from DO/LOOP.
~~~~~~~~~~~~~~~~~~~~~

it depends on the in-situ, or what you want to accompl. in that case
different needs, diff. solutions

i just wanted to prove, not needed to implement all other basic capabilities/tokens/commands just because they do use that command formulate to accomplish a certain task
Yes, they CAN be used as part of the hidden scaffolding behind the scenes for Screen Editor Basic ... at the cost of using two FOR/NEXT stack structure entries and requiring a minimum of two hidden variables whose names cannot conflict with any of the variables actually used in the code (because anonymous NEXT does not clean up the stack and an inner loop cannot reuse the outer loop variable since it cleans up the stack on encountering the same variable in a For/Next stack structure) and a lot of hidden scaffolding, it can be done.

It doesn't qualify as "basic" in any sense of the word, of course, so one would very much NOT want to teach it to beginners as "this is how's its done" ... and one wants to be able to teach beginners how to write structured code when they want to.

And doing it explicitly it excessively complicated and prone to error.

That's what I mean by examination of how the stack is cleaned up in general is rather an argument in favor of DO/EXIT/LOOP/DONE than an argument against it.

We need to add flexibly useable ones,as we want to reserve backward compat.ty with the tokens too[we got not enough free single-byte tokens]
We don't have a single free single-byte token, if that is what you mean by "not-enough". As already noted above, we are up to $FD, $FE is already the prefix token for two-byte tokens, and, IIRC, $FF is a special value. So we are already more than a quarter of the way into the $FE+$xx tokens.

However, DO and LOOP already have tokens, since they are part of V7 Basic, and as TomXP411 reminds me (I did a lot less V7 Basic programming than V2, since I fried my C12D and so had a C64 both before AND after I had a C128) ... the V7 name for "LEAVE" is "EXIT", so that has a token already allocated too. And of course, ELSE has a token allocated.

ELSE/DO/EXIT/DONE/LOOP ARE flexibly useful tokens, and at the cost of only one new token. so if we need to support "flexibly useful tokens", there's your ticket.
 
Last edited:

BruceMcF

Active Member
May 19, 2019
100
30
28
$FF is PI (the symbol)
As a token, and not just as a PETSCII or screencode? If pi can be used as a constant in Basic that would make sense.

Before they use up all of the two-tier tokens, they ought to reserve $FE $FF $xx as the token for a literal constant +127/-128.
 

Schlowski

Member
Sep 24, 2019
45
22
8
As a token, and not just as a PETSCII or screencode? If pi can be used as a constant in Basic that would make sense.

Before they use up all of the two-tier tokens, they ought to reserve $FE $FF $xx as the token for a literal constant +127/-128.
Yes as a token. The pi symbol is always tokenized to $FF in BASIC program code, regardless if it's used as constant or in a string. And of course you can use pi as as constant like in A=pi where pi is the PETSCII symbol.
 

mobluse

New Member
Sep 20, 2019
21
8
3
...
It outputs this:

10 PRINT "HELLO"
20 GOSUB 40
30 END
40 REM WORLD
50 PRINT "WORLD!"
60 RETURN


Make it executable, run it with:
./autonum.sh hello.bas

Then copy the output it gives you and paste it into the emulator, or just let it start the emu for you.
...
One should also have a program that strips out the line numbers and puts in labels such as L40 at the right place if there is e.g. a GOSUB 40 in the program. That way one could edit old programs in a modern way.
 
May 22, 2019
409
211
43
One should also have a program that strips out the line numbers and puts in labels such as L40 at the right place if there is e.g. a GOSUB 40 in the program. That way one could edit old programs in a modern way.
The Commander team is already working on an official editor that will be shipped as part of the system ROM; I'm not 100% sure it will de-number BASIC code, but that seems like a likely feature for importing legacy programs.
 
May 22, 2019
409
211
43
No "EXIT DO" ... the V7 syntax for leaving a DO/LOOP is EXIT. So DO/EXIT/LOOP are already allocated tokens. So is ELSE ... under C7 syntax, ELSE must start a STATEMENT in a line, so it is IF cond THEN action1 : ELSE action2. The only new token would be DONE, which deliberately AVOIDS being BEGIN/BEND to avoid requiring the upgrading the ROM Basic IF/THEN to handle BEGIN/BEND blocks, and to re-use EXIT for single run blocks wrapping FOR/NEXT loops, in addition to being the EXIT from DO/LOOP.
The problem is that multiple types of structured code blocks are being proposed. When you have IF blocks, FOR loops, DO/WHILE loops, SUBs, and FUNCTIONs all need a distinct exit command. (FOR loops should also have a CONTINUE command that will short-circuit the remainder of the body for that iteration.)

EXIT FOR doesn't need to be a single token - the tokens for EXIT and FOR can be combined; the same goes with the other EXIT commands. But we do need to specify which type of block is being exited, so the stack can be unspooled properly.
 

mobluse

New Member
Sep 20, 2019
21
8
3
Because I haven't written BASIC since the 90s, and primarily work with modern languages for work, line numbers and GOTOs kinda make my brain hurt.

So I wrote a small bash script (attached) to take a BASIC script with no line numbers, and auto-generate them!
The script uses bash, awk, sed, and egrep - tools that should be on every linux machine.
It also uses labels to simplify your GOSUBs, and eats extra whitespace so you can break up your code visually.
...
Make it executable, run it with:
./autonum.sh hello.bas

Then copy the output it gives you and paste it into the emulator, or just let it start the emu for you.

If this can already be done a different way, let me know, but I had fun writing it. Now I'm going to write some silly BASIC programs without line-number-induced eye-bleed!
autonum.sh does not work with ON GOTO and ON GOSUB: https://www.c64-wiki.com/wiki/ON

I tried to make a program that translates in reverse, i.e. it goes from a program with line numbers to a program with labels and no line numbers.

./rmnum.sh baseconv.bas

One can use your autonum.sh to convert it back, and I include an example of that: baseconv.bas.non.num. I tried to convert balls.bas back and forth, but that didn't work completely, but I couldn't see what's wrong with it, but it didn't seem like the labels were wrong. rmnum.sh is short for remove line numbers. My program should handle ON GOTO/GOSUB. It's a shell script tested in Linux, but it may work in macOS and Windows 10 (if you install e.g. Ubuntu from Store). It does probably not handle unusual cases, e.g. BASIC in strings etc. It could probably be much optimized.
 

Attachments

Last edited:
  • Like
Reactions: millenniumtree