rfobasic.freeforums.org
http://rfobasic.freeforums.org/

Conditional loops (D/U and W/R) stopping immediately
http://rfobasic.freeforums.org/conditional-loops-d-u-and-w-r-stopping-immediately-t5038.html
Page 1 of 1

Author:  ReNoob [ Mon May 01, 2017 2:56 pm ]
Post subject:  Conditional loops (D/U and W/R) stopping immediately

Hi all. I'm writing a small program to decompress a very simplistic compression scheme. In particular, the used by Infocom to compress their adventure games (if you've never heard of Infocom, ask your grandfather). Short and simple as possible: one sixteen-bit word holds three 5-bit characters. The extra bit, is always zero, except the last block, it is set to signal the final block. This program does that, with one very strange caveat:
Code:
Dim zc[48] % plenty of room in the receiving array
a$="65d378132949c545"
zp=1
DO
  x$=mid$(a$,zp,4)
  h=hex(x$):if x>32768 then lb=1
  For q=2 to 1=0 step -1
    b=BAND(h,31):h=int(h/32)
    zc[zp+q]=b
  Next q
zp+=3
Until lb=1


Pretty straightforward, right? Except the last block doesn't get processed by the F/N loop. As soon as lb is set to 1, it continues on the other side of the until. It does the same with a While/Repeat. I even tried if/goto! Here's what worked: I made the following two changes:
Code:
if x>32768 then t=1
zp+=3:lb=t


Suddenly, it worked! Any idea why these loops would just suddenly stop the second the exit condition was met, before it is supposed to be tested for?
Curiously yours,
'Noob

Author:  mougino [ Mon May 01, 2017 3:53 pm ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

I think this is a syntax error :
Code:
For q=2 to 1=0 step -1


But the reason the last block is not processed maybe is because you're using the wrong variable 'b' instead of 'lb' ?
Code:
zc[zp+q]=b

'b' is never set to 1, so it's always 0...

Nicolas

Author:  mougino [ Mon May 01, 2017 3:57 pm ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

Also, what's 'x' ??
It's never used as well, there's no way in your code it's ever > 32768 since it's always 0!

Either you're showing only half of your code, or if it's the full code, there's no way it produces the expected result.

Nicolas

Author:  ReNoob [ Tue May 02, 2017 11:20 am ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

Everybody, thank you for the feedback, and apologies for the typos. I was in quite a hurry, and more than a little frustrated. Excusing myself further, I also had to remove a lot of print statements. I was putting in tons of print variables to show what numbers where popping up where in the program. I apparently was not very careful in rendering the human-readable view. Summing up: the q is supposed to count downward to zero. the "1=" was a typo. 'b' is the five-bit block shaved off of the main 16-bit block. LB is used to signal the last block and is not set or read anywhere else. Likewise the x>32768 is supposed to be an 'h', the value of which will be greater than 2^15 on the last block. Let me try this again, with print statements put it so you may see yourselves:

Code:
zp=1:lb=0:a$="65d378132949c545"
dim zc[48]

DO
x$=mid$(a$,zp,4)
h=hex(x$)
if h>32768 then lb=1
print x$
   for q=2 to 0 step -1
    b=BAND(h,31):h=int(h/32)
    zc(zp+q]=b: print  b;" ~ ";zp+q
  next q
zp+=3
UNTIL lb=1
print "End of loop."


Typos from the original aside, any ideas?
Thanks,
'Noob

Author:  mougino [ Tue May 02, 2017 7:05 pm ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

This works:
Code:
zp=1:lb=0:a$="65d378132949c545"
DIM zc[48]

DO
x$=MID$(a$,zp,4)
h=HEX(x$)
IF h>32768 THEN lb=1
PRINT x$
FOR q=2 TO 0 STEP -1
  b=BAND(h,31):h=INT(h/32)
  zc[zp+q]=b: PRINT  b;" ~ ";zp+q
NEXT q
zp+=4
UNTIL lb=1
PRINT "End of loop."

Appart from the syntax error in your code (zc(zp+q] instead of zc[zp+q]) I fixed a mistake in zp+=3, it should be zp+=4 because you treat 4 ascii bytes per loop.

Nicolas

Author:  ReNoob [ Thu May 04, 2017 12:57 pm ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

Thanks, Nicholas for pointing out another typo. But zp is not one of them. One 16-bit block renders 3 z-codes (Hence to 2-to-0 loop to put them in the correct order). Incrementing by 4 corrects the MID$ statement, but leaves spurious zeros in the zc[] array. These cannot be overlooked, because zero is a valid z-code (it represents a blank space). The mistake was trying to use it as the index in the MID$ statement, which indeed should be incremented by 4. So I just used a different index variable for the MID$ statement, which is incremented by four.
Thanks again,
'Noob

Author:  brochi [ Sat May 06, 2017 2:39 am ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

Useing LISTs instead of ARRAYs could help here (avoiding indexing issues and therefore also (slightly) more compact/faster).

brochi


Code:
a$="65d378132949c545"

LIST.CREATE     n, zc
zp            = 1

DO
h            = HEX(MID$(a$,zp,4))
LIST.ADD       zc, BAND(h/1024,31), BAND(h/32,31), BAND(h,31)
zp          += 4
UNTIL h       > 32768

PRINT           "End of loop."

LIST.TOARRAY    zc, zc[]
FOR i         = 1  TO (zp-4)/4*3
PRINT          i, zc[i]
NEXT

Author:  mougino [ Sat May 06, 2017 3:14 am ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

Nice optimization Brochi ;)
To be complete your code needs a$="65d378132949c545" at the beginning, otherwise brilliant!

Nicolas

Author:  brochi [ Sat May 06, 2017 11:50 pm ]
Post subject:  Re: Conditional loops (D/U and W/R) stopping immediately

ouh...yes, you are right, didn't pick up the a$ while copying.
Edited it. Thanks!

brochi

Page 1 of 1 All times are UTC - 8 hours [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/