 |

5.1 What are they?
We learned in the previous chapters about data values. Now we'll learn how to
operate with them.
A very simple and classic operation is 1+1.
In this case, both integer values of 1 are
called operands and the +
sign is the operator.
It will add the values of the two operands resulting a new value, that we all
know to be 2. There are also the substraction, multiplication and division operators.
Now, operators can be classified by their operands types.
As you can write 1+1 resulting the value 2, in GS9 you can also write "hello "+"world"
and that will result the string "hello world".
In this example the same additive operator, that can add two integers, will
concatenate the two strings.
Belive it or not a comparation is also an operator. The result is the integer
value 1 if the comparation was successful and 0 if not.
You can't mix different types of operands in the same operation, meaning you can't
add integers with strings and not even with floats, unless you convert the second
operand to the type of the first one ( like 1 + (int)"10" ).
Even if most operators need two operands, there are operators that work only
on one operand.
An expression is a composition of one or more operations.
Expressions can be used as operands for most of the operators.
You can store the result of an expression in a variable in the same way as you
store a constant value or another variable's value. Like a = 1+1; or a = 10 * b;
Because some operators are considered more powerfull than others, the processor will perform them first.
For example, the multiplication operator have priority over the additive one.
Because of that, 1+1*2 is 3, not 4.
So ordering operations is important and you can use brakets to group them as you need.
For example (1+1)*2 is 4.
Now, let's classify the operators supported by GS9.
5.2 Logic operators
The logical operators are working with
integers,
but they consider only two values: false if the number is 0, and true
if the number is different than 0. The true and false values are called boolean values. They work exactly as human logic would expect.
| NOT |
! |
negation, turns false into true and true into false |
| AND |
&& |
is true if and only if both operands are true (non zero) |
| OR |
|| |
is true if at least one operand is true |
| NOT |
false |
true |
| |
true |
false |
|
| AND |
false |
true |
| false |
false |
false |
| true |
false |
true |
|
| AND |
false |
true |
| false |
false |
true |
| true |
true |
true |
|
Logic operators accept other types as well, considering false the followings:
VOID strings, empty tables, uninitialized references and NULL pointers.
The NUL type is not accepted as boolean.

5.3 Arithmetic operators
Those are the classic mathematical operators we use every day.
They work on both
integers and
floats.
The additive operator (+) will also work on
strings
and
tables
and it will concatenate them.
Trying to perform a division or modulo by zero will generate an error.
| SIGN |
- |
inverts the sign of the number |
| ADD |
+ |
adds numbers or concatenate strings |
| SUB |
- |
substracts the second operand from the first |
| MUL |
* |
multiply numbers |
| DIV |
/ |
divide the first operand to the second |
| MOD |
% |
modulo, gives the rest of the division |

5.4 Bit operators
Here is where the
binary format of
integers numbers comes in handy.
We know that any integer can be represented in a binary format with only two digits, 0 and 1.
If we consider 0 to be false and 1 to be true, those binary operators work with
integers like logical operators, but on a bit level.
| bit NOT |
~ |
inverts the sign of the number |
| bit AND |
& |
1&1=1, 1&0=0, 0&1=0, 0&0=0 |
| bit OR |
| |
1|1=1, 1|0=1, 0|1=1, 0|0=0 |
| bit XOR |
^ |
1^1=0, 1^0=1, 0^1=1, 0^0=0 (exclusive or) |
| SHIFT LEFT |
<< |
will shift all bits to the left, loosing the value of the last bit |
| SHIFT RIGHT |
>> |
will shift all bits to the right, loosing the value of the first bit |
Consider that integer numbers in GS9 have 32 bits and their last bit (31) is used for the sign
(is set to 1 for negative numbers).
Also, it's worth mentioning that one shift left operation is echivalent with a multiplication with 2.
And a shift right is echivalent with a division by 2.
| 13 |
00001101 |
| 7 |
00000111 |
| 13 & 7 = 5 |
00000101 |
|
| 13 |
00001101 |
| 7 |
00000111 |
| 13 | 7 = 15 |
00001111 |
|
| 13 |
00001101 |
| 13 << 1 = 26 |
00011010 |
| 13 << 2 = 52 |
00110100 |
|
| 13 |
00001101 |
| 13 >> 1 = 6 |
00000110 |
| 13 >> 2 = 3 |
00000011 |
|

5.5 Assignment operators
You have already used an assignment operator. It's the operator = that sets values into variables.
GS9 language also supports compound assignaments.
Those are combinations of the assignment operator and the operators presented before.
For example, instead of writing a = a + 1, we can quicker write a += 1 or even a++.
Simple enought.
All assignment operators require a variable as the left operand.
| SET |
= |
a = b sets a value of b into variable a |
| ADD SET |
+= |
a += b is a = a + b |
| SUB SET |
-= |
a -= b is a = a - b |
| MUL SET |
*= |
a *= b is a = a * b |
| DIV SET |
/= |
a /= b is a = a / b |
| MOD SET |
%= |
a %= b is a = a % b |
| bit AND SET |
&= |
a &= b is a = a & b |
| bit OR SET |
|= |
a |= b is a = a | b |
| bit XOR SET |
^= |
a ^= b is a = a ^ b |
| SHIFT LEFT SET |
<<= |
a <<= b is a = a << b |
| SHIFT RIGHT SET |
>>= |
a >>= b is a = a >> b |
| INCREMENT |
++ |
a++ is a = a + 1 |
| DECREMENT |
-- |
a-- is a = a - 1 |

5.6 Relational operators
Those operators are used to compare two values.
The result is the integer value 1 (true) if the comparation was successful and 0 (false) if not.
The operators can compare integer and float numbers.
The equal and not equal operators can also compare strings and pointers.
| EQUAL |
== |
a==b is 1 if a is equal with b |
| NOT EQUAL |
!= |
a!=b is 1 if a is not equal with b |
| LESS |
< |
a<b is 1 if a is less than b or 0 otherwise |
| LESS OR EQUAL |
<= |
a<=b is 1 if a is less or equal to b and 0 otherwise |
| GREATER |
> |
a>b is 1 if a is greater than b or 0 otherwise |
| GREATER OR EQUAL |
>= |
a>=b is 1 if a is greater or equal to b and 0 otherwise |

5.7 Conditional expression operator
This operator can be used to quickly select the result of one of two expressions, based on the result of another conditional expression.
| c ? a : b |
If operator c is true (non-zero), then the operation will evaluate
to the value of operator a, otherwise it will evaluate to b
|

5.8 Indexing operators
You have already met the table indexing operator [ ] used to access
tables
elements by their indexes.
Now, since the
strings
are lists of characters and characters have integer numbers associated through the ASCII convention,
it is only fair to be able to access each character in a string, as an integer value.
This is done using the the string indexing operator [[ ]].
| TABLE INDEXING |
[ ] |
t[idx] evaluates to the idx-th element of the table t |
| STRING INDEXING |
[[ ]] |
s[[idx]] evaluates to the idx-th character of the string s |
As with tables, string indexes start with 0, but strings have an extra hidden element to mark the end of the text.
It is called end of string (or short eos) and it has the the integer value 0.
So the size of a string is usually the count of visible characters plus one.

Since the elements of a string are characters and the ASCII codes are integers in the 0 to 255 range,
it is not recomanded to try storing bigger values in the elements of a string, because they will be clamped anyway.
Because of their range of values, charcters are also called bytes.

When indexing tables or strings you must take great care not access elements out of their bounds.
Indexes are valid as long as they are greater or equal to 0 and less than the size of the table or string.
Accessing elements outside this range will make the processor report an error.
So, for mytab[idx], you must have 0<=idx and idx<sizeof(mytab)
And for mystr[[idx]], you must have 0<=idx and idx<sizeof(mystr)

Strings must always contain an eos character (0).
Trying to print a string without an eos marker (with all characters non zero) may produce unexpected behaviour and may lead to a program critical error!

5.9 Reference operators
Those operators work with
reference variables
and are used to set or get the refered variable.
If needed, use brakets to group those operations inside expression.
| ADDRESS |
& |
&a will return a reference variable that refers the variable a |
| CONTENT |
* |
*r will return the variable refered by the reference variable r |
Consider that because the content of a reference variable (*r) represent the same thing as the refered variable,
it can be used in any expressions where the refered variaable could be used.

Now, that you know about operators too, let's have a look at the program flow and take a few decisions...
|
 |