TECO-KURS Pär Emanuelsson Det här är den andra delen i en Teco-kurs, som jag tidigare har hållit på Tekniska Högskolan i Linköping vid två tillfällen. Det blir (minst) en del till, som kommer i senare nummer av Garb. Kommentarer mottages tacksamt. Ja, GARB är ju ingen veckotidning precis, men jag hoppas att det inte går alltför långt mellan avsnitten. Titta tillbaka på majnumret om du är tveksam. Makros Ja, ni vet väl att EMACS står för Editing MACroS? Lite förenklat kan man säga att ett makro helt enkelt är en subrutin, underfunktion, eller vad man nu vill kalla det. Ett generellt anrop av ett makro ser ut: m,nMq sträng1$ sträng2$ ... strängN$ Du känner här igen den allmänna formen av Tecos syntax för kommandoanrop. Skillnaden är här att Q-registret q innehåller Tecokod (eller en pekare till Tecokod) som ska exekveras. Denna Tecokod kan läsa parametrarna m,n samt strängparametrarna, allt efter behag. Argumenten hämtas med: ^X m ^Y n F^Xbåde m och n ^]^Xsträngargument Dessa kommandon kan endast användas inuti Tecomakros. Exempel: ^X + ^Y Ua Addera argumenten m och n och lägg resultatet i Qa. F^X K Radera tecknen m - n. ^]^X Ub ^]^X Uc Lägg första strängargumentet i Qb, lägg andra strängargumentet i Qc. Vad händer då om man forsöker använda ett argument som inte finns medskickat? Om man t.ex. gör 5,Ma och exekverar ^Y i makrot? Jo, då får man resultatet 0. Det är ju inte så bra, för man vill ju kanske skilja på om man fick argumentet 0 eller inget argument alls. Då kan man använda funktionen: F^Y returnera vilka argument som gavs. Observera att det är argumenten till F^Y som kollas, inte argumenten till makrot. För att kolla dem måste man göra F^X F^Y. Dvs hämta alla argument som makrot fick och skicka dem till F^Y. F^Y returnerar: 0 inga argument alls. 1 endast n-argumentet. 2 endast m-argumentet. 3 både n och m. En funktion måste förstås också kunna returnera argument. Det kan den göra med kommandot ^\. ^\ gör att funktionen hoppar tillbaka, samt att argumenten till ^\ returneras till den anropande funktionen (makrot). Vi kanske skulle kunna göra ett litet exempel. Vi gör en funktion som får två argument och returnerar deras summa (mycket avancerat...). :@Ia/ ^Y + ^X ^\ / Märk att vi lägger in makrot i Q-register a. Makrot kan sedan anropas t.ex. som: 3,5 Ma Ub Vi skickar med argumenten 3 och 5 till makrot i Qa och lägger resultatet i Qb. Fördefinierade makron Det finns ett antal fördefinierade makron i olika Q-register. Till exempel: .q skapar lokalt Q-register. .v skapar en global variabel. .I skapar en lokal variabel. Lokal och global syftar på räckvidden. En global variabel har samma värde oberoende av vilken buffert man befinner sig i, medan en lokal variabel kan ha olika värden i olika buffertar, även fast den heter likadant. Detta är värdefulla egenskaper. En global variabel skapar man alltså genom att anropa makrot i Q.v. Variabelnamnet ger man som strängargument. Man kan också direkt tilldela den nya variabeln ett värde genom att skicka det som argument till M.v. Exempel: M.v Antal Rader$ skapar en global variabel med namnet Antal Rader 4 M.l Default$ skapar en lokal variabel med namnet Default och tilldelar den samtidigt värdet 4. Inbyggda funktioner Hur anropar man då Tecos många inbyggda funktioner (som inte ligger i Q-register)?? Jo: man hämtar en pekare till funktionen och gör sedan M på den. Man hämtar en pekare med hjälp av makrot i Q.m. Så här: M(M.m Next Line$) M.m hämtar en pekare till funktionen Next Line och M exekverar makrot som utpekas. Man kan alltså även ha parenteser efter M, vilket gör att uttrycket inom parenteserna evalueras och resultatet används av M på vanligt sätt. I stället för parenteser hade man förstås kunnat lägga in pekaren i ett Q-register: M.m Next Line$ Ua Ma Vilket ger samma resultat. Det finns även ett enklare sätt att exekvera funktioner, nämligen med MM. MM fungerar likadant som ovanstående konstruktion, men funktionen bygger på att Q-register M innehåller en funktion som både letar fram en pekare till den anropade funktionen och exekverar den. Ovanstående exempel blir då: MM Next Line$ Detta var ursprungssättet att anropa Tecos interna rutiner, innan M-X fanns. Detta lever också kvar genom att man lätt kan skapa egna funktioner som kan anropas med M-X genom att ge dem namn som börjar med MM. M-X skalar dock bort det inledande MM från namnet. OBS!! MM är dock lite "farlig" att använda, eftersom Q-registret M måste vara orört. Men det är ju möjligt att man använder det till något annat. Därför använder man oftast den första formen (med parenteser). Vi kanske vill göra en funktion som kan anropas med M-X. Funktionen ska t.ex. skriva ut värdet av Qa på skärmen. Gör såhär: :@I*/ Qa = / M.v MM Skriv Qa$ Den här funktionen kan då anropas med M-X Skriv Qa. Ett lite större exempel Vi tar den "klassiska" definitionen av fakultet. :@I*/ ^Y"E 1 ^' "# ^Y * (^Y - 1 M(M.m Fakultet$)) / M.v MM Fakultet$ Vi lägger in definitionen i MM-variabeln Fakultet. Som synes kan funktioner anropa sig själva (rekursivitet). Slut för idag Det här får räcka för den här gången. Alla givna exempel kan köras t.ex. i Minibufferten eller läggas in i din EMACS.INIT om du har en sån. Experimentera på! Nästa avsnitt kommer att handla om FS-flaggor, samt lite om hur tangenttryckningar tas om hand (interna koder, etc). Vi hörs! /Pär