# Language Reference

## Language Reference

### Datatypes

#### Brief

In Sputnik there is only one datatype called an SV. A SV can be numeric or string data (And more advanced arrays/hashes/objects/classes) and decides how to use the data depending on the situation it is being used in. For example, if you try and multiply two SV variables they will be treated as numbers, if you try and concatenate (join) two SVs they will be treated as strings.

Some examples:

```\$var = 100; // equals the number 100

\$var = 100 * 20; // equals the number 2000

\$var = 100 + (100 / 2); // equals the number 150

\$var = 10 . 20; // equals the string "1020" (. is used to join strings)

\$var = 10 * "omg"; // equals 0 since if a string is used as a number, it will be converted to a number; If it doesn't contain a valid number, it will be assumed to equal 0.

// Example of variable conversions.....
10 / 20 // This action will two Int64 and they will remain Int64s
10 / 20.0 // We have defined one of them as a double so it will convert them both to a double when it does the conversion
// What this means is if you want to make sure your math is indeed using doubles add the . to it such 20.0
// Why? Consider this "\$y = 1 % 3/4;" it wil return NaN ie fail... But if we do "\$y = 1 % 3.0/4.0;" it will work as expected.```

#### Numbers

Numbers can be standard decimal numbers like 2, 4.566, and -7.

Scientific notation is also supported; therefore, you could write 1.5e3 instead of 1500.

Signed Integers (whole numbers) can also be represented in hexadecimal notation by preceding the integer with 0x as in 0x409 or 0x4fff (when using hex notation only 32-bit/64-bit integers numbers are valid not floats/doubles).

Unsigned Integers (whole numbers) can also be represented in hexadecimal notation by preceding the integer with 0x and ending with U as in 0x409U or 0x4fffU (when using hex notation only 32-bit/64-bit integers numbers are valid not floats/doubles).

You can use Signed Octal numbers if you place a 0 before the number such as 077 (only applies if there is no decimal point).

You can use Unsigned Octal numbers if you place a 0 before the number and a U after it such as 077U (only applies if there is no decimal point).

You can use Signed Binary numbers if you place a 0b before the number such as 0b101 this will produce the number 5 (only applies if there is no decimal point).

You can use Unsigned Binary numbers if you place a 0b before the number and a U after it such as 0b101U this will produce the number 5 (only applies if there is no decimal point).

#### Characters

A character is just a single letter/number etc there are a many ways to give a variable a character data type here are a few:

```\$a = (char)'A';
\$a = char('A');
\$a = (char)65;
\$a = (char)0x41;
\$a = @'A';
```

Like strings it is possible to do an escape for the character (see below for list of escapes) example:

```\$a = @'\0'; // Create a null char to be used as a null terminator or something
```

#### Strings

Sputniks strings are ALL UNICODE you can only print UNICODE specific symbols to the console if you change the front to Consolas or something.

Strings are enclosed in double-quotes like "this". If you want a string to actually contain a double-quote use it twice like:

```// "This type of string is parsed for escapes"
// 'This type of string is static and is never parsed'
// qq(This type of string is parsed for escapes)
// qq/This type of string is parsed for escapes/
// qq{This type of string is parsed for escapes}
// qq~This type of string is parsed for escapes~
// qq%This type of string is parsed for escapes%
// qq:This type of string is parsed for escapes:
// qq^This type of string is parsed for escapes^
// qq?This type of string is parsed for escapes?
// qq¬This type of string is parsed for escapes¬
// q(This type of string is static and is never parsed)
// q/This type of string is static and is never parsed/
// q{This type of string is static and is never parsed}
// q~This type of string is static and is never parsed~
// q%This type of string is static and is never parsed%
// q:This type of string is static and is never parsed:
// q^This type of string is static and is never parsed^
// q?This type of string is static and is never parsed?
// q¬This type of string is static and is never parsed¬
// @"This type of string is also never parsed"
//
// When it comes to q, qq you pick the one that suits your needs
// if the large block you are making into a string does not contain
// a ^ then use qq^ string goes inside here  ^ etc```

\$var = "here is a \"double-quote\" - ok?"; // the \n is an escape charactor to cause a special symbol to be placed inside a string in this case it will place a double quote " inside a string.

You can mix quote types to make for easier working and to avoid having to double-up your quotes to get what you want. For example if you want to use a lot of double-quotes in your strings then you should use single-quotes for declaring them:

'This "sentence" contains "lots" of "double-quotes" does it not?'

However if you choose to use to define your strings and then you want to place a ' inside the string it must be done like this:

'Hello this is my string'

In this case is used to place a ' inside a string made of chars.

The "" strings can place variables inside them for example:

"Hello the variable is \$val ok"

And Arrays:

"Hello the variable is \$val ok"

And Hashes:

"Hello the variable is \$val[test] ok"

Warning - Strings made using 'string' are STATIC this means you cannot place variables inside the string like you can with a regular "string"

Note - "" string allows escapes such as \n to form newline however (static) strings do not resolve escapes.

```/*
Escape Sequence		Represents
\\$			Dollar sign
\@			At Sign
\b			Backspace
\f			Formfeed
\n			New line
\m			New line or <BR> depending if #CGI has been set
\r			Carriage return
\t			Horizontal tab
\v			Vertical tab
\s			Space
\'			Single quotation mark
\"			Double quotation mark
\\			Backslash
\?			Literal question mark
\xhh			ASCII character in hexadecimal notation (Expects 2 digits)
\xhhhh			UNICODE character in hexadecimal notation (Expects 4 digits)
\ohhh			ASCII character in octal notation (Expects 3 digits)
\uhhhh			UNICODE character in hexadecimal notation (Expects 4 digits)
\Uhhhhhhhh		UNICODE character in hexadecimal notation (Expects 8 digits first four must be 0000)
\x{h*}			ASCII/UNICODE character in hexadecimal notation (Accepts any valid amount of digits)
\o{h*}			ASCII/UNICODE character in octal notation (Accepts any valid amount of digits)
\C			The following characters become Sputnik code
\c			Ends \C and executes the code found between the \C and \c
\L			Transform all following letters to lowercase
\l			Transform the next letter to lowercase
\I			Transform all following letters to uppercase
\i			Transform the next letter to uppercase
\K			Transform all following letters to the opposite case
\Q			Do not match the following patterns (such as \n \r etc)
\E			Ends \I, \L, \l, \i, \K or \Q functions
\|			Nothing - This sequence outputs nothing
\_			Outputs _
\{			Outputs {
\[			Outputs [
{			The following characters become Sputnik code until } is reached

Example of using the \| escape:
\$a = "cat";
println("\$a\|Dog"); // Note this allows you to place the \$a followed by Dog directly
println("\$aDog"); // Where as this would fail

Example of using the \C escape:
my \$scalar = 6;
say "Code: \C\$scalar * 2\c"; # 'Code: 12'

Example of using the { escape:
my \$scalar = 6;
say "Code: { \$scalar * 2 }"; # 'Code: 12'

More complex example of using the { escape:
my \$Str = "\x48\x65\x6c\x6c\x6f World!";
foreach(\$Str as \$c)
{
println("Char '\$c' | Hex: '0x{Hex(Asc('\$c'),2)}' | Dec '{Asc('\$c')}'");
}

If you don't want to print the return of a \C or { you need to add the ! flag example
my \$i = 0;
println("Value \$i {\\$i++!}") until(\$i == 10);
// The ! flag coming before the } example !} will cause
// the result value of the operation to not be appended
// to the final string

To ignore an escape just place a \ next to it for example:
\\f
*/```

Sputnik strings (in memory) technically do and technically do not have a null terminator... If you are treating the string as binary for some reason the string will still print to screen and even print past null bytes in the string as if they were normal letters without a care in the world. However if you are using it as a normal string the end of the string will always be a null terminator that you can check for and use.

Accessing a strings raw memory and finding the null terminator is not as simple as reading the string with \$var[] since that will only go to length of the string (minus the null terminator) and even a foreach loop will not hit the null terminator either.

Variables can go directly inside strings like so

```println("\$Dog");
// To place a \$Dog in a string like \$DogHello you do it like this
println("\$Dog\|Hello");
or
println("\${Dog}Hello");
println("\$Dog"); // get second character (if string) or second element (if array)```

The benefit of \${Varname} in strings is you get to use Class stuff like so

```Class Test
{
my \$Price;
my \$Name;
};

\$var = new Test();
\$var->\$Price = 77;
\$var->\$Name = "Fox";

say "Price is \${var->\$Price} and name is \${var->\$Name} ok";
// Prints
// Price is 77 and name is Fox ok```

This is very useful in being able to use variables properly inside strings as if they were outside the string.

You can set the index of string using [] example

```\$a = "Cat";
\$a = "?";
say \$a; // C?t```

If you set the index out of bounds it will use spaces to fill in the gap example

```\$a = "Cat";
\$a = "T";
say \$a; // Cat     T```

You can also use += etc on individual chars within a string example

```\$a = "ABC";
\$a += 1;
\$a += 10;
\$a -= 1;
say \$a; // BLB```

#### Multiline Strings

All string can use multiple lines for example:

```println(@"

This is a
multiline
string\n

");```

This type of string does not resolve escapes such as \n so the \n in this string will really be seen as \n literally.

If you wish to place a " inside the @"" string you must place 2 of them like this

```println(@"

This is a
multiline
string and im ""quoted"" ok

");```

It also does not need to be on multiple lines example

`println(@"Hello world!");`

Of could if you wish to resolve the string just use a normal "" like so

```println("

This is a
multiline
string\n

");```

#### String as numbers

Unlike most other languages Sputnik supports the use of *= -= <<= and all the other operators on strings.

However unlike a numeric value each letter of the string is treated as an individual byte.

Since Sputnik strings are Unicode (UTF8) when you do an operation like this it may set the characters value above which is well out of range of a normal byte however when you try pack the string as ASCII or use it as ASCII it will cast the character to a byte anyway solving the problem entirely.

The operation such as | or ^ etc will be performed on each character in sequence.

The string may be cut down to size if the given operation requires it such as &.

In most languages strings simply become a numeric 0 when you try do math on them (or it may be a numeric value if the string contained a float or decimal) but here the string acts in its own unique way.

This will only trigger if both variables you are trying to do the operation on are STRINGS so to avoiding this behavior is very easy by just simply making sure at least one of your variables is not a string.

This is NOT to be confused with the actual binary arrays as shown in the function reference page.

Like Perl the & | ^ on strings works exactly the same as it does in Perl.

However unlike Perl every other operator also applies to the strings such as + - * / etc this may or may not be useful but it is there if you want it.

```\$a = "\x65\x64"; // We can use \xHEXCODE in the strings to define the bytes directly
\$b = "\x65";
\$a += \$b;
printr(\$a);```

```\$a = "ed"; // Or just put the chars directly
\$b = "e";
\$a += \$b;
printr(\$a);```

As stated above all the operators work like this and instead of returning a numeric value it will re-add the bytes to the string in their modified state.

It will try to never add more bytes than needed so if the operation made an Int32 you will have a string with 4 bytes as a result.

A potential problem with this system is some expressions might not produce expected results for example

```\$a = "100";
\$b = "200";

\$a += \$b;

say \$a; // prints: c`````

This is because its accepting the strings as binary there is a simple way to solve this problem you can cast the \$b as an int or float for example

```\$a = "100";
\$b = "200";

\$a += (float)\$b;

say \$a; // prints: 300```

or

```\$a = "100";
\$b = "200";

\$a += (int)\$b;

say \$a; // prints: 300```

Although (int) is a 32-bit integer and (float) is a 32-bit floating point number if you require higher numerical values its recommend you use (Int64) instead of (int) and (double) instead of (float).

#### Bitwise String Operators

Bitstrings of any size may be manipulated by the bitwise operators like ~ | & ^ etc.

If the operands to a binary bitwise op are strings of different sizes, ops act as though the shorter operand had additional zero bits on the right. The granularity for such extension is one or more bytes.

Since Sputnik strings are Unicode (UTF8) when you do an operation like this it makes sure to properly cast as byte to over going over into

```# ASCII-based examples from Perl (applies to Sputnik)
print "j p \n" ^ " a h";            # prints "JAPH\n"
print "JA" | "  ph\n";              # prints "japh\n"
print "japh\n" & '_____';           # prints "JAPH\n";
print 'p N\$' ^ " E<H\n";            # prints "Perl\n";```

If you are intending to manipulate bitstrings, be certain that you're supplying bitstrings: If an operand is a number, that will imply a numeric bitwise operation. You may explicitly show which type of operation you intend by using "" or 0+ , as in the examples below.

```\$foo = 150 | 105;			# yields 255 (0x96 | 0x69 is 0xFF)
\$foo = '150' | 105;			# yields 255
\$foo = 150 | '105';			# yields 255
\$foo = '150' | '105';			# yields string '155' (under ASCII)
\$baz = 0+\$foo & 0+\$bar;			# both ops explicitly numeric
\$biz = "\$foo" ^ "\$bar";			# both ops explicitly stringy
\$biz = (string)\$foo ^ (string)\$bar;	# both ops explicitly stringy
# (of course you can use any cast)```

#### Bitwise Binary Operators

All the above string stuff works on Binary too.

#### Binary

Binary is a special kind of variable in Sputnik.

A binary variable contains a byte array inside itself similar to the normal Sputnik arrays but highly optimized to deal with bytes and very low on ram usage.

Each element in the binary can store a number from 0 to 255 you can grow and shrink binary variables at will do and use a wide variety of functions on them.

What makes the Binary a rather special value in Sputnik is the fact that its never copied or cloned and instead passes itself to everything kind of like a reference.

This means you can pass it around all over the place and use many functions and yet your are still using and modifying your original binary variable the whole time.

This makes it extremely fast since it never has to copy it.

In fact the only time it really needs to do anything else is when you increase its size then it has to extend its internal byte buffer.

The only way to destroy a binary variable is to explicitly use Unset() or BinaryWipe() on it other than that it will remain forever (Or until no more references to it exist then it will delete itself).

Sputnik has a lot of very good Binary functions including stuff like Pack(), Unpack() and even Vec() just like Perl.

Another thing you can do convert to/from any data type to/from binary in Sputnik for example you can place the (binary) cast similar to an (int) cast in C++ to convert stuff to binary in Sputnik.

Everything can be converted to binary including integers, floating points, strings, arrays etc.

You can also convert back to using their casts this makes working with binary effortless in Sputnik.

Also since Binary is a CORE data type in Sputnik (just like Integer/String) you will always know if a variable contains binary or not and it will print/act accordingly unlike PHP for example where it can be extremely difficult to know if you really do have a binary variable or not (Since it uses String for Binary+Strings).

Sputnik does not store Binary inside strings it is a dedicated Byte array you can of course convert a string to binary.

Using Pack to create binary:

```\$bin = Pack("A*", "Hello");
printr \$bin;
// Prints:
// Binary
// (
//      => 72
//      => 101
//      => 108
//      => 108
//      => 111
// )```

Using cast to create binary:

```\$bin = (binary)"Hello";
printr \$bin;
// Prints:
// Binary
// (
//      => 72
//      => 101
//      => 108
//      => 108
//      => 111
// )```

Using bin() to create binary:

```\$bin = bin(72, 101, 108, 108, 111);
printr \$bin;
// Prints:
// Binary
// (
//      => 72
//      => 101
//      => 108
//      => 108
//      => 111
// )```

Of course bin() can use hex:

```\$bin = bin(0x48, 0x65, 0x6C, 0x6C, 0x6F);
printr \$bin;
// Prints:
// Binary
// (
//      => 72
//      => 101
//      => 108
//      => 108
//      => 111
// )```

Binary will always try print as an ASCII string example

```\$bin = bin(0x48, 0x65, 0x6C, 0x6C, 0x6F);
say \$bin;
// Prints:
// Hello```

Bin() supports a number of cool stuff like sequences

```\$bin = bin(@'A', 'B'..'G', 0x10..0x15, 5..8);
printr \$bin;
say BinaryExpand(\$bin);
// Prints
// Binary
// (
//      => 65
//      => 66
//      => 67
//      => 68
//      => 69
//      => 70
//      => 71
//      => 16
//      => 17
//      => 18
//      => 19
//      => 20
//      => 21
//      => 5
//      => 6
//      => 7
//      => 8
// )
// 00 | 41 42 43 44 45 46 47 10 11 12 13 14 15 05 06 07 ABCDEFG.........
// 01 | 08 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- .```

#### Booleans

Booleans are logical values. Only two Boolean values exist: true and false.

They can be used in variable assignments, together with the Boolean operators and, or and not.

Examples:

```\$Boolean1 = true;
\$Boolean2 = false;```

If you use arithmetics together with Boolean values (which is not advisable!), the following rules apply:

A Boolean true will be converted into the numeric value 1

A Boolean false will be converted into the numeric value 0

Example:

```\$Boolean1 = true;
\$Number1 = 100;
\$Number2 = \$Boolean1 + \$Number1;
println( \$Number2 ); // This will result in \$Number2 to be the numeric value 101

\$Boolean1 = true;
\$String1 = "Test is: ";
\$String2 = \$String1 . \$Boolean1;
println( \$String2 ) // This will result in \$String2 being the string value "Test is: True"```

#### Arrays

Variables can also be arrays storing multiple variables in a single variable accessible by its [] index.

Arrays operate very much like PHPs in that it is an array and a hash at the same time.

Heres a simple example:

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements

// Print the details of the array
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);```

An example of adding stuff to end and beginning of an array:

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements
\$lol .= array(5, 6); // Add 2 Elements to end of the array
\$lol ..= array(0); // Add 1 Element to start of the array

// Print the details of the array
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);```

To delete an array you can simply define it as anything including strings but the best way is:

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements
\$lol = array(); // Delete the array

// Print the details of the array
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);```

Copying an array is simple too example:

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements

\$test = \$lol;

// Print the details of the array
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);

println("test :" . \$test);
println("test :" . \$test);
println("test :" . \$test);```

That was a full COPY of the array changing elements in one array will not effect the other unless your first array contained references but we will get into that later.

Arrays can also be modified directly example:

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements

\$lol = "Hello";
\$lol = "hmmm";
\$lol = "hi there!";

// Print the details of the array
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);
println("lol :" . \$lol);```

In the above example you can see simply typing \$var[index] = will cause it to create that index (part of the array) and fill it with what you type, The array will create the new keys (indexes) as you use them you will notice that index 4 to 98 are missing? This is because Sputnik arrays only create keys if they need to and will never fill in gaps for you.

You can of course force it to fix the array indexes so it goes from 0 upwards properly like:

```// Create a simple array with 4 elements
my \$array = array(1, 2, 3, 4);
// Modify it
\$array = "Hello";
\$array = "hmmm";
\$array = "hi there!";
// Print the details of the array
order \$array; // Smooth out the array
printr \$array;
// PRINTS
// Array
// (
//      => 1
//      => hmmm
//      => Hello
//      => 4
//      => hi there!
// )```

Add items to end of an array

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements

\$lol[] = 5;
\$lol[] = 6;
\$lol[] = 7;

// Print the details of the array
printr(\$lol);```

Add items to beginning of an array

```\$lol = array(1, 2, 3, 4); // Create a simple array with 4 elements

\$lol[] = 5;
\$lol[] = 6;
\$lol[] = 7;

\$lol[]! = 0;

// Print the details of the array
printr(\$lol);```

Example of Multi-dimensional array

```\$lol = array(0 => array(3, 4), 1 => array(3 =>array(8, 9))); // Create a simple array with 4 elements

\$lol = "Hello";

// Print the details of the array
println( "lol :" . \$lol );
println( "lol :" . \$lol );
println( "lol :" . \$lol );
println( "lol :" . \$lol );
println( "lol :" . \$lol );
println( "lol :" . \$lol );
println( "lol :" . \$lol );```

If you want to place an array inside an array when creating it you do

```\$b = array( "cat", "dog" );
\$a = array(  1, \$b[<>], 3, 4  );

# So \$a becomes array(  1, "cat", "dog", 3, 4  );
# If we didnt include the [<>] then \$b itself would
# be inserted directly into \$a rather than just copying
# its values```

If you want to place an array inside an array (including its dictionary keys) when creating it you do

```\$b = array( "cat" => "meow", "dog" => "woof" );
\$a = array(  1, \$b, 3, 4  );

# So \$a becomes array(  1, array( "cat" => "meow", "dog" => "woof" ), 3, 4  );
# If we didnt include the [<>] then \$b itself would
# be inserted directly into \$a rather than just copying
# its values```

You can also use the qw// to produce simple arrays example

```// the qw// accepts only alphanumeric letters separated by spaces
\$arr = qw/test omg lol/;
foreach(\$arr as \$lol)
{
println("First test :" . \$lol);
}

// Is equal to
\$arr = array("test", "omg", "lol");
foreach(\$arr as \$lol)
{
println("Second test :" . \$lol);
}
// Alternatively you could use:
// \$arr = qw(test omg lol);
// \$arr = qw{test omg lol};
// \$arr = qw~test omg lol~;
// \$arr = qw!test omg lol!;
// \$arr = qw%test omg lol%;
// \$arr = qw:test omg lol:;
// \$arr = qw^test omg lol^;
// \$arr = qw?test omg lol?;
// \$arr = qw¬test omg lol¬;```

Comparing arrays

```// Compare the full array and all elements requiring a perfect match
if (\$firstarray == \$secondarray)
// Reverse of above
if (\$firstarray != \$secondarray)
// Compare the full array and all elements requiring a even more perfect match
if (\$firstarray === \$secondarray)
// Reverse of above
if (\$firstarray !== \$secondarray)
// (As string) Compare the full array and all elements requiring a perfect match
if (\$firstarray eq \$secondarray)
// (As string) Reverse of above
if (\$firstarray neq \$secondarray)
// (As string) Compare the full array and all elements requiring a perfect match (case insensitive)
if (\$firstarray eqi \$secondarray)
// (As string) Reverse of above
if (\$firstarray neqi \$secondarray)
// (As string) Compare if first is lower than second
if (\$firstarray lt \$secondarray)
// (As string) Compare if first is greater than second
if (\$firstarray gt \$secondarray)
// (As string) Compare if first is lower than or equal to second
if (\$firstarray le \$secondarray)
// (As string) Compare if first is greater than or equal to second
if (\$firstarray ge \$secondarray)
// (As string) Compare if first is lower than second (case insensitive)
if (\$firstarray lti \$secondarray)
// (As string) Compare if first is lower than or equal to second (case insensitive)
if (\$firstarray gti \$secondarray)
// (As string) Compare if first is lower than or equal to second (case insensitive)
if (\$firstarray lei \$secondarray)
// (As string) Compare if first is greater than second (case insensitive)
if (\$firstarray gei \$secondarray)
// (As string) Compare if first is lower or greater than second
if (\$firstarray lg \$secondarray)
// (As string) Compare if first is lower or greater than second (case insensitive)
if (\$firstarray lgi \$secondarray)
// (As string) Tests if two arrays are lower(-1), equal (0) or higher (1)
if (\$firstarray cmp \$secondarray)
// (As string) Tests if two arrays are lower(-1), equal (0) or higher (1) (case insensitive)
if (\$firstarray cmpi \$secondarray)
// (As string) Compare if first is lower than second
if (\$firstarray < \$secondarray)
// (As string) Compare if first is greater than second
if (\$firstarray > \$secondarray)
// (As string) Compare if first is lower than or equal to second
if (\$firstarray <= \$secondarray)
// (As string) Compare if first is greater than or equal to second
if (\$firstarray >= \$secondarray)
// (As string) Compare if first is lower or greater than second
if (\$firstarray <> \$secondarray)```

// Print all elements in the array (Similar to Join() function)

```my \$array = array(1, 2, 3);
println("An \$array[<>]");
// Or
println(\$array[<>]);
// Or
println \$array[<>];```

Theres a lot more arrays can be used for and theres a lot of functions to use with them but that will be shown in another part of this wiki.

#### Hashes (Dictionary)

A Hash (Dictionary) is used to store variables under a key name this is useful for creating a kind of key/value system and is more useful then arrays in situations where you need this.

(Its worth noting a variable can contain both an array and a hash at the same time. This is because an array and an hash share the same data structure the arrays indexes are simply just keys in the hash. Sputnik will keep the hash organized and sorted numerically then alphabetically for use in loops and whatever else.)

The key in a hash is case insensitive.

Everything you can do with arrays you can do with the dictionary they are the same thing entirely just like in PHP.

Heres a brief example:

```\$cc = array("One" => "cat", "Two" => "dog", "Three" => "mouse");

println("cc :" . \$cc);
println("cc[one] :" . \$cc["One"]);
println("cc[two] :" . \$cc["Two"]);
println("cc[three] :" . \$cc["Three"]);```

You can also add more elements to the Hash using the ..= example:

```\$cc = array("One" => "cat", "Two" => "dog", "Three" => "mouse");
\$cc .= array("Four" => "woman", "Five" => "man");

println("cc :" . \$cc);
println("cc[one] :" . \$cc["One"]);
println("cc[two] :" . \$cc["Two"]);
println("cc[three] :" . \$cc["Three"]);
println("cc[four] :" . \$cc["Four"]);
println("cc[five] :" . \$cc["Five"]);```

A more simple approach to adding new values is to simply modify the value directly example:

```\$cc = array("One" => "cat", "Two" => "dog", "Three" => "mouse");
\$cc .= array("Four" => "woman", "Five" => "man");

\$cc["Six"] = "Sheep";
\$cc["One"] = "Not a cat!";
\$cc["Seven"] = "Donkey";

println("cc :" . \$cc);
println("cc[one] :" . \$cc["One"]);
println("cc[two] :" . \$cc["Two"]);
println("cc[three] :" . \$cc["Three"]);
println("cc[four] :" . \$cc["Four"]);
println("cc[five] :" . \$cc["Five"]);
println("cc[six] :" . \$cc["Six"]);
println("cc[seven] :" . \$cc["Seven"]);```

Example of Multi-dimensional hash

```\$lol = array("One" => array(3, 4), "Two" => array(3 =>array(8, 9))); // Create a simple array with 4 elements

\$lol['One'] = "Hello";

// Print the details of the array
println( "lol :" . \$lol );
println( "lol['One'] :" . \$lol['One'] );
println( "lol['One'] :" . \$lol['One'] );
println( "lol['One'] :" . \$lol['One'] );
println( "lol['Two'] :" . \$lol['Two'] );
println( "lol['Two'] :" . \$lol['Two'] );
println( "lol['Two'] :" . \$lol['Two'] );

// Note you can mix array index and hash strings to create all kinds of MD arrays```

You can also use the qww// to produce simple arrays (with keys) example

```# initialize
my \$hash = array();

# populate the hash with a few elements
\$hash = qww(1 one 2 two 3 three 4 four);

# print the %hash
foreach(\$hash as \$key => \$val)
{
print "\$key => \$val\n";
}
// Alternatively you could use:
// \$arr = qww(1 one 2 two 3 three 4 four);
// \$arr = qww{1 one 2 two 3 three 4 four};
// \$arr = qww~1 one 2 two 3 three 4 four~;
// \$arr = qww!1 one 2 two 3 three 4 four!;
// \$arr = qww%1 one 2 two 3 three 4 four%;
// \$arr = qww:1 one 2 two 3 three 4 four:;
// \$arr = qww^1 one 2 two 3 three 4 four^;
// \$arr = qww?1 one 2 two 3 three 4 four?;
// \$arr = qww¬1 one 2 two 3 three 4 four¬;```

You can also spread the qww out like so

```# initialize
my \$hash = array();

# populate the hash with a few elements
\$hash = qww(
Cat		Meow
Dog		Woof
Foo		Bar
);

# print the %hash
foreach(\$hash as \$key => \$val)
{
print "\$key => \$val\n";
}```

There is a lot more you can do with hashes including functions to make using them easier but that will be shown in another part of the wiki.

#### Enum

Enums are a variable that lets you get a number from it and each one is unique.

A local scope MY enum

```my enum
{
\$Cat,
\$Dog,
\$Fox,
\$Cow,
\$Pig
};
println("Cat: " . \$Cat); // Prints 0
println("Dog: " . \$Dog); // Prints 1
println("Fox: " . \$Fox); // Prints 2
println("Cow: " . \$Cow); // Prints 3
println("Pig: " . \$Pig); // Prints 4```

Another local scope but this time with a few base variables

```my enum
{
\$Cat,
\$Dog = 20,
\$Fox,
\$Cow = 55,
\$Pig
};

println("Cat: " . \$Cat); // Prints 0
println("Dog: " . \$Dog); // Prints 20
println("Fox: " . \$Fox); // Prints 21
println("Cow: " . \$Cow); // Prints 55
println("Pig: " . \$Pig); // Prints 56```

Global scope enum accessible by all

```enum Countries
{
\$England,
\$France,
\$Germany,
\$Netherlands,
\$Portugal = 50,
\$Italy,
\$Russia
};

println("England: " . Countries->\$England); // Prints 0
println("France: " . Countries->\$France); // Prints 1
println("Germany: " . Countries->\$Germany); // Prints 2
println("Netherlands: " . Countries->\$Netherlands); // Prints 3
println("Portugal: " . Countries->\$Portugal); // Prints 50
println("Italy: " . Countries->\$Italy); // Prints 51
println("Russia: " . Countries->\$Russia); // Prints 52```

You can also create enums using bitwise flag numbers instead of single ++ incremental decimals by using the FLAGS rule example

```[Flags("true")]
enum Countries
{
\$England,
\$France,
\$Germany,
\$Netherlands,
\$Portugal,
\$Italy,
\$Russia
};

println("England: " . Countries->\$England); // Prints 1
println("France: " . Countries->\$France); // Prints 2
println("Germany: " . Countries->\$Germany); // Prints 4
println("Netherlands: " . Countries->\$Netherlands); // Prints 8
println("Portugal: " . Countries->\$Portugal); // Prints 16
println("Italy: " . Countries->\$Italy); // Prints 32
println("Russia: " . Countries->\$Russia); // Prints 64```

You can still use defaults with flags example

```[Flags("true")]
enum Countries
{
\$England,
\$France,
\$Germany,
\$Netherlands,
\$Portugal = 300,
\$Italy,
\$Russia
};

println("England: " . Countries->\$England); // Prints 1
println("France: " . Countries->\$France); // Prints 2
println("Germany: " . Countries->\$Germany); // Prints 4
println("Netherlands: " . Countries->\$Netherlands); // Prints 8
println("Portugal: " . Countries->\$Portugal); // Prints 300
println("Italy: " . Countries->\$Italy); // Prints 600
println("Russia: " . Countries->\$Russia); // Prints 1200```

You can also combine flags example

WARNING - You must have already defined the flags you wish to combine! You can't combine flags that don't exist in the enum yet.

```[Flags("true")]
enum Countries
{
#\$Test = \$England + \$France IT WOULD NOT WORK HERE
\$England,
\$France,
#\$Test = \$England + \$France IT COULD WORK HERE
\$Germany,
\$Netherlands,
\$Portugal,
\$Italy,
\$Russia,
\$Test = \$England + \$France
};

println("England: " . Countries->\$England); // Prints 1
println("France: " . Countries->\$France); // Prints 2
println("Germany: " . Countries->\$Germany); // Prints 4
println("Netherlands: " . Countries->\$Netherlands); // Prints 8
println("Portugal: " . Countries->\$Portugal); // Prints 300
println("Italy: " . Countries->\$Italy); // Prints 600
println("Russia: " . Countries->\$Russia); // Prints 1200
println("Test: " . Countries->\$Test); // Prints 3```

You can also define an enum as an replacement that will replace an existing enum with the same name example

```enum Cat
{
\$A,
\$B
};

[Replace("true")]
enum Cat
{
\$A,
\$B,
\$C
};

say Cat->\$C; // Prints 2```

You can define an enum with AddOnce so if another enum using same name tries to get added no error will be shown but it will reject it (Replace takes precedence over AddOnce)

```[AddOnce("true")]
enum Cat
{
\$A,
\$B
};

enum Cat
{
\$A,
\$B,
\$C
};

say Cat->\$B; // Prints 1
say Cat->\$C; // error```

#### Enum (Embedding)

An enum can be embedded inside an IF statement (or any statement) so that it can be created on a conditional for example:

```// Check if the enum already exists and
// if it does already exists don't create it
if (!EnumExists("Animals"))
{
// Create the enum using the Embedded keyword
Embedded Enum Animals
{
\$Dog,
\$Cat,
\$Fox
}; // note ; is required here
}
say Animals->\$Dog;
say Animals->\$Cat;
say Animals->\$Fox;
// PRINTS
// 0
// 1
// 2```

### Variables

A variable is a place to store information in a way that is easy to get and change.

#### Declaring Variables

There are 2 ways to create variables either scoped or unscoped example:

`\$var = 100;`

That will either modify an existing variable called \$var and change its value to 100 or it will create the variable on the stack in this case it will create a GLOBAL scope variable.

The second way to create variables is to define its scope example:

`my \$var = 100;`

That will either modify an existing LOCAL variable called \$var and change its value to 100 or it will create the variable on the stack in this case it will create a LOCAL scope variable.

`Global \$var = 100`

That will either modify an existing GLOBAL variable called \$var and change its value to 100 or it will create the variable on the stack in this case it will create a GLOBAL scope variable.

#### Constant Variables

Sputnik does support constant variables that can never be changed once you define them that is they do not change.

```Const \$a = "Hello";
say \$a; // Prints: Hello
\$a = 10; // Cant change it
say \$a; // Prints: Hello
unset(\$a); // Cant even delete it!
say \$a; // Prints: Hello
// BUT you can RE define it
// This is because the only way
// to change a constant variable
// is to TOTALLY replace it by a NEW
// constant variable
Const \$a = "Cat";
say \$a; // Prints: Cat```

This way you can use Const to create a variable and you can feel safe knowing it's not going to suddenly change by accident unless for some reason Const is called again with the same variable name.

However since your Constants should only be called once it should not be possible to get two of them.

Alternatively you could take a look at the Preprocessor and use that to define a @MACRO that does not change as well.

#### Scope

A variable's scope is controlled by when and how you declare the variable. In most cases your variables will be Global unless you specifically set them to Local. Global scope and can be read or changed from anywhere in the script.

If you declare a variable inside a function and you made it Local scope it can only be used within that same function. Variables created inside functions are automatically destroyed when the function ends.

The same is true for classes.

So inside a function you only have the function/class(and class function) itself as a LOCAL scope to use and outside a function your local scope is the actual script itself.

However if you "really" need a new local scope any any point you can use the {...} statement example:

```my \$lol = 100;
{
my \$lol = 88;
println("lol is: " . \$lol);
}
println("lol is: " . \$lol);```

Every local variable defined inside the block exists only in the block.

You can also stack blocks inside each other.

#### Casting

There are 2 ways to cast a value as something else the first:

`println( "The cast is : " . Int(777.42) )`

This will cause everything inside the Int() to be converted to an int this uses the function Int32( \$variable ) (Alias: Int( \$variable )).

The second way is similar to C and works like this:

`println( "The cast is : " . (int)777.42 )`

The "(int)value" type will only convert what it *touches* so if you want to convert a large expression you must cover with () example:

```\$a = 11.6
println( "The cast is : " . (int)(777.42 + \$a) )```

Casting is very useful since there will be times when you really need to be using only INTs or FLOATs and by casting you will make sure that you do.

Its worth noting the actual "(type)value" cast supports casting overloading on Classes where as the function "type(value)" does not.

A special cast is the ability to cast things as an array example

`printr( (array)"Hello World" );`

```\$a = "Hello World";
printr( (array)\$a );```

You can also check if it is an array before casting it

```\$a = "Hello World";
printr( \$a ~~ Array ? \$a : (array)\$a );```

Valid casts are:

```(ascii)
ASCII - Returns a copy of a string but with all Unicode characters stripped
out of it. It will not even try cast the Unicode it will just ignore them.
This is equal to "RAW" mode in BinaryFromStr()

(array)
Array

(binary)
(bin)
Binary = Return binary variable of the strings bytes (Ignores extra unicode bytes)

(bool)
Bool

(char)
Char

(byte)
Byte

(sbyte)
Sbyte

(short)
(int16)
Int16

(int)
Int32

(int32)
Int32

(int64)
Int64

(integer)
Int64

(long)
Int64

(ushort)
(uint16)
Uint16

(uint)
Uint32

(uint32)
Uint32

(uint64)
Uint64

(ulong)
Uint64

(ptr)
IntPtr

(intptr)
IntPtr

(uptr)
UintPtr

(uintptr)
UintPtr

(float)
Float

(double)
Double

(string)
String
```

#### Bit Flags

Bit flags , or bit fields are a great way of storing several boolean values in a single byte (or set of bytes), and are internally represented as binary. In this tutorial we will work with bitwise operators, so if you need to brush up this is what we're using; the following key binary operators.

Sputnik has dedicated functions to handle Setting and Testing for flags you can find them here:

These examples should be self-explanatory.

They show how to do flags using the core language instead of using HasFlag() and SetFlag().

```enum Options {
\$Flag1 = 0x01,
\$Flag2 = 0x02,
\$Flag3 = 0x04,
\$Flag4 = 0x08,
\$Flag5 = 0x10,
\$Flag6 = 0x20
};

// Make a variable to store the flags
Global \$Opt = 0; // No flags are set
\$Opt |= Options->\$Flag2; // Set Flag2 to TRUE
\$Opt |= Options->\$Flag3; // Set Flag3 to TRUE
\$Opt |= Options->\$Flag5; // Set Flag5 to TRUE
TestFlags("Test1");

\$Opt &= ~Options->\$Flag5; // Set Flag5 to FALSE
TestFlags("Test2");

\$Opt &= ~Options->\$Flag3; // Set Flag3 to FALSE
TestFlags("Test3");

\$Opt |= Options->\$Flag5; // Set Flag5 to TRUE
\$Opt |= Options->\$Flag3; // Set Flag3 to TRUE
TestFlags("Test4");

\$Opt &= ~(Options->\$Flag3 | Options->\$Flag5); // Set Flag3 and Flag5 to FALSE
TestFlags("Test4");

\$Opt |= (Options->\$Flag1 | Options->\$Flag6); // Set Flag1 and Flag6 to TRUE
TestFlags("Test5");

Function TestFlags(\$str)
{
println("### \$str BELOW");
println("\\$Opt = {Hex('\$Opt', 2)}");
foreach( Enumerate("Options") as \$Flag => \$ID )
{
if(\$Opt & \$ID)
println("\$Flag is TRUE");
else
println("\$Flag is FALSE");
}
println("### \$str ABOVE\n");
}```

Another example

```enum {
\$OPT_A = 0x01,
\$OPT_B = 0x02,
\$OPT_C = 0x04,
\$OPT_H = 0x08
};

//to store the option flags
my \$opt = 0x0;

//argument array.
my \$argv = qw(a b);
foreach(\$argv as \$c)
{
switch(\$c)
{
case 'a':
//assign option bits to "opt" bit array
\$opt |= \$OPT_A;  break;
case 'b':
\$opt |= \$OPT_B;  break;
case 'c':
\$opt |= \$OPT_C;  break;
case 'h':
\$opt |= \$OPT_H;  break;
//this will happen if they enter an invalid option:
default:
print("Unknown option \$c");
return 1; //break out of application
}
}

//apply bitwise AND to check for assignedness a few times
if(\$opt & \$OPT_A)
print("Hello World!\n");

if(\$opt & \$OPT_B) {
my \$foo = 2000;
print("Foo has been initialized.\n");
}

//compare if two flags were specifically set
if ((\$opt & (\$OPT_B | \$OPT_C)) == (\$OPT_B | \$OPT_C))
print("Flags B and C were set.\n");

if(\$opt & \$OPT_H) {
//print help, may wish to create exit point to stop program from executing
print("\tHelp is not implemented yet\n\tAllowable options: [abch]\n");
return 0;
}

//----------------- Some fun extras: ---------------------//

//Reset bitflag completely
\$opt = 0;

//Apply bitwise OR to append multiple flags
\$opt = (\$OPT_A | \$OPT_B | \$OPT_C);

//Apply bitwise AND+EQUALS to add or remove flags to existing option field
//Then we apply bitwise NOT (a complement) to remove both flags
\$opt &= ~(\$OPT_A | \$OPT_B);

//Options A and B are now removed

//Check if BOTH flags are not set
if ((\$opt & (\$OPT_A | \$OPT_B)) == 0)
print("Flags A and B are not set\n");

//check if only one is not set
if ((\$opt & \$OPT_A) == 0)
printf("Flag A is not set\n");

//end program
return 0;```

### Macros

Sputnik has an number of Macros that are special read-only variables. Macros start with the @ character instead of the usual \$ so are easy to tell apart. As with normal variables you can use macros in expressions but you cannot assign a value to them.

The pre-defined macros are generally used to provide easy access to information and constants such as @PI etc.

Go here for a complete list.

### Classes

Sputnik does support some pbject-oriented programming however its too big for this page alone so its best to go see the classes page

### Operators

#### Operator .. (range mode)

Range and Flip Flop operator -- here we will demonstrate the Range mode.

The first action of this operator is the ability to make ranges of stuff and these ranges may be either a string or an array.

In this example we make a range of the chars from A to F

```// String form
say 'A'..'F';
// Array form
printr array('A'..'F');
// PRINTS
// ABCDEF
// Array
// (
//      => A
//      => B
//      => C
//      => D
//      => E
//      => F
// )```

You can also join multiple ranges together example

```// String form
say ('A'..'F') . ('0'..'3');
// Array form
printr array('A'..'F', '0'..'3');
// PRINTS
// ABCDEF0123
// Array
// (
//      => A
//      => B
//      => C
//      => D
//      => E
//      => F
//      => 0
//      => 1
//      => 2
//      => 3
// )```

Ranges may go backwards

```// String form
say ('F'..'A') . ('3'..'0');
// Array form
printr array('F'..'A', '3'..'0');
// PRINTS
// FEDCBA3210
// Array
// (
//      => F
//      => E
//      => D
//      => C
//      => B
//      => A
//      => 3
//      => 2
//      => 1
//      => 0
// )```

You can also do Numeric changes (cannot be floating points)

```// String form
say (0..3) . (4..2);
// Array form
printr array(0..3, 4..2);
// PRINTS
// 0123432
// Array
// (
//      => 0
//      => 1
//      => 2
//      => 3
//      => 4
//      => 3
//      => 2
// )```

And finally a range may be variables

```// Define some variables
my \$a = 0;
my \$b = 3;
my \$c = 'T';
my \$d = 'Z';
// String form
say (\$a..\$b) . (\$c..\$d);
// Array form
printr array(\$a..\$b, \$c..\$d);
// PRINTS
// 0123TUVWXYZ
// Array
// (
//      => 0
//      => 1
//      => 2
//      => 3
//      => T
//      => U
//      => V
//      => W
//      => X
//      => Y
//      => Z
// )```

#### Operator .. (flip flop mode) and Operator ff

You can define the range operator as .. or ff the only differance is that ff makes there zero chance you might accidently use a range operator.

Range and Flip Flop operator -- here we will demonstrate the Flip Flop mode.

If the LEFT and the RIGHT parts of the .. BOTH return a BOOLEAN value ie TRUE or FALSE (not numeric values it MUST be a true boolean) then it will enter Flip Flop mode.

Once in Flip Flop mode the operator will check if the LEFT is true if it is not TRUE it will return FALSE.

Once the LEFT returns TRUE the operator will also return a number starting 1 then all subsequent calls to the operator (on that line of code) will return the same number perminently regarldess if the LEFT is a match or not.

If the LEFT continues to be TRUE multiple times the operator will increase the number it returns (starting at 1 then going to 2 and so on)

If while in TRUE mode (after the LEFT has been true at least ONCE) if the RIGHT becomes TRUE the operator will the next number but followed by E0 then it will immediately start returning FALSE for all subsequent calls until the LEFT returns true again then its begins all over again.

The operator remembers its STATE on that line of code regardless for how long your program has been running and if its TRUE mode it will continue to return true for all lines even if it NEVER got a LEFT true match in the current iteration of a loop.

This means if at any time in your program the LEFT of the operator is a TRUE then the operator will return a number above 0 every time its used regardless if you call it 5 hours later (as long it is that individual operator).

The only downside could be if you fail to get the *end* result you expected (RIGHT match) then the next time you do the loop it will be returning TRUE all time even if the first one is never found.

So you might want to plan for that possibility

```// Lets make some text and imagine its the files text
my \$FileText =
@"First line.
start
Indented line
end
Back to left margin";
// Break the text into individual lines
my \$lines = Lines(\$FileText);
// Loop through each line of the files text
// Notice we dont use "as" in the foreach?
// This will make it place each line into \$_
// for us
foreach(\$lines)
{
// Print a \t (tab) if the operator gets match
// Or if it's in a TRUE state
// Notice we dont specifiy a variable in the regexp?
// This will cause it to use \$_ automatically
echo "\t" if(m/^start/ .. m/^end/);
// Print the current line of the file
// Of course \$_ is the line from the foreach
echo \$_ . "\n";
}
// PRINTS
// First line.
//         start
//         Indented line
//         end
// Back to left margin```

Same as above but using ff name instead of the .. name of the operator (both are the same for a flip flop)

```// Lets make some text and imagine its the files text
my \$FileText =
@"First line.
start
Indented line
end
Back to left margin";
// Break the text into individual lines
my \$lines = Lines(\$FileText);
// Loop through each line of the files text
// Notice we dont use "as" in the foreach?
// This will make it place each line into \$_
// for us
foreach(\$lines)
{
// Print a \t (tab) if the operator gets match
// Or if it's in a TRUE state
// Notice we dont specifiy a variable in the regexp?
// This will cause it to use \$_ automatically
echo "\t" if(m/^start/ ff m/^end/);
// Print the current line of the file
// Of course \$_ is the line from the foreach
echo \$_ . "\n";
}
// PRINTS
// First line.
//         start
//         Indented line
//         end
// Back to left margin```

A common thing with Flip Flop is to want to exclude one or both endpoints. To do this, you need to actually check the scalar value returned by the .. operator; it will be a number beginning at 1 when the flip condition is met and increasing once each time thereafter, with an "E0" appended when the flop condition is met. (False is returned as a boolean FALSE.)

Exclude starting point

```my \$FileText = "initial\nstart\ninterior\nend\nfinal";
foreach(Lines(\$FileText))
echo "\$_\n" if(((m/start/ .. m/end/) || 0) > 1);
// PRINTS
// interior
// end```

Regex alternative for exclude starting point

```my \$FileText = "initial\nstart\ninterior\nend\nfinal";
foreach(Lines(\$FileText))
echo "\$_\n" if((m/start/ .. m/end/) =~ m/^(?!1(?!\d))\d/);
// PRINTS
// interior
// end```

Exclude ending point

```my \$FileText = "initial\nstart\ninterior\nend\nfinal";
foreach(Lines(\$FileText))
echo "\$_\n" if((m/start/ .. m/end/) =~ m/^\d+\$/);
// PRINTS
// start
// interior```

Exclude both endpoints

```my \$FileText = "initial\nstart\ninterior\nend\nfinal";
foreach(Lines(\$FileText))
echo "\$_\n" if((m/start/ .. m/end/) =~ m/^\d+(?<!^1)\$/);
// PRINTS
// interior```

#### Operator ->>

Variable as first arg. e.g.

```// Define a string
\$a = "Cat and Dog";
// Use the \$a as the first arg of a function
\$result = \$a->>substr(1);
// Print the result
say \$result; // at and Dog
// Prints showing no changes happened to \$a
say \$a; // Cat and Dog```

This can be chained for example

```// Define a string
\$a = "Cat and Dog";
// Use the \$a as the first arg of a function many times
\$result = \$a->>substr(1)->>substr(0, 8)->>substr(1);
// Print the result
say \$result; // t and D
// Prints showing no changes happened to \$a
say \$a; // Cat and Dog```

#### Operator =>>

Variable as first arg assignment. e.g.

```// Define a string
\$a = "Cat and Dog";
// Use the \$a as the first arg of a function
// (this does not change \$a unless the function changes it)
say \$a->>substr(1); // at and Dog
// Prints showing no changes
say \$a; // Cat and Dog

// Now lets try again but this time with =>>
// Use =>> to place \$a as the first arg of a function
// then immediately set the return value to \$a
\$a=>>substr(1);
// Print it showing the change
say \$a; // at and Dog```

#### Operator x

Repetition. e.g.

```\$value = "Test" x 10;
printr \$value;

\$value = array("Cat", "Dog") x 10;
printr \$value;

// Can also do stuff like
print("CAT\n") x 100; //Prints CAT 101 times (counts the zero)```

Can be used on arrays

```\$a = array("One", "Two") x 2;
printr \$a;
/*
Prints:
Array
(
 => One
 => Two
 => One
 => Two
)
*/```

#### Operator xx

Repetition as array. e.g.

```\$value = "Test" xx 10;
printr \$value;

\$value = array("Cat", "Dog") xx 10;
printr \$value;```

Can be used on arrays

```\$a = array("One", "Two") xx 2;
printr \$a;
/*
Array
(
 => Array
(
 => One
 => Two
)
 => Array
(
 => One
 => Two
)
)
*/```

#### Operator []

Append to end of array. e.g.

```my \$myArray = array("One", "Two", "Three");

\$myArray[] = "Four";
\$myArray[] = "Five";

printr(\$myArray);```

#### Operator []!

Append to beginning of array. e.g.

```my \$myArray = array("One", "Two", "Three");

\$myArray[]! = "Zero";
\$myArray[] = "Four";

printr(\$myArray);```

#### Operator [<>]

Print array. e.g.

```my \$array = array(1, 2, 3);
println("An \$array[<>]");
// Or
println(\$array[<>]);
// Or
println \$array[<>];```

Can be used with array creation

```\$a = array("Three", "Four");
\$b = array("One", "Two", \$a[<>]);
printr \$b;
/*
Array
(
 => One
 => Two
 => Three
 => Four
)
*/```

#### Operator [<=>]

Print hashmap. e.g.

```my \$array = array("Cat" => 1, "Dog" => 2, "FoX" => 3);
println("An \$array[<=>]");
// Or
println(\$array[<=>]);
// Or
println \$array[<=>];```

Can be used with array creation

```\$a = array("Cat" => "Meow");
\$b = array("Dog" => "Woof", \$a[<=>]);
printr \$b;
/*
Array
(
[Dog] => Woof
[Cat] => Meow
)
*/```

#### Operator is

Type checking. e.g.

```// Used to check if a variable is a certain type
\$a = (int32)1;

if(\$a is Int32)
{
println(@"\$a is an Int32");
}
else
{
println(@"\$a is NOT an Int32");
}

// Can be used for classes and other objects too
Class Testy
{
};

\$b = new Testy();

if(\$b is Testy)
{
println(@"\$a is an instance of class Testy");
}
else
{
println(@"\$a is NOT an instance of class Testy");
}```

#### Operator ~~

Type checking. e.g.

```// Used to check if a variable is a certain type
\$a = (int32)1;

if(\$a ~~ Int32)
{
println(@"\$a is an Int32");
}
else
{
println(@"\$a is NOT an Int32");
}

// Can be used for classes and other objects too
Class Testy
{
};

\$b = new Testy();

if(\$b ~~ Testy)
{
println(@"\$a is an instance of class Testy");
}
else
{
println(@"\$a is NOT an instance of class Testy");
}```

There is also a strict mode if you add an extra ~ example

```\$a = (int32)1;
if(\$a ~~~ Int32)
{
println(@"\$a is an Int32");
}
else
{
println(@"\$a is NOT an Int32");
}```

#### Operator isnot

Type checking. e.g.

```// Used to check if a variable is not a certain type
\$a = (int32)1;

if(\$a isnot Int32)
{
println(@"\$a is NOT an Int32");
}
else
{
println(@"\$a is an Int32");
}```

#### Operator !~

Type checking. e.g.

```// Used to check if a variable is not a certain type
\$a = (int32)1;
if(\$a !~ Int32)
{
println(@"\$a is NOT an Int32");
}
else
{
println(@"\$a is an Int32");
}```

There is also a strict mode if you add an extra ~ example

```\$a = (int32)1;
if(\$a !~~ Int32)
{
println(@"\$a is NOT an Int32");
}
else
{
println(@"\$a is an Int32");
}```

#### Operator =

Assignment. e.g.

```\$var = 5;     (assigns the number 5 to \$var)
```

#### Operator ++

Increase assignment. e.g.

```\$var++;     (adds 1 to \$var) // Returns x, then increments x by one
++\$var;     (adds 1 to \$var) // Increments x by one, then returns x
```

It can also go infinity

```\$var+++;     (adds 2 to \$var)
```
```\$var++++++;     (adds 5 to \$var)
```

Sputnik follows Perl's convention when dealing with arithmetic operations on character variables and not C's.

For example, in Sputnik, PHP and Perl \$a = 'Z'; \$a++; turns \$a into 'AA', while in C a = 'Z'; a++; turns a into '[' (ASCII value of 'Z' is 90, ASCII value of '[' is 91).

Note that character variables can be incremented but not decremented and even so only plain ASCII alphabets and digits (a-z, A-Z and 0-9) are supported.

Incrementing/decrementing other character variables has no effect, the original string is unchanged.

#### Operator --

Decrease assignment. e.g.

```\$var--;     (subs 1 from \$var) // Returns x, then decrements x by one
--\$var;     (subs 1 from \$var) // Decrements x by one, then returns x
```

It can also go infinity

```\$var---;     (subs 2 from \$var)
---\$var;     (subs 2 from \$var)
```
```\$var------;     (subs 5 from \$var)
------\$var;     (subs 5 from \$var)
```

#### Operator +=

```\$var += 1;     (adds 1 to \$var)
```

#### Operator -=

Subtraction assignment.

```\$var -= 1;     (subs 1 to \$var)
```

#### Operator /=

Division assignment. e.g.

```\$var /= 2;     (divive \$var by 2)
```

#### Operator *=

Multiplication assignment. e.g.

```\$var /= 2;     (multiply \$var by 2)
```

#### Operator **=

Raises a number to the power assignment. e.g.

```\$var **= 2;     (raise \$var by 2)
```

#### Operator |=

BitwiseOR assignment. e.g.

```\$var |= 2;
```

#### Operator ^=

BitwiseExclusiveOR assignment. e.g.

```\$var ^= 2;
```

#### Operator &=

BitwiseAND assignment. e.g.

```\$var &= 2;
```

#### Operator %=

Modulus assignment. e.g.

```\$var %= 2;
```

#### Operator >>=

BitwiseSHIFT RIGHT assignment. e.g.

```\$var >>= 2;
```

#### Operator <<=

BitwiseSHIFT LEFT assignment. e.g.

```\$var <<= 2;
```

#### Operator <<<=

BitwiseUnsignedSHIFT LEFT assignment. e.g.

```\$var <<<= 2;
```

#### Operator >>>=

BitwiseUnsignedSHIFT RIGHT assignment. e.g.

```\$var >>>= 2;
```

#### Operator ||=

OR assignment. e.g.

```\$x ||= 0;   # If \$x was false, it now has a value of 0.
```

#### Operator &&=

AND assignment. e.g.

```\$x &&= 0;   # If \$x was true, it now has a value of 0.
```

#### Operator .=

Concatenates/joins two strings (Adds text to end of variable) assignment. e.g.

```\$var .= "Hello";
```

(Can be used on arrays)

#### Operator ..=

Concatenates/joins two strings (Adds text to beginning of variable) assignment. e.g.

```\$var ..= "Hello";
```

(Can be used on arrays)

#### Operator +

```10 + 20;    (equals 30)
```

#### Operator -

Subtracts two numbers. e.g.

```20 - 10;    (equals 10)
```

Negate a number. e.g.

```\$a = -10;    (equals -10)
\$b = -\$a;    (equals 10 because it will flip-flop)
```

#### Operator *

Multiplies two numbers. e.g.

```20 * 10;    (equals 200)
```

Resolves reference. e.g.

```\$p = "Hello";
\$test = &\$p;
echo(*\$test);    (Resolves the pointer so \$test will appear
as if \$p was there instead)
```

#### Operator /

Divides two numbers. e.g.

```20 / 10;    (equals 2)
```

#### Operator **

Raises a number to the power. e.g.

```2 ** 4;    (equals 16)
```

#### Operator |

BitwiseOR. e.g.

```\$var | 2;
```

#### Operator ^=

BitwiseExclusiveOR. e.g.

```\$var ^ 2;
```

#### Operator &

BitwiseAND. e.g.

```\$var & 2;
```

Reference creator. e.g.

```\$test = "Hello";
\$p = &\$test; // Now \$p links to \$test
```

#### Operator %

Modulus. e.g.

```\$var % 2;
```

#### Operator <<

BitwiseSHIFT Left. e.g.

```14 << 2;    (equals 56 because 1110b left-shifted twice is 111000b == 56)
14 << -12;  (same a doing 14 >> 12)
```

#### Operator >>

BitwiseSHIFT Right. e.g.

```14 >> 2;    (equals 3 because 1110b right-shifted twice is 11b == 3)
14 >> -12;  (same a doing 14 << 12)
```

#### Operator >>>

BitwiseUnsignedSHIFT Right. e.g.

```14 >>> 2;
14 >>> -12;  (same a doing 14 <<< 12)
```

#### Operator <<<

BitwiseUnsignedSHIFT Left. e.g.

```14 <<< 2;
14 <<< -12;  (same a doing 14 >>> 12)
```

#### Operator ~

BitwiseNOT. e.g.

```~ 5;
; Result is -6 because for 32-bit numbers
; 5 == 00000000000000000000000000000101 binary
; -6 == 11111111111111111111111111111010 binary
; and the first bit is signed
```

#### Operator .

Concatenates/joins two strings/arrays/binary etc. e.g.

```"one" . 10;    (equals "one10")
```

#### Operator ==

Tests if two values are equal (case sensitive if used with strings)

(Can be used on arrays)

#### Operator ===

Tests if two values are equal and the same type (case sensitive if used with strings)

```//define variables..
\$str = '9';
\$int = 9;

//Returns true since both variable contains the same value..
\$res = (\$str==\$int);
println("Str '9' == Int 9; " . (\$res ? "True" : "False"));

//Returns false since the two variables are not of the same type..
\$res = (\$str===\$int);
println("Str '9' === Int 9; " . (\$res ? "True" : "False"));```

(Can be used on arrays)

#### Operator !=

Tests if two values are not equal (case sensitive if used with strings)

(Can be used on arrays)

#### Operator !==

Tests if two values are not equal and not the same type (case sensitive if used with strings)

(Can be used on arrays)

#### Operator <

Tests if the first value is less than the second.

#### Operator <=

Tests if the first value is less than or equal to the second.

#### Operator >

Tests if the first value is greater than the second.

#### Operator >=

Tests if the first value is greater than or equal to the second.

#### Operator <>

Test if first value is lower or higher than the second.

#### Operator <=>

Test if second value value is lower , equal or higher respectively than the first value returning as either: -1 0 1

#### Operator eq

Tests if two objects (treated as strings) are equal (case sensitive)

(Can be used on arrays)

#### Operator eqi

Tests if two objects (treated as strings) are equal (case insensitive)

(Can be used on arrays)

#### Operator neq

Tests if two objects (treated as strings) are not equal (case sensitive)

(Can be used on arrays)

#### Operator neqi

Tests if two objects (treated as strings) are not equal (case insensitive)

(Can be used on arrays)

#### Operator cmp

Tests if two objects (treated as strings) are lower(-1), equal (0) or higher (1) (case sensitive)

(Can be used on arrays)

#### Operator cmpi

Tests if two objects (treated as strings) are lower(-1), equal (0) or higher (1) (case insensitive)

(Can be used on arrays)

#### Operator lt

Tests if the first value is less than the second (both treated as strings).

(Can be used on arrays)

#### Operator le

Tests if the first value is less than or equal to the second (both treated as strings).

(Can be used on arrays)

#### Operator gt

Tests if the first value is greater than the second (both treated as strings).

(Can be used on arrays)

#### Operator ge

Tests if the first value is greater than or equal to the second (both treated as strings).

(Can be used on arrays)

#### Operator lti

Tests if the first value is less than the second (both treated as strings, case insensitive).

(Can be used on arrays)

#### Operator lei

Tests if the first value is less than or equal to the second (both treated as strings, case insensitive).

(Can be used on arrays)

#### Operator gti

Tests if the first value is greater than the second (both treated as strings, case insensitive).

(Can be used on arrays)

#### Operator gei

Tests if the first value is greater than or equal to the second (both treated as strings, case insensitive).

(Can be used on arrays)

#### Operator lg

Test if first value is lower or higher than the second (both treated as strings).

(Can be used on arrays)

#### Operator lgi

Test if first value is lower or higher than the second (both treated as strings, case insensitive).

(Can be used on arrays)

#### Operator &&

Logical AND operation. e.g.

```if (\$this && \$that)     (If \$this is true, return \$that, else return \$this)
```

In other words if both are TRUE the if will accept the statement as TRUE otherwise it wont.

#### Operator And

Logical AND operation. e.g.

```if (\$this AND \$that)     (If \$this is true, return \$that, else return \$this)
```

In other words if both are TRUE the if will accept the statement as TRUE otherwise it wont.

#### Operator ||

Logical OR operation. e.g.

```if (\$this || \$that)     (If \$this is true, return \$this, else return \$that.)
```

In other words if either are TRUE the if will accept the statement as TRUE otherwise it wont.

#### Operator Or

Logical OR operation. e.g.

```if (\$this OR \$that)     (If \$this is true, return \$this, else return \$that.)
```

In other words if either are TRUE the if will accept the statement as TRUE otherwise it wont.

#### Operator !

Logical NOT operation. e.g.

```If(!\$var == 5)
```

#### Operator ??

NULL switch. eg.

```\$a = null;
println( \$a ?? "The variable is null" );
```

#### Operator !!

Not null switch. eg.

```\$a = 10;
println( \$a !! "The variable is not null" );
```

#### Operator ? :

Boolean expression TRUE or FALSE switch. eg.

```Println ( 1 == 2 ? "True" : "False" );

// Heres an example of why it looks better
if( \$a == 100 )
{
println ( "True" );
}
else
{
println ( "False" );
}

// Is best written like so
println ( \$a == 100 ? "True" : "False" );
```

Another interesting way to use ? : operator is with the @( ) brace notice it will allow \$cat to increase and yet still return "no" to the argument

```\$cat = 10;
\$dog = 2;

\$value = \$dog == 1 ? "yes" : @(\$cat++,"no");

say "Cat is \$cat";
say "Dog is \$dog";
say "Value is \$value";
```

#### Operator !? :

Booleon expression TRUE or FALSE switch. eg.

```Println ( 1 == 2 !? "False" : "True" );

// Heres an example of why it looks better
unless( \$a == 100 )
{
println ( "False" );
}
else
{
println ( "True" );
}

// Is best written like so
println ( \$a == 100 !? "False" : "True" );
```

#### Operator <stm> if( <expression> )

Execute code if expression TRUE. eg.

```\$test = 200;
println( "Hello World" ) if( \$test == 100 );
println( "Goodbye World" ) if( \$test == 200 );
```

#### Operator <stm> if( <expression> ) else <stm>

Execute code if expression TRUE else execute other code. eg.

```\$test = 200;
println( "Hello World" ) if( \$test == 100 ) else println( "Goodbye World" );
```

### Preprocessor

Sputnik has a built in preprocessor that can do a number of useful things for you check it out here.

### User Defined & Core Language Functions

There is many functions built into language for easy use for a list go here

There are also functions created using Sputnik that you can include in your projects and use.

To create your own funtions see the Function page.

### Character Sets

There are many macros that contain character sets go here for a complete list.

This takes numeric values same as AscW() and returns a string or array

```\$a = c65..c70;
print(\$a); // Prints ABCDEF

\$b = array(c65..c70);
foreach(\$b as \$c)
{
print("\$c,"); // Prints A,B,C,D,E,F,
}```

This takes 2 chars returns a string or array

```\$a = 'A'..'F';
print(\$a); // Prints ABCDEF

\$a = 'A'..'F' . 'a'..'f' . '0'..'9';
print(\$a); // Prints ABCDEFabcdef0123456789

\$a = '0'..'9';
print(\$a); // Prints 0123456789

\$a = 'z'..'a';
print(\$a); // Prints zyxwvutsrqponmlkjihgfedcba

\$b = array('A'..'F');
foreach(\$b as \$c)
{
print("\$c,"); // Prints A,B,C,D,E,F,
}

\$b = array('A'..'F','a'..'f','0'..'9');
foreach(\$b as \$c)
{
print("\$c,"); // Prints A,B,C,D,E,F,a,b,c,d,e,f,0,1,2,3,4,5,6,7,8,9,
}```

Takes decimals and returns string

```\$a = 0..20;
print(\$a); // Prints 01234567891011121314151617181920

\$b = array(0..20);
foreach(\$b as \$c)
{
print("\$c,"); // Prints 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
}```

```# is used a line comment
// is used as a line command
\* */ is used as a multiline comment

/*
anything you put inside
this is classed as
part of the line comment
*/
```