|
Operators Ferite comes with a whole bundle of operators to play with. They allow you to do basic
things such as arithmetic operations all the way to on-the-fly code generation and
execution. With each operator it's action on different types will be described. When an
operator is applied to types it can not deal with, an exception is thrown and must be
handled (see exception handling).
Arithmetic Operators Addition, this operator adds two variables together. Currently it only applies
to numbers and strings. Adding strings together acts as concatenation, and adding a
number onto a string will cause it to be converted to a string and concatenated.
When an object gets asked to be added
to a string, the operator checks for a .toString() function in
the object and calls that - this means that you as the programmer can provide a
custom string representation of the object. This is the same mechnism that is used
when you reference variables in strings using '$'.
Table 2-1. Addition '+' Left \ Right | void | number | string | array | object | void | | | | | | number | | This will return a number. If the left hand side or the right hand side is in
the floating point form the resulting number will be floating point.
| | | | string | The left hand string with (void) at the end. | The left hand string with the value of the number converted to a string. | A string containing the left hand side with the right hand side concatenated onto the end. | The left hand string with the string representation of the array concatenated onto the end. | The left hand string with the result of the toString method in the object called. | array | | | | | | object | | | | | |
Subtraction
Table 2-2. Subtraction '-' Left \ Right | void | number | string | array | object | void | | | | | | number | | This will return a number. If the left hand side or the right hand side is in
the floating point form the resulting number will be floating point.
| | | | string | | | A string containing the left hand side with all the occurances of the right hand side removed. | | | array | | | | | | object | | | | | |
Multiplication '*' only applies to number types. The result is the left hand side multiplied by the
right hand side. If the left hand side or the right hand side is in
the floating point form the resulting number will be floating point.
Division '/' only applies to number types. The result is the left hand side divided by the
right hand side. If the left hand side or the right hand side is in
the floating point form the resulting number will be floating point. If neither are floating
point then the division will be interger based division.
Modulus (%) - Returns the remainder of integer division between two number
variables. If the numbers are in real format they will be implicitly cast into
integers and then the operation will be done.
Assignment Operators The basic assignment operator is '='. This will make the left hand side variable equal
to the right hand side. This is a copy value operator which means that the right hand
side will be copied and then assigned to the left hand side. This is true with
exception of objects where the left hand side will reference the object and it's
internal reference count will be incremented.
It is possible to extend the operator by placing one of the Arithmetic operators in
front al-la C. e.g. +=, -=, *=, /=, &=, |=, ^=, >>=, <<=. It will have the
effect of taking the existing
left hand side, applying the arithmetic operator with the right hand side and then
assigning it back to the left hand side.
As was mentioned when discussing the void variable type, anything can
be assigned to a variable of type void. This can only be done once as the void type mutates
to the type to which has been assigned to it.
Comparison Operators These are used to compare variables. It is only possible to compare like variable
types, i.e you can only compare strings with strings, and numbers with numbers. They
are all straight forward and act as would be expected from their name.
Equal To (==) - true if both sides are equal.
Not Equal To (!=) - true if both sides aren't equal.
Less Than (<) - true if the left hand side is less than the right.
Less Than Or Equal To (<=) - true if the left is less than or equal to the
right hand side.
Greater Than (>) - true if the left hand side is greater than the right.
Greater Than Or Equal To (>=) - true if the left is less than or equal to the right
hand side.
isa (isa) - true if the left hand side expression is of type stated on the right hand side.
eg.
"Hello World" isa string => true
42 isa string => false
|
insantceOf (instanceof) - true if the left hand side expression is an instance of the class stated on the right hand side.
eg.
Console.stdin instanceof Sys.StdioStream => true
Console.stdio instanceof Test => false
|
Incremental and Decremental Operators These allow incrementing and decrementing of variables. Currently it only works with
numbers.
Prefix Increment (++someVariable)
Postfix Increment (someVariable++)
Prefix Decrement (--someVariable)
Postfix Decrement (someVariable--)
If you have programmed within C or Java before you will know how these work. They both
do what they say on the tin, but the difference between Pre and Post fix is subtle
(but at the same time very very useful). With the prefix version the variable is
in/decremented and the new value is returned, with the postfix the variable is
in/decremented and the previous value is returned. e.g.
number i = 0, j = 0;
j = i++; // j = 0, i = 1
j = ++i; // j = 2, i = 2
|
Logical Operators These apply to truth values and tend to be used for flow control.
Not (!) - true if the expression it is applied to is false. You can also use the keyword not
to represent the operator. This is useful when writing clean code.
And (&&) - true if both variables/expressions are true. It is also
possible to use the keyword and to represent
this operator.
Or (||) - true if either variable/expression is true. It is also
possible to use the keyword or to represent
this operator.
Bitwise Operators It must be noted that when numbers are passed to the bitwise operators their values
are explicitly cast into a natural number if they happen to be floating point. This does not
modify the variable being passed.
Example:
10 & 11.1 will actually be 10 & 11
|
AND (&) - does a bitwise AND on the two variables passed to it.
OR (|) - does a bitwise OR on the two variables passed to it
XOR (|) - does a bitwise XOR on the two variables passed to it
Left Shift (<<) - does a bitwise left shift on the two variables passed to it. It is
equivelent to dividing the left hand side by two a number of times which is specified by the right
hand side.
Right Shift (>>) - does a bitwise left shift on the two variables passed to it. It is
equivelent to multiplying the left hand side by two a number of times which is specified by the right
hand side.
Index Operator The index operator allows for accessing information in string's and array's. There are
three main forms that can be used.
[] - This works on only the array type. The result of this is a void variable
being added to the end of the array and being returned. This is the easiest way
of adding variables to the end of the array.
Example:
array a;
a[] = 1;
a[] = 2;
a[] = 3;
|
The above example causes three items to be added to the array a
with each one being set to a value. As arrays can contain any data type you need to assign
something to the variable returned by [], otherwise you will end up with just a void.
[expression] - This will index the array or string based upon the evaluated
expression. If the expression results in a number - that variable will be returned
from the array, or the character at that location within the string will be returned.
If the expression is a string, it wont have any effect on a string, but will cause
the hash value of that string to be taken out the array. If the hash location doesn't
exist, the variable will be created (it will be placed on the end of the array as if
[] had been used) and is returned. For historical reasons,
the first element in the array is 0, the second 1 and so on.
Example:
array a;
a[] = 1;
a[] = 2;
a["Hello World"] = 3;
a[0] // This will get the first value within the array, in this example '1'
a["Hello World"] // This will get the value pointed to by "Hello World", in this exampe '3'
a[2] // This will get the third value (created using the 4th line of the example)
|
[expression..expression] (also refered to as the slice operator) - This is a range expression.
With strings and arrays it allows you to
take a slice of the variable. The range can be ascending - in which case the order in the
variable is preserved, or descending in which case, the slice is made with the contents
being reversed. It is possible to leave out the upper or lower bound expression dictating
that the operator should go to the end or from the beginning respectivly. If a negative number
is given, it is taken to mean from the end of the variable.
Example:
string s = "Hello";
string t = s[-1..0]; // This will take a slice of the entire string and reverse it
string u = s[..2]; // This will take a slice of the first 3 characters in the string s
|
Complex Operators These operators are individual and slightly more complicated that the other operators.
Object or namespace attribute (.) - To get an attribute or a method
within a namespace or instantiated object you need to use '.'. It is not bound
to the type of variable (ie. namespaces and objects act the same) like C.
Example:
Console.println( "Hello World" );
|
Instantiate an object (new) - This operator is used to create an
instance of a class (which can then be assigned to a an object variable. It is used
as follows:
new <class name>( <parameters> )
|
<class name> The name of the class to be instantiated. <parameters> The arguments to be passed to the constructor of the class.
It should be noted that multiple object variables can point to
one object created using the new keyword. This is discussed later on within the
Classes and Objects section.
Example: object newObject = new SomeClass( "aString", 10 );
newObject = new SomeOtherClass( "James", "Taylor" );
(where SomeClass and SomeOtherClass have been defined elsewhere)
|
Evaluate a string (eval) - This is a very powerful operator and
can be very very useful. It also shows off the difference between a pre compiled
language a scripting language. The eval operator allows you to on the fly compile
and execute a script and get a return value. It is used like so:
eval ( <some string with a script> )
|
The string can be any value - but must be a valid script, if not an exception will
be thrown.
Example: eval( "Console.println(\"Hello World\");" );
|
This script is the same as:
Console.println("Hello World");
|
To return a value, you just use the return keyword (mentioned within the function
documentation in the next chapter). The code below will return '42', which will in
then turn be assigned to the variable value.
number value = eval( "return 42;" );
|
This is of course a very simple example and doesn't show what a useful operator it
is, but it does allow you to at runtime modify the behavior of code. It should also
be noted that there are potential security risks involved with this operator and it
should be considered carefully.
Later on in this manual, the operator include is discussed.
Regular Expressions Ferite features regular expressions with a similar syntax to that of Perl. Currently
there is only one operator concerning regular expressions within ferite (although this
is likely to change).
Apply regular expression (=~) This operator works be applying the regular expression defined on the right hand side
to the string on the left hand side. Regular expressions can only be applied to strings.
For more information regarding regular expressions see the section later on in the
manual.
|