Az ELAN programozási nyelv

Típusok, típuskonstrukciók

3. Típusok, típuskonstrukciók

Ez a fejezet az alábbi című alfejezeteket tartalmazza:
3.1. Konkrét típusok
3.2. Új típusok képzése

3.1. Konkrét típusok

Ez az alfejezet az ELAN nyelvben meglévő elemi típusokkal kapcsolatos ismereteket tartalmazza az alábbi felosztásban:
3.1.1. Deklarációs utasítás
3.1.2. Egész típus
3.1.3. Valós típus
3.1.4. Logikai típus
3.1.5. Szöveg típus
3.1.6. Szinonímák

Az ELAN nyelvben az objektumok deklarációik végrehajtásával dinamikusan jönnek létre.
Elemi objektumok: skalár állandók és változók
Összetett objektumok: tömbök, struktúrák, amik szintén állandók és változók lehetnek.

3.1.1. Deklarációs utasítás

Az ELAN nyelvben minden objektumot deklarálni kell!
Deklarációkor egy objektum négyféle jellemzőjét határozhatjuk meg: típusát, használati jogát, nevét, valamint értékét:


típus használati jog név :: érték
típus használati jog név

Az utóbbi esetben az adatnak nem lesz kezdőértéke, s az ELAN-rendszer ellenőrzi, hogy felhasználása előtt kap-e értéket vagy sem.
A típusokról a későbbiekben lesz szó. A használati jog az ELAN nyelvben kétféle lehet:
- konstans (azaz: CONST)
- változó (azaz: VAR)

A név kisbetűket, számjegyeket, valamint szóközt tartalmazhat. Az érték tetszőleges kifejezés lehet. A konstansoknak kötelező értéket adnunk deklaráláskor és ez a későbbiekben nem változhat meg.

Több azonos típusú és használati jogú változó egyetlen deklarációs utasításban megadható, egymástól vesszővel elválasztva.


Példa:


INT CONST nulla::0, egy::1;

A deklaráció hatásköre a teljes programegységre kiterjed, amiben deklaráltuk. A deklarációt akár újból végrehajthatjuk, s ekkor változóink, konstansaink más kezdőértéket kaphatnak, de egy objektum csak egy helyen definiálható.

3.1.2. Egész típus

A típusokat nevükkel, értékhalmazukkal, s a rajtuk végzett műveletekkel definiáljuk. Az egész típus neve: INT, értékhalmaza:

[-2147483647..2147483647]


Példa:


INT VAR i:: 123, # 123 kezdőértékű változó #
j; # kezdőérték nélküli változó #
INT CONST n:: 100 # 100 értékű konstans #
INT VAR k:: n+i; # 223 kezdőértékű változó #


Az egész típus műveletei:

Relációk: <, <=, =, <>, >, >=.

Aritmetikai műveletek: +, -, *, DIV, MOD, ** # ahol ** a hatványozás műveleti jele #

Előjel: +, -.

Egyéb operátorok: SIGN, ABS.

Egyéb függvények: sign, abs, max, min, even, odd.

Ezen függvényeket érdemes a definíciójukkal megadni:


INT PROC sign(INT CONST i):
IF i<0 THEN -1
ELIF i=0 THEN 0
ELSE 1
FI
END PROC sign;

INT PROC abs(INT CONST i):
IF i<0 THEN -i
ELSE i
FI
END PROC abs;

INT PROC max(INT CONST i,j):
IF i>j THEN i
ELSE j
FI
END PROC max;

INT PROC min(INT CONST i,j):
IF i ELSE j
FI
END PROC min;

BOOL PROC even(INT CONST i):
i MOD 2 = 0
END PROC even;

BOOL PROC odd(INT CONST i):
i MOD 2 <> 0
END PROC odd;



Példa:


j:=sign(i); # a sign függvény alkalmazása #
j:=SIGN i; # a SING operátor alkalmazása #

Konverziós függvények:
trunc # valós szám csonkítása egészre #
round # valós szám kerekítése egészre #
int # szövegben levő szám egésszé alakítása #
ascii # szöveg első karakterének ASCII kódja #
code # szöveg első karakterének ASCII kódja #
digit # szöveg első számjegye egészként #


Példa:


földsugár := int("6378388");

Konstansok:
minint # a legkisebb egész szám #
maxint # a legnagyobb egész szám #

3.1.3. Valós típus

A valós típus neve: REAL, értékhalmaza:

[-1.70141183*10**38..1.70141183*10**38]


Példa:


REAL VAR abszolútnulla:: -273.16, # fixpontosan felírt szám #
földtömeg:: 5.976E24, # exponenciális alakú szám #
elektronsugár:: 2.817939E-15, # exponenciális alakú szám #
elektrontöltés:: -1.6021E-19; # exponenciális alakú szám #

A valós típus műveletei:

Relációk: <, <=, =, <>, >, >=.

Aritmetikai műveletek: +, -, *, /, **

# A ** (azaz: hatványozás) műveletnél az alap valós, a kitevő valós vagy egész szám. #
# A / (azaz: osztás) művelet két operandusa vagy két valós, vagy két egész szám. #


Példa:


x:=3/7; # két egész szám hányadosa valós érték #
harmad:=1/3; # két egész szám hányadosa valós érték #
y:=3.0/7.0; # két valós szám hányadosa is valós érték #
z:=3/7.0; # hibás kifejezés #
V:=3.0/7; # hibás kifejezés #

Előjel: +, -.

Egyéb operátorok: SIGN, ABS.

Trigonometrikus függvények: sin, cos, tan, arcsin, arccos, arctan.


Példa: (a hiányzó ctg és arcctg trigonometrikus függvények definíciója)


REAL PROC ctg(REAL CONST x):
1 / tan(x)
ENDPROC ctg;

REAL PROC arcctg(REAL CONST x):
pi / 2 - arctan(x)
ENDPROC arcctg;

Logaritmikus és exponenciális függvények: ln, log10, log2, exp.

Egyéb függvények: sign, abs, max, min, sqrt.

Konverziós függvény: real # egész érték vagy szöveg típusú adat valós típusúvá alakítására #


Példa:


x:=real(i);
g:=real("9.81");

Konstansok:
maxreal # a legnagyobb abszolútértékű pozitív valós szám #
smallreal # a legkisebb abszolútértékű pozitív valós szám #

A valós típus két nevezetes konstansát szinonímanévvel látták el:


LET pi=3.141592653589793;
LET e=2.71828182845904;


3.1.4. Logikai típus

A logikai típus neve: BOOL, értékhalmaza:

TRUE, FALSE # azaz: igaz, hamis #


Példa:


BOOL CONST igaz:: TRUE, # igaz értékű konstans #
hamis:: FALSE; # hamis értékű konstans #
BOOL VAR jó :: FALSE; # hamis kezdőértékű változó #

A logikai típus műveletei:

Relációk: =, <>.

Logikai operátorok: AND, OR, NOT.

A többi logikai operátort nekünk kell definiálni, például a relációk segítségével.


Példa:


BOOL OP XOR(BOOL CONST a, b):
a<>b
ENDOP XOR;

BOOL OP EQV(BOOL CONST a, b):
a=b
ENDOP EQV;

BOOL OP NAND(BOOL CONST a, b):
NOT (a AND b)
ENDOP NAND;

BOOL OP NOR(BOOL CONST a, b):
NOT (a OR b)
ENDOP NOR;

BOOL OP IMP(BOOL CONST a, b):
NOT a OR (a AND b)
ENDOP IMP;


A logikai típushoz nem állnak rendelkezésre automatikusan konverziós műveletek, ezért ezeket nekünk kell megírni:


Példa:


# az alábbi bool nevű eljárás TEXT típusú inputadat alapján BOOL típusú logikai értéket képez:#
BOOL PROC bool(TEXT CONST a):
IF a = "TRUE" THEN TRUE
ELSE FALSE
FI
ENDPROC bool;

# az alábbi text nevű eljárás BOOL típusú inputadat alapján TEXT típusú szöveges adatot képez:#
TEXT PROC text(BOOL CONST a):
IF a THEN "TRUE"
ELSE "FALSE"
FI
ENDPROC text;


3.1.5. Szöveg típus

A szövegek ELAN-ban tetszőleges számú karakterből álló absztrakt sorozatok, nagyon sokféle művelettel ellátva. Csak a típusnevük (TEXT) adható meg deklarációban, azaz nem típuskonstrukciós eszköz, hanem konkrét típus:


TEXT hozzáférési jog név :: kezdőérték


A szövegkonstansok idézőjelek (azaz: " " jelpár) közé tett tetszőleges karaktersorozatok.
Szinonímaként a nyelv három szövegkonstanst definiál:


LET niltext=""; # az "üres" szöveg #
LET blank=" "; # az egy szóközből álló szöveg #
LET quote="""; # az idézőjel, mint szöveg #

Relációk: <, <=, =, <>, >, >=. (Ezek a szöveg típus esetén lexikografikus rendezési relációk.)

Megjegyzés: A lexikografikus rendezést a szövegek esetében hívhatjuk névsor szerinti rendezésnek is.

A szöveg karaktereinek darabszámát megadó művelet:
LENGTH # ha a műveletet operátorként használjuk #
length # ha a műveletet függvényként használjuk #

Konstrukciós műveletek:
+, illetve CAT # két szöveg egymás mögé írása, azaz konkatenációja (= összefűzése) egyetlen szöveggé #
* # adott szöveg sokszorozása #


Példa:


mondat := mondat+" szó"
mondat CAT " szó" # hatása azonos az előző sor hatásával #
hat := "bbbbbb"
hat := 6*"b" # hatása azonos az előző sor hatásával #

Szelekciós műveletek:
HEAD szöveg # a szöveg első karaktere #
TAIL szöveg # a szöveg első karaktere utáni karakterei #

Az összes szövegművelet működik abban az esetben is, ha tartalmilag értelmetlen paramétert kap. Ilyenkor eredményként az üres szöveget adják.


Példa:


PROC léptet(TEXT VAR sz):
TAIL sz + HEAD sz
ENDPROC léptet;

A SUB művelet:
szöveg SUB i # a szöveg i-edik karaktere #

A text függvény:
text(szöveg,db) # a szöveg első db darab karaktere #
text(szöveg,db,kezdet) # a szövegnek a kezdet-től vett db darab karaktere #


Példa:


text("farkasalma",6) # eredménye: "farkas" #
text("rozmaring",4,4) # eredménye: "mari" #



A subtext függvény:
subtext(szöveg,kezdet) # a szövegnek a kezdet-től vett karakterei #
subtext(szöveg,kezdet,vég) # a szövegnek a kezdet-től a vég-ig vett karakterei #


Példa:


subtext("rebarbara",3) # eredménye: "barbara" #
subtext("csombor",2,4) # eredménye: "som" #

PROC kiírás:
TEXT VAR v::"VAKÁCIÓ";
INT VAR i;
FOR i FROM LENGTH v DOWNTO 1
REP
put(subtext(v,i)); line
ENDREP
ENDPROC kiírás;



Transzformációs műveletek (a cserélések eljárások, a többiek függvények):

compress(szöveg) # szóközök lehagyása a szöveg széleiről #

replace(szöveg,kezdet,új) # a szöveg karaktereit kezdet-től az új szöveg karaktereire cseréli, az előtte és mögötte levők változatlanok maradnak #

change(szöveg,mit,mire) # a szövegben az első mit karaktersorozatot a mire karaktersorozatra cseréli #

change all(szöveg,mit,mire) # a szövegben az összes mit karaktersorozatot a mire karaktersorozatra cseréli #

post(szövet,mi) # a szövegben az első mi karaktersorozat kezdete #

post(szövet,mi,kezdet) # a szövegben a kezdet-től az első mi karaktersorozat kezdete #

post(szövet,mi,kezdet,vég) # a szövegben a kezdet-től a vég-ig az első mi karaktersorozat kezdete #

A transzformációs műveletek a szöveg szerkesztésére, szövegrészek keresésére használható függvények, illetve eljárások.

Konverziós függvény:
text(egész érték) #a szükséges számú karakterre konvertálja az egész értéket #

text(egész érték, hossz) # hossz számú karakterre konvertál, elöl szóközökkel kiegészítve #

text(valós érték) # a szükséges számú karakterre konvertál exponenciális alakban #

text(valós érték, hossz) # hossz számú karakterre konvertál fixpontosan, a végén 0-kkal kiegészítve #

text(valós érték, hossz, törtrész hossz) # hossz számú karakterre konvertál, a törtrész hossza is rögzített, elöl szóközökkel kiegészítve #

Konverziós függvények alkalmazásával megoldható a beolvasás ellenőrzése, a kiírás szép formátumú megoldása (pl. a valós számokat e konverzió nélkül a put eljárás exponenciális alakban írja ki, s ez a konverzióval fixpontossá alakítható).


Példa:


put(text(3.14,5,2)) # "3.14" kiírása #

A beolvasás ellenőrzéséhez egy újabb logikai függvényre lesz szükségünk. Ez a függvény azt adja meg, hogy az utolsó konverziós művelet sikeres volt-e:



last conversion ok



Típusellenőrzés esetén a szám típusú változók helyett olvassunk be egy szöveg típusúba, arra alkalmazzuk a típusnevet (int, real) mint konverziós függvényt, majd nézzük meg, hogy az utolsó konverzió sikeres volt-e!


Példa:


INT VAR i; TEXT VAR c;
REP
get(c);
i:=int(c)
UNTIL last conversion ok
ENDREP


3.1.6. Szinonímák

A szinonímák fordítási konstansok, egész és valós értékeket, valamint szövegeket rövidítenek, de a típusuk nem adható meg. Ellentétben a típusos konstansokkal, ezek futási időben nem rendelkeznek önálló memóriacímmel, annyi példányban másolódnak be a programkódba, ahány helyen szerepelnek.


LET szinonímanév = érték



Példa:


LET elemszám=100;
ROW elemszám INT VAR x; # 100 elemű egész tömb definiálása #

Érdekesség, hogy típusoknak is adhatunk szinonímanevet, s ezáltal a programszöveg olvashatóbbá válik.

Van egy másik lehetőség a szinonímák alkalmazására, nevezetesen amikor egy típust keresztelünk el, keresztelünk újra.


LET szinonímanév = típusnév



Ez a lehetőség használható például típusnevek magyarítására. (Szinonímanévként azonban standard típus neve nem használható.)


Példa:


LET EGÉSZ=INT;
EGÉSZ VAR i,j;


3.2. Új típusok képzése

Ez az alfejezet az ELAN nyelvben képezhető összetett típusokat ismerteti, melyek az alábbiak:
3.2.1. Tömb
3.2.2. Rekord
3.2.3. Rekurzív típusok
3.2.4. Paraméteres típusok
3.2.5. Típusszármaztatás

Az ELAN programozási nyelv az összetett típusok képzésének széles körével rendelkezik, ez azonban némileg eltér a más nyelvekben megszokottaktól.

E rész példáiban fel fogjuk használni az előző részben definiált nyelvi elemeket: a négyféle programegységet.

3.2.1. Tömb

Az egyik leggyakoribb struktúra, a szokásosnál szűkebb indextartomány-megadási lehetőséggel:


ROW darabszám elemtípus


A tömbök mindig 1-től indexelhetők, elemeik tetszőleges, de azonos típusúak lehetnek. Elemszámuk csak számkonstans, vagy számkonstansot rövidítő szinonímanév lehet.

Tömb típusú adatok deklarációja hasonló a korábban megismerthez:


ROW darabszám elemtípus hozzáférési jog név::[érték, ... , érték]


A kezdőérték, a bevezető ::-tal együtt elmaradhat, ilyenkor a tömbelemek érték nélküliek lesznek, felhasználásuk előtt kötelező nekik értéket adni. Ha van kezdőérték, akkor az tetszőleges - akár változókat is tartalmazó - kifejezésekből is állhat.

Az egész tömbre a nevével, az elemeire indexeléssel hivatkozhatunk, ahol az index tetszőleges, természetes szám értékű kifejezés lehet:


tömbnév



tömbnév[indexkifejezés]


A szögletes zárójel egyben konstrukciós műveletként is szerepelhet, s így kifejezésekben is használható.


Példa:


ROW 4 INT VAR a;
INT VAR i:: 14;
a := [2,3,5,i DIV 2];

Lehetőségünk van többindexes tömbök deklarálására is, a mátrix például úgy fogható fel, mint vektorok vektora.

Példa:


TYPE MATRIX=ROW 10 ROW 10 INT; # egész elemű 10*10-es mátrix #
MATRIX VAR a,b;
a[1][1] := 1; # egy mátrixelem kap értéket #
# Megjegyzés: a más nyelvekben szokásos a[1,1] jelölés nem használható. #
a[2] := a[1]; # a mátrix egy sora kap értéket #
a := b; # a teljes mátrix kap értéket #

Mint a példából is kiderül, használhatjuk az egész mátrixot, a mátrix egy sorát, vagy pedig egy elemét. Ugyanezen elv alapján a mátrixkonstans vektorkonstansok vektora lesz.


Példa:


TYPE TRANSZF=ROW 2 ROW 2 REAL;
TRANSZF CONST egység :: [[1.0, 0.0],[0.0, 1.0]];

Végezetül nézzünk egy példát tömbök, tömb típusú értéket visszaadó függvények használatára!


Példa: (síkbeli pontok típusa, transzformációikkal)


TYPE PONT=ROW 2 REAL;
PONT CONST origó :: [0.0, 0.0];
PONT PROC nagyít(PONT CONST p, REAL CONST n):
PONT: [p[1]*n, p[2]*n]
ENDPROC nagyít;

Megjegyzés: a típusnév mindig konverziós függvényként is szolgál: [a,b] ROW 2 REAL típusú, PONT:[a,b] már PONT típusú.


PROC put(PONT CONST p):
put("(x="); put(p[1]);
put(", y="); put(p[2]); put(")")
ENDPROC put;
...

Megjegyzés: Az azonosítók átlapolhatósága miatt kiírásra olyan nevű eljárás is írható, mint a szokásos kiíró put eljárás. (Sőt célszerű is!)

3.2.2. Rekord

Az ELAN-ban a rekord tetszőleges típusú mezőkből álló, alternatív részt nem tartalmazó szerkezet:


STRUCT(típus mezőnév, ...)


Ha több azonos típusú mező követi egymást, akkor a típus nevét elég az elsőnél kiírni.


Példa:


TYPE ORSZÁG=STRUCT(TEXT név, nyelv, INT lakosság, REAL terület);

Deklarációs utasításban a tömbökhöz hasonlóan szerepelhet:


STRUCT(típus mezőnév, ...) hozzáférési jog név::[érték, ..., érték]



Az egész rekordra a nevével hivatkozhatunk:


rekordnév



A rekord egyes mezőire a mezőnévvel minősített névvel hivatkozhatunk:


rekordnév.mezőnév



A szögleges zárójel a tömbökhöz hasonlóan itt is konstrukciós műveletként is szerepelhet.


Példa: (a racionális szám típus szerkezete és műveletei)


TYPE RAC=STRUCT(INT számláló, nevező);
RAC CONST egy :: [1,1];

PROC get(RAC VAR r):
put("számláló?"); get(r.számláló);
put(", nevező?"); get(r.nevező);
ENDPROC get;

PROC put(RAC CONST r):
put(r.számláló); put("/"); put(r.nevező);
ENDPROC put;

RAC OP +(RAC CONST a,b):
RAC VAR c;
c:=RAC:[a.számláló*b.nevező+b.számláló*a.nevező,a.nevező*b.nevező];
egyszerűsít(c)
ENDOP +;

RAC PROC egyszerűsít(RAC CONST r):
INT VAR n;
n:=lnko(r.számláló, r.nevező);
RAC:[r.számláló DIV n, r.nevező DIV n]
ENDPROC egyszerűsít;
...


3.2.3. Rekurzív típusok

Az ELAN nyelv lehetőséget ad rekurzív típusok közvetlen definiálására. Egy rekordtípus tartalmazhat tetszőleges mezőjeként önmagával azonos típust, azaz rekurzívan fölhasználható a saját definiálására.


Példa:


TYPE LISTA = STRUCT (INT elem, LISTA köv);
TYPE BINFA = STRUCT (INT elem, BINFA bal, jobb);

Mind a lista, mind a bináris fa ürességének vizsgálata, illetve üresre állítása egy speciális konstans felhasználását igényli, amely tetszőleges rekurzív típus üres eleme. A típusegyenlőség fenntartása miatt azonban itt egy újabb műveletre van szükségünk: a típus őstípusának meghatározására.

Azt a típust, amelyből az adott típus származik, a típus őstípusának nevezzük.

Egy változó őstípusára hivatkozás:


CONCR változó


Minden rekurzív típus egy típusnélküli mutató típusra épít, amely értékhalmazának egyetlen, az összes többitől megkülönböztethető eleme van: az üres elem.

A típusnélküli mutató típus üres eleme:


NIL



Az ürességet lekérdező függvény:


ISNIL



Nézzük meg ezeket a műveleteket a lista típus két eljárásában:

Példa:


BOOL PROC üres (LISTA CONST x):
ISNIL CONCR x
ENDPROC üres;

PROC legyenüres (LISTA VAR x):
CONCR t := NIL
ENDPROC legyenüres;


A rekurzív típus rekurzív mezőire ugyanúgy kell hivatkoznunk, mint a rekordok többi mezőjére, mint ezt a következő, bináris fa bejárására szolgáló eljárásban láthatjuk.

Példa:


PROC bkj bejár (BINFA CONST f):
IF NOT üres (f)
THEN bkj bejár (f.bal);
put (f.elem);
bkj bejár (f.jobb)
FI
ENDPROC bkj bejár;


A paraméterátadási mechanizmus (eredmény szerinti paraméterátadás) miatt a változóparaméterek értékmegosztással kerülnek át a rekurzív eljárásokhoz, majd vissza, azaz bármilyen változtatásuk a teljes struktúrát is változtatja. Ezt használjuk ki a rekurzív típusok konstrukciós műveleteiben.

Példa:


PROC beilleszt (LISTA VAR t, INT CONST x):
INT VAR q;
IF üres (t)
THEN t := LISTA: [x, t]
ELSE beilleszt (t.köv, x)
FI
ENDPROC beilleszt;


Konstansok írásában fel kell használnunk a típus nélküli mutatótípus üres elemét. Ebből a típusnévvel azonos nevű, a típus definíciójakor automatikusan létrejövő konverziós művelet gondoskodik.

Példa:


LISTA CONST üreslista :: LISTA: NIL;
LISTA CONST egyeleműlista :: LISTA: [l, LISTA: NIL];


3.2.4. Paraméteres típusok

A típusok, s így a típusok műveletei is paraméterezhetők újabb típusokkal, azaz például lehetőségünk van általános lista- vagy fatípus definiálására, amelyeket felhasználásukkor paraméterezünk a bennük szereplő elemekkel.

A paraméteres típus definíciója (a paraméter csak típus lehet):


TYPE típusnév (típusparaméter) = típusmegadás



Példa:


TYPE ÚJMÁTRIX (M) = ROW 10 ROW 10 M;

Rekurzív típusoknál természetesen a rekurzív hivatkozást is paraméterezni kell:


Példa:


TYPE LISTA (T) = STRUCT (T elem, LISTA (T) kov);

Változódeklarációkor a típusnév mellett meg kell adnunk a konkrét típust. Rekurzív típusoknál ezen kívül a konstansok típuskonstrukciós függvényeit is paraméterezni kell.



típusnév (paramétertípus) hozzáférési jog név :: kezdőérték



Példa:


ÚJMÁTRIX (INT) VAR x, y, z;
LET T = TEXT; # a TEXT típus új szinonímaneve #
LISTA (T) CONST üreslista:: LISTA (T): NIL;
LISTA (T) CONST egyeleműlista:: LISTA (T): [1.0, LISTA (T): NIL];



Paraméteres típusok műveleteinek megadásakor nemcsak a típust, hanem a műveletet is paramétereznünk kell a megfelelő típussal.


PROC (paramétertípus) név (paraméterek)
típus (paramétertípus) PROC (paramétertípus) név (paraméterek)
típus (paramétertípus) OP (paramétertípus) név (paraméterek)



Példa:


ÚJMÁTRIX (M) OP (M) + (ÚJMÁTRIX (M) CONST a, b):
INT VAR i, j;
ÚJMÁTRIX (M) VAR c;
FOR i FROM 1 UPTO 10
REP
FOR j FROM 1 UPTO 10
REP c [i] [j] := a [i] [j] + b [i] [j]
ENDREP
ENDREP;
c
ENDOP +;

BOOL PROC (T) üres (LISTA (T) CONST x):
ISNIL CONCR x
ENDPROC üres;

PROC (T) legyenüres (LISTA (T) VAR x):
CONCR t := NIL
ENDPROC legyenüres;


3.2.5. Típusszármaztatás

Típusszármaztatáskor az új típus értékkészlete teljesen azonos lesz az őstípussal, azonban semmilyen tekintetben nem kompatibilis vele. (Ezenkívül műveleteiből csak az értékadást és az egyenlőségvizsgálatot örökli.)


TYPE típusnév = típusnév


Az új típus megvalósításakor meg kell írni a műveleteit, itt azonban egy kisebb problémával találkozunk. Az elemi műveleteket vissza kell vezetni az őstípus műveleteire. Erre a célra a korábban megismert CONCR műveletet, illetve a típusnévvel azonos típuskonverziós függvényt kell alkalmaznunk.


Példa: (HOSSZ típus megvalósítása)


TYPE HOSSZ = REAL;
PROC get(HOSSZ VAR x): # ELAN-ban az azonosítók átlapolhatók, ha környezetükből egyértelműen #
# megállapítható, hogy éppen melyik azonosítóról van szó #
get(CONCR x)
ENDPROC get;

PROC put(HOSSZ CONST x):
put(CONCR x)
ENDPROC put;

HOSSZ OP + (HOSSZ CONST x, y):
HOSSZ: ( CONCR x + CONCR y )
ENDOP +;

HOSSZ OP * (REAL CONST x, HOSSZ CONST y):
HOSSZ: ( x * CONCR y )
ENDOP *;

# A szorzás kommutativitása miatt szükség van még egy skalárral szorzó eljárásra, amelyben az operandusok
sorrendje az előbbi fordítottja: #

HOSSZ OP * (HOSSZ CONST y, REAL CONST x):
HOSSZ: ( x * CONCR y )
ENDOP *;
...


Típusszármaztatás nemcsak elemi típusokra lehetséges, hanem összetettekre is. Használatukra ugyanaz a konvenció érvényes, mint az elemiekre.


Példa:


TYPE SZÁMPÁR = STRUCT (INT x, y);
TYPE RAC = SZÁMPÁR;
INT OP SZÁMLÁLÓ(RAC VAR r):
CONCR r.x # az r racionális típusú változó őstípusának x mezője #
ENDOP SZÁMLÁLÓ;
...
RAC VAR c;
get(SZÁMLÁLÓ c);
...
TYPE KOMPLEXEGÉSZ = SZÁMPÁR;
...