.. 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.