Latest revision |
Your text |
Line 282: |
Line 282: |
|
| |
|
| For most purposes the above definitions for AND & OR are sufficient, however Squirrel does not simply return boolean true or false for these operators, rather it returns a specific operand passed to the operator based on the result. | | For most purposes the above definitions for AND & OR are sufficient, however Squirrel does not simply return boolean true or false for these operators, rather it returns a specific operand passed to the operator based on the result. |
| <pre>
| |
| Logical AND will return the *first* operand that evaluates to *false*, if none do, it will return the *last* operand.
| |
|
| |
|
| Logical OR will return the *first* operand that evaluates to *true*, if none do, it will return the *last* operand. | | Logical AND will return the '''first''' operand that evaluates to '''false''', if none do, it will return the '''last''' operand. |
| </pre>
| |
| A common use case of this functionality with the logical OR operator is to fill a variable with the first value that evaluates to true.
| |
|
| |
|
| <syntaxhighlight lang="c#" line="1" start="1" style="font-weight:bold;>
| | Logical OR will return the '''first''' operand that evaluates to '''true''', if none do, it will return the '''last''' operand. |
| local var = othervar || otherothervar || 1;
| |
| </syntaxhighlight>
| |
| | |
| In some cases we may have access to variables that we don't know the value of, they could be null for all we know! This is a good way of providing "backup" values to use in our program.
| |
|
| |
|
|
| |
|
Line 312: |
Line 304: |
| <span style="font-size:120%">'''Bitwise'''</span> | | <span style="font-size:120%">'''Bitwise'''</span> |
|
| |
|
| All data in computer memory is stored as sequences of bits; 0's and 1's. The bitwise operators work directly with those bits for integer values in Squirrel. As a beginner you aren't likely to use these operators unless you have a very specific reason to. We won't go over what each of these does under the hood as it's a bit out of scope for this language introduction, however if you want to learn more about bits and the bitwise operators, [https://www.learncpp.com/cpp-tutorial/bitwise-operators/ learncpp.com] goes over them quite nicely. (Just ignore the C++ specific stuff.) | | All data in computer memory is stored as sequences of bits; 0's and 1's. The bitwise operators work directly with the bits of variables and literals in Squirrel. These operators are rarely used unless you have very specific needs within your program. For day to day use, you're mostly going to be using bitwise AND & bitwise OR to manipulate '''bit flags''', which are variables where each of the 32 bits (or however big the variable is) represents a boolean flag. So instead of having 32 different boolean variables, you can have 1 variable that represents 32 booleans! |
| | | &, |, ^, ~, <<, >>, >>> |
| | |
| {| class="wikitable" style="width:100%; margin:auto; text-align:center font-weight:bold; font-size:110%"
| |
| |+
| |
| !Operator
| |
| !Symbol
| |
| !Form
| |
| !Operation
| |
| |- style="text-align:center"
| |
| |Bitwise NOT
| |
| | ~
| |
| | ~x
| |
| |Flips all bits in x; 1 becomes 0 and 0 becomes 1
| |
| |- style="text-align:center"
| |
| |Bitwise AND
| |
| | &
| |
| | x & y
| |
| |Each bit in x AND each bit in y
| |
| |- style="text-align:center"
| |
| |Bitwise OR
| |
| | <nowiki>|</nowiki>
| |
| | x <nowiki>|</nowiki> y
| |
| |Each bit in x OR each bit in y
| |
| |- style="text-align:center"
| |
| |Bitwise XOR
| |
| | ^
| |
| | x ^ y
| |
| |Each bit in x Exclusive OR each bit in y
| |
| |- style="text-align:center"
| |
| |Left shift
| |
| | <<
| |
| | x << y
| |
| |Shift all bits in x left by integer y spaces
| |
| |- style="text-align:center"
| |
| |Right shift
| |
| | >>
| |
| | x >> y
| |
| |Shift all bits in x right by integer y spaces
| |
| |- style="text-align:center"
| |
| |Unsigned right shift
| |
| | >>>
| |
| | x >>> y
| |
| |Same as normal right shift (>>) but treat x as unsigned (only positive values, no negative ones)
| |
| |}
| |
| | |
| | |
| For day to day use, you're mostly going to be using bitwise AND along with bitwise OR to manipulate '''bit flags''', which are variables where each of the 32 bits (or however big the variable is) represents a boolean flag. So instead of having 32 different boolean variables, you can have 1 variable that represents 32 booleans! | |
| | |
| The m_fFlags datamap of [[CBaseEntity]] in the Source Engine is a real example of this, each of the 32 bits of the integer can represent a flag. Defined in the source code are macros which contain the values for these bits, as you can see below the left shift operator is used to shift the bits (more accurately the only bit) of integer 1 left by an increasing amount of places.
| |
| | |
| <syntaxhighlight lang="c#" line="1" start="1" style="font-weight:bold;>
| |
| #define FL_ONGROUND (1<<0) // At rest / on the ground
| |
| #define FL_DUCKING (1<<1) // Player flag -- Player is fully crouched
| |
| #define FL_ANIMDUCKING (1<<2) // Player flag -- Player is in the process of crouching or uncrouching but could be in transition
| |
| #define FL_WATERJUMP (1<<3) // player jumping out of water
| |
| #define FL_ONTRAIN (1<<4) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
| |
| | |
| ...
| |
| | |
| #define FL_UNBLOCKABLE_BY_PLAYER (1<<31) // pusher that can't be blocked by the player
| |
| </syntaxhighlight>
| |
| | |
| The middle part has been omitted for brevity, the first five macros are equivalent to the integer values: <code>'''1, 2, 4, 8, and 16'''</code> and the last is <code>'''2147483648'''</code>. In VScript, these have been defined in the [https://developer.valvesoftware.com/wiki/Team_Fortress_2/Scripting/Script_Functions/Constants#FPlayer FPlayer] enum and can be used in your programs when necessary, however the way to manipulate bit flags is a bit different than regular integers, you can't just try to add them together with the addition operator!
| |
|
| |
|
| | <span style="font-size:120%">'''Other Operators'''</span> |
|
| |
|
| To add bit flags together, use the bitwise OR (<code>'''|'''</code>) operator.
| | in, instanceof, typeof, comma, ternary |
|
| |
|
| <syntaxhighlight lang="c#" line="1" start="1" style="font-weight:bold;>
| |
| // In real code, you would need to prefix these with "Constants.FPlayer." (e.g. Constants.FPlayer.FL_ONGROUND), this is just a brief demonstration
| |
|
| |
|
| local mybitflags = FL_ONGROUND | FL_DUCKING | FL_ANIMDUCKING; // 7 (1 + 2 + 4)
| | <span style="font-size:120%">'''Operator Precedence'''</span> |
| </syntaxhighlight> | |
|
| |
|
| To remove a flag, use the bitwise AND (<code>'''&'''</code>) operator along with the bitwise NOT (<code>'''~'''</code>) operator on the flag.
| | -, ~, !, typeof , ++, -- highest |
| | /, *, % … |
| | +, - |
| | <<, >>, >>> |
| | <, <=, >, >=, instanceof |
| | ==, !=, <=> |
| | & |
| | ^ |
| | &&, in |
| | +=, =, -=, /=, *=, %= … |
| | , (comma operator) lowest |
|
| |
|
| <syntaxhighlight lang="c#" line="1" start="1" style="font-weight:bold;>
| | IntegerLiteral ::= [1-9][0-9]* | '0x' [0-9A-Fa-f]+ | ''' [.]+ ''' | 0[0-7]+ |
| // In real code, you would need to prefix these with "Constants.FPlayer." (e.g. Constants.FPlayer.FL_ONGROUND), this is just a brief demonstration
| | FloatLiteral ::= [0-9]+ '.' [0-9]+ |
| | | FloatLiteral ::= [0-9]+ '.' 'e'|'E' '+'|'-' [0-9]+ |
| local mybitflags = FL_ONGROUND | FL_DUCKING | FL_ANIMDUCKING; // 7 (1 + 2 + 4)
| | StringLiteral ::= '"'[.]* '"' |
| | | VerbatimStringLiteral ::= '@''"'[.]* '"' |
| printl(mybitflags & ~FL_ONGROUND); // 6
| |
| printl( mybitflags & ~(FL_ONGROUND | FL_ANIMDUCKING) ); // 2
| |
| </syntaxhighlight>
| |
| | |
| To test if a flag is present, use the bitwise AND (<code>'''&'''</code>) operator and compare the result against 0 using the inequality operator.
| |
| | |
| <syntaxhighlight lang="c#" line="1" start="1" style="font-weight:bold;>
| |
| // In real code, you would need to prefix these with "Constants.FPlayer." (e.g. Constants.FPlayer.FL_ONGROUND), this is just a brief demonstration
| |
| | |
| local mybitflags = FL_ONGROUND | FL_DUCKING | FL_ANIMDUCKING;
| |
| local testflags = FL_ONGROUND | FL_DUCKING;
| |
| | |
| printl( (mybitflags & testflags) != 0 ) // true
| |
| printl( (mybitflags & FL_ONTRAIN) != 0 ) // false
| |
| </syntaxhighlight>
| |