5.OPERATORS AND EXPRESSIONS
A Programming Language Manual





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...