Yeah, sorry about that too. I probably should have worded it better.
I get how you feel, I write code for a living and sometimes I just realize I have to start over and it’s really disheartening
.
At some point, an *if
ladder becomes unmanageable. And once you wrap your head around loops you realize it’s actually pretty simple.
I know you didn’t ask for it, but here’s a primer on loops. I hope it can be of help.
Loops
Imagine you own a restaurant and you hire an android to perform menial tasks, and you have a stack of plates to wash in the kitchen. You want the android to start with the first plate, wash it, dry it, and put it away. Then, move on to the next plate and do the same thing. It should keep doing this until it has washed and put away all the plates. But the android doesn’t understand English or any other human language. It only understand code!
In programming, you could write an *if
statement for each plate.
*if (plate_1 = "dirty")
*gosub wash_plate 1
*if (plate_2 = "dirty")
*gosub wash_plate 2
.
.
.
But not only this makes your code verbose, it is not flexible. If the number of plates changes, you also have tweak your code.
Now imagine that instead of writing an *if
statement for each plate you could write something like as long as there are plates, wash them
. That’s a loop!
Use Case
For your use case, you want a way to extricate parts of a longer string, for example, you want the 32
in the string XPTO32FOO
. That is a 2-digits long substring starting from index 5
(1. X, 2. P, 3. T, 4. O, 5. 3...
).
So you need a subroutine that will copy character by character from the original string into a new string. This subroutine will take a string, an index and the length of the substring you want.
*label slice
*params original_string initial_index len
*return
Next, we need a control variable, let’s call i_
for “iteration”, and a temporary variable to hold the value of the substring.
*label slice
*params original_string initial_index len
*temp substring ""
*temp i_ 0
*return
Since ChoiceScript doesn’t have specific commands for loops, we’ll have to emulate it with control flow. That means we will use an *if
statement to check if the loop is not over yet and redirect to the top of the loop again. We will use the control variable i_
for that.
*comment START OF LOOP
*comment --------------
*label slice_start_loop
*if (i_ < len)
*set i_ +1
*goto slice_start_loop
*comment --------------
*comment END OF LOOP
This loop will repeat until the control variable is the same as the desired length.
Next, we add the actual code to copy the characters. We find the current index by adding the control variable to the initial index .
*label slice_start_loop
*if (i_ < len)
*temp current_index (initial_index + i_)
*set substring &(original_string # current_index)
*set i_ +1
*goto slice_start_loop
We also need to check if the current index is not greater than the total length of the original string. For that we move the line where we create the current_index
to before the *if
statement.
*label slice_start_loop
*temp current_index (initial_index + i_)
*if ((i_ < len) and (current_index <= length(original_string)))
...
When the loop ends, we need to save the final result in a global variable, so you can use the value retrieved by the subroutine.
startup.txt
*create result ""
And in the subroutine:
*set result substring
*return
Now we put everything together.
*label slice
*params original_string initial_index len
*temp substring ""
*temp i_ 0
*comment START OF LOOP
*comment --------------
*label slice_start_loop
*temp current_index (initial_index + i_)
*if ((i_ < len) and (current_index <= length(original_string)))
*set substring &(original_string # current_index)
*set i_ +1
*goto slice_start_loop
*comment --------------
*comment END OF LOOP
*set result substring
*return
The way you would use it is like this:
*gosub slice "XXXX42XXXX" 5 2
${result}
There are a couple ways you can blow this subroutine, for example, if you pass a negative value for the length.
I suggest you also take a look for future reference into CSLIB, which is a collection of useful subroutines including one to extract substrings and with necessary guards to avoid blowing the subroutine. 
Now, if you want to spend a few brain cells trying to understand loops
, you can try to come up with a solution of how to extract the values from the string and set the variables one by one.
@CJW, If I’m not mistaken, CSLIB covers most of the same use cases. But Twiger uses strings to emulate arrays, which you can definitely build on top of CSLIB, whereas CSLIB uses the pseudo-arrays of ChoiceScript. I just thought that Twiger’s solution fit @Phenrex’s need better for this specific use case.
It’s something to consider, but might be confusing to have two different way to deal with “arrays” in CSLIB.
Edit: for some reason, the forum messed with the formatting of the post 