-
Notifications
You must be signed in to change notification settings - Fork 10
Functions
The function
keyword is optional. If the function has no parameters, the
void
keyword is optional:
// These are all the same:
function void F( void ) {}
function void F() {}
void F() {}
For a function that returns a value, it is not necessary to have a return statement at the end of the function. As long as the function ultimately returns a value, you can nest the return statements:
// Get absolute value of number.
int Abs( int number ) {
if ( number < 0 ) {
return number * -1;
}
else {
return number;
}
}
A parameter can lack a name. You won't be able to use such a parameter, but you still need to pass an argument for it. This can be used to indicate a parameter is no longer used. This works for script parameters as well.
int Sum( int used1, int, int used2 ) {
return used1 + used2;
}
script "Main" open {
Print( d: Sum( 100, 0, 200 ) ); // Output: 300
}
In a function, the magic identifier, __FUNCTION__
, is a string literal that
contains the name of the current function:
void SomeFunc() {
Print( s: __FUNCTION__ ); // Output: somefunc
}
__FUNCTION__
might look like a predefined macro, but it is not a macro. As a
consequence, it cannot be used in string literal concatenation.
A function parameter can have a default argument. If the user does not supply an argument for the parameter, the default argument will be used:
void Greet( str who = "Mate" ) {
Print( s: "Hello, ", s: who, s: "!" );
}
script "Main" open {
Greet( "Fine Fella" ); // Output: Hello, Fine Fella!
Greet(); // Output: Hello, Mate!
}
Builtin functions now support default arguments that are strings. This means
you can use MorphActor()
with a single argument, as is allowed by the
wiki page, and it will work as intended:
script "Main" enter {
// These are the same:
MorphActor( 0, "", "", 0, 0, "", "" );
MorphActor( 0 );
}
A function can be declared inside a script or inside another function. Such a function is called a nested function:
script "Main" open {
void Greet() {
Print( s: "Hello, World!" );
}
Greet(); // Output: Hello, World!
}
Functions can be nested arbitrarily deep:
script "Main" open {
void F1() {
Print( s: "F1()" );
void F2() {
Print( s: "F2()" );
void F3() {
Print( s: "F3()" );
}
F3();
}
F2();
}
F1();
}
A nested function can access the local variables located outside of it:
script "Main" open {
str msg;
void ShowMsg() {
Print( s: msg );
}
msg = "Hello, World!";
ShowMsg(); // Output: Hello, World!
msg = "Goodbye, World!";
ShowMsg(); // Output: Goodbye, World!
}
Nested functions can have auto
as the return type. The compiler will deduce
the return type from the returned value. If no value is returned, the return
type will be void
:
strict namespace {
script "Main" open {
auto F1() {} // Same as: void F1() {}
auto F2() { return; } // Same as: void F2() {}
auto F3() { return "abc"; } // Same as: str F3() {}
}
}
Passing around a reference to a nested function is not allowed at this time.
Be aware when calling a nested function that has a lot of local variables. The compiler generates code to save and restore local variables. This might be too much a penalty for performance critical code.
Calling a nested function recursively too many times will eventually crash the game.
( return-type parameter-list ) { [statements] }
You can declare and call a nested function at the same time. Such a nested function is called a function literal:
script "Main" open {
Print( s: "Sum: ", d: ( auto() ) {
int sum = 0, i = 1;
while ( i <= 10 ) {
sum = sum + i;
++i;
}
return sum;
}() ); // Output: Sum: 55
}
The above code is equivalent to the following code:
script "Main" open {
auto CalculateSum() {
int sum = 0, i = 1;
while ( i <= 10 ) {
sum = sum + i;
++i;
}
return sum;
}
Print( s: "Sum: ", d: CalculateSum() ); // Output: Sum: 55
}