prgmA
Code:
1→A
Repeat L₃(A
DS<(A,1
End

prgmB

Code:
3→A
While A
Disp A
Repeat L₃(A
DS<(A,1
End
End

prgmC

Code:
For(A,1,3
3→A
Repeat L₃(A
IS>(A,dim(L₃
End
End

prgmD

Code:
If 3-2=1
Then
3→A
Repeat L₃(A
IS>(A,dim(L₃
End
End

prgmE

Code:
If 3-2=1
Then
3→A
For(X,1,5)
IS>(A,dim(L₃
End
End

Let

Code:
{1,2,1→L₃

prgmA and prgmE execute as expected, skipping the End instruction in the loop, but prgmB, prgmC, and prgmD all fail on the line

Code:
Repeat L₃(A

due to ERR: INVALID DIMENSION. What’s up with this, and is it intentional?
TI-BASIC has an entire category of bugs that involve skipping End statements. This is the same issue as the Goto memory leak, e.g. this code snippet which prints 1 and then 0:
Code:
For(A,1,10
Disp A
If 1
Then
Goto L
End
Lbl L
End
Disp 0


The particular issue you've found doesn't need IS>(/DS<( specifically - you can also do the same thing with a Thenless If statement, as in this example which prints 1, 3, then 4:

Code:
For(A,1,2
Disp A
For(B,3,4
Disp B
If 0
End
End


The TI-BASIC interpreter doesn't preprocess End blocks. Instead, it keeps track of the blocks that it's currently inside of on a stack. Running a control flow block start command like Repeat that doesn't result in its block being skipped will push an entry onto the stack containing the location of that command. Running an End command will pop an entry off of the stack, and if necessary move control flow back to that location.

This algorithm works fine, assuming that control flow can never enter a block without first executing its start command or leave a block without first executing its End. Of course, Goto violates both of these by allowing you to jump around the program however you want. But If, IS>(, and DS<( can skip over a single line, which also allows you to enter or exit a block without executing the start command or End.

Here's an example that skips into a block, rather than out of it. It prints out exactly one line. Note that there's an End "missing," as having an extra End gives an error, unlike having too few.

Code:
If 1
Then
If 0
While 1
Disp 0
End


As for whether this is intentional, I would imagine it probably originally wasn't. Today, it may or may not be left in intentionally to avoid breaking programs that rely on it. I have to assume there are some programs using this on purpose, as there's a relatively well-known example on TI-BASIC Developer that uses it to implement subroutines:

Code:
For(A,0,1
If not(A:Goto A
End
 // main program code
Stop
Lbl A
 // subprogram code
End



To go on a bit of a tangent because I don't believe this is really documented elsewhere, there's a similar issue that can occur for blocks that are skipped rather than taken.
When an entire block needs to be skipped (in the case of an If/Then statement whose condition is false, for example), it goes through the program line by line without executing it, looking at the first token on each line and keeping track of the number of block start commands and the number of End commands. Once the number of starts equals the number of Ends, it's reached the end of the block, and can start executing code as normal again.
But DelVar has a quirk where you can put another command right after the variable name without starting a new line and it will run it without throwing an error. Since this command isn't technically on a new line, the block-skipping code ignores it, which lets you have block start commands or End that get executed but not properly skipped.

For example, this program displays 1,2,3,0 if A is 0, but prints nothing if A≥3:

Code:
While A<3
A+1->A
Disp A
DelVar BEnd
Disp 0


In general, the parser gets weirder the more you poke at it - there's also plenty of weird stuff with Lbl (in `"A":Lbl B`, B doesn't work as a label! Fun!), and kg583 has also documented For('s many quirks.

See also: "Memory Leaks" are a Feature, Actually
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement