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
