Skip to content

Program Execution

A Grayscale program consists of one or more source files that are compiled to a native binary by the Grayscale compiler. Each file may contain:

  1. Import declarations
  2. Using declarations
  3. Top-level declarations (functions, structs, enums, constants)

Every Grayscale program must define a main function with no parameters and no return value:

do main() {
// Program starts here
}

The main function is not called explicitly; it is invoked automatically when the program runs.

main() exits when control reaches its closing brace. An explicit return statement inside main() is not allowed. To terminate early, branch the remaining work behind an if/otherwise, or call exit(code) to end the program with a specific status.

Expressions are evaluated left-to-right. Function arguments are evaluated before the function is called.

Short-circuit evaluation applies to && and ||:

do a() -> bool { return false }
do b() -> bool { println("b called"); return true }
do main() {
// If a is false, b() is not called
if a() && b() { println("both") }
// If a is true, b() is not called
if !a() || b() { println("either") }
}

A program terminates when:

  1. The main function returns
  2. A runtime error occurs