A Modula3 programozási nyelv

Alprogramok, modulok

Szintaxis

A lényeget tekintve ebben sem sokban tér el más PASCAL-szerű nyelvektől. Egyetlen kulcsszó, a PROCEDURE szolgál alprogramok definiálására. A függvényeket és az eljárásokat tehát csak a visszatérési érték létezése alapján különbözteti meg.

Egy eljárást csak egyszer definiálhatunk. Egy eljárástípust a következőképpen kell megadni:

TYPE T = PROCEDURE sig,

ahol a sig egy szignatúrát jelöl, aminek így kell kinéznie:

formali
egy formális paraméter deklaráció, később részletesen tárgyalva.
  • R a visszatérési érték típusa. Ezt nem kötelező megadni, ilyenkor nincsen visszatérési érték.
  • S a kivételek halmaza, amelyeket lekezelhet az eljárás. Ezeket felsorolva kell megadni, de ha mindent el szeretnénk kapni, akkor ANY-t kell írni. Ha nem írunk semmit, akkor S egy üres halmaz lesz.
  • Paraméterátadás

    A formális paraméterdeklaráció:

    Mode Name: Type := Default;

    ahol

    Mivel lehet paraméternek kezdőértéket adni, így az eljárás hívásakor elhagyható ez paraméter.

    Túlterhelés

    Rekurzió

    Eljáráshívás

    Az eljáráshívás általános formája:

    P(paraméterlista)
    procedure name(actual parameter1,... actual parametern)
    

    A szokásostól (pl. Modula-2, Pascal) eltérően, a paraméterlistát nemcsak pozicionálisan, hanem név szerint is megadhatjuk. Sőt keverhető is a kétféle megadás, azzal a megkötéssel, hogy előre jönnek a pozicionális paraméterek, és utánuk már csak név szerint kötött paraméterek következhetnek. Lássunk egy példát:

    Ha P a következőképpen deklarált:

    P : PROCEDURE(ch : CHAR; n : INTEGER:=0)

    akkor a következő hívások ekvivalensek:

        P('a', 0)
        P('a')
        P(ch := 'a')
        P(n := 0, ch := 'a')
        P('a', n := 0)
    

    P() illegális, mivel nem köti ch-t. A

    P(n := 0, 'a')
    forma szintén illegális, mert a pozicionális paraméterek csak a lista elején szerepelhetnek.

    További érdekesség az EVAL kulcsszó. Ezzel a paranccsal kiértékelhetünk egy függvényt olyankor, amikor a visszatérési érték nem érdekel minket, csak a függvény mellékhatásait szeretnénk érvényesíteni. Az EVAL tehát elnyeli a visszatérési értéket.

    Itt kell megemlíteni azt is, hogy Modula-3-ban nincs lehetőség operátorok túlterhelésére.

    Modulok

    A Modula-3 fordítási egységei a modulok és interfészek.

    Egy modul olyan mint egy blokk, kivéve az azonosítók láthatóságát: Egy entitás látható egy blokkban, ha az adott blokkban, vagy valamely befoglaló blokkban deklarálták.

    Egy entitás látható egy modulban, ha az adott modulban, vagy valamely a modul által importált vagy exportált interfészben deklarálták.

    A program végrehajtása a moduljainak törzsének végrehajtását jelenti a következő szabályok alapján:

    Azt a modul, melynek törzse utolsóként hajtódik végre, fő modulnak nevezzük. A nyelv implementációitól elvárt, hogy valamilyen eszközt adjanak a program fő moduljának explicit kijelölésére, ha ez a fenti szabályok alapján nem lenne egyértelmű. A nyelv definíciója szerint erre a javasolt az megoldás, hogy a fő modul az, amely a Main nevű interfészt exportálja, melynek tartalma implementációfüggő.

    A program végrehajtása akkor fejeződik be, amikor a fő modul törzsének végrehajtása befejeződik, még akkor is, ha konkurens szálak még futnak.

    Import utasítás

    Az IMPORT utasításnak két formája van. Minden import definíció (formájától függetlenül) szimultán értékelődik ki.

    Az első forma:

            IMPORT I AS J
    

    amelynek hatására importálja az I interfészt, melyre a importáló modulon belül a továbbiakban J-vel hivatkozhatunk. Az I által deklarált entitások láthatóvá válnak a modulban, de az I által importáltak nem.

    Ezek után az I interfészben N néven deklarált entitásra a J.N minősített névvel hivatkozhatunk.

    Az IMPORT I utasítás ekvivalens az IMPORT I AS I utasítással.

    Az második forma:

            FROM I IMPORT N
    

    amelynek hatására N lokális néven lesz elérhető az I interfészben deklarált N entitás. Egy lokális hivatkozás mindig nagyobb precedenciájú;, mint a globális, azaz pl.

            IMPORT I AS J, J AS I;
            FROM I IMPORT N
    
    3/ hatására szimultán a következő lokális nevek keletkeznek: J, I, N sorrendben a következő globális névvel rendelkező entitásokhoz: I, J, J.N

    Ugyanazt a lokális nevet nem szabad többször használni, azaz a következő import utasítás illegális, még akkor is, ha J és K ugyanaz:

            IMPORT J AS I, K AS I;
    

    Egy modult a következőképpen definiálhatunk:

            MODULE <azonosító> EXPORTS <exportált interfészek listája>;
                    <import utasítások>;
                    <deklarációk>;
            <modul törzs - blokk> <azonosító>;
    	Blokk = <deklarációk> BEGIN <Utasítások> END
    
    Utasítás is lehet blokk.

    Ha nincs megadva EXPORTS, akkor alapértelmezésként <AZONOSÍTÓ>lesz az.

    Ha M modul exportálja az I interfészt, akkor I entitásai minősítés nélkül elérhetőek M-ben.

    Bármely eljárás, mely I-ben deklarált, megadható M-ben törzsével együtt. Az eljárás M-beli szignatúrának meg kell felelnie az I-ben lévőnek, azaz:

    A paraméternevek és alapértelmezett paraméterértékek tekintetében az M-en belül az M-beli, mindenhol máshol az I-beli szignatúra használatos.