LISP
Programozási segédlet

IS-LISP az Enterprise 1. verziójára
C 1985 Intelligent Software Ltd.
Progamming: M. Richer
Manual Writing R. Hurley , J. Hurley, R. D. Virgo

Tartalom

Előszó
1. Fejezet: Az elindulás
2. Fejezet: Bevezetés a LISP-be
3. Fejezet: Input / Output
4. Fejezet: Függvények definiálása
5. Fejezet: Kimentés és betöltés
6. Fejezet: Az EXOS
7. Fejezet: A megszakítások kezelése
8. Fejezet: Az IS-LISP függvényei
1. Függelék: EXOS változók
2. Függelék: Hibaüzenetek
3. Függelék: A Funkciós billentyűk

Előszó
Bár a LISP (LIST PROCESSING) már kb. húsz éve van forgalomban, még mindig nagyon népszerű a "Mesterséges Intelligencia" és a "Szakértői rendszerek" területén, ahol ideálisnak tekinthető rugalmassága és kiterjeszthetősége miatt.
Ennek a kézikönyvnek nem célja, hogy a nyelvről minden információt tartalmazó enciklopédia legyen, de leírja az IS-LISP implementációját az Enterprise számítógépen és közelebbi betekintést ad arról, hogyan történik a kommunikáció a felhasználóval és az EXOS operációs rendszerrel. A kezdőnek rövid bevezetést ad a nyelvbe, de feltételezi, hogy az olvasó ismeri a gép működését és vannak - legalábbis korlátozott - ismeretei a Basic nyelvről.
Mivel a LISP interaktív nyelv, amely minden függvényt úgy és akkor kiértékel, ahogy az a számítógépbe került, könnyű rajta kísérletezni a különböző függvényekkel. Tanácsoljuk az olvasónak, hogy próbálja ki a kézikönyvben található példákat, amikor csak lehetséges.

Könyvek a LISP-ről
Sok jó könyv íródott a LISP-ben való programozásról. Különösen ajánljuk a következőket:

1. Fejezet: Az elindulás
Hogy elkezdjünk programozni IS-LISP-ben, tegyük be a cartridge-et az Enterprise mikroszámítógép bal oldalán Iévő portba és kapcsoljuk be a gépet. Ezután nyomjuk meg kétszer a Reset gombot. A hidegindítás szokásos folyamata megy végbe, a gép ellenőrzi a memóriaszekciókat, és az alább látható üzenet jelenik meg a képernyőn.
Most elkezdhetjük a programozást. Az utasítások ugyanúgy vihetők be a billentyűzetről, mint az IS-BASIC használatakor. Minden kommunikáció a felhasználó és a LISP interpreter között az "editor"-on keresztül történik, ami azt jelenti, hogy a kurzor-billentyűk és a joystick használhatók a kurzor mozgatására a képernyőn, hogy szöveget vigyünk be, javítsunk, vagy töröljünk. Amikor egy programsort helyesen beírtunk és megnyomtuk az ENTER gombot, ennek hatására az "EVAL" program működésbe lép, és - feltéve, hogy a sor szintaktikusan helyes - kiértékelődik, a kiértékelés eredménye pedig megjelenik a képernyőn.
Például, két szám összeadására beírhatjuk:

(PLUS 3 4)

és a számítógép kiadja: 7.
Ezen a ponton fontos, hogy emlékeztessünk rá: minden LISP programsor azonnal ellenőrződik és kiértékelődik, rögtön a bevitel és az ENTER billentyű megnyomása után. Ez teljesen más, mint amivel BASIC környezetben dolgozva találkozunk, ahol egy szekció vagy akár az egész program bekerül a gépbe, és csak ezután történik kísérlet a végrehajtásra. Ezt észben tartva elkezdhet kísérletezni és programozni a LISP nyelven. A következő néhány fejezet jó kalauz néhány ismert LISP függvény használatához.

2. Fejezet: Bevezetés a LISP-be
A LISP-ben, mint minden magasszintű nyelvben, a programozó elvárja, hogy szöveges üzeneteket jelentethessen meg a képernyőn, és hogy olyan szavakat használhasson, amik változóneveknek alkalmasak. Az ilyen szavakat a LISP-ben "azonosítóknak" vagy "atomoknak" hívjuk, és ezek a legelemibb objektumok, amik egy LISP programban használhatók.
Az azonosító olyan objektum, amely karakterekből épül fel, (pl.. 2, DOG, T.NIL), és a fenti célok bármelyikére használható. Atom minden azonosító és minden szám (pl. 7, -24). Ezen atomok használatával fel tudjuk építeni az adatstruktúrát, ami a LISP-nek a nevét adja, azaz a listákat.
A lista adattételek egy gyűjteménye, ezek mindegyikének van egy rákövetkezője, kivéve az utolsót. Hasznos, ha ezt úgy tekintjük, mint pointerek egy rendszerét, amelyek mentén a felhasználó végighaladhat egy listán, és minden pointer egy memóriacellához van rendelve, egy cella két pointert tartalmaz. A baloldali pointer az atomot (vagy listát) jelzi, vagyis az adatot, a jobboldali pedig oda mutat, ahol a lista további része kezdődik. Az (A B 1...) listára ezt kapjuk:

Ahogy az elébb jeleztük, egy listában tárolt adattételek maguk is lehetnek listák, így az (A(1 2... ) B... ) lista részletesebben:

Már említettük, hogy egy lista minden tételének van egy rákövetkezője, kivéve az utolsót, amelyre a LISP-nek egy speciális, "NIL" nevű azonosítót tart fenn, az üres lista, a () reprezentálására. így az (X Y) listát reprezentáló teljes diagram:

amelyet megegyezés szerint így ábrázolunk:

Ez mind elmélet és a LISP működésének alapját képezi, de most kezdjünk el ismerkedni ezzel a nyelvvel.

Aritmetika
A LISP-ben az aritmetika azonosítók használatával működik, nem pedig a hagyományos infix operátorokkal, mint "+" és "x". Számok (atomok) összeadására a PLUS parancsot használjuk. A 7+5 összeadás elvégzésére (PLUS 7 5)-öt kell írnunk, erre a 12 választ kapjuk, és hogy a 7+5+3+1 értéket kiszámítsuk, a helyes LISP parancs

(PLUS 7 5 3 1)

amelyre a 16 választ kapjuk.
Az összeadás inverz művelete, a kivonás, a DIFFERENCE parancs segítségével történik, amely az első argumentumból levonja a másodikat, azaz 7-5 így írandó be:

(DIFFERENCE 7 5)

amire 2 lesz az output.
Az infix jelölés mellett, a "-" jelnek egy második jelentése is van, a negatív előjel. A LISP egy másik azonosítóval, a MINUS-szal elkerüli ezt a kettősséget. így 7-5, ami a 7+(-5) formában is írható, a

(PLUS 7 (MINUS 5))

alakot kapja, és ennek eredménye is 2.
A szorzás a TIMES parancs használatával történik, így pl. 7x5 kiszámításához a

(TIMES 7 5)

parancs használatos, amire 35 a válasz, és hogy kiszámítsuk a 7*5*3*1 értéket, a

(TIMES 7 5 3 1)

parancs beírása szükséges, amire a 105 válasz érkezik.

A LISP csak egész számok használatát engedi meg, és ez okozhat némi nehézséget, amikor osztani akarunk, pl. 7/5=1.4, vagy tört formában, 1 2/5. Három különböző, az osztással kapcsolatos LISP parancs van, amelyek eredménye is különböző, a DIVIDE, a QUOTIENT és a REMAINDER.
A DIVIDE parancs egy rendezett párt (speciális listatípust) ad vissza, amelynek első eleme a hányados, második eleme a maradék, pl.

(DIVIDE 7 5) (1 . 2)

A QUOTIENT a hányados egészrészét adja vissza és a törtrészt nem veszi figyelembe, pl:

(QUOTIENT 7 5) (1)

végül a REMAINDER az osztás maradékát adja vissza, pl:

(REMAINDER 7 5) (2)

Jegyezzük meg, hogy a LISP a -32768 és 32767 közti intervallumon belül minden egész számot megenged, és hogy hibát okoz, ha egy aritmetikai számítás eredménye ezen az intervallumon kívül esik.

Változók
A LISP-ben az ALPHA szó reprezentálhat egy változót vagy egy adatrészt, és a két esetet egy szimpla idézőjel segítségével különböztetjük meg. Így ALPHA változót jelent, és értéke elérése után azonnal kiíródik, míg 'ALPHA az ALPHA szót reprezentálja, mint szöveg-adatot. Ha egy ALPHA változó nem kapott értéket, LISP értékét UNDEFINED-nak fogja tekinteni, ez a nyelvben speciális azonosító, erre a használatra fenntartva.
Hogy egy változónak értéket adjunk, ezt megtehetjük a SETQ azonosító használatával. Pl:

(SETQ ALPHA '(A B C D E))

az ALPHA változó értékéül az (A B C D E) listát adja.
Vegyük észre a ' idézőjelet, amely azt eredményezi, hogy (A B C D E) nem kerül kiértékelésre. Amikor a változó hozzárendelése megtörtént, értéke kijelződik, ha zárójel nélkül szerepel, azaz ALPHA.
Például,

(SETQ TEN 10)
(TIMES TEN TEN)

a TEN változónak a 10 értéket adja, majd kiszámítja TEN négyzetét, ami 100. A változóhoz rendelendő kifejezés értékét is ki lehet számítani a SETQ paranccsal, így a

(SETQ ANSWER (TIMES TEN TEN))

utasítás a számítás eredményét, azaz a 100-at fogja az ANSWER változóhoz rendelni.

Listakezelés
Két alapvető függvény van, amivel egy lista bizonyos értékeit lehet megtalálni, mégpedig a CAR és a CDR függvények.
Az IS-LISP a CAR és HEAD parancsot engedi meg adott lista első elemének megjelölésére, a CDR és TAIL parancsokat pedig a további elemekből álló lista megjelölésére.
Tehát az (X Y) listára

(CAR '(X Y)) X
(CDR '(X Y)) (Y)

Tekintsük a következő SETQ utasítás által definiált listát:

(SETQ EXAMPLE'(A (1 2) (X Y Z)))

A diagram erre a listára:

EXAMPLE

 

Egyes tételek az EXAMPLE listából a következő módon nyerhetők:

Utasítás: Eredmény:
(CAR EXAMPLE) Az A azonosító
(CDR EXAMPLE) A két tagból álló ((1 2) X Y Z)) lista
(CAR (CDR EXAMPLE)) Az (1 2) lista
(CDR (CDR EXAMPLE)) Az (X Y Z) lista
(CAR (CAR(CDR EXAMPLE))) Az 1 azonosító.

Az IS-LISP lehetővé teszi , hogy a felhasználó az ilyen utasításokat lerövidítse, ezt írva:

(CAAR EXAMPLE) (CAR(CAR EXAMPLE)) helyett,
(CDDR EXAMPLE) (CDR(CDR EXAMPLE)) helyett,
(CADR EXAMPLE) (CAR(CDR EXAMPLE)) helyett,
(CAAAR EXAMPLE) (CAR(CAR(CAR EXAMPLE))) helyett,
(CADAR EXAMPLE) (CAR(CDR(CAR EXAMPLE))) helyett.

összesen legfeljebb három CAR és CDR utasítás mellett, akármilyen kombinációban.

A T azonosító
A speciális T azonosító az az érték, amit a gép kiad, ha egy Boole-függvény igaznak (true) értékelődött ki. Például,

(NULL NIL  T, mivel NIL ().
(ATOM 3)   T, mivel 3 valóban atom
(EQ 5 5)   T, mivel 5=5
(EQ 5 4)   NIL, mert 5 <> 4

Döntés
A BASIC-ben a döntéseket általában az IF ... THEN ... ELSE ... szerkezetben hozzuk, amit a következő módon alkalmazunk:

IF <1. állítás> THEN <i. kifejezés>
ELSE IF <2. állítás> THEN Q. kifejezés>
ELSE IF <3. állítás> THEN Q. kifejezés>
...
ELSE <kifejezés>

A LISP-ben ez a következő formát kapja:

(COND (<1. állítás> <1. kifejezés>)
          (<2. állítás> <2. kifejezés>)
          ...
          (T <kifejezés>)),

ahol T a speciális azonosító az igaz állítások reprezentálására. Így a COND függvény úgy dolgozik, hogy minden állítást kiértékel, míg csak nem talál egy igazat. Ekkor kiértékeli a megfeleld kifejezést és annak értékét adja vissza.
Példa:

(COND ((ATOM'(X Y)) (TIMES 4 9))
      ((ATOM 4) (TIMES 5 8))
      (T (TIMES 6 7)))

Itt, mivel '(X Y) lista és nem atom, ezért az első állítás NIL-t ad és nem veszi figyelembe a program. A második állítás viszont igaz, hiszen a 4 atom, és így az utasítás értékeként a gép (TIMES 5 8)-at, azaz a 40-et adja vissza.

Ciklus
A LISP-ben egy kifejezés-csoport ismétlése a LOOP paranccsal történik. Így pl. a következő utasítás

(LOOP(PRINT(PLUS 7 5))
     (PRINT(DIFFERENCE 7 5)))

ciklust eredményez, amelyben felváltva a 12, majd a 2, majd a 12..., stb. jelződik ki, amíg meg nem nyomjuk a STOP gombot. Jobban használható a LOOP olymódon, hogy események egy sorozatát idézi elő, mindaddig, amíg egy bizonyos terminális (befejező) feltétel nem teljesül, és ezt a WHILE vagy az UNTIL függvényekkel éri el. Amikor egy ciklus tartalmaz WHILE vagy UNTIL utasítást, addig folytatja a végrehajtást, amíg a WHILE állítás igaz, illetve, amíg az UNTIL állítás hamis marad.
Adjuk a C változónak a 7-es értéket a (SETQ C 7) paranccsal, A-t állítsuk 0-ra a (SETQ A 0) paranccsal.
Ekkor alkalmazzuk ezt a ciklust:

(LOOP (WHILE (GREATERP C 0) A)
      (SETQ A (PLUS A C))
      (SETQ C (SUB1 C)))

Ez a 7+6+5+4+3+2+1=28 értéket fogja adni, mivel a ciklus mindig megismétlődik, amikor C>0.
Egy másik megoldás: Adjuk C-nek a 0 értéket a (SETQ C 0) paranccsal és A-t is 0-zzuk a (SETQ A 0) paranccsal.
Ekkor alkalmazzuk ezt a ciklust:

(LOOP (UNTIL (EQ C 8) A)
      (SETQ C (PLUS A C))
      (SETQ C (ADD1 C)))

ami az 1+2+3+4+5+6+7=28 választ adja, mivel addig ismétlődik a ciklus, mígnem C=8.

3. Fejezet: Input / Output
A legfontosabb parancsok bérmelyik nyelvben az input/output függvények, mivel ezek nélkül semmilyen értéket nem vihetnénk be a gépbe és számításaink eredményét sem nyerhetnénk vissza.

Input szintaxis
A legszokásosabb módja, hogy adatokat / programokat vigyünk a LISP-be, a READ függvény használata. Ez lehetővé teszi, hogy rendezett párokat, listákat, változókat és -32768 és 32767 közti számokat vigyünk be az aktuális input csatornán keresztül. Amikor először kapcsoljuk be a rendszert, az input csatorna száma "0", a billentyűzethez kapcsolva, bár ez megváltoztatható az OPEN, illetve az RDS parancsokkal, amint ez a 6. fejezetben szerepel.
Jegyezzük meg, hogy ahol % jel van olvasás közben, onnan kezdve egészen az első sorvég jelig mindent commentnek tekint a gép és nem veszi figyelembe.
Az azonosítók inputjának színtaxisa olyan, hogy a gép elfogadja az A....Z, a....z, 0....9 karaktereket, valamint a következő speciális karaktereket:

- mínusz   _ aláhúzás   = egyenlőség
, vessző   ; pontosvessző   : kettőspont
[ bal szögletes zárójel   * csillag   & et-jel
$ dollár   ~ hullám   # hashmark
@ kukacjel   / per-jel   ? kérdőjel
+ plusz   |     { kapcsos zárójel
^ hatvány   < kisebb-jel   > nagyobb-jel
\ backslash            

Például, A?BC, ::><:<-40:, + legális azonosítók.
Minden más karaktert az escape ('!') karakternek kell megelőznie, ha egy azonosítóban szerepel. Általában minden "(" balzárójelet közvetlenül le kell zárni egy ")" jobbzárójellel, de a "szuperzárójel", "]" használható az összes megnyitott balzárójel lezárására. Például:

(DEFUN SQUARE (X) (TIMES X X]

Általában egy azonosító idézése ügy történik, hogy a ' karaktert tesszük eléje, pl. 'ABC. Ehelyett dupla idézőjelek közé is tehetjük, pl. "ABC". Ez könnyű megoldás arra, ha különleges karaktereket, pl. space-eket akarunk az azonosítókba rakni.

Pl. (PRINTC"A B")

Output formátum
Az outputot általában a négy print utasítás egyikével visszük ki: PRIN, PRINC, PRINT, és PRINTC.
Két különböző formátum van: a PRIN típusú és a PRINC típusú. A PRIN-nel készült output visszaolvasható lesz a READ utasítással, és, ahol kell az azonosítók escape ('!') jelet kapnak. A PRINC utasítás viszont nem látja el az azonosítókat ezzel a jellel, hanem változatlanul viszi ki.
Az output képzésének egy másik módja a SPRINT függvény használata, ahol az egyes tételek egy sorba kerülnek, ahol ez lehetséges, egyébként pedig ebben a formában:

(<függvény-név>
  <1. arg.>
  <2. arg.>
  <3. arg.>
  ...
  <n. arg.>)

Amikor a definíció elkészült, SPRINT két üres sort visz ki, és a NIL értéket adja vissza.

4. Fejezet: Függvények definiálása
Mint már említettük, a LISP nagyon rugalmas nyelv, amely kiterjeszthető úgy, hogy az egyedi felhasználók igényeinek eleget tegyen. Amikor éppen beléptünk a LISP környezetbe, már egy egész sor függvény áll rendelkezésünkre, amely definiált és hívható egyszerűen a megfelelő függvénynéven, pl.

(PLUS 4 7)

A "PLUS" függvény a LISP interpreter részeként van definiálva és hatására a "kiértékelő" megkeresi a 4 és a 7 összegét. Nagyon valószínű, hogy néha használni akarunk valamilyen függvényt, amely még nincs definiálva és ilyenkor magunknak kell definiálni a DEFUN parancs segítségével.
A parancs szintaxisa:

(DEFUN NAME (PARAMETERS) (BODY))

ahol NAME az a név, amin a függvényt ezentúl hívjuk; PARAMETERS a függvény input adatai; végül BODY egy vagy több, előzőleg definiált LISP függvényből áll.

1. Példa:
Tekintsük azt a helyzetet, amikor 2x+3y értékét kell meghatározni több ízben egy program futása során. Beírhatnánk a következő programrészt minden alkalommal:

(PLUS (TIMES 2 X) (TIMES 3 Y))

Ezt nyilvánvalóan sokáig tart begépelni és jobb lenne, ha volna egy függvényünk, amivel ezt mindig végrehajtjuk. Ezt megtehetjük a következő utasítással:

(DEFUN OPERATE (P Q) (PLUS (TIMES 2 P) (TIMES 3 Q)))

A LISP interpreter válaszol:

(LAMBDA (P Q) (PLUS (TIMES 2 P) (TIMES 3 Q)))

jelezve, hogy a függvényt sikeresen definiáltuk.
Ha most a 2x+3y függvényt ki akarnánk értékelni, egyszerűen beírhatnánk:

(OPERATE x y)

"x" és "y" értéke adódik a függvényben "p" és "q" értékéül, s a gép kiszámítja a függvényt, a kiértékelő segítségével. Pl:

(OPERATE 4 5) 23

A függvénynek ez a használata igen struktúrált programozási módhoz vezet, amit "top-down" megközelítésnek nevezünk. Ebben definiálódik egy függvény, amely használható egy második függvény definíciója részeként, amely ismét használható egy harmadik függvény definíciója részeként, stb., s a legtöbb LISP program így íródik.

2. Példa:
Tekintsük azt a feladatot, ahol egy második függvényt, "OPERATE2"-t kell definiálni, amely 3(2x+3y) alakú. Ez a második függvény nagyon könnyen definiálható az elsőt, "OPERATE"-et felhasználva:

(DEFUN OPERATE2 (P Q) (TIMES 3 (OPERATE P Q)))

A 3(2X+3Y) érték most már kiszámítható egyetlen függvényhívással:

(OPERATE2 X Y)

Rekurzió
A rekurzió olyan eszköz a LISP programozó kezében, amely igen nagy rugalmasságot tesz lehetővé programok felépítésekor. Rekurzió segítségével lehet egy függvényt definiálni, amely ismételten hívja önmagát, míg egy bizonyos feltétel nem teljesül. Működésében nagyon hasonlít a standard LOOP-hoz, de általában rövidebb és hatékonyabb programot eredményez.

Példa:
Tekintsük azt a feladatot, hogy miképp definiáljuk a következő LEN rekurzív függvényt: LEN vesz egy LIST(A B C D E) listát és megszámolja, hány atom van a listában. Ezt a következőképp tehetjük:

(DEFUN LEN(X)
  (COND
    ((ATOM X) 0)
    (T (ADD1 (LEN (CDR X]

Opcionális változók
Definiálhatunk egy függvényt, amelyik hívható (pl.) egy, de két argumentummal (változóval) is:

(DEFUN ADDON (A (B.2))
  (PLUS A B))

Itt az első változót mindig meg kell adni, míg a második opcionális -- ha nem adjuk meg, a 2 értéket veszi fel. Pl.:

(ADDON 4 8) 12
(ADDON 5)   7

Egy függvénynek akárhány közönséges és opcionális változója lehet, azzal a megszorítással, hogy az opconális változók mind a közönségesek után következnek.
Jegyezzük meg, hogy a default érték (alapértelmezés, a fenti példában a 2) kiértékelődik, ha nem adtuk meg, tehát a fenti példa így is írható:

(DEFUN ADDON (A (B.(PLUS 1 1)))
  (PLUS A B))

Lokális változók
Ha egy függvényt pl. egy közönséges és két opcionális argumentummal definiáltunk:

(DEFUN A-FUN (A (B.1) (C.NIL)) ... )

és mindig egy argumentummal hívjuk, akkor a B és C változók valójában lokális változók: használhatók "ideiglenes tárnak" az A-FUN függvényen belül és eltűnnek, amikor megtörtént a visszatérés a függvényből.

Függvények szerkesztése
Amikor írunk egy LISP programot, gyakran fogunk benne hibát találni és szükségünk lesz arra, hogy megváltoztassuk egy függvény definícióját. Például tegyük fel, hogy begépeljük:

(DEFUN SQUARE (X) (TIMES X Y))

mert véletlenül az egyik X helyett Y-t ütöttünk be. A SQUARE függvény editálásához írjuk be:

(FEDIT SQUARE)

A LISP szerkesztő-módba lép és ezt fogjuk látni:

(LAMBDA (X) (TIMES X Y))

Így reprezentálja a gép a függvényt: A DEFUN szót és a függvény nevét a LAMBDA szóval helyettesítette.
Hogy a függvényt editáljuk, vigyük a kurzort az Y-hoz, ahogy szokás és írjuk felül X-re. Amikor befejeztük a javítást, nyomjuk meg az ESC gombot. A SQUARE függvényt ezzel újradefiniáltuk, a helyes formára.
Ha az új definíció olvasásakor hiba derült ki (pl. egy fölösleges "." vagy ")", vagy file-vég, ami kevés jobbzárójelet jelent), a hibaüzenet megjelenik a képernyő tetején néhány másodpercre. Ez eltűnik, és a kurzor visszatér, hogy a hibát ki lehessen javítani.

5. Fejezet: Kimentés és betöltés
A SAVE és a LOAD parancsok lehetővé teszik, hogy a rendszer állapotát kazettára vigyük és az később használható legyen. Mielőtt megkísérli, hogy a rendszert kimentse, győződjön meg róla, hogy bent van-e egy üres kazetta az adatátvitelre, és hogy az Enterprise mikroszámítógép output csatlakozójából jövő vezetékek a magnó "MIC" és "REM" foglalatához csatlakoznak-e.
A rendszer aktuális állapotának egy nevet kell adni, ha ez pl. TUESDAY, akkor beütve a

(SAVE "TUESDAY")

parancsot, ez az állapot kimentődik a kazettára, készen arra, hogy későbbi időpontban betöltsük. Az újrabetöltés egyszerűen a

(LOAD "TUESDAY")

parancs beütésével történik, és így az összes, felhasználó által definiált kifejezés újra betöltődik a számítógép memóriájába. Ne felejtsük el csatlakoztatni a magnó "EAR" és "REM" csatlakozóit az ENTERPRISE input csatlakozójához.

Megjegyzés:
Amikor a kazettáról új file-t töltünk be, minden, éppen a számítógépben levő információ felülíródik. Ha ez az információ fontos, először mentsük ki a SAVE függvénnyel, ahogy fent leírtuk.

6. Fejezet: Az EXOS
Az EXOS az Enterprise mikroszámítógép kiterjeszthető operációs rendszere. Interface-t szolgáltat az IS-LISP és a gép hardware-e közt. Az EXOS fő alkotórészei egy csatorna alapú input-output (I/O) rendszer és bonyolult memóriakezelő eszközök. Az I/O rendszer lehetővé teszi a berendezésfüggetlen kommunikációt egy egész sor beépített berendezéssel, valamint további, a géphez csatolható berendezés-meghajtó egységgel.
A beépített berendezések:

  1. Video-meghajtó szöveg- és grafikakezelésre.
  2. Billentyűzet-kezelő, a joystick-kel, automatikus ismétlővel és programozható funkciós gombokkal.
  3. Képernyő-editor, szövegkezelési lehetőségekkel.
  4. Könnyen kezelhető sztereó hang-generátor.
  5. Kazettás magnó.
  6. Centronics kompatibilis párhuzamos interface.
  7. RS232 típusú soros interface.
  8. Hálózati interface

A rendszernek sok alkotórészét néhány egybyte-os változó, az úgynevezett "EXOS-változók" irányítják. Ezeknek a változóknak egy teljes listája az 1. függelékben található.
A kezdő LISP programozónak nem sok dolga akad az EXOS-beli kommunikációval. Előbb-utóbb azonban szüksége lesz erre a kommunikációra. A fejezet további része ennek mikéntjéről szól.

Képernyő - editor
Amikor a gépet éppen bekapcsoltuk, és az IS-LISP cartridge a helyén van, a felhasználó a "képernyő-editor"-ral kommunikál, amelyik pedig a LISP interpreterrel tartja a kapcsolatot. Ez lehetővé teszi, hogy a felhasználó mozgassa a kurzort a képernyőn, illetve a képernyőt mozgassa fel és le.

Csatornák
Ahogy a fejezet elején említettük, minden az I/O csatornákon keresztül történik. A LISP-et úgy tervezték meg, hogy a legegyszerűbb műveletek ennek a ténynek az ismerete nélkül is elvégezhetők. Ugyanakkor, a rendszer teljes kihasználásához szükséges, hogy tudjuk, hogyan kezelhetők ezek a csatornák és a megfelelő EXOS változók.
Közvetlenül a gép bekapcsolása után a következő csatornák lesznek automatikusan nyitottak:

A kommunikáció a különböző berendezésekkel mindig ezeken a csatornákon keresztül történik, hacsak nincs az egyik valamilyen okból lezárva.
A 0., 2., 3. és 5. csatornát lehetőleg nyitva kell hagyni. Ha nincs rá nyomós ok, ne zárjuk le ezeket.

Új csatornák
Néha szükségünk lehet arra, hogy új csatornát nyissunk egy berendezés-meghajtó egység számára, hogy a kommunikáció ne a megadott alapcsatornák valamelyikén történjen. Erre két függvény szolgál: az OPEN és a CREATE. A legtöbb esetben a kettő ekvivalens, de mikor szalagon vagy lemezen file-t nyitunk, a CREATE új file-t létesít, míg az OPEN feltételezi, hogy a file már létezik.

Példa:
Tekintsük azt a feladatot, hogy egy függvényt kell definiálnunk, amely bizonyos függvényeket nyomtat párhuzamos nyomtatón SPRINT utasítással.
Ez a következő programmal oldható meg:

(DEFUN SPRINTER (EXP)
  (OPEN 10 "PRINTER:")
  (WRS 10)
  (SPRINT EXP)
  (WRS 0)
  (CLOSE 10))

A program megnyitja a 10. csatornát a párhuzamos nyomtató számára, majd a WRS 10 utasítással az aktuális outputot erre a csatornára irányítja. Az "EXP" paraméterrel definiált függvény a SPRINT utasítással, kikerül a nyomtatóra, majd az aktuális outputot újra az alapcsatornához rendeli a program.

Megjegyzés:
A csatornák használata közben könnyen elfeledkezünk arról, hogy az input és az output automatikusan az alapértelmezett csatornákon halad, ahogy ezt meg fogjuk alább mutatni, és az átirányításhoz az SNDS, RDS, WRS, és GRS parancsokra van szükség.

Berendezés
Alapcsatorna
Parancs
Hang
3
SNDS
Szöveg (INPUT)
0
RDS
Szöveg (OUTPUT)
0
WRS
Grafika
1
GRS

Példa:
A 12. csatorna megnyitása inputhoz:

(OPEN 12 "DEVICE:")
(RDS 12)

File-nevek
Amikor csatornát nyitunk, ilyen alakú parancsot használunk:

(OPEN 12 "<berend.>:<filenév>.<kiterj.>")

ahol <berend.>, <filenév>, <kiterj.> egyike sem kötelező.
A használható berendezések listáját lásd alább, ha nincs megadva, az alapértelmezés a szalag.

KEYBOARD: A billentyűzet
VIDEO: Video képernyő berendezés
EDITOR: Szövegszerkesztő berendezés
PRINTER: Centronics port
SOUND: Hang-berendezés
SERIAL: RS232 port
NET: Hálózat-berendezés
TAPE: Kazetta berendezés

File-kezelés
Néha szükségünk lehet arra, hogy információt vagy függvényeket mentsünk ki szalagra, anélkül, hogy a teljes környezetet kimentenénk. Ezt a következő függvény definiálásával tehetjük:

(DEFUN FILE EXP)
  (CREATE 11 "TAPE:RH")
  (WRS 11)
  (PRINT EXP)
  (WRS 0)
  (CLOSE 11))

Amikor a FILE függvényt hívjuk, az EXP paraméter tartalma kimentődik egy "RH" nevű file-ba. Ez később használható lesz egy második függvény segítségével, amely a kifejezést a szalag-file-ból előveszi.
Példa:

(DEFUN EXTRACT ((TEMP))
  (OPEN 11 "TAPE:RH")
  (RDS 11)
  (SETQ TEMP (READ))
  (RDS 0)
  (CLOSE 11)
  TEMP)

(EXTRACT) begépelésével, az "RH" file-ban levő kifejezést fogjuk megkapni.

EXOS parancsok
Három LISP függvény van, az EXOS-READ, az EXOS-WRITE és az EXOS-TOGGLE, amelyek arra szolgálnak, hogy egy tapasztalt programozó lekérdezzen vagy megváltoztasson bizonyos rendszerváltozókat. Az 1. függelék tartalmazza ezeknek a változóknak a listáját, elhelyezkedésükkel együtt, és rövid leírást ad meg arról, mire használhatók.
Az "EXOS-változók" használatára és fontosságára álljon itt példaként egy függvény kinyomtatásának feladata, SPRINT utasítással, RS232 soros porttal összekötött printerre, amely 1200 BAUD sebességgel működik. A LISP parancsokat végigvizsgálva látjuk, hogy nincs függvény a sebesség csökkentésére, de az 1. Függelékből látjuk, hogy van egy megfelelő EXOS változó, amely így használható:

(DEFUN SERPRINT (EXP)
  (EXOS-WRITE 16 8) % Set BAUD rate to 1200
  (OPEN 11 "SERIAL:")
  (WRS 11)
  (SPRINT EXP)
  (WRS 0)
  (CLOSE 11))

7. Fejezet: A megszakítások kezelése
Az IS-LISP Enterprise változatóban van egy speciális azonosító, ami lehetővé teszi, hogy a LISP programozó függvényeket írjon, amelyek kihasználják az interrupt rendszert.
Mikor éppen bekapcsoltuk a mikroszámítógépet, a HANDLER változó UNDEFINED, és akármilyen software interrupt érkezik, ez SOFTWARE INTERRUPT (ERROR 4) kijelzést eredményez. Viszont, a felhasználónak lehetősége van, hogy definiáljon egy függvényt - nevezzük FRED-nek - egy változóval, ami maga a megszakításkezelő, ezt írva:

(SETQ HANDLER "FRED)

Amikor software-megszakítás érkezik, a FRED fog hívódni, az interrupt típus, mint egyetlen változója szerint (ld. alább).
Páldául, ha így definiáljuk FRED-et:

(DEFUN FRED (TYPE)
  (COND
    ((EQ TYPE 24)(PRINTC "UNDEFINED FUNCTION")))
    ((EQ TYPE 48)(PRINTC "NETWORK INTERRUPT"))
    ((EQ TYPE 64)(PRINTC "TIME-OUT"))
    (T NIL)))

Látjuk, hogy egy ilyen egyszerű függvény is, mint ez, számos hasznos eszközt ad a felhasználó kezébe:

A következő táblázat mutatja a HANDLER-nek adott értékeket, amikor a software interrupt beérkezik:

Kód Interrupt
16 1. funkciós gomb
17 2. funkciós gomb
18 3. funkciós gomb
19 4. funkciós gomb
20 5. funkciós gomb
21 6. funkciós gomb
22 7. funkciós gomb
23 8. funkciós gomb
24 9. funkciós gomb
25 10. funkciós gomb
26 11. funkciós gomb
27 12. funkciós gomb
28 13. funkciós gomb
29 14. funkciós gomb
30 15. funkciós gomb
31 16. funkciós gomb
32 STOP billentyű
33 tetszőleges billentyű
48 hálózat (NET)
64 óra

(A 9-16-os funkcióbillentyűk shift-eltek.)

Funkciós gomb-interruptok
Ha egy funkciós gomb az üres stringgel van beprogramozva, megnyomásakor software interruptot generál. A LISP felügyelete alatt bizonyos gombok előre vannak programozva hasznos parancsokra, pl. FEDIT, a többiek az üres stringre.

Stop-interrupt
Ha a (8-as számú) STOP_IRQ EXOS-változó nem-0 értékű, akkor a STOP-gomb olyan kódot fog visszaadni, mint bármely más gomb, ami valójában a STOP-gombot hatástalanítja. Egyébként, ha a STOP-gombot nyomjuk meg, 32-es software interrupt érkezik.

Megszakítás tetszőleges billentyű megnyomására
Ha a (9-es számú) KEY_IRQ EXOS változó 0 értéket kap (alapértelmezése 255!), akkor, akármelyik gombot nyomjuk meg, 33-as software interrupt érkezik, a kódot is visszaadva.

Hálózati interrupt
Amikor üzenet érkezik a hálózathoz, általában software interrupt generálódik (kivéve, ha a (19-es számú) NET_IRQ EXOS-változó 0). Ez azért hasznos, mert így a felhasználó, elolvasva az üzenetet, reagálni tud rá.
Megjegyzés: A (18-as számú) ADDR_NET EXOS-változó fogja ekkor tartalmazni annak a hálózati csatornának a számát, amelyről az adat beolvasható.

Óra-interrupt
Az (5-ös számú) TIMER EXOS-változó általában 0 értékű. Ha viszont más értékre állítjuk, az EXOS-WRITE paranccsal, akkor ettől kezdve másodpercenként eggyel csökken. Amikor 0-vá válik, ezzel egy 64-es software interruptot generál. Ez hasznos lehet képernyőn működő óraként, ahogy azt alább láthatjuk.

Példa:
Az itt következő programrész hibakereséshez (debug) ad segítséget. Ha megnyomjuk a SHIFT+F1 gombot, a LISP a DEBUG függvényt fogja hívni, amely lehetővé teszi, hogy a felhasználó begépeljen tetszőleges LISP kifejezést, amely kiértékelődik, és az eredmény kinyomtatásra kerül. Például, a változók értékei megtudhatók, egyszerűen a nevük beírásával. Befejezéskor a felhasználó beírja: "BYE", és a program folytatja addigi tevékenységét.

(SETQ HANDLER 'FRED)

(DEFUN FRED (TYPE)
  (AND (EQ TYPE24) (DEBUG)))

(DEFUN DEBUG((INPUT))
  (PRINTC "Lisp debugger - type BYE to leave")
  (LOOP
    (PRINTC"DEBUG>")
    (LOOP (WHILE (ATOM (SETQ INPUT (ERRORSET
    (READ))))))
    (SETQ INPUT(CAR INPUT))
    (UNTIL (EQ INPUT'BYE)
      (PRINTC"***Leaving Debug"))
    (ERRORSET(PRINT(EVAL INPUT)))))

Az interruptkezelés hatékony eszköz egy tapasztaltabb programozó kezében és lehetséges vele bonyolult függvényeket alkotni, amelyek akkor lépnek működésbe, amikor egy speciális software interrupt érkezik.
Megjegyzés: a LISP nem válaszol az interruptokra, amíg a felhasználóra vár, hogy az valamit begépeljen (vagyis, amíg a kurzor villog).

8. Fejezet: Az IS-LISP függvényei
Ez a fejezet a LISP függvények alfabetikus felsorolását tartalmazza, leírja struktúrájukat és működésüket, és néhány példát ad használatukra. Mindegyik függvény az itt felsorolt kategóriák egyikébe tartozik:

A LISP függvények argumentumait "< >" zárójelek közé tesszük, vagy "[ ]" zárójelek közé, az utóbbi opcionális argumentumot jelez.
A függvény eredménye is meg van adva, és ez egy lista (azaz (a b c ... z)), egy egész szám a -32768 és a 32767 közti intervallumban, vagy a "tet" szó, ami azt jelenti, hogy az eredmény típusa tetszőleges LISP típus lehet.

(ABS <szám>) --> szám
Subr

Az argumentum abszolút értékét adja. Pl.:

(ABS 23) 23
(ABS-19) 19

(ADD1 <szám>) --> szám
Subr

Az argumentumnál 1-gyel nagyobb számot ad. Pl.:

(ADD1 23) 24

(AND <1. kifejezés> <2. kif.>... ) --> NIL vagy tet
Fsubr

Sorra kiértékeli argumentumait. Ha az egyik NIL, a függvény mindenképp NIL-t ad; egyébként az utolsó argumentum értékét adja. pl:

(AND(NUMBERP 10 (ATOM 'A B))) NIL
(AND (LISTP '(A B))'XYZ) XYZ

(APPEND <X> <y>) --> list
Subr

Ha <x> és <y> listák, akkor ez a függvény azt a listát fogja adni, amelyik először <x>, majd <y> elemeit sorolja fel. Pl.:

(DEFUN APPEND (X Y)
  (COND
    ((ATOM X) Y)
    (T (CONS (CAR X) (APPEND (CDR X) Y ]

(APPEND'(A B) 'C D)) (A B C D)

(APPLY <fg> <arg>) --> tet
Subr

Az <fg> függvény értékét adja az <arg> argumentumok mellett. Pl.:

(APPLY NUMBERP'(10)) T

(ASSOC <kód> <a lista>) --> NIL vagy (<kód> érték)
Subr

Megkeresi a rendezett párok megfelelő listáját az adott kódra. Ha a keresés sikerrel járt, egy (<kód>.érték) párt ad; egyébként NIL-t.Pl.:

(DEFUN ASSOC (U ALIST)
  (COND
    ((ATOM ALIST) NIL)
    ((ATOM (CAR ALIST) ERROR "BAD
      ASSOCIATED LIST"))
    ((EQUAL U (CAAR ALIST)) (CAR ALIST))
    (T (ASSOC U (CDR ALIST]

(ASSOC'A'((B.2) (A.-3))) (A.-3)

(AT <sor> <oszlop>) --> NIL
Subr

A kurzort az aktuális output csatornán a(<sor>,<oszlop>) pozícióra viszi.

(AT 10 20) NIL

(ATOM <x>) --> T vagy NIL
Subr

T-t ad (igaz), ha <x> nem rendezett pár.

(ATOM '(A.B)) NIL
(ATOM 'A)    T
(ATOM 10)    T
(ATOM CAR)   T

AUTOLOAD
Id

Amikor az EVAL program megkísérli egy

(<azonosító> <arg>)

alakú kifejezés kiértékelését, és azt találja, hogy <azonosító> UNDEFINED, ez általában hibát eredményez. A felhasználó viszont írhat egy autoloadert, amely LISP függvény, és mindig kiértékelődik, amikor a felhasználó definiálatlan értékű függvényt hív.
Az autoloader beállítható a

(SETQ AUTOLOAD 'FRED)

paranccsal. Így a FRED függvény mindig hívódik, amikor definiálatlan függvény szerepel a programban, ennek a függvénynek a nevével, mint egyetlen argumentummal. Ez a top-down struktúrájú programozásban a leghasznosabb, mert így a felső szinten lévő függvények tesztelhetők anélkül, hogy az alsóbb szintek függvényeit definiálnánk.

(BAND2 <x> <y>) --> szám
Subr

Az <x> és <y> számok bitenként képzett AND-jét fogja adni, amikor bináris formában szerepelnek.
Pl., mivel 7 bináris formája 111, 3-é 11, ezért

(BAND2 7 3) 3

(BEAM <kifejezés> --> NIL
Subr

Ha (kif.> nem NIL, akkor az aktuális grafikus csatornán a sugárzás megkezdődik, különben befejeződik.

(BEAM NIL)  kikapcsolás
(BEAM T)    bekapcsolás

BLANK
Var

Ez reprezentálja a space karaktert. Pl.:

(PRINC BLANK)

egy space karaktert ad ki a képernyőre.

(BNOT <szám>) --> szám
Subr

A szám bitenkénti NOT-ját képezi, azaz x-ből (-x)-1 lesz. Pl.:

(BNOT 7)   -8
(BNOT -3)  2

(BORDER <szám>) --> NIL
Subr

Ha 0 < szám < 255, akkor így a keret színe a <szám> által reprezentált színre változik. Pl.:

(BORDER 42)

(BOR2 <x> <y>) --> szám
Subr

A két szám, <x> és <y>, bitenkénti OR-ját képezi. Pl., mivel 7 binárisan 111, 3 pedig 11, ezért

(BOR2 7 3) 7

(BXOR2 <x> <y>) --> szám
Subr

Az <x> és <y> számok bitenkénti exkluzív-OR-ját képezi. Pl., mivel 7 binárisan 111, 3 pedig 11, ezért

(BXOR2 7 3) 4

(CAPTURE <régi> <új>) --> NIL
Subr

Minden olvasási műveletet átirányít a <régi> csatornáról az <új> csatornára. Pl.

(CAPTURE 34 102) NIL

(CAR <x>) --> tet
Subr

Az <x> pontozott pár első mezejét adja eredményül. A 25-ös hiba lép fel, ha <x> nem rendezett pár. A CAR név helyett HEAD is írható. A CAR függvény kiterjeszthető a CAAR és a CAAAR rövidítéseket használva, a CAR CAR, ill. a CAR CAR CAR függvények reprezentálására. Pl.:

(CAR '(A.B))       A
(CAR '((A.B).C))   (A.B)
(CAAR '((A.B).C))  A

(CDR <x>) --> tet
Subr

Az <x> rendezett pár második mezejét adja. A 25-ös hiba lép fel, ha <x> nem rendezett pár. A CDR név helyett TAIL is írhatd. A CDR függvény kiterjeszthető a CDDR és a CDDDR rövidítéseket használva, a CDR CDR, ill. a CDR CDR CDR függvények reprezentálására. Pl.:

(CDR '(A.B))       B
(CDR '(A.(B.C)))   (B.C.)
(CDDR '(A.(B.C)))  C

(CHARACTER <szám>) --> id
Subr

A <szám>, mint ASCII kód által definiált azonosítót adja. A BASIC-beli CHR$ LISP-ekvivalense. Pl.:

(CHARACTER 65)  A

(CHARP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> azonosító, különben NIL-t. Pl.:

(CHARP 'A)  T
(CHARP 10)  NIL

(CHARS <kif.>) --> szám
Subr

Azoknak a karaktereknek a számát adja ki, amelyeket egy atom generálna, ha kinyomtatnák. Az érték függ az argumentum típusától.

Példa:

(CHARS 'A)   1
(CHARS 10)   6
(CHARS CAR)  10

(CLEAR) --> NIL
Subr

Törli az aktuális grafikus lapot.

(CLOSE <szám>) --> <szám>
Subr

Ha <szám> érvényes csatornaszáma egy nyitott file-nak, akkor azt lezárja. Pl.:

(CLOSE 1)

lezárja az 1-es csatornához tartozó file-t.

(CODEP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> kódpointer, különben NIL-t. Pl.:

(CODEP (A.B.))  NIL
(CODEP CAR)     T

(COMMENT <tet1> <tet2>...) --> NIL
Fsubr

Arra használjuk, hogy szöveges megjegyzéseket helyezzünk el egy kifejezésben. Pl.:

(COMMENT EZ NEM ÉRTELMEZŐDIK)  NIL

(COND (állítás) (állítás) ...) --> TET
Subr

Ez egy módszer feltételes struktúra irányítására, hasonló a BASIC-beli IF THEN ELSE parancshoz:

IF <áll1> THEN <kif1>
ELSE IF <áll2> THEN <kif2>
...
ELSE <kif.>

a LISP-ben így írható:

(COND (<áll1> <kif1>)
     (<áll2> <kif2>)
     ... (T<kif.>))

Példa:

(COND ((EQ A 3) (PRINT "A=3"))
  ((EQ A 4) (PRINT "A=4"))
  (T NIL))

(CONS <car rész><cdr rész>) --> lista
Subr

Új listát alkot a két megadott kifejezésből. Pl.:

(CONS'A'B)           (A.B)
(CONS'A(CONS'B NIL)) (A B)

(CONSTANTP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> szám vagy kódpointer, különben NIL-t. Pl.:

(DEFUN CONSTANTP (OR (NUMBERP X) (CODEP X]

(CONSTANTP 10) T
(CONSTANTP 'A) NIL

(COPY <x>) --> <x>
Subr

<x> egy példányát adja.

(DEFUN COPY (X)
  (COND
    ((ATOM X)X)
    (T (CONS (COPY (CAR X)) ((COPY (CDR X]

(COPY"(ABCDE)) (ABCDE)

(CREATE <szám> <filenév>) --> <szám>
Subr

Ez a függvény megnyitja a <filenév> file-t a <szám> csatornaszámon. Ekvivalens az "ACCESS OUTPUT "-tal specifikált BASIC OPEN parancshoz - ld. a BASIC kézikönyvet. pl.:

(CREATE 15 "NAME")

CRLF
Var

CRLF értéke egy kocsi vissza / soremelés.

(CURSOR <kif>) --> NIL
Subr

Ha <kif> nem NIL, akkor a kurzor az aktuális output csatornán bekapcsolódik; különben kikapcsolódik. Pl.:

(CURSOR NIL) NIL kurzor ki
(CURSOR T)    NIL kurzor be

(DEFLIST <dlista> <ind>) --> lista
Subr

A <dlista> argumentum olyan lista, amelyiknek minden eleme kételemű lista; <dlista>-ban minden azonosítónak megvan az <ind> indikátorral jelzett tulajdonság-listán elhelyezett tulajdonsága. Az indikátorok egy listáját kapjuk vissza. Pl.:

(DEFIN DEFLIST (U IND)
  (COND
    ((ATOM U) NIL)
    (T (PUT (CAAR U) IND (CADAR U))
    (CONS (CAAR U) (DEFLIST (CDR U) IND)))))

(DEFLIST '((V DD) (H RG)) 'NAME) (V H)

ami ugyanaz, mint:

(PUT 'V 'NAME 'DD) DD
(PUT 'H 'NAME 'RG) RG

és visszakapható, így:

(GET 'V 'NAME) DD

(DEFMAC <név> <paraméter> <törzs>... ) --> <név>
Fsubr

Ez a szokásos mód makrók definiálására. Pl.:

(DEFMAC IF X
  (LIST
    "COND"
    (LIST (CADR X) (CADDR X))
    (LIST T (CAR (CDDDR X)))))

Ez az IF makrót definiálja, amelyet 3 argumentummal hívunk:

(IF A B C)

A" kiértékelődik,: ha igaz, e lesz az eredmény; különben C. Pl.:

(IF (ZEROP X) 4 5) 4, ha X=0
(IF (ZEROP X) 4 5) 5, ha X<>0

(DEFUN <név> <paraméterek> <törzs>...) --> <név>
Fsubr

Ez a szokásos mód függvények definiálására. Pl.:

(DEFUN SQUARE (X) (TIMES2 X X)) SQUARE

(DEFVIDEO <+mód> <g-mód> <g-szín> --> NIL
Subr

Ez a függvény definiálja azokat a paramétereket, amelyeket csak a TEXT és a GRAPHICS függvények használnak.
<+mód> 40 vagy 80 és a képernyő oszlopainak számát jelöli.

<g-mód> a következők egyike:

<g-szín> a következők egyike:

Pl.:

(DEFVIDEO 40 1 0) NIL

(DEL <ch>) --> <ch>
Subr

Lezárja a <ch> EXOS csatornát. A legtöbb berendezés esetben ekvivalens a CLOSE függvénnyel. Pl.:

(DEL 1) 1

(DELETE <x> <y>)--> lista
Subr

Az <y> listát adja vissza, amelyből kitörölte <x> első előfordulását. Pl.:

(DEFUN DELETE (A L)
  (COND
    ((ATOM L) L)
    ((EQUAL A (CAR L)) (CDR L))
    (T (CONS (CAR L)(DELETE A (CDR L))))))

(DELETE 'A '(B A C A) (B C A)

(DIFFERENCE <x> <y>) --> szám
Subr

Az <y> számot kivonja az <x> számból és kiadja az eredményt. Pl.:

(DIFFERENCE 7 3) 4

(DIGIT <x>) --> T vagy NIL
Subr

T-t ad, ha <x> azonosító, amelynek kinyomtatott neve számjeggyel kezdődik (0-9). Pl.:

(DIGIT 'A)    NIL
(DIGIT '!0A) T

(DISPLAY <csat><tól><sor><nál>) --> NIL
Subr

<sor> db sort jelenít meg a képernyőn, a <csat> csatorna page-ének <tól> sorától kezdve, az első sort a képernyő <nál> sorára teszi. Minden argumentumnak egésznek kell lennie. Pl.:

(DISPLAY 4 10 7 1) NIL

a 4-es csatorna page-ének 10-16. sorait jeleníti meg, a képernyő legfelső sorában kezdve.

(DIVIDE <x> <y>) --> <hányados.mar>
Subr

Az <x> számot osztja el az <y> számmal és a (hányados.maradék) párt adja vissza. Pl.:

(DIVIDE 7 3) (2.1)

DOLLAR
Var

Ez a $ karakter.

(EDIT <kif>) --> tet
Subr

Egy szöveges lapot nyit meg, és a SPRINT használatával megjeleníti <kif>-et. Ekkor szerkeszteni lehet <kif>-et, ehhez használható az összes szövegszerkesztési lehetőség, a befejezés az "ESC" gomb megnyomásával történik. A módosult forma beolvasásra kerül és megjelenik a képernyőn. Függvények editálására viszont a szokásos mód az FEDIT függvény hívása.

(ELLIPSE <x> <y>) --> NIL
Subr

Ellipszist rajzol, az aktuális képernyő-pozícióval, mint középponttal, az aktuális grafikus csatornán, az aktuális tintaszínnel. <x>, ill. <y> rendre az x-sugarat, ill. az y-sugarat jelöli. Pl.:

(ELLIPSE 200 100) NIL

(ENVELOPE <en><er>[<cp><cl><cr><pd>]) --> NIL
Fsubr

A hangburkolónak egy teljes leírása található a BASIC kézikönyvben.

A szögletes zárójelben levő paraméterek egy fázist határoznak meg és legfeljebb 12-szer ismételhetők.

Pl.:

(ENVELOPE 1 1 10 30 20 10) NIL

(EOF) --> T vagy NIL
Subr

Megvizsgálja, hogy az aktuális input csatornán file-végnél tartunk-e. Értéke T, ha igen, különben NIL.

(EQ <kif1> <kif2>) --> T vagy NIL
Subr

A függvény T-t ad, ha argumentumaira a következők egyike igaz:

  1. Mindkettő ugyanaz az azonosító.
  2. Mindkettő ugyanaz a szám.
  3. Mindkettő ugyanaz a lista a LISP memóriában.

Pl.:

(EQ 1 'A)   NIL
(EQ 10 10) T
(EQ '(A B) '(A B)) NIL

(EQUAL <kif1> <kif2>) --> T vagy NIL
Subr

Megvizsgálja, hogy két adott általános kifejezés azonos-e. Pl.:

(DEFUN EQUAL (X Y)
  (COND
    ((EQ X Y) T)
    ((OR (ATOM X) (ATOM Y)) NIL)
    ((EQUAL (CAR X) (CAR Y)) (EQUAL (CDR X) (CDR Y)))
    (T NIL)))

(EQUAL 1 'A) NIL
(EQUAL '(A B) '(A B)) T

(ERROR <szám>)--> nincs értéke
Subr

Feloldja a <szám> LISP hibakódot.

(ERRORSET <tet>) --> szám vagy tet
Fsubr

Kiértékeli az argumentumot. Ha eközben nem derül ki hiba, akkor visszaadja <tet> kiértékelésének eredményét, mint egy rendezett párt, a NIL-lel, különben a hibakódot. Pl.:

(ERRORSET (ATOM 10)) (T)
(ERRORSET (A.B)) 17

(EVAL <tet>) --> <tet>
Subr

Argumentumának második kiértékelését hajtja végre. Pl.:

(EVAL '(CAR '(A B))) A

(EVLIS <lista> --> lista
Subr

Kiértékeli a lista összes elemét és az eredmények listáját adja. Pl.:

(DEFUN EVLIS (ARGS)
  (COND ((ATOM ARGS) NIL)
    (T (CONS (EVAL (CAR ARGS))
    (EVLIS (CDR ARGS))))))

(EVLIS '((CHARP 'Z) (EQ 'A'B))) (T NIL)

(EXOS-READ <var>) --> <szám>
Subr

A <var> EXOS változó aktuális értékét adja ki. Pl.:

(EXOS-READ 10) 234

(EXOS-TOGGLE <var>) --> <szám>
Subr

Kapcsolóként működik és "váltja" a megfelelő EXOS változót. Az eredmény a változó aktuális státuszának komplemense. Pl.:

(EXOS-TOGGLE 8) 0

(EXOS-WRITE <var> <val>) --> <val>
Subr

A <var> EXOS változót a <val> értékre állítja be. Pl.:

(EXOS-WRITE 10 234) 234

(EXPAND <lista> <függvény>) --> lista
Subr

<függvény>-nek két argumentumúnak kell lennie. Ha a listában n elem van, L(1), L(2), ... , L(n), akkor a következő listát kapjuk eredményül:

(<függvény> L(1) (<függvény> L(2)(...
(<függvény> L(n-1) L(n))...)))

Pl.:

(DEFUN EXPAND (L FN)
  (COND
  ((ATOM (CDR L)) (CAR L))
  (T (CONS FN
  (CONS (CAR L)
  (CONS (EXPAND (CDR L) FN) NIL))))))

EXPAND '(A S C D) 'PLUS2)--> (PLUS2 A
  (PLUS2 B (PLUS2 C D)))

(EXPANDMACRO <macro függvény> <teszt> --> tet
Subr

A debug-hoz hasznos eszköz, akkor alkalmazható, amikor makrókkal dolgozunk. Pl.:

(EXPANDMACRO IF '(IF(EQ X 3)4 5))

lásd. DEFMAC-nál IF definícióját.

(EXPLODE <azon>) --> list
Subr

Egy listát ad, <azon> kinyomtatott nevének karaktereivel. Pl.:

(EXPLODE 'ABCDE) (A B C D E)
(EXPLODE .... )   NIL

(FEDIT <fgv>) --> NIL
Fsubr

Hasonló EDIT-hez, lehetővé teszi, hogy az <fgv> függvényt megváltoztassuk. Nyomjuk meg az "ESC" gombot az editálás végeztével, hogy a függvény újradefiniálódjon.

(FKEY <kn> <str>) --> NIL
Subr

A <kn> funkciós gombhoz a <str> stringet rendeli, amely legfeljebb 23 karakter lehet.
<kn> az 1-16 intervallumba esik, 9-16 az 1-8-ból SHIFT-tell állnak elő. Pl.:

(FKEY 1 "Most be vagyok programozva!") NIL

(FLAG <azlis> <ind>) --> NIL
Subr

A listában minden azonosítót az <ind> jelzővel lát el. Pl.:

(FLAG '(A B C D) 'FINE) NIL

(FLAGP <azon> <ind> --> T vagy NIL
Subr

Arra használatos, hogy megvizsgáljuk, az <azon> azonosító az <ind> jelzővel van-e ellátva. Pl.:

(FLAGP 'A 'FINE) T vagy NIL

(FLATTEN <x>) --> lista
Subr

<x> egész részfa-struktúráját megszünteti. Pl.:

(DEFUN FLATTEN (X)
  (COND
    ((NUL X) NIL)
    ((ATOM X) (CONS X NIL))
    (T (NCONC (FLATTEN (CAR X)))
      (FLATTEN (CDR X))))))

FLATTEN '(A((B)) NIL (C.D) E)) (A B C D

(FLUSH <ch>) --> NIL
Subr

Kiüríti a <ch> hálózati csatornát. Pl.:

(FLUSH 17) NIL

(FSUBRP <x>) --> T vagy NIL
Fsubr

T-t ad, ha <x> egy Fsubr típusú függvény kódpointere, NIL különben. Pl.:

(FSUBRP COND) T
(FSUBRP 'A)    NIL

FUNARG
Id

FUNARG értéke határozatlan. Az interpreteren belül van speciális jelentése, ún. FUNARG lezárásoknál.

(FUNCTION <fn>) --> FUNARG <fn> környezet
Fsubr

Éppen úgy működik, mint QUOTE <qu>, de csak függvényekre alkalmazható. Amikor az eredményül kapott formába (ún. FUNARG lezárás) bizonyos argumentumokat helyettesítünk, minden változónak ugyanaz lesz az értéke, mint a lezárási operáció elvégzése előtt.

(GENSYM) --> azon
Subr

Egyetlen azonosítót ad vissza, ennek formája G0000, G0001, stb. Értéke egyesével növekszik.

(GET <azon> <ind>) --> tet
Subr

Az <azon> azonosító listáján levő tulajdonságot adja eredményül, az <ind> jelző mellett, vagy NIL-t, ha ilyen tulajdonság nincs. Pl.:

(GET 'V 'NAME DD

(GETCHAR)
Subr

Egyetlen karaktert olvas be az aktuális input-folyamból, ez lesz az eredmény. Jegyezzük meg, hogy az a függvény nem ugyanaz, mint a BASIC-beli INKEY$. INKEY$ LISP ekvivalense:

(DEFUN INKEY ()
  (RDS 5)
  (PROG1 (AND (ZEROP (READSTATUS)) (GETCHAR)) (RDS 0)))

Pl.:

(GETCHAR) J

(GRAPHICS) --> NIL
Subr

Ha van megnyitott grafikus csatorna, akkor megjeleníti a képernyőn; különben standard grafikus lap kerül megnyitásra, és megjelenik a képernyő felső húsz sorában. A grafikus mód és a színek a DEFVIDEO paranccsal definiálódnak.

(GREATERP <x> <y>) --> T vagy NIL
Subr

T-t ad, ha az <x> szám nagyobb, mint az <y> szám; különben NIL-t. Pl.:

GREATERP 7 3) T

(GRS <ch>) --> <szám>
Subr

Hatására <ch> lesz az aktuális grafikus csatorna, az előző száma pedig az eredmény.

HANDLER
Id

A LISP működése közben "software interruptok" érkezhetnek az operációs rendszertől. A HANDLER változó beállítható úgy, hogy az interrupt érkezésekor a rendszer egy bizonyos műveletet végezzen el. Lásd a 7. fejezetet.

(HEAD <x>) --> tet
Subr

Ez a függvény a CAR függvénnyel azonos. Pl.:

(HEAD 'A.B)) A

(IMPLODE <idlist>) --> id
Subr

Összeláncolja az <idlist>-ben lévő atomokat, s az így kapott azonosítót adja vissza. Pl.:

(IMPLODE '(A B CD EF G)) ABCDEFG

(IN <ioport>) --> szám
Subr

A Z80 <ioport> input/output portjától kapott értéket adja vissza. Pl.:

(IN 129) 3

(INK <col>) --> NIL
Subr

A palettáról választott "logikai" színre cseréli az aktuális grafikus csatorna tinta-színét. Pl.:

(INK 10) NIL

(INTERN <id>) --> <id>
Subr

Keresi <id>-et az oblist listán. Ha ott nem találja, kiegészíti vele a listát és eredményül is <id>-et ad. Pl.:

(INTERN 'WRITE) WRITE

(JOY <num>) --> szám
Subr

A <num> joystick szám státuszát adja eredményül -- a definíciót lásd a BASIC kézikönyvben. Pl.:

(JOY 1) 17

LAMBDA
Id

Speciális jelentése van az interpreteren belül - egy ún. lambda kifejezés.

(LAST <x>) --> tet
Subr

Az <x> lista utolsó tagját adja vissza. Pl.:

(DEFUN LAST(X)
  (COND
    ((ATOM X) X)
    ((NULL (CDR X)) (CAR X))
    (T (LAST (CDR X)))))

(LAST'A B C)) C

(LENGTH <x>) --> szám
Subr

Az <x> lista hosszát adja - a legfelső szinten mérve. Pl.:

(DEFUN LENGTH(X)
  (COND
    ((ATOM X) 0)
    (T (ADD1 (LENGTH(CDR X))))))

(LENGTH 'A) 0
(LENGTH '(A B (C.D) E))
4

(LESSP <x> <y>) --> T vagy NIL
Subr

T-t ad, ha az <x> szám szigorúan kisebb, mint az <y> szám; különben NIL-t. Pl.:

(LESSP 7 3) NIL

(LINELENGTH <tet>) --> szám
Subr

Egy sor hosszát adja, ahogy azt a SPRINT utasítás használja. Pl.:

(LINELENGTH 60) 40 (az előző érték)

(LIST <arg1> <arg2> ... ) --> lista
Subr

Az (<arg1> <arg2> ... ) listát adja. Pl.:

(LIST 'A 'B '-9 'C) (A B -9 C)

(LISTP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> rendezett pár; különben NIL-t. Pl.:

(LISTP '(A B)) T

(LITER <x>)--> T vagy NIL
Subr

T-t ad, ha <x> olyan azonosító, aminek kinyomtatott neve betűvel kezdődik; különben NIL-t. Pl.:

(LITER 'A)    T
(LITER '!0A) NIL

(LOAD <filenév>)
Subr

Betölt egy SAVE függvénnyel kimentett memóriarészt, vagy egy LISP kifejezésekből álló ASCII file-t. Pl.:

(LOAD "NAME")

(LOOP <tev1> <tev2> ... )--> tet
Subr

Addig végzi a <tev1>, <tev2>, ... tevékenységeket, amíg a WHILE vagy UNTIL részben lévő állítás nem válik hamissá/igazzá. Pl.:

(LOOP (PRIN '*) (SETQ CT (SUB1 CT))(UNTIL
(ZEROP CT)))

egy sornyi *-ot nyomtat ki, ha előtte (SETQ CT <szám>) utasítás szerepelt.

LPAR
Var

LPAR értéke a "(" karakter.

MACRO
Id

Speciális jelentése van az interpreteren belül - egy ún. Macro kifejezés. Pl.:

(DEFUN MAP (X FN)
  (LOOP
    (UNTIL (ATOM X) NIL)
    (FN X)
    (SETQ X (CDR X))))

(MAP 'ABC D) '(LAMBDA (X) (PRIN X))) NIL

az (A B C D) (B C D) (C D) (D) NIL outputot fogja adni.

(MAPC <x> <fn>) --> NIL
Subr

Az <fn> függvénybe helyettesíti sorra az <x> lista elemeit, s ezenkívül még egy NIL-t ad eredményül. Pl.:

(DEFUN MAPC(X FN)
  (LOOP
    (UNTIL (ATOM X) NIL)
    (FN (CAR X))
    (SETQ X (CDR X))))

(MAPC'(A B C D) '(LAMBDA (X) PRIN (X))) NIL

az ABCD NIL outputot adja.

(MAPCAN <x> <fn>) --> lista
Subr

Az a követelmény, hogy az <fn>-be való minden helyettesítés listát ad eredményül. A MAPCAN függvény az így kapott listák összeláncoltját adja.

(DEFUN MAPCAN (X FN)
  (COND
    ((ATOM X) NIL)
    (T (NCONC (FN (CAR X)) (MAPCAN (CDR X) FN)))))

(MAPCAN'(A B C D)'(LAMBDA(x) (LIST xx))) (A A B B C C D D)

(MAPCAR <x> <fn>) --> lista
Subr

Azt a listát adja eredményül, amely az <x> lista elemeinek sorra <fn>-be való helyettesítésekor jön létre.

(DEFUN MAPCAR (X FN)
  (COND
    ((ATOM X) NIL)
    (T(CONS(FN(CAR X))(MAPCAR(CDR X) FN)))))

(MAPCAR'A B C D) '(LAMBDA(X) (CONC X X))) ((A.A) (B.B) (C.C) (D.D))

(MAPCON <x> <fn>) --> lista
Subr

Követelmény, hogy az <fn>-be való minden helyettesítés listát adjon. MAPCON <fn>-be helyettesíti rendre <x>-et, (CDR <x>)-et, (CDDR <x>)-et, amíg a lista el nem fogy és a kapott listák összeláncoltja lesz az eredmény.

(DEFUN MAPCON (X FN)
  (COND
    ((ATOM X) NIL)
    (T (NCONC (FN X) (MAPCON (CDR X) FN)))))

(MAPCON '(A B C D) '(LAMBDA (X) (LIST
(CONS 1 X)))
((1 A B C D)(1 B C D)(1 C D) (1 D)

(MAPLIST <x> <fn>) --> lista
Subr

Azt a listát adja ki, amely az <x>-nek, (CDR<x>)-nek, (CDDR<x>)-nek,..., stb. <fn>-be való helyettesítésekor adódik, míg a lista ki nem merül.

(DEFUN MAPLIST (X FN)
  (COND
    ((ATOM X) NIL)
    (T (CONS (FN X) (MAPLIST (CDR X) FN)))))

(MAPLIST'(A B C D)'(LAMBDA (x)
(LENGTH x)))
(4 3 2 1)

(MAX2 <x> <y>) --> szám
Subr

Az <x> és az <y> számok közül a nagyobbikat adja. Pl.:

(MAX2 7 3) 7

(MEMBER <x> <y>) --> NIL vagy lista
Subr

NIL-t ad, ha <x> nem eleme az <y> listának. Különben <y>-nak az x-szel kezdődő szeletét adja. Pl.:

(DEFUN MEMBER (X Y)
  (COND
    ((ATOM Y) NIL)
    ((EQUAL X (CAR Y)) Y)
    (T (MEMBER X (CDR Y)))))

(MEMBER'A'(B C A D E)) (A D E)

(MEMQ <x> <y>) --> NIL vagy lista
Subr

Ugyanaz, mint MEMBER, azzal a különbséggel, hogy az összehasonlításhoz EQ-t alkalmaz, nem pedig EQUAL-t. Pl.:

(DEFUN MEMQ(X Y)
  (COND
    ((ATOM Y) NIL)
    ((EQ X (CAR Y)) Y)
    (T (MEMQ X (CDR Y)))))

(MEMQ'A B) '(A B (A B) C)) NIL

(MESSOFF <szám>) --> szám
Subr

A MESSOFF és a MESSON függvények bizonyos rendszerüzenetek kiírásának vezérlésére alkalmasak. Egy vezérlő byte-ban levő biteket vezérel, az alábbiak szerint:

Például, (MESSON 2) a kontrollszummát írja ki, míg (MESSOFF 8) leállítja a hibakeresést.

(MESSON <szám>) --> szám
Subr

ld. MESSOFF

(MIN2 <x> <y>) --> szám
Subr

Az <x> és <y> számok közül a kisebbiket adja ki. Pl.:

(MIN2 7 3) 3

(MINUS <szám>) --> szám
Subr

A <szám> negáltját adja. Pl.:

(MINUS 7)   -7
(MINUS -3) 3

(MINUSP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> szám és x<0; különben NIL-t. Pl.:

(MINUSP -3) T
(MINUSP 4)   NIL

(MKQUOTE <x>) --> lista
Subr

A (QUOTE<x>) listát adja. Pl.:

(MKQUOTE '(A B C)) (QUOTE(A B C))

(NCONC <x> <y>) --> lista
Subr

Összeláncolja <x>-et és <y>-t, anélkül, hogy <x>-et átmásolná. úgy működik, mint APPEND, de nem olyan megbízható. Kétséges esetben használjuk APPEND-et! Pl.:

(DEFUN NCONC(A B (W))
  (COND
    ((ATOM A) B)
    (T (SETQ W A)
    (LOOP
      (UNTIL (ATOM (CDR W)))
      (SETQ W (CDR W)))
      (RPLACD W B)
      A)))

(NCONC '(A B C) '(D E)) (A B C D E)

NIL
Id

A "hamis" igazságértéket adja.

(NOT <x>) --> T vagy NIL
Subr

Ha <x> NIL, akkor T-t ad; ha <x> T, akkor NIL-t ad. Pl.:

(NOT NIL) T

(NULL <x>) --> T vagy NIL
Subr

Ha <x> NIL, T-t ad; NIL-t különben. Teljesen ekvivalens a NOT függvénnyel (ld. fent). pl.:

(NULL 1) NIL
(NULL T) NIL
(NULL NIL) T

(NUMBERP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> szám; különben NIL-t. Pl.:

(NUMBERP 7) T

(OBLIST) --> lista
Subr

Listát ad az összes, a rendszer számára ismert azonosítóról. (FLATTEN (OBLIST)) egy egyszerűbb listát ad.

(ONEP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> az 1-es szám; különben NIL-t. Pl.:

(ONEP 1) T
(ONEP 2) NIL

(OPEN <szám> <filenév>) --> <szám>
Subr

Megnyitja a <filenév> nevű file-t / eszközt, a <szám> csatornaszámon. Hasonlít a Basic-beli OPEN parancshoz. Pl.:

(OPEN 15 "NAME")

(OR <kif1><kif2><kif3>...) --> tet
Fsubr

Az első nem-NIL argumentumot adja; ha ilyen nincs, akkor NIL-t. Pl.:

(OR (NUMBERP 'A) (CONS A B)(ZEROP 'T)) (A.B)

(ORDERP <id1> <id2>) --> T vagy NIL
Subr

T-t ad, ha <id1> kinyomtatott nevének ASCII kódja nagyobb, mint <id2>-é; különben NIL-t ad. Pl.:

(ORDERP 'A 'B)    NIL
(ORDERP 'B 'A)    T
(ORDERP 'AB 'AA) T

(ORDINAL <id>) --> szám
Subr

<id> kinyomtatott nevének első karakterét adja, ASCII kódban. Pl.:

(ORDINAL 'APPLE) 65

(OUT <érték> <ioport>) --> <érték>
Subr

Elküldi <érték>-et a Z80 <ioport>-tal specifikált input-output portjához. Pl.:

(OUT 10 254) 10

(PAINT) --> NIL
Subr

Kitölti az összes olyan vonalat, amely az aktuális képernyő-pozíciótól olyan határig tart, amely az aktuális képernyő-pozíciótól különböző színű.

(PAIR <x> <y>) --> lista
Subr

<x> és <y> azonos elemszámú listák kell, hogy legyenek. PAIR rendezett párok egy listáját adja, amelyeknek CAR-ja <x>-ből, CDR-je <y>-ból van. Pl.:

(PAIR '(A B)'(1 2)) ((A.1)(B.2))

(PALETTE <c0> <cl> <c2> <c3> <c4> <c5> <c6> <c7>) --> NIL
Subr

A palettát specifikálja az aktuális grafikus csatornára, a <c0>,...,<c7> egész számokkal a 0-255 intervallumban, mindegyikük egy-egy színt specifikál.
Megjegyzés 2-szín-módban c2, ..., c7 fölösleges, 4-szín-módban c4, ..., c7 fölösleges, 16-szín-mbdban a többi 8 szín c0, ..., c7-ből a szokásos módon származtatható. Pl.:

(PALETTE 10 20 40 5 73 122 5 0) NIL

(PAPER <col>) --> NIL
Subr

Átváltoztatja az aktuális grafikus csatorna háttérszínét <col>-ra. Ennek hatása akkor látszik, amikor a csatornára legközelebb CLEAR utasítást adunk ki. Pl.:

(PAPER 29) NIL

(PEEK <cím>)--> szám
Subr

<cím> memóriacím tartalmát adja ki. pl.:

(PEEK 10) 6

PERIOD
Var

Értéke a "." karakter.

(PLIST <id>)--> lista
Subr

Az <id> azonosító tulajdonság-listáját adja. Pl.:

(PLIST 'A) ((tul1. ért1)(tul2. ért2)....)

(PLOT <x> <y>) --> NIL
Subr

A rajzolósugarat a grafikus képernyő (<x>,<y>) pozíciójába mozgatja. Ha a rajzolósugár bekapcsolt állapotban van, vonalat húz. Pl.:

(PLOT 200 100) NIL

(PLOTR <x> <y>) --> NIL
Subr

Az aktuális képernyő-pozíciótól x irányba <x>, y irányba <y> elmozdulást tesz. Ha a rajzolósugár bekapcsolt állapotban van, vonalat húz. Pl.:

(PLOTR 100 200) NIL

(PLOTMODE <szám>) --> NIL
Subr

A rajzmódot állítja be az aktuális grafikus csatornán, a következőképp:

Pl.:

(PLOTMODE 2) NIL

(PLOTSTYLE <szám>) --> NIL
Subr

A vonal típusát adja meg az aktuális grafikus csatornán. <szám> egész az 1-14 intervallumban, 1-es folytonos vonalat jelent, a többi szám különböző pontozott vonalakat. Pl.:

(PLOTSTYLE 5) NIL

(PLUS <arglista>) --> szám
Fsubr

Az <arglista>-ban megadott egész számok összegét szolgáltatja. Pl.:

(PLUS 10 3 16) 29

(PLUS2 <x> <y>) --> szám
Subr

Ha pontosan két számot kell összeadni, akkor ez a hatékonyabb módja. Pl.:

(PLUS2 7 3) 10

(POKE <cím> <érték>) --> <érték>
Subr

A memória <cím> által megadott helyére <érték>-et ír. Pl.:

(POKE 10 23) 23

(PRIN [<arglista>]) --> tet
Subr

Az <arglista>-ban levő argumentumok kiértékelődnek, és kiíródnak, közbenső blank jelek nélkül. A speciális karakterek elé escape jel kerül. pl.:

(PRIN 'A BLANK 'B) A! B

(PRINC [<arglista>]) --> tet
Subr

Ugyanolyan, mint PRIN, azzal a különbséggel, hogy a speciális karakterek elé nem kerül escape jel. Pl.:

(PRINC 'A BLANK 'B) A B

(PRINT [<arglist>]) --> NIL
Subr

Ugyanaz, mint PRIN, azzal a különbséggel, hogy a CR/LF-et is magában foglalja, és NIL-t ad.

(PRINTC [<arglista>]) --> NIL
Subr

Ugyanolyan, mint PRINT, de a speciális karakterek elé nem kerül escape jel.

(PROG1 <kif1> <kif2>) --> <kif1>
Subr

Az első argumentumot adja vissza. Pl.:

(PROG1 'A 'B) A

(PROG2 <kif1> <kif2>) --> <kif2>
Subr

A második argumentumot adja vissza. Pl.:

(PROG2 'A 'B) B

(PROGN <kif1><kif2>...<kifn>) --> tet
Fsubr

Kiértékeli rendre <kif1>-et, <kif2>-t,..., <kifn>-et, és <kifn>-et adja vissza. Pl.:

(PROGN 'A 3 4 'B) B

(PUT <id><ind><tul>) --> <tul>
Subr

A <tul> tulajdonságot <id> tulajdonságlistájára teszi az <ind> indikátor alatt.

(QUOTE <tet>) --> kiértékeletlen<tet>
Fsubr

Leállítja a kiértékelést, és LISP-en keresztül kiírja: '<tet>. Pl.:

(QUOTE A) A
(QUOTE 'A) "A"

(QUOTEP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> idézett kifejezés, különben NIL-t. Pl.:

(QUOTEP '(QUOTE Z)) T

(QUOTIENT <x> <y>) --> szám
Subr

Elosztja az <x> számot az <y> számmal, és - a maradékot figyelmen kívül hagyva - kiadja a "hányadost". Pl.:

(QUOTIENT 7 3) 2

(RANDOM <szám>) --> szám
Subr

Véletlen számot ad a 0-(<szám>-1) intervallumban, hacsak a <szám> nem 0; ekkor az intervallum 0-32767. <szám> maximális lehetséges értéke 2000. Pl.:

(RANDOM 1967) 1510

(RANDOMISE <mag>) --> <mag>
Subr

A véletlen számok "irányítására" használatos. Ha <mag> 0, akkor a sorozat nem jósolható, ha viszont nem 0, egy konkrét ismételt sorozatot nyertünk. Pl.:

(RANDOMISE 43) 764

(RDS <ch>) --> <cr>
Subr

<ch> csatornát aktuális input áramnak véve, a megelőző input áramot adja. Pl.:

(RDS 1) 0

(READ) --> tet
Fsubr

A függvény az aktuális input csatorna soronkövetkező s-kifejezéséből kiolvasott eredményt adja ki.

(READLINE) --> tet
Fsubr

Az aktuális input csatornából a következő újsor karakterig olvas, ebből egyetlen azonosítót képez, ezt adja eredményül.

(READ-STATUS) --> <szám>
Subr

Az aktuális input csatorna státuszát adja ki. Értékei:

(RECLAIM) --> <szám>
Subr

Megadja a szabad LISP cellák számát. Ennek a számnak kb. az ötszöröse lesz a szabad byte-ok száma.

(REDIRECT <régi> <új>) --> NIL
Subr

Az összes output operációt átirányítja a <régi> csatornáról az <új> csatornára. Pl.:

(REDIRECT 42 104) NIL

(REMAINDER <x> <y>) --> szám
Subr

Az osztás maradékát adja.

(REMAINDER 7 3) 1
(REMAINDER -7 3) -1

(REMFLAG <azon. lista><ind>) --> NIL
Subr

Az <azon. lista> azonosító listát megfosztja a flag-ektől. Pl.:

(REMFLAG '(A B)'FINE) NIL

(REMOB <id>) --> <id>
Subr

Megkeresi az <id> azonosító oblist-jét, és ha van, eltávolítja. Pl.:

(REMOB 'A) A

(REMPROP <azon> <ind>) --> tet
Subr

Az <azon> azonosító tulajdonság-listájáról eltávolítja az <ind> tulajdonságot. NIL-t ad, ha ezt a tulajdonságot nem találja. Pl.:

(REMPROP 'V 'NAME) DD

(REPEAT <szám><kif>) --> NIL
Fsubr

Kiértékeli a <kif> kifejezést, egymásután <szám>-szor. Pl.:

(REPEAT 5 (PRINC 'AB)) NIL, AB AB AB AB AB jelenik meg.

(REVERSE <x>) --> lista
Subr

Az <x> lista megfordítottját adja vissza. pl.:

(REVERSE '(A B(C D) E)) (E (C D) B A)

(REVERSEIP <x>) --> lista
Subr

Ugyanazt teszi, mint a REVERSE, csak sokkal gyorsabban, viszont kevésbé megbízható. Pl.

(REVERSEIP'(A B C D)) (D C B A)

RPAR
Var

Értéke a ")" karakter.

(RPLACA <mod><kif>) --> tet
Subr

A <mod> CAR mezejét helyettesíti <kif>-fel. pl.:

(RPLACA '(A B) 1) (1 B)

(RPLACD <mod><kif>) --> tet
Subr

A <mod> CDR mezejét helyettesíti <kif>-fel. Pl.:

(RPLACD '(A B) 1) (A . 1)

(SASSOC<kulcs><alista>) --> (kulcs><érték>) vagy tet
Subr

Egy adott <kulcs> kulcsot keres <alista>-ban, és ha megtalálta, a (kulcs,érték) párt adja vissza. Különben a függvény argumentumok nélkül értékelődik ki. Pl.:

(SASSOC 'A '((B.27) (A.-3)) FN) (A . -3)
(SASSOC 'A '((B.27) '(LAMBDA NIL 5)) 5

(SAVE <filenév>) --> <filenév>
Subr

Kimenti e rendszer aktuális állapotát (amely később LOAD-dal visszanyerhető) Pl.:

(SAVE "NAME")

(SET <azon><kif>) --> <kif>
Subr

<azon> értékét <kif>-re változtatja. Pl.:

(SET 'X 42) 42

(SETATTRIBUTES <szám>) --> NIL
Subr

A grafikus attribútum-flag-byte-ot változtatja <szám>-ra (az aktuális grafikus csatornán). Alapvetően ez a flag-byte határozza meg, hogyan történik a rajzolás attribútum-módban. A teljes leírást lásd az EXOS specifikációknál. A függvény NIL-t ad eredményül. Pl.:

(SETATTRIBUTES 3) NIL

(SETCOLOUR <szám><szín>) --> NIL
Subr

A <szám> "logikai" színt teszi a palettán a <szín> szín helyére. Pl.:

(SETCOLOUR 3 24) NIL

(SETQ <azon><kif>) --> <kif>
Fsubr

Ugyanolyan, mint SET, csak az első argumentum automatikusan idézve szerepel. Pl.:

(SETQ X 42) 42

(SET-TIME <azon>) --> NIL
Subr

Lehetővé teszi, hogy a rendszer óráját átállítsuk (ld. TIME). Az <azon> argumentumnak nyolc karakter hosszú azonosítónak kell lennie, amely az időt a következő formában ábrázolja: hh:mm:ss

(SET-TIME "01:30:42") NIL

(SETVIDEO <ind><col><x><y>) --> NIL
Subr

Egy video oldalt definiál, közvetlenül az oldal megnyitása vagy kreálása előtt kell hívni.
<ind> értékei lehetnek:

A zárójelben megadott felbontások a teljes képernyőre vonatkoznak, két-szín-módban. A függőleges felbontás teljes képernyőre 27 karakter, azaz 243 pixel.
<col> értékei lehetnek:

<x> és <y> a video oldal méretét határozza meg.

1 < x < 42
0 < y < 255

Pl.:

(SETVIDEO 1 2 40 20) NIL

(SNDS <ch>) --> <szám>
Subr

Hatására <ch> lesz az aktuális grafikus csatorna, az előzőt pedig eredményül adja. Pl.:

(SNDS 56) 34

(SOUND <env><p><vl><vr><sty><ch><d><f>) --> NIL
Subr

Egy hangot eredményez (feltételezve, hogy az aktuális hangcsatorna nyitva van a SOUND eszközre). A paraméterek jelentése:

A rutin NIL-t ad eredményül. Pl.:

(SOUND 255 20 3 10 30 40 0 0) NIL

(SPRINT <kif>) --> NIL
Subr

Ez a program formattáló. A <kif> kifejezést szebb formában jeleníti meg.

(SUB1 <szám>) --> szám
Subr

<szám>-1-et ad vissza. Pl.:

(SUB1 23) 22

(SUBLIS <alista> <kif>) --> tet
Subr

Az eredmény úgy alakul ki, hogy <kif> CAR részének minden előfordulásába <alista> CDR részét helyettesítjük. pl.:

(SUBLIS '((A.10)(B.C)) '(H A (B) A)) (H 10 (C) 10)

(SUBRP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> egy szubrutinra mutató kódpointer, különben NIL-t. Pl.:

(SUBRP CAR) T

(SUBST <x> <y> <kif>) --> lista
Subr

<kif>-ben mindenhol <y> helyett <x>-et helyettesít. Pl.:

(SUBST 'A 'B '(C B (A) (B A))) (C A (A) (A))

T
Id

A TRUE igazságértéket jelenti.

(TAIL <x>) --> tet
Subr

Ez a függvény a CDR-rel azonos. Pl.:

(TAIL '(A.B)) B

(TERPRI) --> NIL
Subr

A képernyőre egy kocsi-vissza jelet tesz ki.

(TEXT) --> NIL
Subr

Új szöveges oldalt nyit, az oldal oszlopainak számát a legutóbbi DEFVIDEO hívás határozza meg.

(TIME) --> azonosító
Subr

A pillanatnyi időt adja, egy nyolckarakteres azonosítóban, ebben a formában: hh:mm:ss
Az óra bekapcsoláskor indul, 00:00:00-ról, és a SET-TIME függvénnyel állítható át (ld. ott). Pl.:

(TIME) 00:10:38

(TIMES <arglista>) --> szám
Fsubr

Kiértékeli <arglista> elemeit, és összeszorozza őket, a szorzatot adja eredményül. Pl.:

(TIMES 2 5 -3) -30

(TIMES2 <x><y>) --> szám
Subr

Hatékonyabb mód pontosan két szám, <x> és <y> összeszorzására. Pl.:

(TIMES2 3 7) 21

UNDEFINED
Id

Amikor egy azonosítót először használunk, "UNDEFINED" értéket kap.

(UNTIL <kif>)
Fsubr

A LOOP ciklusutasításban szerepel. Pl.:

(UNTIL (EQ A 3))

VERSION
Id

String, amely leírja, milyen LISP verzió működik éppen.

(WHILE <kif>)
Fsubr

A LOOP ciklusutasításban szerepel. Pl.:

(WHILE (EQ A 3))

(WRS <handle>) --> <handle>
Subr

Hatására a <handle> csatorna lesz az aktuális output áram. Pl.:

(WRS 2) 3

(ZEROP <x>) --> T vagy NIL
Subr

T-t ad, ha <x> a nulla szám; különben NIL-t ad. Pl.:

(ZEROP 0) T

1. Függelék: EXOS változók
Az alábbi lista megadja azokat az EXOS változókat, amelyek az EXOS-READ, EXOS-WRITE és az EXOS-TOGGLE parancsokkal kezelhetők.
Minden változó beállítható a 0-tól 255-ig terjedő értékek bármelyikére. Ugyanakkor, sokan közülük kapcsolóként működnek, be- vagy kikapcsolnak valamit, ahol 0 felel meg a "be" és 255 a "ki" iránynak.

0 IRQ_ENABLE_STATE 0. bit - hang megszakítás
2. bit - 1 Hz megszakítás
4. bit - Video megszakítás
6. bit - Külső megszakítás
Az 1., 3., 5., 7. biteknek 0-nak kell lenni. Ezt a változót normál használatban ne módosítsuk.
1 FLAG_SOFT_IRQ Egy eszköz nem-0-ra állítja, software-megszakítás céljából.
2 CODE_SOFT_IRQ Egy software megszakítás rutin vizsgálja, a megszakítás okának kiderítése céljából.
3 DEF_TYPE Az alapértelmezésként szereplő eszköz típusa: 0 - szalag, 1 - lemez.
4 DE_CHAN A default csatorna száma.
5 TIMER 1 Hz-es visszaszámláló, a nulla elérésekor software megszakítást okoz, és megáll.
6 LOCK_KEY A rögzített billentyűk aktuális helyzete: 0 - reteszeletlen, 1 - CAPS lock, 2 - SHIFT lock, 8 - ALT lock.
7 CLICK_KEY 0 - a billentyűzet hangja bekapcsolva, 1 - kikapcsolva.
8 STOP_IRQ 0 - a STOP billentyű megszakítást okoz, 1 - a STOP billentyű a kódját adja vissza.
9 KEY_IRQ 0 - bármely billentyű megnyomása software-megszakítást okoz, és a kódját is visszaadja.
10 RATE_KEY A leütött billentyű 1/50 s-onként ismétli magát.
11 DELAY_KEY Késleltetés az önismétlés kezdetéig, 0 - önismétlés letiltva.
12 TAPS_SND 0 - magnó kontroll hang engedélyezve.
13 WAIT_SND 0 - ha a SOUND DRIVER pufferje megtelíti, vár. <>0 - SQFUL hibakódot ad.
14 MUTE_SND A hangburkoló pufferjének mérete fázisokban.
16 BAUD_SER A soros-csatorna sebessége:
6 - 300 baud,
8 - 1200 baud,
10 - 2400 baud,
12 - 4800 baud,
14 - 9600 baud.
17 FORM_SER A soros-csatorna formátumát adja meg:
0. bit adatbitek száma (0=8 bit, 1=7 bit)
1. bit paritás vezérlés (0=kikapcs.)
2. bit paritás választós (0=páros, 1=páratlan)
3. bit stop, bitek száma (0=2, 1=1)
18 ADDR_NET A gép hálózati-száma.
19 NET_IRQ 0 - adat érkezése a hálózaton megszakítást okoz.
20 CHAN_NET A hálózaton fogadott adatblokk csatornaszáma.
21 MACH_NET Az adó gép hálózati száma.
22 MODE_VID Video-mód.
23 COLR_VID Szín-mód.
24 X_SIZ_VID Video-lap X mérete.
25 Y_SIZ_VID Video-lap Y mérete.
26 ST_FLAG 0 - megjeleníti a státusz sort.
27 BORD_VID Keret-szín.
28 BIAS_VID A paletta 8...16 színeit meghatározó érték (BIAS).
29 VID_EDIT Az editorhoz rendelt video-lap csatornaszáma.
30 KEY_EDIT Az editorhoz rendelt billentyűzet csatornaszáma.
31 BUF_EDIT Az editor pufferének mérete (256 byte-os lapokban).
32 FLG_EDIT Az editor flag-byte-ja.
33 SP_TAPE A nem-0 érték lassú magnókezelést eredményez.
34 PROTECT Nem-0 értek esetén védett file-t hoz létre.
35 LV_TAPE A magnó-kimenet jelszintje.
36 REM.1 0 - REMOTE 1 bekapcsolva, <>0 - REMOTE 1 kikapcsolva.
37 REM.2 0 - REMOTE 2 bekapcsolva, <>0 - REMOTE 2 kikapcsolva.

A következő EXOS változó számokat a felhasználó ne változtassa: 0,1,2.

2. Függelék: Hibaüzenetek

Az alábbi lista az IS-LISP interpreter által adott hibajelzéseket sorolja fel.

1. Memória-túllépés.
2. A végrehajtás megszakítva (a STOP billentyűt számítás közben megnyomták).
3. Megszakítás nyomtatás közben.
4. Software megszakítás (meghatározatlan handler).
5. Aritmetikai túlcsordulás.
6. Osztás nullával.
7. Argumentumként várt szám.
8. Elvárt: azonosító.
9. Elvárt: byte (szám a 0-255 intervallumban).
10. Elvárt: byte vagy negatív szám.
11. Elvárt: csatorna (szám a 0-255 intervallumban).
12. Elvárt: indikátor.
13. Fölösleges "." vagy ")" olvasáskor.
14. Illegális pont-jelölés.
15. Túl nagy szám olvasáskor.
16. Túl hosszú string (minden string legfeljebb 255 karakter hosszú lehet).
17. Definiálatlan függvény.
18. Adott Fsubr alkalmazása függvényként.
19. Adott szám alkalmazása függvényként.
20. Rossz LAMBDA kifejezés.
21. Rossz FUNARG kifejezés.
22. Túl sok argumentum egy LAMBDA-kifejezéshez.
23. Túl kevés argumentum egy LAMBDA-kifejezéshez.
24. Az opcionális argumentumoknak követnie kellene az egyszerű argumentumokat.
25. Egy atom CAR-jának vagy CDR-jének képzése.
26. Rossz COND kifejezés.
27. Rossz asszociációs-lista.
28. Rossz tulajdonság-lista.
29. Primitív függvény argumentumszáma nem helyes.
30. A rendszerváltozók módosítása lehetetlen.
31. Rendszer-azonosító egy LAMBDA/MACRO paraméter listában.
32. MACRO forma egy nulla paraméterrel.
33. A MACRO paraméternek atomnak kéne lennie.
34. Rossz MACRO kifejezés.
35. Különböző hosszúságú listák a PAIR függvény argumentumaiként.
36. Rossz argumentum egy véletlen függvényhez (0-2000-ig terjedő egésznek kell lennie).
37. Ismétlési faktorként számot vár.
38. Rossz idézendő argumentum.
39. RPLACA/RPLACD számára listát vár.
40. Nincs jó azonosító lista IMPLODE számára.
41. Túl sok karakter IMPLODE számára.
42. SET, ill. SETQ azonosítót vár.
43. Nincs elég memória a file betöltésére: próbáljuk meg a nem szükséges csatornákat lezárni és kíséreljük meg újra.
44. A betöltött kiterjesztésekkel együtt nem menthető ki.
45. Rossz argumentum a SET-TIME számára.

3. Függelék: A Funkciós billentyűk

Az Enterprise mikroszámítógépnek nyolc funkciós billentyűje van, F1-től F8-ig címkézve. Önállóan vagy SHIFT-tel együtt használva 16 funkciót látnak el összesen, amelyeket a felhasználó definiálhat az FKEY függvény segítségével. Pl:

(FKEY 5 "SZIA. 5. GOMB MEGNYOMVA")

beprogramozza KEY5-öt, hogy a fenti üzenet íródjon ki a megnyomásakor.
Bekapcsoláskor vagy reset után, az F1 ... F8 gombok alapértelmezése az alábbi:

Billentyű Funkció
1 (FLATTEN (OBLIST))
2 (DEFUN
3 (FEDIT
4 (EXOS-TOGGLE 36) - váltja a REMOTE 1 kazettát.
5 (TEXT)
6 (GRAPHICS)
7 (EXOS-TOGGLE 7) - váltja a billentyű-hangot
8 (RECLAIM)
9-16 null string, "". Alapértelmezésben software-megszakítást okoznak megnyomáskor.

Készült a Texgraf Ipari Szövetkezet nyomdájában
Felelős vezető: dr. Bernáth Tibor - 87.1713 Texgraf, Dunaharaszti

Vissza a könyvekhez

Vissza a felhasználói programokhoz