Re: No such variable.

Discussions related to the BB4W & BBCSDL interpreters and run-time engines
Hated Moron

Re: No such variable.

Post by Hated Moron »

On 24/09/2023 17:28, The Famous Cash via groups.io wrote (cross-posted from the Discussion Group):
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.
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!
Hated Moron

Re: No such variable.

Post by Hated Moron »

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.
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.

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.
Hated Moron

Re: No such variable.

Post by Hated Moron »

On 24/09/2023 23:55, Bob Cash wrote (cross-posted from the Discussion Group):
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.
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.

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.
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.
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.

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.
Hated Moron

Re: No such variable.

Post by Hated Moron »

On 25/09/2023 13:52, The Famous Cash via groups.io wrote (cross-posted from the Discussion Group):
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!
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.
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.
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.
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.
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.

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 truth is I was ecstatic when I stumbled across BB4W...
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.