Seed7 
 FAQ 
 Manual 
 Screenshots 
 Examples 
 Algorithms 
 Download 
 Links 

 Manual 
 Introduction 
 Tutorial 
 Declarations 
 Statements 
 Types 
 Parameters 
 Objects 
 File System 
 Syntax 
 Tokens 
 Expressions 
 OS access 
 Actions 
 Errors 

 Declarations 
 Normal 
 Syntax 
 System 
 Manual 
Declarations
 previous   up   next 

3. DECLARATIONS

A declaration specifies the identifier, type, and other aspects of language elements such as variables, constants and functions. In Seed7 everything must be declared before it is used. Seed7 uses three kinds of declarations:

  • Normal declarations
  • Syntax declarations
  • System declarations

which are described in detail in the following subchapters.

3.1 Normal declarations

Normal declarations are the most commonly used form of declarations. To contrast them to the syntax declarations normal declarations are sometimes called semantic declarations. Seed7 uses uniform looking declaration constructs to declare variables, constants, types, functions and parameters. For example:

    const integer: ONE is 1;

declares the 'integer' constant 'ONE' which is initialized with the value 1. Variable declarations are also possible. For example:

    var integer: number is 0;

declares the 'integer' variable 'number' which is initialized with the value 0. Type declarations are done as constant declarations where the type of the declared constant is 'type':

    const type: myChar is char;

Function declarations are also a form of constant declaration:

    const func boolean: flipCoin is
      return rand(FALSE, TRUE);

Each object declared with a 'const' or 'var' declaration obtains an initial value. It is not possible to use 'const' or 'var' declarations without initial value. Declarations with initialisation expressions are also possible. For example

    var string: fileName is NAME & ".txt";

The expression is evaluated and the result is assigned to the new object. This is done in the analyze phase of the interpreter or compiler, before the execution of the program starts. The initialisation expressions may contain any function (or operator) call. That way user defined functions can also be used to initialize a constant or variable:

    const boolean: maybe is flipCoin;

Constant and variable declarations can be global or local. The mechanism to define a parameter like 'x' is similar to the 'const' or 'var' declarations:

    const func float: inverse (in float: x) is
      return 1/x;

Function parameters, such as the parameter 'statement' in the example below, act as closures:

    const proc: possiblyDo (in proc: statement) is func
      begin
        if flipCoin then
          statement;
        end if;
      end func;

Abstract data types such as 'subtype', 'struct', 'subrange', 'array', 'hash', 'set', 'interface' and 'enum' are realized as functions which return a type. E.g.: The type 'array' is defined in the "seed7_05.s7i" library with the following header:

    const func type: array (in type: baseType) is func

User defined abstract data types are also possible.

The initialisation uses the creation operation ( ::= ). Explicit calls of the create operation are not needed.

The lifetime of an object goes like this:

  1. Memory is reserved for the new object (stack or heap memory make no difference here).
  2. The content of the new memory is undefined (It may contain garbage), therefore a create statement is necessary instead of an assignment.
  3. The create statements copies the right expression to the left expression taking into account that the left expression is undefined.
  4. If the object is variable other values can be assigned using the assign statement ( := ). The assignment can assume that the left expression contains a legal value. This allows that for strings (and some other types which are just references to a memory area) the memory containing the old string value (and not the memory of the object itself) can be freed when necessary.
  5. At the end of the lifetime of an object the destroy statement is executed. For strings (and some other types which are just references to a memory area) the memory containing the string value (and not the memory of the object itself) is freed.
  6. The memory of the object is freed.

The first three steps are usually hidden in the declaration statement. The expression

    ONE . ::= . 1

is executed to assign 1 to the object ONE. There are two reasons to use ::= instead of := to assign the initialisation value.

  1. The assignment ( := ) can only be used to assign a value to a variable and initialisation is also needed for constants.
  2. Sometimes some initialisations are needed for the new object in addition to the pure assignment.

For all predefined types the creation operator ( ::= ) is already defined. To allow the declaration of objects of a new user defined type the constructor operation for this type must be defined.

3.2 Syntax declarations

Syntax declarations are used to specify the syntax, priority and associativity of operators, statements, declarations and other constructs. A syntax declaration which defines the '+' operator is:

    $ syntax expr: .(). + .()   is ->  7;

Most syntax definitions can be found in the file "syntax.s7i". A detailed description of the syntax declarations can be found in chapter 9 (Structured syntax definition) There is also a hard coded syntax for function calls with a parenthesis enclosed parameter list where the parameters are separated by commas. The hard coded syntax is described in chapter 11 (Expressions). Here we use a more complex syntax description:

3.3 System declarations

With system declarations the analyzer and the interpreter are informed about which objects should be used for various system internal purposes. An example of a system declaration is

    $ system "integer" is integer;

This defines that the type of all integer literals is 'integer'. Additionally 'integer' is used as type for all integers generated by primitive actions. There are different objects which are defined by a system declaration

  • The types of literals and simple expressions for example: 'string' for strings and 'integer' for integers
  • Which objects should be used as result values for primitive actions for example:
            TRUE, FALSE and empty
  • The EXCEPTIONS which are to be raised by primitive actions for example:
            NUMERIC_ERROR and MEMORY_ERROR
  • Which objects should be used for several implicit actions for example:
            := ::= 'destroy' 'write' and 'flush'

The following system declarations exist

    $ system "type" is type;
    $ system "expr" is expr;
    $ system "integer" is integer;
    $ system "char" is char;
    $ system "string" is string;
    $ system "proc" is proc;
    $ system "float" is float;

    $ system "true" is TRUE;
    $ system "false" is FALSE;
    $ system "empty" is empty;

    $ system "memory_error" is MEMORY_ERROR;
    $ system "numeric_error" is NUMERIC_ERROR;
    $ system "range_error" is RANGE_ERROR;
    $ system "io_error" is IO_ERROR;
    $ system "illegal_action" is ILLEGAL_ACTION;

    $ system "assign" is := ;
    $ system "create" is ::= ;
    $ system "destroy" is destroy;
    $ system "ord" is ord;
    $ system "in" is in;
    $ system "prot_outfile" is PROT_OUTFILE;
    $ system "flush" is flush;
    $ system "write" is write;
    $ system "writeln" is writeln;
    $ system "main" is main;


 previous   up   next