3. Operators
Note:
Most operators in gsl are totally equivalent to the operators in C / JAVAA new value is assigned to a variable in GSL by the expression (exactly like in the declaration when assigning an initial value): VARNAME = NEW_VALUE
where <VARNAME> is the name of the variable to be changed and NEW_VALUE is the desired new value.
Note that the value of this expression is the value of the right side (NEW_VALUE). So int i = 1;
int j = 2;
int k = 3;
i = (j = k) + 10;
The last line will first assign k's value 3 to j, 3 is also the value of the bracket which is then
added to 10 resulting in i beeing 13.In GSL, the types int,bool,string,float are evaluated by value, so if you assign one int variable to another int variable, the will only share their value. If you then alter one of both, the other one will keep its value. This is called assignment by value, since you only assign the var value, not a reference to the variable. Example: int i1 = 0;
int i2 = i1;//i1 and i2 are 0 now
i1 = 10; //i2 is still 0
If you need a reference to an int,float,bool or string, you can use pointers like in C. However, to not make things to complicated and since they are only rarely used, these are discussed only in later chapters. The types array and struct (and object) are assigned by reference. So, if you assign one array variable to another or hand an array to a function, they will point to the same array instance. So, if you then change the values of one, the other one will also have its values changed, since they are the same. Example: array a = array();
array b = a;
a[0] = "bla"; //b[0] is now also "bla" since a and b are the same array instance
Assigning arrays or structs by values can be done by cloning them and passing the clone. The clone function, which doesn't do more than just creating a new copy of the struct/array and copying all entries/members is defined in the essentials.gsl and thus doesn't have to be included manually. Example: array by value array a = array();
array b = clone(a);
a[0] = "bla"; //b[0] is now not "bla" since a and b are different arrays For the types int and float, the following arithmetic operators are defined in gsl:
If both operands where int, the result will also be of type int, if any of the two was float then the result will be a float. Operator precedence: The operations *,/,% are evaluated before + and -. If two operators have the same precedence, than they will be evaluated from the left to the right. Example: int result1 = 1 - 2 - 3;
int result2 = 1 - 2 * 3;
result1 is (1 - 2) - 3 == -4, since equal operators are evaluated from the left to the right.
result2 is 1 - (2 * 3) == -5, since multiplication precedes substraction.Concerning strings, the operator + concatenates two strings. This concatenation precedes any arithmetic addition. So, if one of the two operands is a numeric type and the other one is a string, then the numeric type will be cast to string and then concatenated to the string, not the other way round. Examples: string s = "foo" + "bar"; //s is "foobar" now
int i = 2;
string s = "3";
string t = i + s;
t is now "23" (not "5"!) because concatenation precedes arithmetic addition.All arithmetic operators and the string concatenation can be shortened if combined with an assignment that matches the form "a = a OP b" to "a OP= b" So for example: i = i + 4;
j = j % 3;
can be written as:
i += 4;
j %= 3;
But note that this puts an implicit bracket around the second operand, so: a = a * b + c
is not equal to
a *= b + c
since in the first case a*b is evaluated before the addition with c, but in the second case b+c is first evaluated and then multiplied with a.GSL supports the post increment operator VAR++ and the post decrement operator VAR-- These expressions evaluate to the value of <VAR> prior to the inc-/decrementation and they increment/decrement <VAR>. So, these two lines are semantically equivalent: i = i + 1;
i++; A comparison is an oparator that takes two values and returns a boolean value. For all variable types, gsl supports the comparisons
For numerical, boolean and string values, these comparisons test if the two variables contain the same value. For structs and arrays, they test if x and y really hold the same instance of an array/struct, NOT if their content is equal! In addition, the following operators are defined only for numerical types:
Examples: 3<4; //True, since 3 is less than 4
1<=1; //True, since 1 is less or equal to 1
("foo" + "bar") == "foobar";//True, since both sides represent the same literal
array()==array(); //False, both arrays share the same content (nothing) but they aren't the same instance
array a = array();
array b = a;
a==b; //True, a and b contain the same instance of an array For boolean types, the following logical operators are defined in GSL:
Example: bool b;
b = (true || false); //true
b = (true && false); //false
b = !false; //true
Note that GSL uses "short circuiting" for && and ||. That means, if the expression x in the expression "x&&y" evaluates to false, than the whole expression evaluates to false without evaluating y. The same is true for x evaluating to true in the expression "x||y". This can be used to test something for null (or something else) and only evaluate the second part if the variable is not null: Example: (b != null && a != null && b < a)
b < a is undefined and will throw an error if b or a are null. However due to the short circuit, b < a will not be evaluated if b or a are null.In gsl each variable can be set to null which means something like "no value at all". Structs, objects and arrays are set to null by default. Be careful when using null with bool,float and int variables. The operators that normally operate on these types like +,-,*,||,&& do not work on null values and will throw an error when used on null values. An array entry is also considered null if it doesn't exist yet. But be careful! If a[0] evaluates to null, then there can be two cases: a) the entry doesn't exist. b) the entry exists but null was assigned to it. The difference is that, when iterating over an array the b) cases will be iterated! So if you want to erase an entry from an array don't set it to null, it won't be erased! Rather use the unset() operator (see next chapter). The unset(VARNAME) operator unsets the variable named <VARNAME>. If var name is a local or global variable it will be removed. If the var is used afterwards, you will receive an error, that it cannot be resolved, since it doesn't exist anymore. If unset is used on an array entry (example: unset(a[0]);), then this entry is removed from the array. Note that the unset operator returns the value of the variable it has just unset. It is possible to use unset on struct members which will remove the member from this struct. However this is highly discouraged as it may result in undefined behaviour! Examples: int a = 5;
unset(a);
a = 3; //Error, a can no longer be resolved, it doesn't exist anymore
array a = array();
a[0] = "bla";
a[0] == null; //false, a[0] is NOT null
unset(a[0]);
a[0] == null; //true, a[0] doesn't exist anymore, so it equals null Syntax: EXPRESSION instanceof TYPENAME
The instanceof operator evaluates the expression <EXPRESSION>. Then,it returns true if the value of the expression is of type <TYPENAME> or derived from it. If it ain't, then it returns false.
It can be used to check if a struct is of a specified derived type, or if a var is of a given type. Examples: var a = 5;
bool b = (a instanceof int);//true, since 5 is an instance of integer
typedef Point2D struct{
int x;
int y;
}
typedef Size struct{
int width;
int height;
}
struct s = Size();
bool b;
b = (s instanceof struct); //True, since Size is derived from struct
b = (s instanceof Size); //True, since s contains an instance of Size
b = (s instanceof Point2D); //False, Size is not derived from Point2D In GSL explicit typecasts to type <T> are done by prefixing the expression that should be casted with (T). Example: string s = "23";
int i = (int)s; //Explicit cast to int
For more information see Typecasting. The $ operator is a prefix operator that converts its argument to string, appends it to an internal buffer and also returns it. This internal buffer is read and flushed by some system calls to do stuff like the macro replacement. int i = 15;
int j = $i; //"15" is appended to the internal buffer and 15 is assigned to j A conditional expression, is a construction of three expressions seperated by ? and :. If the first expression's value is true, then the second expressions value is used as value for the whole expression. If not, then the third expression's value is used. The syntax is like this: CONDITION?THENEXPRESSION:ELSEEXPRESSION
<CONDITION> is an expression that must evaluate to a boolean value. If the value is true, then the value of the whole expression is the value of <THENEXPRESSION>. If the value of <CONDITION> is false, then the value of the whole Expression is the value of <ELSEEXPRESSION>
Examples: string s = (3<5?"foo":"bar"); //since 3<5 is true, s is now "foo"
string s2 = (s!="foo"?"foo":"bar"); //since s!="foo" is false, s2 is now "bar"
Masking null with the empty string: string s = ... // s may be null;
string s2 = (s==null?"":s); //if s was null then s2 is "", else s2 is s
|