A BLISS programozási nyelv



Sablonok makrókkal

BLISS-32-ben sablonok ugyan nincsenek, de makrók segítségével meg lehet oldani. A makrók egyébként is erősségei a nyelvnek. Négy típusuk van:

Egyszerű makró

MACRO név ( paraméterek ) - Itt a makró meghívásakor a paraméterek behelyettesítődnek a törzsbe, és a hívás helyére ez a paraméterezett makrótörzs kerül. Pl.

MACRO SQR_AV(F1,F2) = MTH$SQRT(((F1)*(F1)+(F2)*(F2))/2) %;

Egy példa a makróhívásra:

SQR_AV(0,.A+.B)

amit a fordító a következő kifejezéssé fejt ki:

MTH$SQRT((0)*(0)+(.A+.B)*(.A+.B))/2)

Feltételes makró

MACRO név ( paraméterek ) [] - Itt a makró csakis akkor kerül kifejtésre, ha van elég paramétere.Különben a hívás helyére az üres karakterfüzér kerül. A felesleges paramétereket minden makrótípus esetén a %REMAINING tartalmazza, így a feltételes makrók segítségével rekurzió hozható létre, pl.

MACRO DIFFS(F1,F2)[]= F1 =.F1 - .F2; DIFFS(F2,%REMAINING) %;

A DIFFS(A,B,C,D) makróhívás a következőképp, rekurzivan kerül kifejtésre:
A = .A - .B; DIFFS(B,C,D);
tovább: A = .A - .B; B = .B - .C; DIFFS(C,D) majd
A = .A - .B; B = .B - .C; C = .C - .D; DIFFS(D)
Itt már nincs elegendő paraméter, tehát a kifejtés véget ér:
A = .A - .B; B = .B - .C; C = .C - .D;

Iteratív makró

MACRO név ( paraméterek ) [ iteratív paraméterek ] - Ez a makró is csak akkor kerül kifejtésre, ha van elég paramétere (iteratívval együtt). Ekkor a paraméterek behelyettesítődnek (a paraméterlista elejéről a rende paraméterek, utána az iteratívok), és a hívás helyére ez a paraméterezett makrótörzs kerül. Ezután az iteratív paraméterek helyébe behelyettesítődött paraméterek törlődnek a listából, és kezdődik minden elölről. Ld. pl. a

MACRO IM1(F1)[F2]=F1+F2%;

makrót, ami pl. a PLIT(IM1(2,A,B,C,D) híváskor a

PLIT(2+A,2+B,2+C,2+D)

kifejezéssé fejtődik ki. Ez a példa az iteratív makrók két fontos tulajdonságát is bemutatja: egyrészt, hogy a rendes paraméterek minden iterációban megjelennek, míg az iteratív paraméterek csak egyszer; valamint azt is, hogy az iterációk eredményeit a fordító lexikális elemekkel választja el (a szövegkörnyezettől függően, a jelen esetben vesszővel). Újabb példa:

MACRO SHIFT[A,B]=A^B%; BIND PTR = PLIT(SHIFT(1,2,3,4,5,6),0+SHIFT(1,2,3,4))

Az utolsó sor kifejtése:

BIND PTR = PLIT(1^2,3^4,5^6,0+1^2+3^4);

Névvel jelölt paraméterű makrók

KEYWORDMACRO ( paraméterek ) - Itt a paramétereknek lehet alapértelmezett értékük is, és a hívásnál a paramétereket névvel jelölt formában (paraméternév = érték) kell megadni. Használatuk kifejezetten előnyös, ha a makró sok paraméterrel rendelkezik, amelyek sorrendjét nehéz megjegyezni, és/vagy sok az alapértelmezett érték. Itt egy egyszerű példa:

KEYWORDMACRO COPYVECTOR(DEST,SOURCE,N=1) = INCR I IN 1 TO N DO DEST[.I]=SOURCE[.I]%;

A COPYVECTOR(N=10,SOURCE=V1,DEST=V2) makróhívás kifejtése: INCR I IN 1 TO 10 DO V2[.I]=V1[.I]
Bonyolultabb példa: Legyen egy QVAL nevű blokk típusunk, amely 64 bit hosszú, és a következőképpen épül fel:

OFFSET 16 UNSIGNED F 3 UNSIGNED CNT 13 UNSIGNED VALUE 32 UNSIGNED

Egy QVAL típusú változót a következőképp láthatunk el kezdőértékkel:

MACRO INIT_QVAL(OFFSET,F,CNT,VAL)=INITIAL(WORD(OFFSET, ((F) AND %O7) OR ((CNT)^3 AND %O177770)), LONG(VAL))%; OWN X: BLOCK[QVAL_SIZE] INIT_QVAL(0,3,-1,2);

Az X változó fenti deklarációjakor a kezdőérték fordítási időben teljesen kiszámolásra kerül (hála a fordítóprogramba épített optimalizációnak is).