Seed7 - The extensible programming language
Seed7 FAQ Manual Screenshots Examples Libraries Algorithms Download Links
Manual Introduction Tutorial Declarations Statements Types Parameters Objects File System Syntax Tokens Expressions OS access Actions Foreign funcs 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 sub-chapters.

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 initialization 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 initialization 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 call-by-name parameters:

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

  1. The assignment ( := ) can only be used to assign a value to a variable and initialization is also needed for constants.
  2. Sometimes some initializations 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 "bigInteger" is bigInteger;
$ 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 "file_error" is FILE_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