Page 1 of 3

Odd behavour

Posted: Sat Feb 03, 2018 4:10 pm
by Martin_Head
I have been trying to get an old Basic program to run in QPC2. And I came across a problem.

This is a simplified version of the the piece of code I was debugging, to show the effect.

Code: Select all

100 DIM a(5)
110 one
1000 DEFine PROCedure one
1010 LOCal x
1020 x=2
1030 a(x)=100
1040 PRINT a
1045 PRINT
1050 a(x)=two
1060 PRINT a
1070 END DEFine one
1080 DEFine FuNction two
1090 x=x+1
1100 RETurn 200
1110 END DEFine two
The desired result, is array element 2 ends up as 200

In QDOS this happens, but in SMSQ/E, element 3 gets set to 200

I can program around the problem. But is this a bug in QDOS that got fixed in SMSQ/E, or is it a bug in SMSQ/E?

Re: Odd behavour

Posted: Sat Feb 03, 2018 5:31 pm
by Pr0f
x is not defined as local in function two

Re: Odd behavour

Posted: Sat Feb 03, 2018 8:10 pm
by pjw
Martin_Head wrote:<> in SMSQ/E, element 3 gets set to 200
This is the correct result. QDOS is simply mistaken ;)

Re: Odd behavour

Posted: Sat Feb 03, 2018 8:40 pm
by pjw
Pr0f wrote:x is not defined as local in function two
x here is one's local x. If two were called from another procedure that defined x as local,
it would act on that procedure's version of x, as in:

Code: Select all

dim a(3)
one: x=x+1: print a, x\
another:    print a, x\
:
def proc one
rem GLOBal x
  x=1: a(x)=1
  two: a(x)=2
three: a(x)=3
enddef one
:
def proc another
loc x
  x=1: a(x)=1
  two: a(x)=2
three: a(x)=3
enddef another
:
def proc   two: x = x + 1
def proc three: x = x + 1

Re: Odd behavour

Posted: Sat Feb 03, 2018 9:23 pm
by Pr0f
According to Qdos keywords manual:

LOCal allows identifiers to be defined to be LOCal to a function or procedure. Local identifiers only exist
within the function or procedure in which they are defined, or in procedures and functions called from the
function or procedure in which they are defined. They are lost when the function or procedure
terminates. Local identifiers are independent of similarly named identifiers outside the defining function
or procedure. Arrays can be defined to be local by dimensioning them within the LOCal statement.

so then x would be local in scope for both procedure one in which it is defined local, and also procedure two

Hence x=x+1 in procedure two would operate on the local x in procedure one

Re: Odd behavour

Posted: Sat Feb 03, 2018 9:24 pm
by Pr0f
which ROM is that you are using for QDOS?

Re: Odd behavour

Posted: Sat Feb 03, 2018 11:23 pm
by pjw
Pr0f wrote:which ROM is that you are using for QDOS?
The behaviour of Martin's sample is distinctly odd! Behaves the same in JS and Minerva 1.98
Try:

Code: Select all

1047 b = two
1050 a(x)=b
then you get the 'correct' result.
The example I gave works identically in SMSQ/E, JS and Minerva (provided you add enddef to
procs one and two). Ie it conforms to the statement Pr0f gave of the scope of locals, which
Martin's sample appears not to do.

Re: Odd behavour

Posted: Sun Feb 04, 2018 1:04 am
by janbredenbeek
What happens here is that calling function 'two' has a side effect of incrementing x by one.
In QDOS, a(x) is evaluated first as the variable to be set (when x = 2), and then 'two' is called which returns 200 and increments x to 3, but the result is stored in a(2) because x was 2 at the start of the assignment.
In SMSQ/E however, a(x) appears to be evaluated after calling 'two' so this evaluates to a(3), which is then assigned the result of the function.
I'm not sure which one is 'correct' according to the definition of S*BASIC. It might as well be that this behaviour was never anticipated so both could be right (or wrong)!

Jan.

Re: Odd behavour

Posted: Sun Feb 04, 2018 9:23 am
by pjw
janbredenbeek wrote:What happens here is that calling function 'two' has a side effect of incrementing x by one.
In QDOS, a(x) is evaluated first as the variable to be set (when x = 2), and then 'two' is called which returns 200 and increments x to 3, but the result is stored in a(2) because x was 2 at the start of the assignment.
In SMSQ/E however, a(x) appears to be evaluated after calling 'two' so this evaluates to a(3), which is then assigned the result of the function.
Yes, that seems to explain the logic.
I'm not sure which one is 'correct' according to the definition of S*BASIC. It might as well be that this behaviour was never anticipated so both could be right (or wrong)!
The fact that it was changed under SMSQ/E to something that seems more 'correct' to me, is all the confirmation I need ;)

Re: Odd behavour

Posted: Sun Feb 04, 2018 10:10 am
by stevepoole
Hi,
If I remember correctly, the QDOS 'expression evaluator' evaluates a statement from left to right, (except where parentheseses override priority).
So the QDOS evaluation is correct ?
As for SMSQ/E, I cannot remember reading about expression evaluation priorities at all... or any changes to them.
So it looks like SMSQ/E got it wrong...
To make matters more compatible, x as a parameter to 'two' would be automatically local, and help get rid of the bug !
Thanks very much for reportig this awkward bug.
Steve.