A Modula2 programozási nyelv

Típusok, típuskonstrukciók

Típusok

A típusdeklaráció fordítási idôben értékelôdik ki, ezért a típusok statikusak. Két típus egymással típuskompatibilis, ha az egyiket a másikkal definiáltuk, az egyik a másik részintervalluma, vagy mindkettô ugyanannak a típusnak a részintervalluma. A nyelvben beépített sztring típus nincs, csak karaktertömbbel szimulálhatjuk ezt a típust. Amikor egy sztring literált egy olyan karaktertömbnek adunk értékül, melybe a sztring hosszánál több elem fér, tömbben egy speciális sztring terminátor karakter kerül a sorozat végére. Az A típusdeklaráció szintaxisa:

Tipus = TipusDeklaracio
 

Beépített típusok

 A beépített típusok a következôk: elôjeles egész szám (INTEGER), elôjel nélküli egész szám (CARDINAL), valós szám (REAL), karakter (CHAR) és logikai (BOOLEAN). A karakter és logikai típusok tekinthetôk felsorolási típusnak is. Az ISO Modula-2-ben van LONGREAL, COMPLEX és LONGCOMPLEX típus is. A Topspeed Modula-2-ben léteznek különbözô méretû numerikus típusok is: SHORTINT, LONGINT, SHORTCARD, LONGCARD, LONGREAL.
 

Felsorolási típusok

 A felsorolási típusok definíciójában konstans azonosítók felsorolásával jelölhetô ki a típusértékek halmaza. Az elsô konstanshoz tartozó típusérték a nulla, a többi konstanshoz a felsorolás sorrendjében eggyel növekvô típusérték rendelôdik hozzá; ez határozza meg a típus rendezését is. Szintaxis:

Tipus = (Konstans1, ..., KonstansN)

 Az INC és DEC mûveletek a típusértéket léptetik egyesével, az ORD és VAL mûveletek a konstanshoz hozzárendlet típusértéket adják vissza.

 Az egész szám, karakter, logikai és felsorolási típusok együttes neve diszkrét típusok.

Részintervallum típusok

 Részintervallum típusok beépített vagy elôzôleg definiált diszkrét típusból szûkíthetôk le az értékkészlet részintervallumának kiválasztásával. A két határ is beletartozik az intervallumba; a felsô határ nem lehet kisebb az alsó határnál, azaz az intervallum nem lehet üres. Az intervallum két határának típusa meg kell egyezzen, ez lesz a részintervallum bázistípusa. Egész típusú határok esetén a bázistípus automatikusan INTEGER lesz, ha az alsó határ negatív, és CARDINAL, ha nemnegatív. Szintaxis:

Tipus = [AlsoHatar..FelsoHatar]
 

Tömb típusok

 A tömb indextartománya diszkrét típusú lehet. Az elemek típusa azonos, számukat a definíció rögzíti. Az elemekre indexeléssel lehet hivatkozni.
Szintaxis:

Tipus = ARRAY IndexTartomany OF BazisTipus
vagy
Tipus = ARRAY Index1, ..., IndexN OF BazisTipus
vagy
Tipus = ARRAY Index1 OF ... OF ARRAY IndexN OF BazisTipus

Formális paraméternek nyílt tömb is megadható. Ilyen esetben az eljárás törzsében a HIGH függvénnyel kérdezhetô le a legmagasabb indexérték. (Az átadott tömbök indextartománza [0..N-1] intervallumra képzôdik le.) Például, ha a formális paraméterek közt szerepel m1: ARRAY OF ARRAY OF ARRAY OF INTEGER, akkor a törzsben a HIGH(m1) adja a legelsô dimenzió felsô indexhatárát, HIGH(m1[0,0]) pedig a harmadik dimenzióét.
 

Rekord típusok

 A rekord elôre meghatározott számú fix mezôbôl áll, amelyek típusa egymástól független. A rekord definíciója a mezôkhöz azonosítókat - szelektorokat - rendel hozzá, ezeknek láthatósági köre a rekordra korlátozódik. Szintaxis:

Tipus = RECORD
  Mezo1, Mezo2: Tipus1;
  ...
  MezoN: TipusN;
END

 A nyelv tartalmaz unió típust is, amikor mezôk vagy mezôk csoportjai a rekordnak ugyanarra a részterületére - egymás fölé - definálódnak. Érdekesség, hogy ezt is rekord formájában kell megadni:

Tipus = RECORD
   ...
  CASE Varians: Tipus OF
    Eset1: Mezo11: Tipus11; ...; Mezo1N: Tipus1N; |
    ... |
    EsetN: MezoN1: TipusN1; ...; MezoNN: TipusNN;
  END
  ....
END

 A rekord unió formájú részében szereplô mezôkre való hivatkozás közben nincsen ellenôrzés arra, hogy a variánsmezô értéke valóban az az eset-e, amelynek listájában a hivatkozott mezô áll.  Egy variánsrekordon belül több ilyen CASE konstrukció is elôfordulhat, és ezek  még fix mezôkkel is keveredhetnek.

 Ha többször egymás után ugyanannak a rekordnak mezôire hivatkozunk, érdemes használni a WITH utasítást, mert ekkor elhagyható a minôsített hivatkozás. Szintaxis:

WITH Rekord DO Utasitas END
 

Halmaz típusok

 Halmaz típusok olyan diszkrét bázistípusból képezhetôk, amely típusértékei beleférnek a gép szóhosszába, amelyet az implementációfüggö WordLength konstans ad meg. Erre a megszorításra azért van szükség, hogy egyetlen gépi kódú utasítással lehessen bármely halmazmûveletet megvalósítani. Szintaxis:

Tipus = SET OF BazisTipus

 Elôre definiált halmaztípus a BITSET:

BITSET = SET OF [0..WordLength - 1].
 

Mutató típusok

 A mutató típus mindig egy másik típusból adódik, értékei olyan pointerek, amelyek bázistípusú értékekre mutatnak. Szintaxis:

Tipus = POINTER TO BazisTipus

 Az ADDRESS elôre definiált, LOC-ra mutató típus kompatibilis minden mutató típussal és a CARDINAL típussal. A NIL konstans szintén kompatibilis minden mutató típussal és a sehová sem mutató mutatót jelöli. Csak az értékadás és az egyenlôségvizsgálat a beépített mûveletek. A SYSTEM modulban található ADDADR, SUBADR, DIFADR mûveletek jelentése  rendre: mutatóhoz egy pozitív érték hozzáadása,  mutatóból egy pozitív érték kivonása, két pointer különbsége. A NEW illetve a DISPOSE eljárások hozzák létre illetve szabadítják fel a mutatóhoz rendelt struktúrát.
 

Eljárás típusok

 Az eljárás típus definíciója az alprogramok fejlécéhez hasonlít. Az egy típusba tartozó eljárások formális paramétereinek sorrendje es sorrendben típusuk, valamint függvényeknél az eredmény típusa azonos. Szintaxis:

EljarasTipus = PROCEDURE(Parameterek)
vagy
FuggvenyTipus = PROCEDURE(Parameterek): EredmenyTipus

 Az elôre definiált PROC típus a paraméter nélküli eljárásokat foglalja magába.
 

Absztrakt típusok

 A nyelv nem támogatja absztrakt típusok létrehozását és használatát. Ehelyett általában átlátszatlan (opaque) típusokat használunk, amikor az reprezentációt olyan formában rejtjük el, hogy az értékre mutatóval lehet hivatkozni a típus mellé adott mûveletekben. Szabatosan, az átlátszatlan típus egy olyan típus melyet egy definíciós modul exportál, de a típus implementációjának részletei az implementációs modulban vannak eltejtve. Például a Vector ADT -t megvalósító típushoz egy alábbi definíciós modul képzelhetõ el:

DEFINITION MODULE Vector;

TYPE Vector;

PROCEDURE NewVector( x, y: REAL; VAR v: Vector);
    (* Memóriát allokál a az új vektorhoz *)

PROCEDURE DestroyVector(VAR v: Vector);
    (* Felszabadítja a memóriát *)

PROCEDURE GetX( v: Vector) : REAL;
    (* X kórdináta *)

...

END Vector.

 Minden, az ISO szabványnak megfelelõ Modula-2 implementációban a definiciós modulban definiált átlátszatlan típust az implemetációs részben újra kell definiálni vagy egy másik átlátszatlan típusként vagy pedig pointerként.

IMPLEMENTATION MODULE Vector;

FROM Storage IMPORT ALLOCATE, DEALLOCATE;

TYPE Vector = POINTER TO VectorData;
  VectorData = ARRAY[1..2] OF REAL;
 

PROCEDURE NewVector( x, y: REAL; VAR v: Vector);
BEGIN
  ALLOCATE(v, SIZE( VectorData));
  v^[1]:=x;
  v^[2]:=y;
END NewVector;

PROCEDURE DestroyVector(VAR v: Vector);
BEGIN
  DEALLOCATE(v, SIZE(VectorData));
END DestroyVector;

PROCEDURE GetX( v: Vector) : REAL;
  RETURN v^[1];
END GetX;

...

END Vector.
 

Típusosztályok, generic

 A nyelv nem támogatja típusosztályok és generic osztályok létrehozását és használatát.