suve
Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774 Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774 Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774 Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774 Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774 Warning: Illegal string offset 'doublequoteopening' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 766 Warning: Illegal string offset 'doublequoteclosing' in /usr/home/svgames/domains/svgames.pl/public_html/dokuwiki/inc/parser/xhtml.php on line 774

awful: tutorial: loops

We've just learned how to use structures - arrays in dictionaries - in awful. But having to access every index with a separate statement is obviously non-efficient - it would be much simpler if we could somehow execute an expression multiple times without copy-pasting. Here's where loops come into play.

While you're out, get some milk

:set &c i10
!while $c
   :write $c s' '
   :sleep f1.0
   :sub &c i1
!done
:writeln sxBOOM!x

Above snippet demonstrates the use of awful's pwhilep loop. As can be seen, the loop is opened using the !while construct, which should contain the looping condition. Upon encountering the loop's entry point, the condition will be evaluated and, if it's false, the loop will be skipped. End of loop code is marked using the !done construct - upon meeting it, the interpreter jumps back to the appropriate !while construct, evaluates the condition, and either executes loop code again, or jumps past loop end.

I'm not gonna repeat myself

The pwhilep loop has one important feature, which sometimes can prove a drawback - since the condition is evaluated at the beginning of loop body, the statements inside may not got executed at all. But what if we want the loop body to always be executed at least once? Well, that's when we use the prepeatp loop.

:set &cnt sss
!repeat
    :writeln s'Random number: ' :random i0 i100
    :write s'Another? y/n: '
    :read &cnt
!until :eq s'n' $cnt

Above snippet demonstrates the use of awful's prepeatp loop. As we can see, the loop is opened using the !repeat construct, which should not be given any arguments. After that, we write the statements we want to be repeated, and then close the loop body using the !until construct. Similarly to !while, the !until construct should be passed a condition - however, one important thing to remember is that whereas in the pwhilep loop we specified the condition to continue looping, in the prepeatp loop we specify the condition to stop looping.

I want to break free!

Sometimes you may want to have more than a single return point from a loop, or simply perform an operation only for selected arguments.
That's where the !break and !continue constructs come useful.

:set &sum i0
:set &i i0
!while :lt $i i100
   :add &i i1
   !if :eq i0 :mod $i i5
       !continue
   !fi 
   !if :eq i0 :mod $i i7
       !continue
   !fi
   :add &sum $i
!done
:writeln s'Sum: ' $sum

The above snippet will calculate the sum of all numbers in 1-100 range, excluding numbers divisible by 5 or 7. The loop iterates from 1 to 100. If $i is divisible by 5 or 7, the !continue construct is used to omit all other expressions present in the loop and jump back to the looping condition. To completely exit a loop, instead of returning to the looping condition, the !break construct can be used.

:set &x &y i0
!while :lt $x i10
   !while :lt $y i10
      !if :eq i100 :mul $x $y
          :writeln  s'x = ' $x s', y = ' $y
          !break i2
      !fi
      :add &y i1
   !done
   :add &x i1   
!done

Both !break and !continue constructs can be passed an additional, single argument, describing how many loops should it continue/break out of. This parameter must be a literal or a const; it is impossible to use a variable or an expression here.

By your powers combined, I am Captain Vodka!

:set &fib :arr i1 i1
:set &c i2
!repeat
    :set &fib[$c] :add $fib[:sub $c i1] $fib[:sub $c i2]
    :add &c i1    
!until :eq $c i20

Loops work very nicely with arrays and dictionaries. In the example above, we use a simple loop to generate an array of 20 Fibonacci Numbers.


Next: ⇒ Constants ⇒
Back: ⇐ Dictionaries ⇐

wikistrona zmodyfikowana 2014/0601/2317