Conflict with integer variables inside IF statement

This is where most of us started. Classic Spectrum basic.

Moderator: Programming Moderators

User avatar
Protocultor
Posts: 21
Joined: Tue May 30, 2017 12:54 am

Conflict with integer variables inside IF statement

Postby Protocultor » Mon Jul 27, 2020 4:41 pm

Hello guys, there is something strange (for me) in the way IF + AND conditions work when including an integer variable. Watch the following proof of concept:

Code: Select all

#program IF_AND
  10 REM "IF/AND" PoC
  20 REM "vars" which exist just to test the checking
  30 LET a=0: LET %b=0
  40 REM simple counter
  50 LET %c=0
  60 REPEAT 
  70 REM Float var & INKEY check
  80 IF a=0 AND INKEY$ =" " THEN PROC space()
  90 REPEAT UNTIL %c=10
 100 PRINT ' 
 110 REPEAT 
 120 REM Integer var & IN check
 130 IF %b=0 AND ( IN 32766&1=0) THEN PROC space()
 140 REPEAT UNTIL %c=20
 150 PRINT '
 160 REPEAT 
 170 REM The following will not work, integer var & INKEY check
 180 REM IF %b=0 AND ( INKEY$ =" ") THEN PROC space()
 190 REPEAT UNTIL %c=30
 200 STOP 
 210 DEFPROC space()
 220 PRINT "Space! ";
 230 LET %c=%c+1
 240 PAUSE 8
 250 ENDPROC 
As you can tell, it only prints "space" every time the user presses it, up to 10 times. It checks it in three different ways, shown in lines 80, 130 and 180. But the last one, in 180, is just not accepted by the editor parser; try to remove the REM and make it work.

I suppose the rejection of INKEY$ means every condition joined by AND/OR has to be an integer expression when you have an integer variable involved in one of them. Fortunately in this case, IN can be used for the same purpose but, is it supposed to always be this way? Is there a workaround? Any help is appreciated.

User avatar
SevenFFF
Posts: 565
Joined: Mon Jun 05, 2017 5:30 pm
Location: USA

Re: Conflict with integer variables inside IF statement

Postby SevenFFF » Mon Jul 27, 2020 4:49 pm

You can use SGN {..} to embed a floating point expression inside an integer expression, and INT {..} to embed an integer expression inside a floating point expression.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins

User avatar
Protocultor
Posts: 21
Joined: Tue May 30, 2017 12:54 am

Re: Conflict with integer variables inside IF statement

Postby Protocultor » Mon Jul 27, 2020 5:51 pm

SevenFFF wrote:
Mon Jul 27, 2020 4:49 pm
You can use SGN {..} to embed a floating point expression inside an integer expression, and INT {..} to embed an integer expression inside a floating point expression.
Duh! I remember having read that in the manual, but I insisted in using (..) instead of {..}
The following solves it:

Code: Select all

 180 IF %b=0 AND INT { INKEY$ =" "} THEN PROC space()
Many thanks... again!

User avatar
Protocultor
Posts: 21
Joined: Tue May 30, 2017 12:54 am

Re: Conflict with integer variables inside IF statement

Postby Protocultor » Tue Jul 28, 2020 1:14 pm

If someone else is having issues, the following is an explanation of everything integers my silly head could understand:
https://www.facebook.com/groups/ZXNextB ... 774152963/
"Integer Land" will be the official name of the feature for me now.

smurphboy
Posts: 20
Joined: Wed May 06, 2020 7:06 pm

Re: Conflict with integer variables inside IF statement

Postby smurphboy » Tue Jul 28, 2020 2:34 pm

It's a post in a private Facebook group. Is it possible to post the information here as well - for those of us who don't Facebook?

User avatar
Protocultor
Posts: 21
Joined: Tue May 30, 2017 12:54 am

Re: Conflict with integer variables inside IF statement

Postby Protocultor » Tue Jul 28, 2020 3:26 pm

Oh, I didn't realize it was private. Verbatim copy:
People are still struggling with integer expressions. So I think I will echo here what I just mentioned on another post.

Rule 1
As soon as you use % at the beginning of an expression, EVERYTHING after it in the same expression is in, what I call, integer land. This means that any variables have an implied % before them.

Rule 2
Usual operator precedence rules do not work. There is no operator precedence. This means that * is the same priority as +. For example, "4+7*6" would be 46 usually, but "%4+7*6" will be 66 in integer land. The fix is to use parentheses: "%4+(7*6)"

Rule 3
To use normal variables in an integer expression, you can use INT{}. For example, to use n in and integer expression and not %n, you should use "int {n}"

Rule 4
To use a integer expression in a normal expression, you should assign the integer expression to a normal variable. For example: "LET n=%n".

I hope that helps people going forward.
I'm adding a couple of interesting comments to the same post:
Q: why using % breaks operator (+-/*) priority? it is confusing. is there any plan to fix it in the future?
A: It's because integer-land is it's own sub-language. It's not integrated completely into BASIC for technical reasons (mainly due to maintaining compatibility and amount of room in the ROM). This sub-language doesn't have the concept of operator precedence. This is because there's a lot less code when you drop that feature. And since there was a lack of space in the ROM to add integers, this had to be dropped.
So really do get the mindset that when you're using %, you're stepping out of BASIC and into a new integer-based expression language.
Can I add, if anything might be negative, you must enclose it in SGN{}. This effectively uses the MSB is a negative indicator (2s compliment), so the range is from -32768 to +32767. Without it, numbers wrap around from 0 to 65536.
e.g.
IF % SGN{n<0} THEN...

smurphboy
Posts: 20
Joined: Wed May 06, 2020 7:06 pm

Re: Conflict with integer variables inside IF statement

Postby smurphboy » Tue Jul 28, 2020 3:51 pm

That is really useful - thanks for sharing it here.


Who is online

Users browsing this forum: No registered users and 2 guests