Using Loops

Contributed by dohcan
This tutorial assumes basic knowledge of mIRC scripting, such as the syntax for if statements, how variables work, and the such. If you do not know these, you might try one of our more basic tutorials and work your way up to this.

The basic concept of a loop (a programming language loop, that is) is simple. Do something until a certain condition is met. Almost all loops have three common parts. Those parts are:

1. Loop control variable - usually an ordinal (read: 1, 2, 3 or a, b, c) value that is incremented or decremented until a certain condition is met.

2. Condition - this is usually presented in the form of an "if" statement that controls the flow of the loop.

3. Body - this is where all of action takes place. Whatever you want your loop to do, this is where you put it.
Using the While Loop

In mIRC, there is what is known as a "while loop", with the following pseudo-code illustrating how a while loop works:

NOTE:
lcv = loop control variable
con = condition
body = body of the loop

lcv = initial value

while (lcv is within con)
begin while
  body
  alter lcv
end while
To make an example, suppose you wanted to list all of the nicknames in a channel, each on a separate line. This task could easily be done using a while loop.
alias listnicks {
  var %lcv
  ; declare the loop control variable as local, this will clean it up 
  ; automatically when the alias is finished executing

  %lcv = 1
  ; set the initial value of the lcv to 1, we start at the first nickname

  while (%lcv <= $nick(#, 0)) {
    ; $nick(#, 0) is the total nicks on the active channel
    ; we make sure the lcv is within the bounds

    echo -a Nickname %lcv $+ : $nick(#, %lcv)
    ; we output the lcv'th nickname

    inc %lcv
    ; we increment the lcv by one since so we can go to the next nickname
    ; since we have the condition to check the bounds of the lcv, once we have outputted
    ; the last nickname, the condition will become false and the loop will quit

  }
  ; end the loop
}
While this is a very simple alias that doesn't do anything really useful, it does show how you can perform a large number of operations with a few lines of code.
More Features of the While Loops
After you get tired of listing the nicknames of channels (which you will, trust me), you will probably want to try more complicated (read: useful) tasks. You will have to make the body of the while loop more complex. To aid you along, the while loop has two special commands worth noting.
1. break - allows you to immediately stop a while loop, as if the condition had suddenly become false

2. continue - allows you to jump back to the beginning of the loop (note: the lcv is NOT modified or altered when you call continue)
To show how to use these two new features, suppose we want to make an alias that will list the nicknames of a channel, but we do not want to list any nicknames that have "joe" in them and we want to completely stop if we find a nickname with "john" in it.
alias listnicks2 {
  var %lcv, %nick
  ; declare the loop control variable
  ; also declare nickname variable, since we will be using it several times

  %lcv = 1
  ; again, initialize the lcv to one, to start with the first nickname

  while (%lcv <= $nick(#, 0)) {
    ; same as before, set the condition to make sure the lcv is within 
    ; the bounds of the total number of nicknames
    
    %nick = $nick(#, %lcv)
    ; get the current nickname and store it in the nick variable
    ; this is to avoid writing $nick(#, %lcv) several times

    if (joe isin %nick) {
      ; if joe is in the current nickname, then we go to the next nickname, 
      ; by incrementing the lcv, and call the continue function to 
      ; skip back to the beginning of the loop
      inc %lcv
      continue
    }

    if (john isin %nick) {
      ; if john is in the current nickname, then we want to stop the loop altogether, 
      ; which we do by calling the break function
      ; since we're stopping, we do not need to increment the lcv
      break
    }

    ; finally, output the current nickname
   
    echo -a Nickname %lcv $+ : %nick
    
    ; increment the lcv so we can go to the next nickname
    inc %lcv
  }
  ; end the while loop
}
While this example is, for the most part, as useless as the first one, it does illustrate how the continue and break functions can serve for exceptions in the body. This is very useful when you are analyzing data. You can use the continue function to skip already analyzed data or you can use the break function to quit when you have found what you want.

As a side note, it is generally considered good programming practice to make sure you only exit a loop via the loop condition, but sometimes that is unavoidable, and for those times, break and continue are very helpful.
Other Loops
The while loop is a very useful loop, because it is optimized for speed and the code to manage one is generally very neat. As of the writing of this tutorial, however, the while loop is a fairly new feature to mIRC. Before while loops, many people used what is known as a "goto loop." The layout of a goto loop is similar to the while loop, but it has one more element, a label, or a place to "go back to", hence the name goto loops. Since the while loop is much more preferred, I will not go over the the goto loop much, except show the basic layout.
NOTE:
lcv = loop control variable
con = condition
body = body of the loop
label = label where the loop should return to


lcv = initial value

label

if (lcv is within con)
begin loop
  body
  alter lcv
  go back to label
end loop
As you can see, the layout is similar except for three changes, the addition of the label, the "if" statement as opposed to the "while" statement, and the explicit call to return the to label (or back to the beginning). The first 'listnicks' alias written with a goto loop would look like this (I won't bother commenting this one):
alias listnicks3 {
  var %lcv
  %lcv = 1
  :start
  if (%lcv <= $nick(#, 0)) {
    echo -a Nickname %lcv $+ : $nick(#, %lcv)
    inc %lcv
    goto start
  }
}
A note on labels. You write them such as ":labelname" but when you reference them in a goto statement, you leave off the ":".

One advantage (maybe) of a goto loop is you could have multiple conditions depending on the situation, and jump around at will. How useful this is depends on you...
Last Words
Earlier I said most while loops have three common pieces, loop control variable, condition, and body. Some while loops, however, may not have a loop control variable that is. These are known as 'endless loops'. Endless loops can also occur if you have a poorly constructed loop condition, but that is another story. Back to what we were talking about, take this chunk of code for example:
var %ticks = $ticks
while ($true) {
  if ($calc($ticks - %ticks) >= 1000) break
  else echo -a BLAH
}
What this piece of code does is runs the loop for approximately one second (or 1000 ticks), then breaks. It works because $true always evaluates to true. This type of usage is good when the number of iterations is unknown. In this case, we do not know how many times BLAH will be echoed in one second.

I also mentioned something about performance earlier, how using a while loop is optimal. To illustrate that, take these two simple aliases:

Using goto loop
bench-goto {
  echo -a Benchmarking, please wait.
  var %bench.time = $ticks
  var %bench.mark = 0
  :start
  if ($calc($ticks - %bench.time) < 5000) {
    inc %bench.mark
    goto start
  }
  echo -a %bench.mark mMarks in five seconds
}
Using while loop
bench-while {
  echo -a Benchmarking, please wait.
  var %bench.time = $ticks
  var %bench.mark = 0
  while ($calc($ticks - %bench.time) < 5000) {
    inc %bench.mark
  }
  echo -a %bench.mark mMarks in five seconds
}
On my system, the while loop is approximately 10% faster. For complex operations or operations done several times (such as scanning for clones in large channels), this could result in a sizable gain in performance.

Now you know how to construct and use a loop in mIRC, and you also know the benefits of the different types of loops in mIRC.
All content is copyright by mircscripts.org and cannot be used without permission. For more details, click here.