No tutorial would be complete without a Hello World example. Below is the source code for Hello World in Regent, with descriptions of the various portions of the program following. The source for this and other tutorials can also be found in the GitHub repository.
Regent is an embedded language. The outermost level of the source code is a Lua script. By default, everything you see in a Regent program is written in Lua. The program switches into Regent when certain keywords (e.g., task
) are used. This allows Regent and Lua code to be used side-by-side in the same program.
In order to register Regent’s keywords with the Lua interpreter, every Regent program starts with the following line:
(If you forget this line, you will typically see a parser error, as Lua attempts to interpret Regent keywords as Lua variable names.)
Execution of a script begins in Lua. The code runs top-to-bottom, like a standard scripting language. Unlike a conventional language, Regent constructs can also be embedded in the program.
Important: in most cases, Lua code cannot directly call Regent tasks. (The exception, regentlib.start
, is shown below.) This means that it is best to think of Lua running “at compile time” from the perspective of Regent. Exactly what this means, and how to use it, will be explored in a future tutorial.
As an example, the line below loads the std/format
module from the Regent standard library, which provides utilities for formatted printing.
The module here is actually a Lua value. It is stored in a Lua variable (via local
) under the name format
. As we’ll see below, Regent code can access Lua variables. This means that once we load the module in Lua, we can make use of it in our Regent code.
Next we define a Regent task. This is done with the task
keyword. Note that, once we reach the task
keyword, subsequent code is in Regent (until the matching end
). After end
we return to Lua to continue execution.
Regent tasks are covered in a future tutorial, but for now it is sufficient to say that they behave like functions.
After this, we define the main task. The main task, like main
in many languages, takes no arguments and produces no result. (Unlike many languages, the name main
is just a convention in Regent. It could be anything.)
Here, our main task invokes hello_world
to produce the output message.
Finally, at the end of the file, we start the program (beginning with main
). Note that, as described earlier, this is the only place where Lua is permitted to call into Regent. After this call, execution begins at main
and proceeds through the Regent program.
In our example, main
calls hello_world
, which calls format.println
, which prints a line to the standard output of the program.
The start
call does not return. Furthermore, the Lua execution environment used to compile the Regent program is also unavailable after this function is called. So complete any Lua programming prior to calling this function.
Continue to the next tutorial to see how to use tasks to achieve parallel execution.