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 numeric 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 numbers, will concatenate the two strings. Belive it or not a comparation is also an operator. The result is the numeric 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 numbers with strings, unless you convert the second operand to the type of the first one ( like 1 + NUM("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 used with numbers, 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 also accept other types. For example a NULL pointer is considered false..

5.3 Arithmetic operators

Those are the classic mathematical operators we use every day.
They work on both numbers. The additive operator (+) will also work on strings and tables and it will concatenate them. Pointers can also be added and, in this case, they can even be combined with numbers.

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

Trying to perform a division or modulo by zero will generate an error.

5.4 Bit operators

Here is where the binary format of integer 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.

Even if GS uses only float numbers, these operations will perform on their bits like on integer values. However, due to the limitations of float numbers, not all integer values can be represented with floats.

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

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 number 1 (true) if the comparation was successful and 0 (false) if not.
If the operators have different types the == operator will always return false and the != operator will always return true. The equal and not equal operators can also compare other types (strings, tables, etc.)

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. If using expressions with this operator, take care for the operations order.

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 numbers associated through the ASCII convention, it is only fair to be able to access each character in a string, as an numeric 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

In GS9 strings are "immutable", meaning you can't change their content. So you can only use the indexing operator on strings to read their characters as numbers in the 0 to 255 range, representing the associated ASCII codes.

In C/C++ language strings always contain an additional character with the value 0, named EOS (end of string). GS9 strings store this character internally too, but it is not accessible through the indexing operator.

When indexing tables or strings you must take great care not access elements outside heir 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)

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