DO Stuff: There’s an old programmers’ adage: “Where there’s an IF, there’s a DO,” and darned if it isn’t true.
By David Shirey
Editor's Note: This article is excerpted from chapter 5 of 21st Century RPG: /Free, ILE, and MVC, by David Shirey.
Fortunately, most of what we said for IFs is true for DO loops.
The DO itself has been eliminated from /Free (use FOR). And the DOWGT, DOULT, and others of that ilk are out as well.
What you are left with is simpler and more straightforward: DOW and DOU with a conditional statement. The basic syntax is:
Despite the changes in syntax, these two commands operate the same way they do in positional RPG. That is, the difference is the point in the construct where the decision is made whether to continue with the loop or get out. For the DOW, it is done at the start of the loop; for DOU, it is at the end. In both cases, an ENDDO is required.
As with the IF statement, you can use parentheses and logical operators to write more complex conditions, and you can split them up on multiple lines with a semicolon only at the end-of-line group. For example:
Now, please don’t think that I consider the above example a good example of coding. God help you if you end up ever having to duplicate this kind of logic. In reality, I would break this up into a couple of nested IFs, even though I hate those, too. It’s just an example, not my vision of reality.
To be honest, this is one that I don’t use that much. But strangely enough, right after I switched to /Free, I used it. Haven’t touched it since. For some reason, using it puts me in a FORTRAN sort of mood and makes me want to drink Harvey Wallbangers. Never really liked them when they were popular, so it’s a good reason to try to avoid the FOR. The Galliano bottles were cool, though.
But, sometimes you need to do a loop a given number of times, and that is what the FOR is there for.
FOR i = 1 to 5;
your indented logic statements; ENDFOR
(There is a syntax error in the above statement. Do you see what it is? Hint: have I mentioned the importance of the semicolon before?)
The From and To limits in the FOR can easily be variables.
One important thing to note is that the FOR statement will automatically update the i value each time the loop ends. So don’t do it yourself. That would be sooooo weird.
Leaving a Loop
Sometimes you may be in an IF statement or a loop and decide you just want to get out. It can be a panic situation. You know, you feel the walls beginning to close in, and the longer the loop runs, the tighter and tighter and tighter ..., well, you get the idea. Often what we do is set a flag and fudge the structure of the loop so that when this flag is set, you can exit. Of course, back in the real olden days we would just do a GOTO and get out, but that was abused and has rightfully been banished by the Great Queen who rules Game of War.
Fortunately, /Free supports the LEAVE and ITER opcodes.
LEAVE will take you to the next statement after the end of the loop you are currently in. It truly gets you out of the loop. Ta-dah!
ITER causes you to jump to the ENDDO (or ENDFOR) and perform the normal checking that is done to see if you should get out or do another iteration. You skip any code within the loop but come back in the loop for another go-round.
In other words, LEAVE does just that: it kicks you out of the loop you are in. ITER bypasses all of the logic between you and the end of the loop, but keeps you in the loop and lets it do the normal checking to see if you should be set free or if you have another ticket to ride.
Both of these opcodes work only if you are in a DOx or FOR loop. You can code it inside a DOx or FOR loop that is in an IF or SELECT statement, but if you just put it in a standalone IF or SELECT, you will get a compile error.
The CALL opcode was not moved over to /Free. Instead, you will use the prototyped call, CALLP.
The format for this is pretty simple:
Like the EVAL opcode, however, the CALLP is optional. So you may see the call to a program set up to look more like a BIF statement:
Some people consider this the only civilized way to set up a call, and they use it frequently. For my money, I prefer the first form. The main issue to me is one of clarity. I like having the CALLP there because that is a very clear visual sign that a call is being made. I suppose I should be smart enough to instantly recognize that the other is a call, but I am not. In this case it is obvious, but if I had named my PR spec AP_CREDIT_CHECK instead of DWS0001 (an obvious program name), it might not be quite so clear. And don’t worry, we will talk about what PR specs are later.
It’s a small thing, but to me it sometimes seems that now that we have a version of RPG that is very easy to read and understand, we are taking steps to make it more cryptic. I agree, it looks more Web-like that way, but I would hardly argue that Web languages are easy to read.
But chose whatever form seems best to you. They both work just fine. And, as we shall see later, sometimes you have to use the format without the CALLP.
While we are talking about control logic statements, I want to say just a final word about indenting your code.
Indenting is something RPG programmers generally don’t think about too much (since you can’t do it in fixed-format mode). But indenting is probably the single most powerful structure tool a programmer has. Anyone who has struggled to match up IFs and ENDIFs in a big logic section has to appreciate the ability to be able to indent code and so easily see which ENDIF matches up with which IF.
So get in the habit right now. I like to indent four spaces; some people like more or fewer, but they are crazy. The important point is to start to build indenting into your coding style with /Free right away. You won’t regret it.
What Ya Shoulda Learned
OK, we are a couple of chapters into /Free now, and your feet should be getting pretty wet. You already know enough to do quite a bit of damage, but we are not going to stop here. Before we go on, though, I want to quickly review what we have talked about here.
- First, you should have a good handle on setting up the IF
- Second, need I mention that you have to have a semicolon after each statement?
- Use parentheses as necessary to make the whole thing easier to read and compile (that is, for the compiler to understand what you want).
- Use the new mathematical comparison operators (versus the old alphabetic abbreviations).
- If you do use not on an expression, be sure to surround the expression with parenthesis for clarity.
- In addition, we went over the SELECT/WHEN.
- And the FOR.
- Plus the DOW/DOU, which when used in conjunction with a condition statement replace the DOWEQ, operators from positional RPG.
- And finally, we saw the prototyped call parm, CALLP, and its two
- But most important, you have not only learned about these things but actually used them in your sample /Free program. You did try each one of these, right? I hope so.
And now we are tired; happy but tired. So let’s rest for just a minute before we move on to /Free I/O.