This section describes the outer-most contexts of Mars source code. There are two such contexts: module-level, and the interactive prompt.
Mars modules are files containing top-level nodes. Mars source files typically end in the .mar extension. While this is not strictly necessary for a Mars program, it is not possible to import a module unless it ends in .mar.
A module provides procedure and type declarations, which may form all or part of a program. Modules may be used in several ways, including being imported by other modules, having their functions called from the command line, or executed directly as a program.
There are three forms of top-level node: type declarations, procedure definitions and import statements:
module ::= NEWLINE* toplevel_node* toplevel_node ::= import | typedef | proceduredef
The order in which top-level nodes appear has no consequence.
The import statement (not actually considered a statement) is a line which may only appear in the top-level context of a module:
import ::= "import" identifier NEWLINE
The identifier is the name of a module, to be found in another file on the system. The import statement adds all types and procedure declared in the imported module to the current one, as if they had been declared directly. There are no namespaces - all types and procedures are lumped in together.
If a module is imported more than once, subsequent imports are ignored. Therefore, it is legitimate for a module to import another module twice, or for two imported modules to each import the same module, or even for modules to have cyclic imports.
The module is found by searching for files of the same name, but with the .mar extension. For instance, the following line:
import foo
causes Mars to search for a file called foo.mar.
Mars searches the following places, in order:
If a file of the given name is found, it is imported into the current module. If it is not, it is a critical error and the compiler MUST reject the program.
Modules designed to be executed directly are called programs.
For a module to be considered a program, it must have a function called main, of type () -> io Num. Mars interpreters or compilers may directly execute such a program, by calling this function.
The I/O side-effects of evaluating main form the behaviour of the program, while the result should be considered the exit status of the program. The result is rounded towards zero and converted into a signed integer with the same word size as the C int type; if the value is larger than this type allows, the result is undefined. On a successful execution, the main function should return 0.
A Mars program SHOULD be marked as executable on filesystems which support it, and begin with the following line:
#!/usr/bin/env mars
This allows the program to be executed directly in a Unix environment in which Mars has been correctly installed.
Modules SHOULD NOT begin with this line, or be marked executable, unless they contain a main function intended for direct execution, in order to avoid confusion.
The interactive environment allows Mars modules to be explored at the command prompt, without having to write wrapper code just to try out a function.
The prompt asks the user for a sequence of statements. Each statement is executed immediately after it is typed. Statements executed at the interactive prompt are considered to be in an I/O context. Executing statements at the command line differs from statements inside a procedure in a number of ways: