math_operators
                no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
| — | math_operators [2007/09/01 05:53] (current) – created - external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ======Math operators====== | ||
| + | The client' | ||
| + | document will explain all of them and the most important concepts. | ||
| + | |||
| + | =====Tokens===== | ||
| + | All expressions are broken into tokens.  | ||
| + | an operator.  | ||
| + | is the action that you apply to operands.  | ||
| + | are the operands, and + is the operator. | ||
| + | |||
| + | There are three types of operands: rvalues, lvalues, and numbers.  | ||
| + | is an operand that provides a value that you can use. An lvalue is an | ||
| + | operand that can be used as the target of an assignment operator.  | ||
| + | is, well, a number. | ||
| + | |||
| + | As an example, an lvalue is a variable name. In the expression foo = 5, foo | ||
| + | is the lvalue.  | ||
| + | than to assign to it. In the expression var1 = var2, var2 is the rvalue. | ||
| + | Rvalues also include string literals. | ||
| + | |||
| + | Numbers are different, because numbers look like lvalues, but behave like | ||
| + | rvalues.  | ||
| + | rvalues. | ||
| + | |||
| + | ^PRECEDENCE ^OPERATOR  | ||
| + | | 1 | Sub-expression  | ||
| + | | 2 | Logical NOT	     | ! **bool**  | ||
| + | | 2 | Bitwise NOT	     | ~ **int**  | ||
| + | | 2 | Prefix Decrement	  | ||
| + | | 2 | Prefix Increment	  | ||
| + | | 2 | Suffix Decrement  | ||
| + | | 2 | Suffix Increment  | ||
| + | | 2 | Unary Plus	     | + **float**  | ||
| + | | 2 | Unary Minus	  | ||
| + | | 2 | String length	  | ||
| + | | 2 | Word Count	  | ||
| + | | 2 | Variable Dereference  | ||
| + | | 2 | Variable Dereference  | ||
| + | | 2 | Double Expansion  | ||
| + | | 3 | Exponent		  | ||
| + | | 4 | Multiplication	  | ||
| + | | 4 | Division		  | ||
| + | | 4 | Modulus		  | ||
| + | | 5 | Addition  | ||
| + | | 5 | Subtraction  | ||
| + | | 5 | String Catenation  | ||
| + | | 6 | Bitwise shift left     | **int**  | ||
| + | | 6 | Bitwise shift right    | **int**  | ||
| + | | 7 | Less Than              | **op**  | ||
| + | | 7 | Less than or equal to  | **op**  | ||
| + | | 7 | Greater than           | **op**  | ||
| + | | 7 | Greater than or equal to | **op**  | ||
| + | | 8 | Pattern match          | **op** =~ **op**  | ||
| + | | 8 | Pattern doesn' | ||
| + | | 9 | Equal, ignore case     | **op**  | ||
| + | | 9 | Not equal, ignore case | **op**  | ||
| + | | 9 | Equal                  | **op**  | ||
| + | | 9 | Not equal              | **op**  | ||
| + | |10 | Bitwise AND            | **int** & **int**  | ||
| + | |11 | Exclusive OR           | **int**  | ||
| + | |12 | Bitwise OR             | **int**  | ||
| + | |13 | Logical AND            | **bool**  | ||
| + | |14 | Logical XOR            | **bool**  | ||
| + | |15 | Logical OR             | **bool**  | ||
| + | |16 | If-then-else  | ||
| + | |17 | Assignment	  | ||
| + | |17 | Addition-assign  | ||
| + | |17 | Subtraction-assign  | ||
| + | |17 | Multiplication-assign  | ||
| + | |17 | Division-assign  | ||
| + | |17 | Modulus-assign  | ||
| + | |17 | Bitwise AND-assign  | ||
| + | |17 | Exclusive OR-assign  | ||
| + | |17 | Bitwise OR-assign  | ||
| + | |17 | Bitshift left-assign  | ||
| + | |17 | Bitshift right-assign  | ||
| + | |17 | Logical AND-assig  | ||
| + | |17 | Logical OR-assign  | ||
| + | |17 | Logical XOR-assign  | ||
| + | |17 | Exponent-assign  | ||
| + | |17 | strcat-assign  | ||
| + | |17 | String prefix-assign  | ||
| + | |17 | Swap values	  | ||
| + | |17 | Last Value             | **op**  | ||
| + | |||
| + | [1] The operand must be an [[lval]]\\ | ||
| + | [3] Short circuit operator.\\ | ||
| + | [4] You do not have to give an explicit operand.  | ||
| + | |||
| + | =====How operands are handled===== | ||
| + | There are four different kinds of operands | ||
| + | |||
| + | =====Escapes to text mode===== | ||
| + | [...] | ||
| + | {...} | ||
| + | ' | ||
| + | " | ||
| + | |||
| + | =====Epic-only operators===== | ||
| + | |||
| + | |||
| + | =====Operators that behave different in epic===== | ||
| + | |||
| + | =====How errors in expressions are handled===== | ||
| + | |||
| + | The string concatenation operators, ##, #=, and #~, are a special case, as they | ||
| + | are not present in C or C++. As their name indicates, they are used to join | ||
| + | two or more strings together, end to end. For example: | ||
| + | |||
| + |    @ foo  = [foo] ## [bar]              /* sets $foo to " | ||
| + |    @ foo #= [blah]  | ||
| + |    @ foo #~ [hmm]                       /* sets $foo to " | ||
| + | |||
| + | Also like C/C++, parentheses may be used to force certain parts of the | ||
| + | expression to be evaluated first (mainly in the event that the user wishes | ||
| + | for it to evaluate in an order other than that of operator precedence). | ||
| + | Parentheses may be nested.  | ||
| + | |||
| + | foo * 4 + 5 /* returns 17 */ | ||
| + | foo * (4 + 5) /* returns 27 */ | ||
| + | 4 + ((foo + 9) / 3) /* returns 8 */ | ||
| + | |||
| + | All assignment operators always return the value assigned, which allows for | ||
| + | the assignment of multiple variables at once. Keep in mind that expressions | ||
| + | are evaluated right to left. For example, if $foo is 12 and $bar is 11: | ||
| + | |||
| + | @ foo += bar *= 2 /* $bar is 22, $foo is 34 */ | ||
| + | |||
| + | Since the release of the EPIC4 pre-betas, the client has been growing ever | ||
| + | more perlish. Like perl, the =~ and !~ operators match with wildcards. =~ is | ||
| + | a direct opposite of !~, where it returns true if the patterns patch, while | ||
| + | !~ returns false. In this example, $bar is " | ||
| + | |||
| + |    @ foo = bar =~ [*pi*]  | ||
| + | @ foo = bar !~ [*z*] /* returns 1 */ | ||
| + | |||
| + | The various bitwise operators are of special interest also. Assuming $foo is 12 | ||
| + | and $bar is 11: | ||
| + | |||
| + | foo & bar /* returns 8 */ | ||
| + | foo | bar /* returns 15 */ | ||
| + | foo ^ bar /* returns 7 */ | ||
| + | |||
| + | The exponential operator takes numbers to various powers. It is especially | ||
| + | useful, since many script writers create a $power() function for this purpose. | ||
| + | It supports negative and fractional exponents as long as the system' | ||
| + | library (libm) does. Assuming $foo is 9: | ||
| + | |||
| + | foo ** 2 /* returns 81 */ | ||
| + | foo ** 0.5 /* returns 3 */ | ||
| + | |||
| + | The {pre, | ||
| + | users everywhere swear by. They have also been known to swear at them, for | ||
| + | reasons you will soon see. Assume $foo is 5, each column shows 3 ways of | ||
| + | doing the same thing, from least efficient to most efficient: | ||
| + | |||
| + | @ foo = foo + 1 @ foo = foo - 1 | ||
| + | @ foo += 1 @ foo -= 1 | ||
| + | @ foo++ @ foo-- | ||
| + | |||
| + | However, these operators have pitfalls, which are mainly discovered by those | ||
| + | who do not understand how they work. Both may either prefix or postfix a | ||
| + | variable; prefix causes it to evaluate before the operation, postfix causes | ||
| + | it to evaluate aster.  | ||
| + | However, it does make a difference in this example: | ||
| + | |||
| + | while ( foo++ < 10 ) { ... } | ||
| + | |||
| + | The expression is evaluated for whether $foo is less than 10, and then $foo | ||
| + | is incremented.  | ||
| + | form, $foo would be incremented **before** the expression was evaluated, which | ||
| + | would cause the loop to have one less iteration. | ||
| + | |||
| + | Another pitfall of the autoincrement and decrement operators is the | ||
| + | ambiguity introduced by insufficient whitespace when used in conjunction | ||
| + | with addition and subtraction operators.  | ||
| + | |||
| + | @ foo = 4 | ||
| + | @ bar = 8 | ||
| + | @ foobar = foo+++bar | ||
| + | |||
| + | How should one interpret the last assignment?  | ||
| + | ${foo++ + bar} or ${foo + ++bar}?  | ||
| + | to not write code that looks so silly and unreadable.  | ||
| + | and there is no ambiguity.  | ||
| + | |||
| + | Another popular operator familiar to most C/C++ programmers is the tertiary | ||
| + | operator (sometimes referred to as the alternation operator).  | ||
| + | a function similar to IF, except is much more compact and efficient.  | ||
| + | let $foo be 5 again: | ||
| + | |||
| + | @ bar = foo > 3 ? 1 : 0 /* sets $bar to 1 */ | ||
| + | @ bar = foo > 8 ? 1 : 0 /* sets $bar to 0 */ | ||
| + | |||
| + | Functions (built-in and scripted) can also be used within expressions.  | ||
| + | function will be evaluated, and its return value is used in the expression: | ||
| + | |||
| + | @ foo = pattern(b* foo bar blah) /* sets $foo to "bar blah" */ | ||
| + | |||
| + | All functions implicitly use a special operator, (). That is, the pair of | ||
| + | parentheses themselves compose an operator, though of course it is somewhat | ||
| + | different in nature from more traditional operators like ' | ||
| + | Functions (aliases with return values) require the () to function properly. | ||
| + | |||
| + | A similar operator is [], which is used for alias and variable structures. | ||
| + | We've already seen that it can be used to explicitly switch the evaluation | ||
| + | context to text. This can be extended to structure elements, such that | ||
| + | they can be expanded on the fly: | ||
| + | |||
| + | @ foo.1.1 = [foo] | ||
| + | @ foo.1.2 = [bar] | ||
| + | alias blah echo $foo[1][$0] | ||
| + |    /blah 2                              /* expands to $foo.1.2 -> " | ||
| + | |||
| + | The same can be applied to aliases and functions as well. Because of the | ||
| + | nature of the [] operator, anything may be expanded inside it, variables and | ||
| + | functions alike. | ||
math_operators.txt · Last modified: 2007/09/01 05:53 by 127.0.0.1
                
                