-
Notifications
You must be signed in to change notification settings - Fork 10
Declarations
A namespace object does not need to be declared before it can be used. In the following example, a variable, a constant, and a function are used before they are declared:
script "Main" open {
v = C;
F(); // Output: 123
}
int v;
enum { C = 123 };
void F() { Print( d: v ); }
When declaring an array, the length of any dimension can be omitted. The length will be determined based on the number of values found in the brace initializer. So if the array is initialized with 5 values, the length of the dimension will be 5:
// This array is initialized with 5 strings, so the length of the array is 5.
str names[] = {
"Positron",
"Hypnotoad",
"AC3",
"Frank",
""
};
For multidimensional arrays, the nested brace initializer with the most values will determine the length of the dimension:
// The outmost brace initializer contains three values, the inner brace
// initializers, so the length of the first dimension will be 3. Of the three
// inner brace initializers, the second brace initializer contains the most
// values, so the length of the second dimension will be 4.
int years[][] = {
{ 1989 },
{ 1992, 1993, 1994, 1996 },
{ 2008, 2009 }
};
An array can be initialized with a string. Each character of the string, including the NUL character, initializes an element of the array. If the dimension length is omitted, the dimension length will be the length of the string, plus 1 for the NUL character. The array must be one-dimensional and have either int
or raw
element type:
int letters[] = "abc"; // Same as: int letters[] = { 'a', 'b', 'c', '\0' };
World and global variables can be declared inside a script (or a function). It is the same thing as declaring the variable outside the script, except that the name of the variable will not be visible to code outside the script.
script "DeathCounter" death {
global int 1:deaths;
++deaths;
}
You can specify the length of world and global arrays. World and global arrays can be multidimensional.
script "Main" open {
global int 1:array[ 10 ];
global int 2:multiArray[ 10 ][ 20 ];
array[ 0 ] = 123;
multiArray[ 0 ][ 1 ] = 321;
}
Enumerations, structures, and type aliases can be nested inside scripts or functions.
A local scope is created by the block statement, statements that support a variable declaration as a condition, and the initialization part of the for
and foreach
loops. To put your objects in local scope, prefix the declarations with the let
keyword:
script "Main" open {
let int var = 123;
{
// This `var` hides the outer `var` and will not be visible after the
// closing brace of the block statement:
let int var = 321;
Print( d: var ); // Output: 321
}
Print( d: var ); // Output: 123
}
In a namespace block qualified with strict
, the let
keyword is implied, so you get block scoping by default:
// In a namespace block, the `let` keyword is not necessary.
strict namespace {
script "Main" open {
int var = 123;
{
// This `var` hides the outer `var` and will not be visible after the
// closing brace of the block statement:
int var = 321;
Print( d: var ); // Output: 321
}
Print( d: var ); // Output: 123
}
}
When the variable type is auto
, the compiler will deduce the type of the variable from its initializer. The variable type will be whatever the type of the initializer is. For example, if the variable is initialized with an integer such as 123, the type of the variable will be int
; or if the variable is initialized with a string, the type of the variable will be str
:
strict namespace {
script "Main" open {
auto number = 123; // Same as: int number = 123;
auto string = "abc"; // Same as: str string = "abc";
static fixed array[] = { 1.0, 2.0, 3.0 };
auto r = array; // Same as: fixed[]& r = array;
auto f = array[ 0 ]; // Same as: fixed d = array[ 0 ];
}
}
When an enumerator is the initializer, the base type of the enumeration will be selected as the variable type. If you want the enumeration itself to be the variable type, use auto enum
:
strict namespace {
script "Main" open {
enum FruitT { APPLE, ORANGE, PEAR };
auto f1 = ORANGE; // Same as: int f1 = ORAGE;
auto enum f2 = PEAR; // Same as: FruitT f2 = PEAR;
}
}
Type deduction is only supported for local variables.
A type alias is a name that refers to some type information. A type alias can be used as a type for variables, structure members, function parameters, or whatever else that can have a type. The variable, or whatever the object, will get all of the type information referenced by the type alias.
A type alias declaration starts with the typedef
keyword and continues like a variable declaration. The variable name becomes the name of the type alias, and the type of the variable, including array dimensions, becomes the type information to be referenced by the type alias:
// Declare some type aliases.
typedef int NumberT;
typedef str Str10_T[ 10 ];
// Declare some variables and use the type aliases.
NumberT number; // Same as: int number;
Str10_T stringArray; // Same as: str stringArray[ 10 ];
A declaration for a function alias starts with the typedef
keyword and continues like a function declaration, except that the function body is not specified. You cannot declare variables of a function type, but you can declare variables of reference-to-function type:
// Declare some function aliases.
typedef void PlainFuncT();
typedef str StrFuncIntIntT( IntT, IntT );
// Declare some variables and use the type aliases.
PlainFuncT? func; // Same as: void function()? func;
StrFuncIntIntT? func2; // Same as: str function( int, int )? func2;
The name of a type alias is called a type name. Type names must end with a lowercase letter, an underscore, or nothing at all, followed by a capital T. Some valid type names: NumberT
, Str10_T
, T
.
An enumeration is a group of related constants, called enumerators. The first enumerator has a value of 0, the next constant has a value of 1, and so on. The value increases by 1:
enum {
FRUIT_APPLE, // 0
FRUIT_ORANGE, // 1
FRUIT_PEAR // 2
};
The value of an enumerator can be set explicitly. The next value will increase starting from the new value:
enum {
FRUIT_APPLE, // 0
FRUIT_ORANGE = 10, // 10
FRUIT_PEAR // 11
};
An enumeration has a base type. The value of every enumerator will be of the base type. By default, int
is the base type, but you can change it. If int
is not the base type, then you must explicitly set the value of every enumerator:
strict namespace {
enum : str {
FRUIT_APPLE = "Apple",
FRUIT_ORANGE = "Orange",
FRUIT_PEAR = "Pear"
};
script "Main" open {
// Output: AppleOrangePear
Print( s: FRUIT_APPLE + FRUIT_ORANGE + FRUIT_PEAR );
}
}
Enumerations can be named and then used as a variable type. The only thing special about enumeration variables is that they must be initialized and updated with one of the enumerators:
enum Fruit {
FRUIT_APPLE,
FRUIT_ORANGE,
FRUIT_PEAR
};
script "Main" open {
enum Fruit f = FRUIT_PEAR; // Works fine. Initializer is an enumerator.
f = 2; // Error: value assigned not an enumerator.
}
If you don't want to type the enum
keyword when declaring an enumeration variable, you can name the enumeration with a type name. This will implicitly create a type alias that refers to the enumeration:
enum FruitT {
FRUIT_APPLE,
FRUIT_ORANGE,
FRUIT_PEAR
};
FruitT f = FRUIT_PEAR; // Same as: enum FruitT f = FRUIT_PEAR;
The last enumerator can have a comma after it:
enum {
FRUIT_APPLE,
FRUIT_ORANGE,
FRUIT_PEAR, // Comma here is allowed.
};
Structures work much like in C:
// Declare a structure.
struct Boss {
int id;
str name;
};
// Declare and initialize a structure variable.
struct Boss bigBoss = { 123, "Really Mean Boss" };
script "Main" open {
// Output: Boss ID is 123
Print( s: "Boss ID is ", d: bigBoss.id );
// Output: Boss name is Really Mean Boss
Print( s: "Boss name is ", s: bigBoss.name );
}
If you don't want to type the struct
keyword when declaring a structure variable, you can name the structure with a type name. This will implicitly create a type alias that refers to the structure:
struct BossT {
int id;
str name;
};
BossT bigBoss; // Same as: struct BossT bigBoss;
BossT bosses[ 10 ]; // Same as: struct BossT bosses[ 10 ];