Difference between revisions of "LSL Operators"
Siann Beck (Talk  contribs) (Operator precedence) 
m (Twiddled formatting in ++/ note.) 

(42 intermediate revisions by 19 users not shown)  
Line 1:  Line 1:  
−  {{LSL Header}}  +  {{LSL Headerml=*}}{{LSLCFixMe}}<! This article is woefully incomplete, it needs more Operator tables > 
−  Operators are used to cause an operation (or mathematical action) to be performed on two operands. The easy and common example is 1 + 2 where 1 and 2 are operands, and the '''+''' is the operator.  +  Operators are used to cause an operation (or mathematical action) to be performed on one (such as !) or two operands. The easy and common example is 1 + 2 where 1 and 2 are operands, and the '''+''' is the operator. This concept can be extended much further with LSL since operands can be variables with the special case of the assignment operators requiring that the left hand side be a variable. 
−  +  The following table lists the operators in descending order of evaluation, i.e. higher in the table means higher evaluation precedence. Multiple operators on the same line share evaluation precedence. Parenthesize an expression if you need to force an evaluation order.  
{ bgcolor="#FFFFFF" border="1" cellspacing="2" cellpadding="6"  { bgcolor="#FFFFFF" border="1" cellspacing="2" cellpadding="6"  
−  +   bgColor="#A7C1F2"  
−  !  +  ! Operator 
+  ! Description  
+  ! Usage Example  
    
−   ()  +   <code>()</code> 
+   parentheses: grouping and evaluation precedence  
+   <code>integer val = a * (b + c);</code>  
    
−   (''type'')   +   <code>[]</code> 
+   brackets: list constructor  
+   <code>list lst = [a, 2, "this", 0.01];</code>  
+    
+   <code>(''type'')</code>  
+   typecasting  
+   <code>string message = "The result is:" + (string)result;</code>  
    
−   ! ~ ++   +   <code>!</code> <code>~</code> <code>++</code> <code></code> 
+   logical NOT, bitwise NOT, increment, decrement  
+   <code>counter++;</code>  
    
−   * / %  +   <code>*</code> <code>/</code> <code>%</code> 
+   multiply/dot product, divide, modulus/cross product  
+   <code>integer rollover = (count + 1) % 5;</code>  
    
−     +   <code></code> 
+   subtraction, negation  
+   <code>integer one = 3  2;</code>  
+  <code>integer neg_one = 1;</code>  
    
−   +   +   <code>+</code> 
−  text = "Hello" + "  +   addition, string concatenation 
+   <code>integer two = 1 + 1;</code>  
+  <code>string text = "Hello" + " world";</code>  
    
−   +   +   <code>+</code> 
−  newList = oldList + addList;  +   list concatenation 
+   <code>list myList = [1, 2, 3] + [4, 5];</code>  
+  <code>list newList = oldList + addList;</code>  
    
−   << >>  +   <code><<</code> <code>>></code> 
+   [https://en.wikipedia.org/wiki/Arithmetic_shift arithmetic] left shift, [https://en.wikipedia.org/wiki/Arithmetic_shift arithmetic] right shift  
+   <code>integer eight = 4 << 1;</code>  
+  <code>integer neg_one = 2 >> 1;</code>  
    
−   < <= > >=  +   <code><</code> <code><=</code> <code>></code> <code>>=</code> 
−  +   less than, less than or equal to, greater than, greater than or equal to  
−   isFalse = (6  +   <code>integer isFalse = (6 <= 4);</code> 
    
−   ==  +   <code>==</code> <code>!=</code> 
+   comparison: equal, not equal  
+   <code>integer isFalse = ("this" == "that");</code>  
    
−   &  +   <code>&</code> 
−  four = 4 & 4;  +   bitwise AND 
+   <code>integer zero = 4 & 2;</code>  
+  <code>integer four = 4 & 4;</code>  
    
−   ^  +   <code>^</code> 
−  six = 4 ^ 2;  +   bitwise XOR 
+   <code>integer zero = 4 ^ 4;</code>  
+  <code>integer six = 4 ^ 2;</code>  
    
−   <nowiki></nowiki>  +   <code><nowiki></nowiki></code> 
−  six = 4 <nowiki></nowiki> 2;  +   bitwise OR 
+   <code>integer four = 4 <nowiki></nowiki> 4;</code>  
+  <code>integer six = 4 <nowiki></nowiki> 2;</code>  
    
−   <nowiki></nowiki>  +   <code><nowiki></nowiki></code> 
+   logical OR  
+   <code>integer isTrue = (FALSE <nowiki></nowiki> TRUE);</code>  
    
−   &&  +   <code>&&</code> 
+   logical AND  
+   <code>integer isFalse = (FALSE && TRUE);</code>  
    
−   = += = *= /= %=  +   <code>=</code> <code>+=</code> <code>=</code> <code>*=</code> <code>/=</code> <code>%=</code> 
+   assignment  
+   <code>integer four = 4;</code>  
+  <code>integer eight = four; eight *= 2;</code>  
}  }  
−  '''Note:'''  +  '''Note:''' Modulus (<code>%</code>), like division, cause a ''Script runtime error. Math Error'' when its second operand equals zero. 
+  '''Note:''' The <code>%</code> operator only accepts integer (<code>%</code> as modulus) and vector (<code>%</code> as cross product) operands.  
+  
+  '''Note:''' Unlike most other languages that use the Cstyle <code>&&</code> and <code></code> operators, '''both''' operands are '''always''' evaluated. For example,  
+  
+  <source lang="lsl2">if (TRUE  1/0) llSay(PUBLIC_CHANNEL, "Aha!");</source>  
+  
+  : will cause a Math Error rather than say "Aha!"  
+  
+  '''Note:''' The <code>++</code> (increment) and <code></code> (decrement) operators have two versions, pre and post. The ''pre''increment (or ''pre''decrement) operator increments (or decrements) its operand by 1; the value of the expression is the incremented (or decremented) value. The ''post''increment (or ''post''decrement) operator increases (or decreases) the value of its operand by 1, but the value of the expression is the operand's original value ''prior'' to the operation.  
+  
+  <source lang="lsl2">integer count = 0;  
+  if( ++count == 1 ) // 'count' is incremented then evaluated.  
+  llSay(PUBLIC_CHANNEL, "Aha"); // message will be said.</source>  
+  
+  <source lang="lsl2">integer count = 0;  
+  if( count++ == 1 ) // 'count' is evaluated then incremented.  
+  llSay(PUBLIC_CHANNEL, "Aha"); // message will not be said.</source>  
+  
+  
+  '''Note:''' The order of precedence of boolean operators is unclear. It is possible that there is a [http://jira.secondlife.com/browse/SVC779 bug] in the expression parser, making precedence inconsistent, or it may simply be that '''''' and '''&&''' have equal precedence; testing is inconclusive. Thus, when in doubt, parenthesize.  
+  '''SubNote:''' As the above bug has been closed as expected behavior, one can only assume the boolean operators have equal precedence.  
+  
+  '''Note:''' The order of evaluation appears to be backwards from most languages. If the value of x starts as 1 then the first two conditions below evaluate false and the second two evaluate true:  
+  
+  <source lang="lsl2">(x && (x = 0) == 0 && x)</source>  
+  <source lang="lsl2">(x && (x = 0) == 0 && x == 0)</source>  
+  <source lang="lsl2">(x == 0 && (x = 0) == 0)</source>  
+  <source lang="lsl2">(x == 0 && (x = 0) == 0 && x)</source>  
+  
+  Both sides are evaluated regardless of the the truth of either side.  
+  
+  
+  '''Note:''' Equality test on lists does not compare contents, only the length.  
{ {{Prettytable}}  { {{Prettytable}}  
+  +  
==+ Operator==  ==+ Operator==  
−  <code>left + right</code>  +  <code>result = left + right</code> 
{{Hl2}}  {{Hl2}}  
!Left Type  !Left Type  
Line 101:  Line 173:  
Adds '''left''' and '''right'''<br/>Not useful for combining rotations, use [[#* Operator*]] or [[#/ Operator/]] instead.  Adds '''left''' and '''right'''<br/>Not useful for combining rotations, use [[#* Operator*]] or [[#/ Operator/]] instead.  
}  }  
+  
+  { {{Prettytable}}  
+  +  
+  ==Shorthand Operators==  
+  Alternatives to the simple '=' operator...  
+  {{Hl2}}  
+  !Simple assignment operator  
+  !Shorthand operator  
+    
+  a = a + 1  
+  a += 1  
+    
+  a = a – 1  
+  a = 1  
+    
+  a = a * (n+1)  
+  a *= (n+1)  
+    
+  a = a / (n+1)  
+  a /= (n+1)  
+    
+  a = a % b  
+  a %= b  
+  }  
+  
+  =={{WikipediaDe Morgan's lawsw=n}}==  
+  { {{Prettytablestyle=margintop:0; float:left;}}  
+  + Bitwise Equivalencies  
+  !AND  
+  !OR  
+    
+   <code>~(a & b)</code>  <code>~a  ~b</code>  
+    
+   <code>~a & ~b</code>  <code>~(a  b)</code>  
+    
+   colspan="2"   
+    
+   <code>a & ~b</code>  <code>~(~a  b)</code>  
+    
+   <code>~(a & ~b)</code>  <code>~a  b</code>  
+    
+  }  
+  { {{Prettytablestyle=margintop:0; float:left;}}  
+  + Boolean Equivalencies  
+  !AND  
+  !OR  
+    
+   <code>!(a && b)</code>  <code>!a  !b</code>  
+    
+   <code>!a && !b</code>  <code>!(a  b)</code>  
+    
+   colspan="2"   
+    
+   <code>a && !b</code>  <code>!(!a  b)</code>  
+    
+   <code>!(a && !b)</code>  <code>!a  b</code>  
+    
+  }  
+  Due to {{WikipediaDe Morgan's lawsw=n}}, by row, code in the '''AND''' column is logically equivalent to code in the '''OR'''. '''a''' and '''b''' need not be variables, they can be expressions. In certain circumstances these equivalencies can be used to simplify complex code. It is important not to confuse the two sets when using them. The first two rows depict De Morgan's laws as it is formulated, the second two build upon it.  
{{LSLC}}{{LSLCSyntax}}{{LSLCKeywords}}  {{LSLC}}{{LSLCSyntax}}{{LSLCKeywords}} 
Latest revision as of 05:20, 21 December 2015
LSL Portal  Functions  Events  Types  Operators  Constants  Flow Control  Script Library  Categorized Library  Tutorials 
Operators are used to cause an operation (or mathematical action) to be performed on one (such as !) or two operands. The easy and common example is 1 + 2 where 1 and 2 are operands, and the + is the operator. This concept can be extended much further with LSL since operands can be variables with the special case of the assignment operators requiring that the left hand side be a variable.
The following table lists the operators in descending order of evaluation, i.e. higher in the table means higher evaluation precedence. Multiple operators on the same line share evaluation precedence. Parenthesize an expression if you need to force an evaluation order.
Operator  Description  Usage Example 

()

parentheses: grouping and evaluation precedence  integer val = a * (b + c);

[]

brackets: list constructor  list lst = [a, 2, "this", 0.01];

(type)

typecasting  string message = "The result is:" + (string)result;

! ~ ++ 

logical NOT, bitwise NOT, increment, decrement  counter++;

* / %

multiply/dot product, divide, modulus/cross product  integer rollover = (count + 1) % 5;



subtraction, negation  integer one = 3  2;

+

addition, string concatenation  integer two = 1 + 1;

+

list concatenation  list myList = [1, 2, 3] + [4, 5];

<< >>

arithmetic left shift, arithmetic right shift  integer eight = 4 << 1;

< <= > >=

less than, less than or equal to, greater than, greater than or equal to  integer isFalse = (6 <= 4);

== !=

comparison: equal, not equal  integer isFalse = ("this" == "that");

&

bitwise AND  integer zero = 4 & 2;

^

bitwise XOR  integer zero = 4 ^ 4;



bitwise OR  integer four = 4  4;



logical OR  integer isTrue = (FALSE  TRUE);

&&

logical AND  integer isFalse = (FALSE && TRUE);

= += = *= /= %=

assignment  integer four = 4;

Note: Modulus (%
), like division, cause a Script runtime error. Math Error when its second operand equals zero.
Note: The %
operator only accepts integer (%
as modulus) and vector (%
as cross product) operands.
Note: Unlike most other languages that use the Cstyle &&
and 
operators, both operands are always evaluated. For example,
if (TRUE  1/0) llSay(PUBLIC_CHANNEL, "Aha!");
 will cause a Math Error rather than say "Aha!"
Note: The ++
(increment) and 
(decrement) operators have two versions, pre and post. The preincrement (or predecrement) operator increments (or decrements) its operand by 1; the value of the expression is the incremented (or decremented) value. The postincrement (or postdecrement) operator increases (or decreases) the value of its operand by 1, but the value of the expression is the operand's original value prior to the operation.
integer count = 0; if( ++count == 1 ) // 'count' is incremented then evaluated. llSay(PUBLIC_CHANNEL, "Aha"); // message will be said.
integer count = 0; if( count++ == 1 ) // 'count' is evaluated then incremented. llSay(PUBLIC_CHANNEL, "Aha"); // message will not be said.
Note: The order of precedence of boolean operators is unclear. It is possible that there is a bug in the expression parser, making precedence inconsistent, or it may simply be that  and && have equal precedence; testing is inconclusive. Thus, when in doubt, parenthesize.
SubNote: As the above bug has been closed as expected behavior, one can only assume the boolean operators have equal precedence.
Note: The order of evaluation appears to be backwards from most languages. If the value of x starts as 1 then the first two conditions below evaluate false and the second two evaluate true:
(x && (x = 0) == 0 && x)
(x && (x = 0) == 0 && x == 0)
(x == 0 && (x = 0) == 0)
(x == 0 && (x = 0) == 0 && x)
Both sides are evaluated regardless of the the truth of either side.
Note: Equality test on lists does not compare contents, only the length.
Left Type  Right Type  Result Type  Description 

integer  integer  integer  Adds left and right 
integer  float  float  Adds left and right 
float  integer  float  Adds left and right 
string  string  string  Concatenates right onto the end of left. 
list  *  list  Concatenates right onto the end of left. 
*  list  list  Affixes left onto the start of right. 
vector  vector  vector  Adds left and right 
rotation  rotation  rotation  Adds left and right Not useful for combining rotations, use * or / instead. 
Simple assignment operator  Shorthand operator 

a = a + 1  a += 1 
a = a – 1  a = 1 
a = a * (n+1)  a *= (n+1) 
a = a / (n+1)  a /= (n+1) 
a = a % b  a %= b 
De Morgan's laws
AND  OR 

~(a & b) 
~a  ~b

~a & ~b 
~(a  b)

a & ~b 
~(~a  b)

~(a & ~b) 
~a  b

AND  OR 

!(a && b) 
!a  !b

!a && !b 
!(a  b)

a && !b 
!(!a  b)

!(a && !b) 
!a  b

Due to De Morgan's laws, by row, code in the AND column is logically equivalent to code in the OR. a and b need not be variables, they can be expressions. In certain circumstances these equivalencies can be used to simplify complex code. It is important not to confuse the two sets when using them. The first two rows depict De Morgan's laws as it is formulated, the second two build upon it.