Latest revision |
Your text |
Line 1: |
Line 1: |
− | {{mirc title|Evaluation Brackets}}
| + | Normal code is executed, as you are probably aware, top down and left right. '''Evaluation brackets''' are a mechanism by which a program can alter the natural behavior of the [[mIRC]] [[interpreter]]. |
− | Standard mIRC code is executed, as expected, top down and left right. '''Evaluation brackets''' (or '''Eval Brackets''') are a mechanism by which a program can alter the natural behavior of the [[mIRC]] [[interpreter]].
| |
| | | |
| Evaluation brackets allows us to: | | Evaluation brackets allows us to: |
Line 13: |
Line 12: |
| [[File:Eval1.png]] | | [[File:Eval1.png]] |
| | | |
− | Typical code is evaluated from left to right, one word at a time.
| + | A typical code is evaluated from left to right, one word at a time. |
| | | |
| <source lang="mIRC">alias x echo -a $1 | return $1 | | <source lang="mIRC">alias x echo -a $1 | return $1 |
Line 158: |
Line 157: |
| | | |
| === Multiple evaluations === | | === Multiple evaluations === |
− | If we follow the simple rule above, we can easily evaluate a specific code segment multiple times. Consider the following example: | + | If we follow the simple rule above, we can easily evaluate a specific code segment multiple files. Consider the following example: |
| | | |
| <source lang="mIRC">alias exe echo -a I was called! | return Hi! | | <source lang="mIRC">alias exe echo -a I was called! | return Hi! |
| ; example: | | ; example: |
− | alias example echo -a [ [ [ $!!exe ] ] ]</source> | + | alias example echo -a [ [ [ [ [ $!!!!exe ] ] ] ] ]</source> |
| | | |
| The above code prints: | | The above code prints: |
Line 168: |
Line 167: |
| I was called! | | I was called! |
| Hi! | | Hi! |
− |
| |
− | '''Note''': The graph below was made as though [ [ [ [ [ $!!exe ] ] ] ] ] with fives 5 '!' on $exe instead of two, but for technical reason 3 or more '!' can't be rendered for now.
| |
| | | |
| [[File:Eval6.png]] | | [[File:Eval6.png]] |
− |
| |
| | | |
| Here is a more interesting example of multiple evaluations: | | Here is a more interesting example of multiple evaluations: |
Line 189: |
Line 185: |
| | | |
| == Solving the space issue using $+() == | | == Solving the space issue using $+() == |
− | By now we already know that the following code will only evaluated once since it violates the first rule: spaces in the code segment. | + | By know we already know that the following code will only evaluated once since it violates the first rule: spaces in the code segment. |
| | | |
| <source lang="mIRC">//echo -a [ [ a $!me ] ]</source> | | <source lang="mIRC">//echo -a [ [ a $!me ] ]</source> |
Line 205: |
Line 201: |
| | | |
| == $+ Special behaviors == | | == $+ Special behaviors == |
− | Inside evaluation brackets, the $+ concatenation construct (unlike $+(), $+ itself is not an identifier, it doesn't return a value) exhibits some special behavior.
| |
− |
| |
− | === [ A $+ B ] Format ===
| |
− | The rule about [ A $+ B ] is:
| |
− |
| |
− | The '''[ token_A $+ token_B ]''' arrangement will cause token_A to evaluate once and then be concatenated to token_B (evaluated zero times). and then the concatenated string is evaluated. I.e.:
| |
− | [ A $+ B ] <=> $($(A, 1) $+ $(B, 0), 2)
| |
− |
| |
− | Additional pairs of $+ are treated in the same way as if they were grouped using evaluation brackets:
| |
− |
| |
− | [ A $+ B $+ C ] <=> [ [ A $+ B ] $+ C ]
| |
− |
| |
− | Which can be written as:
| |
− |
| |
− | <source lang="mIRC">$($($($(A, 1) $+ $(B, 0), 2), 1) $+ $(C, 0) ,2)</source>
| |
− |
| |
− | This pattern can be extended to unlimited number of tokens.
| |
− |
| |
− | Here is a quick example showing how the second token is never evaluated:
| |
− |
| |
− | <source lang="mIRC">//echo -a [ x $+ $y ] and [ x $+ %y ]</source>
| |
− |
| |
− | Which prints:
| |
− | x$y and x%y
| |
− |
| |
− | Let's wrap this section with a strange line of code:
| |
− |
| |
− | <source lang="mIRC">//var %x = % $+ y, %y%x = Works! | echo -a [ %x $+ %x ]</source>
| |
− |
| |
− | [[File:Eval8.png]]
| |
− |
| |
− | === A [ $+ B ] Format ===
| |
− | With the A [ $+ B ] Format, we have:
| |
− |
| |
− | The token_A [ $+ token_B ] arrangement will cause token_A (evaluated zero times) to be concatenated to token_B (evaluated zero times) and then the concatenated string is evaluated. I.e.:
| |
− | A [ $+ B ] <=> $($(A, 0) $+ $(B, 0), 2)
| |
− |
| |
− | Note that a $+ at the beginning of an evaluation bracket causes this zero-eval behavior to propagate to every other token in the group:
| |
− |
| |
− | <source lang="mIRC">A [ $+ B $+ C $+ ... ] <=> $($(A, 0) $+ $(B, 0) $+ $(C, 0) $+ ..., 2)</source>
| |
− |
| |
− | Consider the following example. Before of the initial $+, all the other identifiers are never evaluated before being concatenated:
| |
− |
| |
− | <source lang="mIRC">//echo -a X [ $+ $a $+ $b $+ $c $+ $d ]</source>
| |
− |
| |
− | As expected, we get:
| |
− | X$a$b$c$d
| |
− |
| |
− | Here is a better example
| |
− |
| |
− | <source lang="mIRC">//var %x$a$b$c$d = Example! | echo -a %x [ $+ $a $+ $b $+ $c $+ $d ]</source>
| |
− |
| |
− | The code above prints:
| |
− | Example!
| |
− |
| |
− | [[File:Eval10.png]]
| |
− |
| |
− | Note that other, unrelated, tokens are still evaluated as we expect:
| |
− |
| |
− | <source lang="mIRC">//echo -a X [ $+ $a $+ $b $+ $c $me ]</source>
| |
− |
| |
− | As expected, we get:
| |
− | X$a$b$c David
| |
− |
| |
− | === A [ $+ [ B ] ] Format ===
| |
− | The A [ $+ B ] format is not very helpful alone since B is never evaluated. We can combine our ability to evaluate things multiple times with the A [ $+ B ] format to form some more usable things.
| |
− |
| |
− | <source lang="mIRC">A [ $+ [ B ] ] <=> $($(A, 0) $+ $(B, 1), 2)</source>
| |
− |
| |
− | The most common application of this is '''dynamic variables'''. Consider the following segment:
| |
− |
| |
− | <source lang="mIRC">//var %foo.6 = Works! | echo -a %foo. [ $+ [ $calc(2*3) ] ]</source>
| |
− |
| |
− | [[File:Eval9.png]]
| |
− |
| |
− | The most common form is %var. [ $+ [ $nick ] ] which allow you to retrieve a value from a variable specifically created for $nick.
| |
− |
| |
− |
| |
− | == Inside identifiers ==
| |
− | By now you know evaluation brackets happen before the code itself evaluates, but what about identifiers?
| |
− |
| |
− | === Spaced out [ ] ===
| |
− |
| |
− | If you space out the [ ] inside the identifier, the previous rules apply
| |
− |
| |
− | //echo -a [ $me ] $+( [ $!me ] )
| |
− |
| |
− | Here both [ ] are resolved at the same time. However after [ ] are resolved, the line becomes:
| |
− |
| |
− | //echo -a David $+( $me )
| |
− |
| |
− | And here $+() will normally evaluate $me, so doing that results in a double evaluatation of the parameter, watch out.
| |
− |
| |
− | More importantly, since the resolution of [ ] happens before the identifier itself is evaluated, it will correctly parse code that is a direct result of the evaluation brackets. Here is some code to demonstrate this behavior:
| |
− |
| |
− | <source lang="mIRC">//var -s %x = mid(@Example!,2,8, %y = ) | echo -a $ [ $+ [ %x $+ [ %y ] ] ]</source>
| |
− |
| |
− | The above code prints:
| |
− | <span style="color: #000099;">* Set %x to mid(@Example!,2,8</span>
| |
− | <span style="color: #000099;">* Set %y to )</span>
| |
− | Example!
| |
− |
| |
− | Here is another one:
| |
− |
| |
− | <source lang="mIRC">//var %x = @@XYZ@@,3,3 | echo -a $mid( [ %x ] )</source>
| |
− |
| |
− | Which will print:
| |
− | XYZ
| |
− |
| |
− | The interpreter is able to handle the commas and braces as part of the code.
| |
− |
| |
− | === Non spaced out [ ] ===
| |
− | If you don't space out the [ ], they will be interpreted when the identifier evaluate each parameter:
| |
− |
| |
− | alias changev1to2 if (2) noop
| |
− | alias changev1to3 echo -a param: $1 | if (3) noop
| |
− | alias custom echo -a $1 $3
| |
− | //if (1) noop $changev1to2 $custom($v1,$changev1to3( [ $v1 ] ),[ $v1 ])
| |
− |
| |
− | Here, the first parameter passed to $custom, $v1, will have the value '2', because just before $custom is evaluated, $changev1to2 is evaluated, and that changes $v1.
| |
− |
| |
− | The [ $v1 ] for the $changev1to3 alias, is resolved when the line is evaluated for the /noop command, because of the spacing. At this point $v1 is '1', from the original //if that is executed.
| |
− |
| |
− | The non spaced [ $v1 ] for the third parameter of $custom, is not resolved for the /noop command, here are the inbetween steps:
| |
− |
| |
− | * //if evaluates, the condition is '1' so $v1 is set 1
| |
− | * noop $changev1to2 $custom($v1,$changev1to3( [ $v1 ] ),[ $v1 ]) is the command to be executed for that if
| |
− | * [ ] are processed for the line, the [ $v1 ] for the $changev1to3 alias is resolved, so $v1 is our current value so far: 1
| |
− | * the line is evaluated, $changev1to2 is evaluated and set $v1 to 2
| |
− | * $custom is evaluated, its first parameter $v1, is then 2
| |
− | * the second parameter of $custom evaluates "$changev1to3( 1 )" to $null, but it sets $v1 to 3 ('1' is our previous $v1 code, although it's no problemo here, keep in mind: it's double evaluated!)
| |
− | * the third parameter of $custom evaluates: the [ ] are resolved, $v1 evaluates once (no double evaluation) to 3
| |
− |
| |
− | '''Note''': the non spaced [ $v1 ] is not required to get $v1 to be 3, not using [ ] would also correctly make $v1 3 since $changev1to3 was just called, but it illustrates that the [ ] are not resolved at the same stage depending on the spacing.
| |
− |
| |
− | '''Note2''': non spaced [ ] inside identifier are equivalent to $eval(), they do not make the identifier reevaluate the code:
| |
− |
| |
− | //var %a 1,32 | echo -a $gettok(a b,[ %a ]) is just going to evaluate twice ,1,32 and then pass 1,32 as the second parameter to $gettok
| |
− |
| |
− | This makes non spaced [ ] inside bracket pretty useless. Spaced out [ ] are handy for passing dynamic parameters to an identifier (again this double evaluates the argument so be careful):
| |
− |
| |
− | $ident( [ %params ] )
| |
− |
| |
− | == Escaping Evaluation Brackets ==
| |
− | Evaluation brackets can be escaped by using double brackets ([[) without spaces. For example:
| |
− |
| |
− | <source lang="mIRC">//echo -a [[ [[ example! ]] ]] </source>
| |
− |
| |
− | The code above prints:
| |
− | [ [ example! ] ]
| |
− |
| |
− | Note that without a complete pair, a single bracket is not treated as anything special. The following example is also acceptable:
| |
− |
| |
− | <source lang="mIRC">//echo -a [[ [[ example! ] ]</source>
| |
− |
| |
− | It's a good time to also note that escaped evaluation brackets are not exactly the same as using $chr(91) and $chr(93). The escaped evaluation brackets happen at the same phase of evaluation as the actual evaluation bracket processing. Consider the following example:
| |
− |
| |
− | <source lang="mIRC">//echo -a $mid( [[ [[ example! ]] ]] , 1) => $mid( $chr(91) example! $chr(93) , 1)</source>
| |
− |
| |
− | The code above prints:
| |
− | [ [ example! ] ] => [ example! ]
| |
− |
| |
− | == Additional Odd Behaviors ==
| |
− | Below are a few odd behaviors that are worth mentioning.
| |
− |
| |
− | === [ A $+ ] B Format ===
| |
− | The reason we have not mentioned this format above is because its behavior is rather buggy. The [ A $+ ] B format behaves like [ A $+ B ] where B is evaluated zero times. This behavior propagates to multiple tokens as well. For example:
| |
− |
| |
− | <source lang="mIRC">//echo -a [ A $+ ] $me $+ $me $+ $me</source>
| |
− |
| |
− | Prints:
| |
− | A$me$me$me
| |
− |
| |
− | This is more of a buggy behavior than anything else and should be avoided. Any code that relies on this is almost certainly doing something wrong.
| |
− |
| |
− | === $++ ===
| |
− | This construct behaves just like the $+ construct without exhibiting the special behavior inside the evaluation brackets. Note that normally there is no reason to use this construct. Here is an example:
| |
− |
| |
− | <source lang="mIRC">//echo -a [ $!!me $++ $!me ] vs. [ $!!me $+ $!me ]</source>
| |
− |
| |
− | The above code prints:
| |
− | $!me$me vs. $me$!me
| |
− |
| |
− | Or with the previous example:
| |
− |
| |
− | //echo -a [ A $+ ] $me $++ $me $++ $me
| |
− |
| |
− | Which evaluates the last two $me correctly.
| |
− |
| |
− | == Commands with Special Behavior ==
| |
− | Not all commands are equal. Below is a list of some regular commands that have special evaluation routines that allow us to get the job that would otherwise require evaluation brackets:
| |
− |
| |
− | #{{mIRC|/var}}
| |
− | #{{mIRC|/set}}
| |
− | #{{mIRC|/inc}}
| |
− | #{{mIRC|/dec}}
| |
− | #{{mIRC|/unset}}
| |
− | #{{mIRC|/sockwrite}}
| |
− |
| |
− | <source lang="mIRC">alias example {
| |
− | var %x $+ $calc(4 * 4) $+ y 200
| |
− | inc %x $+ $calc(4 * 4) $+ y
| |
− | echo -a : %x [ $+ [ $calc(4*4) $+ y ] ]
| |
− | unset %x $+ $calc(4 * 4) $+ y
| |
− | echo -a : %x [ $+ [ $calc(4*4) $+ y ] ]
| |
− | }</source>
| |
− |
| |
− | The code above will print:
| |
− | :201
| |
− | :
| |
− |
| |
− | Note that unlike the reset of the commands, '''{{mIRC|/unset}}''' cannot set variables in the format of %var {{mIRC|$+}} %var. Evaluation brackets are needed to fix this. see {{mirc|variables#Special behaviors & quirks|here}}
| |
− |
| |
− | == Quirks ==
| |
− |
| |
− | jaytea
| |
− |
| |
− |
| |
− | [[Category:mIRC|evaluation brackets]]
| |