Indeed. As I'm sure you are aware, in order for 'forward references' to work (i.e. referencing a procedure or function before it is declared) BBC BASIC scans the entire program looking for DEF lines, so it can build a table of their names and pointers. You are confusing this process by using the 'indirect function call' syntax (i.e. PROC or FN followed by an expression in parentheses); BASIC dutifully attempts to evaluate the expression (in this case XXX) and finds that there is no variable with that name!When I ran the program, I encountered "No such variable at line xxx".
...
I was surprised to discover I had misnamed the temporary function DEFFN(XXX) and this supposedly innocuous line halfway down the program generated the error.
Re: No such variable.
Re: No such variable.
On 24/09/2023 17:28, The Famous Cash via groups.io wrote (cross-posted from the Discussion Group):
Re: No such variable.
In an ideal world, if this process results in an error, such as 'No such variable', the associated line number (ERL) would refer to the erroneous DEF line; this would immediately draw attention to the source of the error. Unfortunately in practice it reports the number of the line which triggered the 'DEF scan', which isn't helpful.Hated Moron wrote: ↑Sun 24 Sep 2023, 18:31 As I'm sure you are aware, in order for 'forward references' to work (i.e. referencing a procedure or function before it is declared) BBC BASIC scans the entire program looking for DEF lines, so it can build a table of their names and pointers.
Since the earliest days of BBC BASIC, there has been some doubt over whether an error occurring in a function or procedure call should be reported as being in the calling line or the called line; the interpreter cannot always determine which would be most helpful. I think my BASICs behave differently from Sophie's BASICs in this respect.
Clearly in the context of this thread the current behaviour is non-optimum, but since all three of my implementations (BBC BASIC for Windows, the BBC BASIC for SDL 2.0 assembly-language interpreter and the BBC BASIC for SDL 2.0 C interpreter) would need to be changed to alter this, I don't intend to do so. The OP was exceptionally unlucky to encounter it.
Re: No such variable.
On 24/09/2023 23:55, Bob Cash wrote (cross-posted from the Discussion Group):
It's perhaps worthy of note that C doesn't do this automatically. You must either write C code to avoid forward-references altogether (i.e. ensure subroutines are listed in the program before they are called) or include explicit forward-declarations so that the compiler knows what 'signature' the function has. Of course forward references don't cause an issue at run-time because the linker takes care of that.
I'm pretty sure that when I added that feature this possible side-effect never occurred to me. I'm tempted to modify the C version of the interpreter (only) so that ERL is set to the DEF line, I can do that quite easily. It wouldn't help you, because you're using the assembler (32-bit x86) version, but it would avoid the more confusing consequences moving forward.
As a long-standing BBC BASIC programmer I'm sure you will have come across the issue of forward-references in one context: assembly-language code! You''ll be familiar with the need for (at least) two-passes of the assembler to resolve forward-references to labels, and the use of OPT to control this. Forward-references in BASIC code are fundamentally no different, except that the 'look ahead' is done for you automatically.Many thanks for your explanation.
I was just puzzled as I do not know about forward referencing and never encountered this error over many years.
It's perhaps worthy of note that C doesn't do this automatically. You must either write C code to avoid forward-references altogether (i.e. ensure subroutines are listed in the program before they are called) or include explicit forward-declarations so that the compiler knows what 'signature' the function has. Of course forward references don't cause an issue at run-time because the linker takes care of that.
But presumably in every case putting an open-parenthesis immediately after the PROC or FN? Normally, the DEF scan doesn't trigger an expression evaluation (nor should it) therefore none of the errors associated with evaluation, such as 'No such variable', will occur. But by including that parenthesis you activated the 'indirect call' mechanism (one of my extensions) and hence the evaluation.It was just interesting. In experimenting, I discovered different error messages could be generated, depending on the type of corrupt variation I could think of.
I'm pretty sure that when I added that feature this possible side-effect never occurred to me. I'm tempted to modify the C version of the interpreter (only) so that ERL is set to the DEF line, I can do that quite easily. It wouldn't help you, because you're using the assembler (32-bit x86) version, but it would avoid the more confusing consequences moving forward.
Re: No such variable.
On 25/09/2023 13:52, The Famous Cash via groups.io wrote (cross-posted from the Discussion Group):
Valid DEFs just don't look like that, indeed I don't think it's ever legitimate to have a parenthesis immediately following FN or PROC in the definition, only when one is called.
The thing is, of course, that it's features like these that distinguish BBC BASIC from the scores of other perfectly functional and competent BASIC interpreters. If you never use them, BBC BASIC doesn't really offer any advantages.I never understood assembly or got my head round any aspect of machine code. SYS calls and the like are used without any real clue about what I’m doing!
What you haven't explained is why the open parenthesis, after the FN, is there. In standard BBC BASIC, FN or PROC is never immediately followed by a parenthesis, that's specifically why I chose that syntax for indirect function and procedure calls. So as a 'placeholder' that's a rather surprising usage; had you used say DEF FNxxx or DEF PROCxxx like a conventional definition the issue wouldn't have arisen.to avoid being distracted from loads of things in my mind, hastily typed a temporary DEFFN( in a space where I was working just as a reminder to code later.
But the key point is that every one has that pesky open-parenthesis, causing it to call the expression evaluator! Those are just the expected errors resulting from attempting to evaluate a pointer expression.DEFFN( and DEFFN() produce syntax error.
DEFFN(X) produces no such variable error.
DEFFN(“X”) produces type mismatch error.
DEFFB(9) and DEFFN(X%) produce address out of range error.
Valid DEFs just don't look like that, indeed I don't think it's ever legitimate to have a parenthesis immediately following FN or PROC in the definition, only when one is called.
And here I am desperately trying to stop people using BB4W because it's obsolescent! Twenty-two years old, almost to the day, and long overdue for being put out to grass.the truth is I was ecstatic when I stumbled across BB4W...