When we added SUB and FUNCTION to BASIC, and the compiler remained a single pass, which meant a SUB had to be defined before its use. The issue comes up, where does your program start. We adopted the C convention of using MAIN: Some other BASICs use that as well or we could have made it START:
BASICtools allows compiling files (normal method as your program gets bigger) as well as being able to type in short programs to test something. The later I find to be very useful for quick debugging.
The compiler looks for unreachable code, which is code that will not be executed because it precedes a SUB or FUNCTION. But that is an issue when you type in a short program such as...
print "hello world"
Obviously the code here starts at the beginning, but the compiler has difficulty knowing that, as it can't see ahead. So to get around that when you type in a program what really gets compiled is
User__Typing: print "hello world"
This makes the compiler happy as BASICtools inserts that label which makes it possible to be executed in all cases even if it is followed by a SUB, FUNCTION or MAIN: But it is what I call cheap magic being done for you by BASICtools. The problem with cheap magic, is unless you document it, the user doesn't get to understand the why (until now).
When compiling a file, code such as
SUB dosomething '... END SUB print "hello world"
Causes the compiler issues, as it is an attempt to inline execute a SUB which when it would return, would go to never never land. (a technical term). The compiler does not flag it that way, but does flag the print statement as unreachable code. This would be OK, with a MAIN: inserted before the print statement.
The issue is when you type a program in, the compiler looks at each line of code as it is typed in, flagging errors immediately. The BASICtools ignores any #include, as those are handled during a file compile.
I recently sent a user a small set of code to test an i2c interface. I typed this in line by line to check syntax
#define I2Cspeed50 #include <I2C.bas> DIM LCD_CMD(8) DIM LCD_DATA(16) LCD_CMD(0) = 254 LCD_CMD(1) = 54 ' get the version number print I2CIN(10,11,80,2,LCD_CMD,1,LCD_DATA) ' if this does not show 1, then the display is not responding print LCD_DATA(0) ' unless the previous number is 1, then this is meaningless
The user copied it into a file and that caused errors as there was no MAIN: which the compiler flagged. Now I should have assumed that and added the MAIN: , but sometimes I'm too close to the compiler and BASICtools and don't think about that.
As I2C.bas includes a number of subroutines that unreachable code error becomes an issue. I've thought about ways to get around that, but never followed through. Now though I think I will start inserting some code into all the .bas libraries that include SUBs.
GOTO I2C_SKIP ' ... all the other include code I2C_SKIP: print "**WARNING** you need a MAIN:"
So if you don't have a MAIN: in your code, you will see that warning printed before any of your other print statements executed. And if you do have a MAIN: then no warning.