Seppo Mustonen: Sukrojen ohjelmointi Survossa

5. Hapuilukoodit, tulostus ja kohdistimen liikuttelu

Kun sukro tutkii toimituskentän sisältöä (esim. käyttäjän siihen kirjoittamia tietoja tai Survon operaatioilla saatuja tuloksia), sen pitää löytää tarvittujen tietojen paikat ja poimia tiedot sukromuistiin jatkotoimenpiteitä varten. Näkevään käyttäjään verattuna sukrot ovat sokeita; niiden on yritettävä hapuilemalla saavuttaa etsimänsä.
     Survoon on tätä varten lisätty useita näppäintoimintoja, joita sukrokielessä vastaavat omat sanansa, eräänlaiset hapuilukoodit. Samoin tarvitaan käskyjä, joilla löydetyt tiedot siirretään toimituskentästä sukromuistiin ja vastaavasti sukromuistista takaisin toimituskenttään. Myös toimituskentässä liikkumista ja kohdistimen sijaintia on kyettävä seuraamaan.

Hapuilukoodeja

{find <merkki>} (näppäinyhdistelmä {pre} C <merkki>) etsii annetun merkin seuraavan sijaintikohdan nykyisellä rivillä. Kohdistin siirtyy merkin kohdalle. Ellei merkkiä löydy kohdistin jää paikalleen.
     {next word} (näppäimet {pre} W) siirtää kohdistimen nykyisen rivin seuraavan sanan alkuun. Jos kohdistin osoittaa jo rivin viimeistä kuvaruudulla näkyvää sanaa, se jää paikoilleen.
     {find Wi} etsii aivan vastaavasti muistipaikassa Wi olevan sanan ensimmäisen merkin nykyiseltä riviltä.
     {save word Wi} tallettaa kohdistimen koskettaman sanan (välilyönnit toimivat erottimina) muistipaikkaan Wi. Jos kohdistin osoittaa (tyhjää) välilyöntiä, tämä tallentuu sukromuistiin.
     {save char Wi} tallettaa kohdistimen osoittaman merkin muistipaikkaan Wi.
     {save line Wi} tallettaa toimituskentän rivin sen osan, joka on kohdistimesta oikealle, muistipaikkaan Wi . Rivin lopussa olevia välilyöntejä ei talleteta.

Tulostuskoodeja

Kaikki sukro-ohjelmassa oleva teksti, joka ei ole aaltosuluissa, jäljentyy toimituskenttään aivan kuin käyttäjä itse kirjoittaisi sen. Esim. lisäystila ja valittu tekstin tehostustapa (väri) vaikuttaa tulokseen. Sukrot saattavat kirjoittaa väliin myös sukromuistiin kerääntyneitä tietoja esim. ehdollisesti sen mukaan, millaisia tuloksia jossain sovelluksessa on saatu.

{print Wi} kirjoittaa muistipaikan Wi sisällön kohdistimen osoittamasta paikasta eteenpäin. Kohdistin siirtyy vastaavasti. Mahdolliset kirjoitettavalla kohdalla olevat varjomerkit (värit) eivät muutu. Lisäystila ei vaikuta kirjoittamiseen, vaan kirjoitus peittää aikaisemman tekstin. Toiminta on samankaltaista kuin toimituskenttään tulostavilla Survon operaatioilla.
     {write Wi} toimii kuten {print Wi}, mutta se käyttäytyy niin kuin käyttäjä itse kirjoittaisi saman tekstin. Siis esim. valittu kirjoitustehostus (väri) ja lisäystila otetaan huomioon. Samoin tekstin sisältämät sanat siirtyvät automaattisesti seuraavalle riville, elleivät mahdu nykyisen näkyvään osaan.

Kohdistimen paikkaa ja liikuttelua koskevia koodeja

REF-napin (koodi {ref}) ja nuolinappien ({r},{l},{u},{d}) ohella sukroille on tarjolla muutamia lisämahdollisuuksia.
     {save cursor Wi,Wj} tallettaa kohdistimen paikan siten, että rivinumero menee muistipaikkaan Wi ja sarakenumero paikkaan Wj .
     {save corner Wi,Wj} tallettaa kuvaruudussa näkyvän toimituskentän osan ensimmäisen rivin ja sarakkeen numerot vastaavalla tavalla.
     {jump Wi,Wj,Wk} siirtää kohdistinta toimituskentässä siten, että kentän rivi Wi näkyy ensimmäisenä kuvaruudulla ja itse kohdistin asettuu rivin Wj sarakkeeseen Wk . Parametrien Wi, Wj ja Wk paikalla voi olla myös kokonaislukuja.
     {jump Wi,Wj,Wk,Wh} siirtää ikkunaa ja kohdistinta niin, että kuvaruudussa näkyy ensimmäisenä rivi Wi ja sarake Wk . Kohdistin sijoittuu rivin Wj sarakkeeseen Wh . Parametreina saa olla myös kokonaislukuja.
     jump-koodin rakenne vastaa läheisesti Survon GOTO-käskyä mutta käyttäjälle näkymättömällä tavalla.

Esim. jos kohdistimen ja ikkunan paikka talletetaan käskyparilla

    {save corner Wrivi1,Wsarake1}
    {save cursor Wrivi,Wsarake}   ,
sama ikkunan asema ja kohdistimen paikka tavoitetaan myöhemmin käskyllä
    {jump Wrivi1,Wrivi,Wsarake1,Wsarake} .
Huomaa, että vastaava asia hoidetaan yksinkertaisimmin tallettamalla paikka {ref}-koodilla ja palaamalla takaisin samalla {ref}-koodilla. Vasta kun käytetään samanaikaisesti useita viitepaikkoja, nyt esitetty keino on tarpeen.

Esimerkki 1: Puutteelliset vuosiluvut

Toimituskentässä on lista päiväyksiä, joissa vuosiluvusta on joskus jätetty kaksi ensimmäistä numeroa pois. Tehdään sukro VUODET, joka täydentää ko. merkinnät. Sukron tulee myös huomauttaa virheellisistä päiväyksistä, joissa ei ole riittävä määrä pisteitä.
   8  1 SURVO 84C EDITOR Wed May 01 16:41:48 1991         D:\SUOPAS\ 120  80 0
   1 *
   2 *Päiväykset:
   3 */VUODET_
   4 *27.12.1989
   5 *1.3.87
   6 *2511.1990
   7 *1.5.91
   8 *12.7.67
   9 *

Koska merkinnät ovat erimittaisia, vuosilukua tulee etsiä aina rivin alusta toisen pisteen perästä. Listan oletetaan päättyvän tyhjään riviin. Sukro VUODET ohjelmoidaan silloin esim. näin:
  15  1 SURVO 84C EDITOR Wed May 01 16:45:24 1991         D:\SUOPAS\ 120  80 0
   9 *
  10 *TUTSAVE VUODET_
  11 *{tempo -1}{init}
  12 / Siirry uudelle riville:
  13 + A: {R}
  14 / Talleta rivin ensimmäinen sana:
  15 *{save word W1}
  16 / Jos sana on tyhjä, luettelo on käyty läpi. Lopeta:
  17 - if W1 '=' {sp} then goto Loppu
  18 / Etsi ensimmäinen piste ja talleta se:
  19 *{find .}{save char W1}
  20 / Jos pistettä ei löytynyt, päiväys on virheellinen:
  21 - if W1 '<>' . then goto Virhe
  22 / Siirry askel oikealle. Etsi ja talleta seuraava piste:
  23 *{r}{find .}{save char W1}
  24 / Jos pistettä ei löytynyt, päiväys on virheellinen:
  25 - if W1 '<>' . then goto Virhe
  26 / Poista piste vuosiluvun edestä kirjoittamalla välilyönti:
  27 * {}
  28 / Talleta vuosiluku. Kirjoita piste takaisin paikalleen:
  29 *{save word W1}{l}.
  30 / Jos vuosiluku on yli 99, ei muuteta. Siirrytään seuraavaan tapaukseen:
  31 - if W1 > 99 then goto A
  32 / Koska vuosiluku alle 100, lisätään siihen 1900 ja kirjoitetaan se:
  33 *{W1=W1+1900}{print W1}{goto A}
  34 / Virheellisissä tapauksissa kirjoitetaan huomautus rivin loppuun:
  35 + Virhe: {line end}  Virheellinen päiväys{goto A}
  36 + Loppu: {tempo +1}{end}
  37 *

Kun sukro aktivoidaan rivillä 3, syntyy korjattu luettelo:
   8  1 SURVO 84C EDITOR Wed May 01 16:48:12 1991         D:\SUOPAS\ 120  80 0
   1 *
   2 *Päiväykset:
   3 */VUODET_
   4 *27.12.1989
   5 *1.3.1987
   6 *2511.1990  Virheellinen päiväys
   7 *1.5.1991
   8 *12.7.1967
   9 *

Esimerkki 2: Toimituskentän rivien lukumäärä

Sukro RIVILUKU etsii toimituskentän rivien lukumäärän siirtämällä kohdistinta alaspäin niin kauan, ettei se enää liiku. Tämä havaitaan tarkkailemalla rivinumeroa.
  10  1 SURVO 84C EDITOR Wed May 01 17:24:42 1991         D:\SUOPAS\ 120  80 0
  39 *
  40 *TUTSAVE RIVILUKU
  41 / def Wrivi=W1 Wsarake=W2 Wrivi2=W3 Wsarake2=W4
  42 *{tempo -1}{init}
  43 / Pannaan paikka muistiin. Nykyinen rivi on Wrivi:
  44 *{ref}{save cursor Wrivi,Wsarake}
  45 / Siirrytään seuraavan rivin alkuun;
  46 + A: {R}
  47 / Talletetaan uusi rivinumero Wrivi2
  48 *{save cursor Wrivi2,Wsarake2}
  49 / Jos rivinumerot ovat samat, ollaan kentän lopussa:
  50 - if Wrivi = Wrivi2 then goto L
  51 / Muuten päivitetään Wrivi ja yritetään uudelleen:
  52 *{Wrivi=Wrivi2}{goto A}
  53 / Palataan alussa merkittyyn paikkaan ja "unohdetaan" se:
  54 + L: {ref}{ref}
  55 / Siirrytään (komento)rivin loppuun ja kirjoitetaan rivien lukumäärä:
  56 *{line end}  ={print Wrivi}
  57 *{tempo +1}{end}
  58 *
  59 */RIVILUKU_ =120
  60 *

Rivillä 59 on näytetty, miten sukro kirjoittaa vastauksensa. Sukroa RIVILUKU ei kuitenkaan käytännössä tarvita, sillä sukrokieleen kuuluu käsky {save dim Wi,Wj}, joka tallettaa suoraan sukromuistiin toimituskentän rivien ja sarakkeiden määrät.

Esimerkki 3: Sanan kääntäminen nurinpäin

Sukro NURIN kääntää seuraavan rivin alkuun kirjoitetun sanan kirjaimet päinvastaiseen järjestykseen ja kirjoittaa tuloksensa muodossa:
   7  1 SURVO 84C EDITOR Wed May 01 17:50:39 1991         D:\SUOPAS\ 120  80 0
  62 *
  63 */NURIN 
  64 *SUKROMUISTI käännettynä nurin on ITSIUMORKUS.
  65 *

Sukron listaus on seuraavanlainen:
  14  1 SURVO 84C EDITOR Wed May 01 17:51:52 1991         D:\SUOPAS\ 120  80 0
  65 *
  66 *TUTSAVE NURIN_
  67 / def Wnurin=W1 Wkirjain=W2
  68 *{tempo -1}{init}{line start}
  69 / Siirrytään seuraavan rivin alkuun, jolla on tutkittava sana:
  70 *{R}
  71 / Tyhjennetään Wnurin, johon kootaan nurin kirjoitettu sana:
  72 *{Wnurin=}
  73 / Talletetaan kohdistimen osoittama kirjain:
  74 + A: {save char Wkirjain}
  75 / Jos kirjaimen paikalla on väli {sp}, sana on päättynyt:
  76 - if Wkirjain '=' {sp} then goto L
  77 / Kopioidaan uusi kirjain aikaisemman tuloksen eteen:
  78 *{Wnurin=Wkirjain&Wnurin}
  79 / Siirrytään askel oikealle ja mennään tutkimaan seuraavaa kirjainta:
  80 *{r}{goto A}
  81 / Poistetaan alkuperäisen sanan perästä mahdolliset muut tekstit:
  82 + L: {erase}{erase}
  83 / Kirjoitetaan vastaus:
  84 * käännettynä nurin on {print Wnurin}.{tempo +1}{end}
  85 *

Sukrossa käytetään (rivillä 78) käskyä {Wi=Wj&Wk} joka kopioi muistipaikkojen Wj ja Wk peräkkäin asetetut sisällöt paikkaan Wi .

Sukrojen ohjelmointi Survossa - Seppo Mustonen 1991
  1. Johdanto
  2. Esimerkki
  3. Sukrokielen koodisanoja
  4. Sukromuisti
  5. Hapuilukoodit, tulostus ja kohdistimen liikuttelu
  6. Sukrojen aloittaminen ja kytkeminen toisiinsa
  7. Ehdolliset toiminnat
  8. Käyttäjän vuorovaikutus
  9. Aritmetiikka ja muistin välitön hallinta
  10. Sukrotiedostot
  11. Sukrojen lajit
  12. Sukrojen laatiminen käytännössä
  13. Virhetilanteet
  14. Näytesovelluksia
Liite: Sukrokielen koodisanat