.. Mars Documentation Copyright (C) 2008-2009 Matt Giuca 7/1/2009 .. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. .. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. .. You should have received a copy of the GNU General Public License along with this program. If not, see . .. _ref-toplevel: ************* The top level ************* .. sectionauthor:: Matt Giuca This section describes the outer-most contexts of Mars source code. There are two such contexts: module-level, and the interactive prompt. Modules ======= 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: :ref:`type declarations `, :ref:`procedure definitions ` and :keyword:`import` statements: .. productionlist:: module: NEWLINE* `toplevel_node`* toplevel_node: `import` | `typedef` | `proceduredef` The order in which top-level nodes appear has no consequence. .. index:: keyword: import .. _import: The :keyword:`import` statement ------------------------------- The :keyword:`import` statement (not actually considered a statement) is a line which may only appear in the top-level context of a module: .. productionlist:: import: "import" `identifier` NEWLINE The :token:`identifier` is the name of a module, to be found in another file on the system. The :keyword:`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 :file:`foo.mar`. Mars searches the following places, in order: 1. The directory the current module is located in. 2. The environment variable :envvar:`MARSPATH`, if it exists, should contain a list of paths separated by colons (":"). Each of these paths are searched, in order from left to right. 3. The implementation may define a fixed sequence of paths to search as a fallback. For instance, the current implementation (on Unix) searches in ``/usr/lib/mars``, then ``/usr/local/lib/mars``. 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. Programs -------- Modules designed to be executed directly are called *programs*. For a module to be considered a program, it must have a function called :func:`main`, of type :type:`() -> io Num`. Mars interpreters or compilers may directly execute such a program, by calling this function. The I/O side-effects of evaluating :func:`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 :type:`int` type; if the value is larger than this type allows, the result is undefined. On a successful execution, the :func:`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 :func:`main` function intended for direct execution, in order to avoid confusion. Interactive environment ======================= 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: 1. Firstly, the interactive prompt allows special commands which are not valid Mars syntax. These commands all begin with a colon (":"), and are outside the scope of this document. Type "``:?``" at the prompt for information. 2. These statements may not be compound statements. They must be of the form :token:`basic_statement`. 3. Statements are checked semantically immediately after being typed. Any semantic errors merely cause the statement to be ignored, rather than the entire program being rejected. 4. Statements of the form :token:`expression_stmt` have special behaviour -- the resulting value is converted into a string using the built-in :func:`show` function, and then that string is printed to standard output. This allows the result of an expression to be seen, rather than just thrown away. 5. Variable assignment works differently to the way it works in a procedure body. If a variable is assigned when it already exists, its previous value and type are discarded, and the variable is re-declared with the type of the expression. This means that variables may be re-assigned with a new type, which is not possible in the body of a procedure.