Funkce dostupné v moderních interpreterech Loga

16. 10. 2007
Doba čtení: 9 minut

Sdílet

V dalším článku o jazyku Logo si popíšeme některé nestandardní funkce a procedury, které jsou dostupné v modernějších interpreterech Loga. Jedná se o funkce pro práci se soubory, ovládání textového terminálu, komunikaci po síti a dále o funkce podporující běh programu ve více vláknech a multitasking apod.

Obsah

1. Práce se soubory
2. Ovládání textového terminálu
3. Komunikace po síti
4. Internet a jeho využití v Turtle Tracks
5. Použití soketů v MSW Logu
6. Multitasking, vytváření a synchronizace vláken
7. Odkazy na další informační zdroje
8. Obsah následující části tohoto seriálu

1. Práce se soubory

Při programování se dříve či později setkáme s nutností načítat nějaké informace ze souborů či je naopak do souborů zapisovat. V jednodušších případech je možné použít přesměrování standardního vstupu a výstupu pomocí prostředků dostupných přes shell (příkazový řádek), ovšem v případech složitějších je nutné z vytvářeného programu přímo manipulovat se soubory a/nebo adresáři. Práce se soubory sice není v Logu plně standardizována, ovšem mnohá dnešní Loga jsou založena buď na StarLogu nebo UCB Logu, a proto používají i shodné a relativně obecné procedury, pomocí kterých je možné se soubory manipulovat (nebylo tomu tak vždy, stačí se podívat do manuálů některých starších implementací Loga, kde se to jen hemží systémově závislými souborovými funkcemi). Některé z procedur, jež jsou dostupné například v UCB Logu či MSW Logu, jsou vypsány v následující tabulce:

Procedura Význam
openread otevření souboru v režimu čtení
openwrite otevření souboru v režimu zápisu
openappend otevření souboru v režimu připojování (tj. zápis bez smazání předchozího obsahu)
openupdate otevření souboru v režimu čtení i zápisu
close uzavření souboru
setwrite soubor otevřený pomocí openwrite se stane standardním výstupním proudem (pro proceduru print apod.)
setread soubor otevřený pomocí openread či openupdate se stane standardním vstupním proudem
eofp vrací true či false podle toho, zda čtení dosáhlo konce souboru
eof? shodné s procedurou eofp

Zajímavé je, že nejsou použity žádné zástupné identifikace souborů (handles, jak tomu je například v céčku), ale soubor určený pro čtení, zápis či jinou operaci je jednoznačně identifikován svým jménem a případnou cestou, tedy řetězcem. V tomto případě je samozřejmě vhodné uložit jméno souboru do proměnné a místo řetězce se jménem používat zástupnou proměnnou. Ovšem v jednodušších případech se můžeme spokojit s opakovaným uváděním jména souboru, například:

; otevření souboru hello.txt
openwrite "hello.txt

; standardní výstupní operace jsou přesměrovány
; do právě otevřeného souboru
setwrite "hello.txt

; zápis do souboru pomocí funkce print
print [Hello world!]

; zrušení přesměrování pro standardní
; výstupní operace
setwrite []

; uzavření souboru a zápis všech změn
close "hello.txt

; nyní již print opět tiskne na standardní výstup
; nebo interní terminál interpreteru Loga
print [Write done] 

2. Ovládání textového terminálu

V předchozí části tohoto seriálu jsme si popsali funkce, které je možné použít pro čtení dat ze standardního vstupu a jejich zápis na standardní výstup. Jak standardní vstup tak i výstup je většinou představován textovým terminálem, který je používán i samotným interpreterem Loga. Většinou se práce s terminálem omezuje právě na vstup a výstup dat (čísel, řetězců, seznamů atd.). Při programování aplikací, které mají být v co největší míře interaktivní, například v jednoduchých hrách, však potřebujeme terminál přímo ovládat a zjišťovat například to, zda je stisknuta nějaká klávesa, měnit polohu textového kurzoru, nastavovat okraje terminálu, modifikovat barvu vypisovaného textu apod.

Jedná se o funkce, které jsou sice obecně nepřenositelné, tj. zdaleka ne všechny implementace Loga je podporují (může se jednat i o omezení dané použitým operačním systémem, kupodivu se většinou jedná o Loga běžící v systémech s grafickým uživatelským rozhraním), ovšem v některých případech může být znalost těchto procedur prakticky využita. Následuje výpis vybraných procedur určených pro ovládání terminálu:

Procedura Význam
keyp (UCB Logo) predikát pro test, zda je stisknuta nějaká klávesa
key? (UCB Logo) predikát pro test, zda je stisknuta nějaká klávesa
cleartext (UCB Logo) smazání obsahu textového terminálu
setcursor (UCB Logo) přesun kurzoru na souřadnice zadané dvojicí čísel (seznamem)
cursor (UCB Logo) funkce vracející aktuální souřadnice kurzoru ve formě seznamu (dvojice čísel)
setmargins (UCB Logo) nastavení levého a pravého okraje terminálu (opět je předávaná dvojice čísel uložená v seznamu)
settextcolor (UCB Logo) nastavení barvy popředí a pozadí (dvojice čísel v rozsahu 0–7 nebo pro některé terminály 0–15)
keyboardon (MSW Logo) registrace příkazů spuštěných ve chvíli, kdy je stisknuta nějaká klávesa

Následuje velmi jednoduchá ukázka ovládání terminálu, která byla odladěna v UCB Logu (Berkeley Logu), které je možné použít jak na Unixových systémech (samozřejmě včetně Linuxu), tak i pod DOSem a Microsoft Windows. Po spuštění procedury vigor je obsah terminálu smazán a na souřadnicích [10, 10] je zobrazena hvězdička. Touto hvězdičkou je možné pohybovat pomocí kláves [h], [j], [k], [l], tedy stejným způsobem, jako v textovém editoru vi (schválně jsem nepoužil ovládání pomocí kurzorových kláves, protože pak by program nemusel být přenositelný). Klávesou [q] je běh procedury a tím i celého programu ukončen. Význam slova forever je pravděpodobně zřejmý – jedná se o jednoduchý způsob zápisu „nekonečné“ smyčky, tj. smyčky, ve které se podmínka ukončení testuje uvnitř jejího těla a ne na začátku či na konci. Místo několika příkazů if je možné použít i knihovní proceduru case:

; pohyb kurzorem pomocí kláves [h] [j] [k] [l]
to vigor
    ; souřadnice kurzoru jsou umístěny
    ; ve dvojici proměnných x a y
    make "x 10
    make "y 10
    ; vymazání terminálu, nastavení kurzoru
    ; na souřadnice [10, 10] a vykreslení hvězdičky
    ; (je nutné použít "print" nebo "show" a ne "type")
    cleartext
    setcursor (list :x :y)
    print "*

    ; "nekonečná" smyčka, ve které se posunuje hvězdičkou
    forever [
        ; načtení znaku (s čekáním)
        make "c readchar
        ; posun hvězdičky: změna její souřadnice
        if :c="h [make "x :x - 1]
        if :c="l [make "x :x + 1]
        if :c="j [make "y :y + 1]
        if :c="k [make "y :y - 1]
        ; klávesou [q] se běh programu ukončí
        if :c="q [stop]
        ; vymazání terminálu, nastavení kurzoru
        ; na souřadnice [x, y] a vykreslení hvězdičky
        cleartext
        setcursor (list :x :y)
        print "*
    ]
end 

Druhý příklad je taktéž odladěn pro UCB Logo (Berkeley Logo). Po jeho spuštění jsou na textovém terminálu zobrazeny všechny barevné kombinace barvy pozadí a popředí textu (background, foreground). Vzhledem k tomu, že jsou podporovány barvy číslované 0–7, lze vytvořit celkem 8×8=64 kombinací. Připomínám, že procedura type neprovádí odřádkování (přechod kurzoru na nový řádek), kdežto procedura print ano. Zdrojový text tohoto jednoduchého demonstračního příkladu má tvar:

; vykreslení textu ve všech barevných kombinacích
to duha
    repeat 8 [
        make "foreground repcount - 1
        repeat 8 [
            make "background repcount - 1
            settextcolor :foreground :background
            type "***
        ]
        print []
    ]
end 

logo1701
Screenshot terminálu po spuštění demonstračního příkladu duha

3. Komunikace po síti

Některé implementace programovacího jazyka Logo umožňují tvořit programy, které mohou komunikovat po datových sítích; dnes typicky po Internetu, dříve například po síti AppleTalk (Mac OS) či po sítích založených na Ethernetu a Netware (většinou se jednalo o Loga pracující v DOSu nebo Windows 3.11). Mezi interpretery Loga vybavené možností komunikace po Internetu patří například už popisovaný Turtle Tracks nebo MSW Logo. Autor programu Turtle Tracks využívá při komunikaci po síti některé možnosti platformy Java, ve kterém je tato implementace Loga napsána. MSW Logo je určeno pro spouštění v systémech Microsoft Windows a k práci se sítí používá TCP stack dostupný v těchto operačních systémech. Především v tomto případě došlo ke zjednodušení volání mnoha procedur (díky vložené mezivrstvě mezi programem napsaným v Logu a API operačního systému), zejména v porovnání s céčkovými programy, které pro komunikaci využívají původní rozhraní (Windows API).

4. Internet a jeho využití v Turtle Tracks

Jak již bylo v předchozí kapitole napsáno, používá Turtle Tracks pro komunikaci po Internetu metody dostupné každému programu běžícímu v JVM (Java Virtual Machine). Jedná se především o metody objektu Socket, InputStreamReader a OutputStreamRe­ader. Pro účely programů napsaných v Logu jsou však tyto metody vhodným způsobem zjednodušeny, takže pro vlastní komunikaci v Logu jsou dostupné pouhé čtyři procedury (samozřejmě doplněné o standardní vstupně/výstupní procedury Loga), které jsou spolu se stručným popisem vypsány v následující tabulce:

Procedura Význam
loadurl načtení dat ze zadaného URL
opensocket otevření soketu (režim klienta) pro zadanou IP adresu nebo jméno serveru
openurl otevření síťového prostředku specifikovaného pomocí URL
serversocket vytvoření soketu pro práci v režimu serveru (naslouchání)

5. Použití soketů v MWS Logu

MSW Logo narozdíl od Turtle Tracks využívá implementaci protokolů z rodiny TCP/IP dostupnou na šestnáctibitových i třicetidvou­bitových operačních systémech Microsoft Windows. Pro programátory pracující s tímto interpreterem Loga je k dispozici deset procedur, které vhodným způsobem obalují poměrně komplikované aplikační programové rozhraní (API) Windows Socket. Všech deset procedur je vypsáno v následující tabulce:

Procedura Význam
netstartup zapne podporu práce se sítí v MSW Logu
netshutdown vypne podporu práce se sítí v MSW Logu
netaccepton povolení přijímaní dat přes sokety (režim serveru)
netacceptoff zákaz přijímaní dat přes sokety
netacceptrece­ivevalue procedura vrátí data přijatá přes soket
netacceptsendvalue procedura pro vysílání dat (typicky řetězce nebo i seznamu)
netconnecton povolení vysílání dat přes sokety (režim klienta)
netconnectoff zákaz vysílání dat přes sokety
netconnectsendvalue vysílání dat přes otevřený soket
netconnectrece­ivevalue příjem dat přes otevřený soket

V dalším demonstračním příkladu je ukázána jednoduchá komunikace pomocí soketů přes TCP port 5124. Číslo zvoleného portu je vyšší než 1024, proto je program možné spustit i z běžného uživatelského účtu. Pokud by nedošlo ke spojení (například v případě omezení čísel portů na proxy serveru či firewallu), je možné na obou stranách linky vyzkoušet některé běžně povolené porty, například 8080 apod.:

; Start up the network
netstartup

; Wait for someone to connect to you on socket 5124
show netaccepton 5124 [print [Ok to Send Again]] []
true

; Connect to MyMachineName on socket 5124 (myself)
show netconnecton "MyMachineName 5124 [] [print netconnectreceivevalue]
true

; Wait little for connection to establish
wait 100
Ok to Send Again
Ok to Send Again
Ok to Send Again

; Send some data
show netacceptsendvalue [Who are you that called me]
true

; Wait a little before we shut things down
wait 100
Who are you that called me

; Stop the network
netconnectoff
netacceptoff
netshutdown 

6. Multitasking, vytváření a synchronizace vláken

V implementaci Loga Turtle Tracks je podporován i běh více vláken (threads), která mezi sebou mohou být synchronizována pomocí kritických sekcí a bariér). Každé vlákno, které může být vytvořeno procedurami thread, threadapply apod., má přiřazen jednoznačný identifikátor (jedná se o návratovou hodnotu těchto procedur). Jak bariéry, tak i kritické sekce jsou pojmenovány, přičemž interně si Turtle Tracks jejich jména uchovává v hešovací tabulce. To znamená, že i když je v Logu jméno reprezentováno dvěma různými řetězci (se stejným obsahem), stále se bude jednat o jednu a tutéž bariéru či kritickou sekci, protože klíč do hešovací tabulky zůstane stejný.

Procedura Význam
THREAD seznam, který je této proceduře předán, je spuštěn v novém vlákně (typicky se jedná o volání funkce)
THREADAPPLY seznam, který je této proceduře předán, je vyhodnocen zadaným labda výrazem v novém vlákně
THREADAPPLYID shodné s předchozí procedurou, ale navíc se předává identifikátor vlák­na
THREADTERMINATE ukončení vlákna se specifikovaným identifikátorem
CURRENTTHREAD tato funkce vrací identifikátor běžícího vlákna
BARRIER vytvoření pojmenované bariéry se zadanou kapacitou (celé kladné číslo) a kódem, který se má v případě nezablokované bariéry provést
CRITICAL vytvoření pojmenované kritické sekce a pokus o spuštění kódu v této sekci (pokud již v dané sekci neběží jiné vlákno)
STOPTHREAD zastavení vlákna a případné zaslání informace o chybě

bitcoin_skoleni

7. Odkazy na další informační zdroje

  1. Young People's Logo Association:
    The Logo Library
  2. StarLogo Pages at MIT,
    http://el.www­.media.mit.edu/grou­ps/el/Projects/star­logo/
  3. StarLogo Pages at Northwestern University,
    http://ccl.nor­thwestern.edu/cm/star­logo/
  4. NETLogo Pages,
    http://ccl.nor­thwestern.edu/ne­tlogo/
  5. MSWLogo,
    http://www.sof­tronix.com/lo­go.html

8. Obsah následující části tohoto seriálu

V osmnácté části seriálu o programovacím jazyce Logo si ukážeme tvorbu animací, která je podporovaná například ve známém MSW Logu. Výklad bude samozřejmě doprovázen několika praktickými demonstračními příklady.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.