LOCAL with no parameters

Soruk
edited April 2023 in General BBC BASIC
I've come across a program that has a procedure with a LOCAL statement with no parameters.

From what I can discern, with Acorn's BASICs on everything from BASIC 1 on the BBC B all the way through to the latest BASIC V and VI on RISC OS, and also BASIC IV for 32016, this is a no-op, it seems to be doing nothing.

Richard's BASICs report "Syntax error", having briefly tested the Z80 BASIC ROM image, the Master 512 (80186) version and the latest BBC BASIC for Console under Linux.

As of commit 1FA2F48 and earlier, Matrix Brandy also reports "Syntax error", arguably this (edit: LOCAL with no parameters) is a mistake, after all why would you declare a LOCAL statement with no parameters? However, in keeping with my aim that Matrix Brandy is a superset of Acorn's BASIC and should be able to run a program that runs on Acorn, I am inclined to make it also a no-op.

Thoughts and comments?

Comments

  • Having thought about this some more, and chatting with some of the folks at last weekends ABUG meet, the correct path for Matrix Brandy is to follow Acorn's behaviour. While arguably LOCAL all by itself is very unlikely to be intentional, if it doesn't trip up Acorn's BASICs then it shouldn't trip up Matrix Brandy either. I've gone a couple of steps further - it's implemented so if the interpreter is running in strict mode (not compiled with -DDEFAULT_IGNORE or -strict passed at the command line) then it will generate "Syntax error", and this strict operation can also be switched on and off at run-time via a new SYS call - SYS "Brandy_Strict", x where X is 1 to enable, or 0 to disable.
  • [Richard Russell]
    edited May 2023
    I think my take on this would be: what is the general behaviour with empty comma-separated lists in BBC BASIC? If VDU can accept an empty list, and assigning values to an array can accept an empty list, and PRINT# can accept an empty list, then it's reasonable to argue that LOCAL should behave the same way for reasons of consistency:
    VDU
    a() =
    PRINT #F%
    LOCAL
    
    But if LOCAL is anomalous in this regard it's probably a bug in Acorn's BASICs, and therefore shouldn't be slavishly followed in other versions. If you go down the route of saying that Brandy (or any other implementation) should copy bugs that's a very slippery slope!

    Incidentally I consider NEXT and PRINT as special cases because although they can take a comma-separated list the 'empty list' case actually does something specific (terminating the most recent FOR and outputting a newline respectively) so shouldn't be treated the same as other empty lists which (if they are accepted at all) mean 'do nothing'.

    If you do think Matrix Brandy should accept LOCAL with no parameters, then in my view it's essential that it also accepts an empty list in all the other cases, otherwise there would be an indefensible inconsistency.
  • [Richard Russell]
    edited May 2023
    Further to my previous comment, in the absence of a formal specification for BBC BASIC it is instructive to compare the various informal, but published, syntax descriptions available:

    BBC Micro User Guide:
    LOCAL <string-var>|<num-var> {,<string-var>|<num-var>}

    BBC BASIC for MS-DOS manual:
    LOCAL <n-var>|<s-var>{,<n-var>|<s-var>}

    BBC BASIC for Windows/SDL 2.0 manuals:
    LOCAL <n-var>|<s-var>|<array()>{,<n-var>|<s-var>|<array()>}

    RISC OS BBC BASIC Reference Manual:
    LOCAL [variable] [,variable...]

    In the BBC Micro and 'Russell' manuals an empty list is not compliant with the syntax description, since both state that at least one variable must be supplied.

    The RISC OS manual implies that an empty list is compliant, because the first parameter is included in square brackets. But based on the earlier documents I would speculate that this has been retrospectively altered in an attempt to 'document away' a bug!

    So that would suggest to me that LOCAL ought not to accept an empty list.

    Obviously I have an axe to grind, but any suggestion that Acorn's BASICs have precedence over others in providing a 'reference' implementation of BBC BASIC is something I would vehemently disagree with, and it fails to respect the rôle of the British Broadcasting Corporation in being the custodian and ultimate arbiter of what is and isn't BBC BASIC.

    Edit:
    Incidentally the syntax description in the RISC OS manual implies that LOCAL ,variable (note the comma) is permitted, I doubt that it is.
  • RISC OS does not permit LOCAL ,variable.

    I totally get your point and agree with you about Acorn's BASICs. Though it is strange when they ported their implementation to the NS32016 (for the Cambridge Scientific) and later ARM, they replicated this bug.

    It is a tricky one, when I'm trying to make something source-compatible (as in BASIC source, not 6502/ARM!) aside from embedded assembler, if a program runs correctly on the BBC an Archimedes but fails on Matrix Brandy, then in a sense I have failed in that objective. But LOCAL with no parameters is arguably a bug in the program, which is why I've connected it with the STRICT flag (internally, run_flags.flag_cosmetic) that is normally used to generate an error on unsupported operations that could otherwise be relatively safely ignored (such as some VDU codes and audio bits and pieces in the text-mode interpreters.
  • [Richard Russell]
    edited May 2023
    Soruk wrote: »
    Though it is strange when they ported their implementation to the NS32016 (for the Cambridge Scientific) and later ARM, they replicated this bug.
    It's not at all strange! :smile:

    It's highly unlikely that each of those versions was written from scratch, using the specification (such as it is) as the starting point. If my experience is any guide anyway, the 32016 version will have been created by translating the 6502 assembly language code, and the ARM version by translating either the 6502 or 32016 assembly-language source code.

    So any bugs/features in the earlier version(s) will naturally have been transferred directly into the later versions as a result of that translation process, quite possibly without any awareness that the bugs were present in the first place.
    It is a tricky one, when I'm trying to make something source-compatible
    I thought Matrix Brandy was supposed to be an implementation of the BBC BASIC Programming Language (as was Brandy before it), not an emulation of a particular earlier version such as Acorn's or mine.

    There are features of Brandy which were clearly not designed to achieve source-code compatibility with other versions, such as the ON ERROR LOCAL behaviour, which is different from either Acorn's or my BASICs, and the major difference in the in-memory representation of the program and its data, making it incompatible with self-modifying code or direct heap access.
    if a program runs correctly on the BBC an Archimedes but fails on Matrix Brandy, then in a sense I have failed in that objective.
    I have never pretended that my BASICs (not even the Z80 version) were designed to be source-compatible with anything else, they definitely weren't (and aren't). Rather they were designed to be compatible with the published BBC BASIC specification, such as it existed and wasn't ambiguous.