Hlavní navigace

Jazyk Shine: funkce, datové typy a práce s řetězci

4. 4. 2024
Doba čtení: 23 minut

Sdílet

 Autor: Depositphotos
V dalším článku budou popsány funkce s proměnným počtem parametrů, datové typy tabulka a pole, práce s řetězci (včetně jejich interpolace) a nezapomeneme se zmínit ani o některých vlastnostech překladače shinec.

Obsah

1. Funkce s proměnným počtem parametrů

2. Funkce s povinným parametrem následovaným proměnným počtem parametrů

3. Předání tabulky do funkce

4. Předání pole do funkce

5. Rozdíly mezi tabulkou a polem

6. Odlišná forma zápisu tabulek

7. Od tabulek k polím s plnohodnotnými prvky nil

8. Manipulace s poli: operace push a pop

9. Manipulace s poli: operace shift a unshift

10. Převod obsahu celého pole na řetězec operací join

11. Rozdíly mezi řetězci v jazycích Lua a Shine

12. Interpolace řetězců

13. Operátory v jazyce Shine

14. Zobrazení naparsovaného zdrojového kódu převedeného do formy stromu

15. Zobrazení bajtkódu

16. Zobrazení pseudokódu používaného virtuálním strojem s JITem

17. Obsah závěrečné části

18. Repositář s demonstračními příklady

19. Odkazy na relevantní články a seriály na Rootu

20. Odkazy na Internetu

1. Funkce s proměnným počtem parametrů

V jazyce Lua je umožněno vytvářet funkce akceptující proměnný počet parametrů. Tato technika byla v programovacím jazyce Shine zjednodušena, takže je možné pojmenovat parametr, do kterého se uloží všechny nepovinné parametry tak, jakoby se jednalo o tabulku (interně se také jedná o tabulku). Před jméno tohoto parametru je nutné zapsat trojici teček. V jazyce Lua je naproti tomu použita pouze trojice teček, ovšem přístup k hodnotám je složitější.

Podívejme se na jednoduchý příklad, v němž budeme sčítat hodnoty všech předaných parametrů. Může jich být libovolný počet a nemusíme předat ani jeden parametr:

function sum(...args)
    s = 0
 
    for i, v in ipairs(args) do
        s = s + v
    end
 
    return s
end
 
s = sum(1, 2, 3, 4)
print(s)
 
s = sum(1)
print(s)
 
s = sum()
print(s)

Po spuštění tohoto příkladu se zobrazí očekávané výsledky:

10
1
0

2. Funkce s povinným parametrem následovaným proměnným počtem parametrů

Samozřejmě je možné v definici funkce zkombinovat povinné parametry s proměnným počtem parametrů. Základní koncept je ukázán na dalším demonstračním příkladu, v němž je definována funkce s jedním povinným parametrem, za nímž mohou následovat parametry nepovinné:

function mac(coefficient, ...args)
    s = 0
 
    for i, v in ipairs(args) do
        s = s + v * coefficient
    end
 
    return s
end
 
s = mac(1.0, 1, 2, 3, 4)
print(s)
 
 
s = mac(0.5, 1, 2, 3, 4)
print(s)
 
 
s = mac(2.0, 1, 2, 3, 4)
print(s)

Výsledky opět odpovídají očekávání – vždy se jedná o součet hodnot 1, 2, 3 a 4, ovšem pokaždé s jinou váhou:

10
5
20

Pro úplnost se ještě podívejme na funkci s jedním parametrem s výchozí hodnotou (pokud není příslušný argument zadán), za nímž může následovat libovolný počet parametrů:

function mac(coefficient=1.0, ...args)
    s = 0
 
    for i, v in ipairs(args) do
        s = s + v * coefficient
    end
 
    return s
end
 
s = mac(1.0, 1, 2, 3, 4)
print(s)
 
 
s = mac(0.5, 1, 2, 3, 4)
print(s)
 
 
s = mac(2.0, 1, 2, 3, 4)
print(s)
 
 
s = mac(10, 20)
print(s)
 
 
s = mac(10)
print(s)

Takto budou vypadat výsledky pro všechny výše uvedené kombinace argumentů předaných do funkce nazvané mac:

10
5
20
200
0

3. Předání tabulky do funkce

Připomeňme si, že jak v jazyce Lua, tak i v jazyce Shine je základním kontejnerem (tedy datovou strukturou navrženou tak, že může obsahovat další hodnoty) tabulka (table), která je interně rozdělena na část s polem a část se slovníkem. Hodnotami uloženými v poli se prochází pomocí ipairs nebo s využitím indexů ve formě selektorů, zatímco s hodnotami uloženými ve slovníkové části se prochází pomocí pairs nebo s využitím klíčů ve formě selektorů.

Tabulku je pochopitelně možné předat při volání funkce a v případě jazyka Shine můžeme uvedením typu zajistit, že se nebude předávat hodnota odlišného typu. Funkci pro výpočet sumy hodnot tedy můžeme upravit tak, že bude akceptovat jediný povinný parametr typu tabulka, což je ostatně patrné i z toho, s jakým argumentem se tato funkce volá:

function sum(values is Table)
    s = 0
 
    for i, v in ipairs(values) do
        s = s + v
    end
 
return s
end
 
s = sum({1, 2, 3, 4})
print(s)
 
s = sum({1})
print(s)
 
s = sum({})
print(s)
Poznámka: povšimněte si, že se této funkci skutečně předává tabulka.

Výsledky:

10
1
0

4. Předání pole do funkce

Pole, tedy přesněji řečeno typ Array, je v jazyce Shine podtypem tabulky, takže do funkce sum můžeme přímo předat i pole:

function sum(values is Table)
    s = 0
 
    for i, v in ipairs(values) do
        s = s + v
    end
 
    return s
end
 
s = sum([1, 2, 3, 4])
print(s)
 
s = sum([1])
print(s)
 
s = sum([])
print(s)

V takovém případě je ovšem většinou vhodnější povolit předávání pouze polí a nikoli obecných tabulek. Změníme tedy typ parametru funkce sumTable na Array:

function sum(values is Array)
s = 0
 
for i, v in ipairs(values) do
    s = s + v
end
 
return s
end
 
s = sum([1, 2, 3, 4])
print(s)
 
s = sum([1])
print(s)
 
s = sum([])
print(s)

Nyní již nebude možné do takto upravené funkce předat obecnou tabulku:

function sum(values is Array)
    s = 0
 
    for i, v in ipairs(values) do
        s = s + v
    end
 
    return s
end
 
s = sum({1, 2, 3, 4})
print(s)
 
s = sum({1})
print(s)
 
s = sum({})
print(s)

V tomto případě se ohlásí chyba:

Error: 23_array_type_2.shn:11: bad argument #1 to 'sum' (Array expected got Table)
stack traceback:
        [C]: in function 'error'
        23_array_type_2.shn:1: in function 'sum'
        23_array_type_2.shn:11: in main chunk
        [string "shine"]: in main chunk
        [string "shine"]: in main chunk
        [C]: at 0x56196cdf9510

5. Rozdíly mezi tabulkou a polem

V předchozím textu jsme se již zmínili o tabulkách a polích. Připomeňme si nejdříve, jak se pracuje s tabulkami. V první řadě se jedná o slovníky spojené s polem; interně jsou tedy některé prvky vybírány přes klíč a jiné přes index. To má více důvodů, jedním z nich je snaha o větší efektivitu jak z pohledu paměti, tak i výpočetní náročnosti. Jednoduchý slovník může v jazyce Lua vypadat následovně:

t = {foo=1, bar=2.5, baz="*"}
 
for k, v in pairs(t) do
    print(k, v)
end

Naprosto stejně lze se slovníkem pracovat v jazyku Shine:

t = {foo=1, bar=2.5, baz="*"}
 
for k, v in pairs(t) do
    print(k, v)
end

Výsledek:

baz     *
foo     1
bar     2.5

Jedním z problematických rysů tabulek je fakt, že nelze uložit hodnoty nil:

t = {foo=1, bar=nil, baz="*"}
 
for k, v in pairs(t) do
    print(k, v)
end

Nyní se vypíšou pouze dva prvky z tabulky a nikoli prvky tři:

foo     1
baz     *

Ovšem naprosto stejně se chová i jazyk Shine:

t = {foo=1, bar=nil, baz="*"}
 
for k, v in pairs(t) do
    print(k, v)
end
Poznámka: toto chování je odlišné od Pythonu, v němž můžeme bez problémů psát:
x={"foo":1, "bar":None, "baz":"*"}
 
for k,v in x.items():
    print(k,v)

S výsledky:

foo 1
bar None
baz *

6. Odlišná forma zápisu tabulek

Při zápisu definice tabulek se v programovacím jazyku Lua používá jako oddělovač prvků (či dvojic klíč-hodnota) čárka. V jazyce Shine je tento zápis samozřejmě taktéž podporován a navíc je možné jednotlivé prvky jednoduše oddělit prázdným řádkem tak, jak je to ukázáno v dalším demonstračním příkladu:

t = {
    foo=1
    bar=true
    baz="*"
}
 
for k, v in pairs(t) do
    print(k, v)
end

Výsledek po spuštění v interpretru jazyka Shine:

baz     *
foo     1
bar     true

Naproti tomu standardní interpret jazyka Lua tento zápis nerozpozná:

lua: 27_table_3.lua:3: '}' expected (to close '{' at line 1) near 'bar'

7. Od tabulek k polím s plnohodnotnými prvky nil

Připomeňme si, že do tabulek není možné uložit hodnotu nil, a to ani do „polní“ části tabulek. Ostatně si to můžeme ověřit spuštěním tohoto skriptu, v jehož tabulce má poslední prvek právě hodnotu nil:

t = {"foo", 2, "bar", true, nil}
 
for i, v in ipairs(t) do
    print(i, v)
end

Nezávisle na tom, zda použijeme interpret jazyka Lua či Shine, dostaneme stejné výsledky – pole se čtyřmi prvky:

1       foo
2       2
3       bar
4       true
Poznámka: ve skutečnosti bude situace ještě horší, pokud nil uvedeme jako například třetí prvek:
t = {"foo", 2, nil, "bar", true, nil}
 
for i, v in ipairs(t) do
    print(i, v)
end

Nyní bude výsledkem zdánlivě dvouprvková tabulka:

1       foo
2       2

Ovšem zbylé prvky jsou schovány ve „slovníkové“ části dostupné přes iterátor pairs:

t = {"foo", 2, nil, "bar", true, nil}
 
for k, v in pairs(t) do
    print(k, v)
end

Výsledky:

1       foo
2       2
4       bar
5       true

Naproti tomu pole v jazyku Shine hodnotu nil obsahovat mohou:

t = ["foo", 2, "bar", true, nil]
 
for i, v in ipairs(t) do
    print(i, v)
end

Výsledky to dokazují:

0       foo
1       2
2       bar
3       true
4       nil

Prvky nil mohou být v poli kdekoli, tedy na začátku, uprostřed i na konci:

t = [nil, "foo", 2, nil, "bar", true, nil]
 
for i, v in ipairs(t) do
    print(i, v)
end

Pole se i v tomto případě bude stále chovat jako běžné pole:

0       nil
1       foo
2       2
3       nil
4       bar
5       true
6       nil

8. Manipulace s poli: operace push a pop

S poli, tedy s hodnotami typu Array lze provádět několik operací, které jsou dostupné formou metod. Mezi dvě užitečné operace patří push a pop. Operace push připojuje prvek na konec pole, tedy na index odpovídající #pole, kde operátor # vrací délku pole či tabulky. A naopak operace pop čte a odstraňuje prvky z konce pole: na pole tedy můžeme nahlížet jako na zásobník, jehož TOS (Top Of Stack) je umístěn na konci pole:

function print_array(t)
    for i, v in ipairs(t) do
        print(i, v)
    end
    print("-------------------")
end
 
t = []
 
t.push("foo")
t.push("bar")
t.push("baz")
print_array(t)
 
for i = 0, 2 do
    t.pop()
    print_array(t)
end

Výsledky:

0       foo
1       bar
2       baz
-------------------
0       foo
1       bar
-------------------
0       foo
-------------------
-------------------

9. Manipulace s poli: operace shift a unshift

Mezi další dvě operace s poli patří shift a unshift, které ovšem mohou být poněkud matoucí (jejich význam je totiž jakoby prohozen). Operace unshift přidává prvek na začátek pole a odsouvá další prvky na vyšší indexy, zatímco operace shift přečte první prvek z pole, odstraní ho a posune všechny ostatní prvky o index níže. Ostatně celá funkce obou operací je patrná z dalšího demonstračního příkladu:

function print_array(t)
    for i, v in ipairs(t) do
        print(i, v)
    end
    print("-------------------")
end
 
t = []
 
t.unshift("foo")
t.unshift("bar")
t.unshift("baz")
print_array(t)
 
for i = 0, 2 do
    t.shift()
    print_array(t)
end

Nejprve se vypíše pole naplněné trojicí operací unshift a následně se postupně prvky z pole zase čtou a odstraňují:

0       baz
1       bar
2       foo
-------------------
0       bar
1       foo
-------------------
0       foo
-------------------
-------------------

10. Převod obsahu celého pole na řetězec operací join

Podobně jako v dalších programovacích jazycích (Python atd.) je možné celé pole, resp. v již zmíněném Pythonu spíše seznam, převést na řetězec, a to konkrétně operací typu join. V některých jazycích je tato operace představována metodou třídy string, ovšem v jazyce Shine se jedná o metodu třídy array, tj. její volání má prohozeného příjemce a argument:

t = []
 
for i = 0, 10 do
    t.push(i)
end
 
joined = t.join(",")
print(joined)
 
joined = t.join(" ")
print(joined)
 
joined = t.join("; ")
print(joined)

Výsledky by měly vypadat takto:

0,1,2,3,4,5,6,7,8,9,10
0 1 2 3 4 5 6 7 8 9 10
0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10

11. Rozdíly mezi řetězci v jazycích Lua a Shine

I když jazyk Shine do značné míry vychází z jazyka Lua, jsou některé jazykové konstrukce diametrálně odlišné. Asi nejvíce je to patrné na operátoru určeném pro spojení dvou řetězců. V jazyce Lua se tento operátor zapisuje formou dvou teček a je asociativní zleva. To znamená, že můžeme velmi snadno spojit tři řetězce a vypsat výsledek tohoto spojení (tedy nový řetězec):

s1 = "Hello"
s2 = "\x20"
s3 = 'world'
 
print(s1 .. s2 .. s3)

Výsledkem bude podle očekávání zpráva

Hello world

Ovšem naprosto stejný kód, tentokrát spuštěný v interpretru jazyka Shine, vypíše odlišnou hodnotu:

s1 = "Hello"
s2 = "\x20"
s3 = 'world'
 
print(s1 .. s2 .. s3)

Nyní je totiž operátor .. chápán jako specifikace rozsahu u „řezů“ (slices):

$ shine 32_string.shn 
 
Range(Hello, Range( , world))

Ve Shine se pro spojení řetězců používá odlišný operátor, a to konkrétně tilda. Kód je tedy nutné přepsat do této podoby:

s1 = "Hello"
s2 = "\x20"
s3 = 'world'
 
print(s1 ~ s2 ~ s3)
Poznámka: tato nekompatibilita je poměrně závažná v praxi.

12. Interpolace řetězců

Podobně jako v mnoha moderních programovacích jazycích lze i ve Shine využít takzvanou interpolaci řetězců. Řetězec je v tomto případě nutné chápat jako šablonu, do které se doplňují hodnoty konstant, výrazů a proměnných. Hodnoty (výrazy), které se mají do řetězce „propsat“, je nutné zapsat mezi složené závorky a navíc musí být před levou složenou závorkou znak %. Navíc platí podmínka, že aby interpolace proběhla, musí být řetězce uloženy ve dvojitých uvozovkách:

s1 = "Hello"
s2 = 'world'
 
print("%{s1} %{s2}!")

Tento skript po svém spuštění vypíše:

Hello world!

Pokud ovšem řetězce uložíme do jednoduchých uvozovek (apostrofů), interpolace neproběhne:

s1 = "Hello"
s2 = 'world'
 
print('%{s1} %{s2}!')

Výsledkem bude v tomto případě výpis původního řetězce:

%{s1} %{s2}!
Poznámka: v tomto ohledu se tedy Shine podobá shell skriptům.

13. Operátory v jazyce Shine

Již v předchozí kapitole jsme narazili na nový význam některých operátorů. Proto si všechny operátory podporované tímto programovacím jazykem vypišme, a to jak s uvedením priority (od nejvyšší k nejnižší), tak i asociativity. Většina operátorů existuje již v jazyce Lua, některé však dostaly odlišný význam a najdeme zde i nové operátory (unpack atd.):

Operátor Priorita Asociativita Stručný popis
#_ 14 zprava doleva délka pole/tabulky
       
** 13 zprava doleva umocnění
       
not_ 12 zprava doleva logická negace
!_ 12 zprava doleva logická negace
~_ 12 zprava doleva bitová negace
       
* 11 zleva doprava součin
/ 11 zleva doprava podíl
% 11 zleva doprava zbytek po dělení (modulo)
       
+ 10 zleva doprava součet
~ 10 zleva doprava spojení řetězců
10 zleva doprava rozdíl
.. 10 zprava doleva operace range (slice)
       
>>> 9 zleva doprava aritmetický posun doprava
>> 9 zleva doprava bitový posun doprava
<< 9 zleva doprava bitový posun doleva
       
& 8 zleva doprava bitová operace AND
       
^ 7 zleva doprava bitová operace XOR
       
| 6 zleva doprava bitová operace OR
       
< 5 zleva doprava relační operace na relaci menší než
> 5 zleva doprava relační operace na relaci větší něž
<= 5 zleva doprava relační operace na relaci menší nebo rovno
>= 5 zleva doprava relační operace na relaci větší nebo rovno
       
is 4 zleva doprava typová shoda
as 4 zleva doprava typová koerce
       
== 3 zleva doprava porovnání na rovnost
!= 3 zleva doprava porovnání na nerovnost
~~ 3 zleva doprava operace match
!~ 3 zleva doprava negace operace match
       
and 2 zleva doprava logický součin
       
or 1 zleva doprava logický součet
…_ 1 zprava doleva operace unpack

14. Zobrazení naparsovaného zdrojového kódu převedeného do formy stromu

V závěrečné části dnešního článku se podívejme na některé možnosti nabízené překladačem shinec (viz „c“ na konci tohoto jména). Při použití přepínače -p se zobrazí zdrojový kód po svém naparsování a převodu do formy stromu. Nejedná se o čistý AST ale spíše o derivační strom s podrobnějšími informacemi o tom, na kterém místě v původním kódu je uzel (uzly) uložen.

Ukažme si to na následujícím zdrojovém kódu, který obsahuje jediný výraz:

x = 1 + 2

Derivační strom si necháme zobrazit tímto příkazem:

$ ./shinec -p expression1.shn

A výsledkem by měla být tato (relativně dobře čitelná) struktura:

--Shine parse tree:
{
    "type": "Chunk",
    "body": [
        {
            "type": "ExpressionStatement",
            "line": 1,
            "expression": {
                "type": "AssignmentExpression",
                "oper": "=",
                "right": [
                    {
                        "right": {
                            "type": "Literal",
                            "line": 1,
                            "value": 2
                        },
                        "left": {
                            "type": "Literal",
                            "line": 1,
                            "value": 1
                        },
                        "type": "BinaryExpression",
                        "operator": "+",
                        "line": 1
                    }
                ],
                "left": [
                    {
                        "type": "Identifier",
                        "line": 1,
                        "name": "x",
                        "check": true
                    }
                ]
            }
        }
    ]
}

Vyzkoušejme si to ještě na nepatrně složitějším příkladu s operátory s různou prioritou:

x = 1 + 2 * 3 ** 4

Výsledný derivační strom:

--Shine parse tree:
{
    "type": "Chunk",
    "body": [
        {
            "type": "ExpressionStatement",
            "line": 1,
            "expression": {
                "type": "AssignmentExpression",
                "oper": "=",
                "right": [
                    {
                        "right": {
                            "type": "BinaryExpression",
                            "operator": "*",
                            "right": {
                                "type": "BinaryExpression",
                                "operator": "**",
                                "right": {
                                    "type": "Literal",
                                    "line": 1,
                                    "value": 4
                                },
                                "left": {
                                    "type": "Literal",
                                    "line": 1,
                                    "value": 3
                                }
                            },
                            "left": {
                                "type": "Literal",
                                "line": 1,
                                "value": 2
                            }
                        },
                        "left": {
                            "type": "Literal",
                            "line": 1,
                            "value": 1
                        },
                        "type": "BinaryExpression",
                        "operator": "+",
                        "line": 1
                    }
                ],
                "left": [
                    {
                        "type": "Identifier",
                        "line": 1,
                        "name": "x",
                        "check": true
                    }
                ]
            }
        }
    ]
}

15. Zobrazení bajtkódu

Zobrazit si můžeme i bajtkód získaný po parsingu a překladu. Nechme si například zobrazit bajtkód získaný překladem tohoto jednoduchého skriptu:

x = 1
y = 2
z = x + y
print(z)

Zobrazení bajtkódu se provede příkazem:

$ shinec -b example.shn

Výsledek by měl vypadat následovně:

-- BYTECODE -- expression.shn:0-4
0001    GGET     0   0      ; "require"
0002    KSTR     1   1      ; "core"
0003    CALL     0   2   2
0004    TGETS    0   0   2  ; "__magic__"
0005    GGET     1   3      ; "_G"
0006    TGETS    1   1   4  ; "module"
0007    VARG     2   2   0
0008    TGETS    3   0   5  ; "environ"
0009    CALL     1   1   3
0010    KPRI     1   0
0011    KSHORT   1   1
0012    KPRI     2   0
0013    KSHORT   2   2
0014    KPRI     3   0
0015    ADDVV    3   1   2
0016    GGET     4   6      ; "print"
0017    MOV      5   3
0018    CALL     4   1   2
0019    RET0     0   1

Z výsledků je patrné, že se používají instrukce tříadresového kódu, který bývá efektivnější, než zásobníkový kód používaný například virtuálním strojem jazyka Python. Instrukce KPRI nastaví první operand (index proměnné) na hodnotu specifikovanou ve druhém operandu, instrukce KSHORT načte konstantu a například ADDVV sečte proměnné s indexy 1 a 2, výsledek uloží do proměnné s indexem 3.

16. Zobrazení pseudokódu používaného virtuálním strojem s JITem

Poslední zajímavostí překladače shinec je jeho schopnost zobrazit pseudokód tak, jak je (či bude) zpracováván virtuálním strojem programovacího jazyka Shine s JITem. Pro tento účel se použije přepínač -o:

$ shinec -o expression.shn
 
;TvmJIT opcode tree:
 
(!line "@expression.shn" 1)(!define __magic__ (!index (!call1 require "core") "__magic__"))(!call (!index _G "module") !vararg (!index __magic__ "environ"))
(!line 1) (!define (x) (!nil))(!massign (x) (1))
(!line 2) (!define (y) (!nil))(!massign (y) (2))
(!line 3) (!define (z) (!nil))(!massign (z) ((!add x y)))
(!line 4) (!call print z)

Výsledek připomíná – nikoli náhodou – Scheme či LISP. Umožňuje provádění symbolických manipulací při optimalizacích atd.

17. Obsah závěrečné části

Ve třetí a současně i závěrečné části miniseriálu o programovacím jazyku Shine si popíšeme tři důležité vlastnosti Shine, které v původním jazyku Lua nenalezneme. V první řadě se jedná o podporu tříd tak, jak je tomu v mnoha dalších mainstreamových jazycích. Dále se zmíníme o pattern matchingu a taktéž o podpoře takzvaných rozsahů (range), s nimiž jsme se nepřímo setkali při zmínce o rozdílných vlastnostech operátoru .. (dvě tečky).

18. Repositář s demonstračními příklady

Demonstrační příklady popsané v dnešním článku byly uloženy do veřejného Git repositáře, z něhož si je můžete snadno stáhnout a otestovat ve své instalaci jazyka Shine:

interpolace řetězců, první příkladinterpolace řetězců, druhý příklad
# Soubor Stručný popis Odkaz
1 01_hello_world.lua program typu „Hello, world“ ve variantě pro programovací jazyky Lua i Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/01_hello_world.lua
2 02_hello_world.lua program typu „Hello, world“ ve variantě pro programovací jazyky Lua i Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/02_hello_world.lua
       
3 03_print_values.lua volání funkcí s větším počtem parametrů, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/03_print_values.lua
4 03_print_values.shn volání funkcí s větším počtem parametrů, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/03_print_values.shn
       
5 04_comments.lua zápis komentářů do programového kódu, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/04_comments.lua
6 04_comments.shn zápis komentářů do programového kódu, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/04_comments.shn
7 05_comments.shn zápis komentářů do programového kódu, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/05_comments.shn
       
8 06_function_call.lua definice a volání funkcí, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/06_function_call.lua
9 06_function_call.shn definice a volání funkcí, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/06_function_call.shn
       
10 07_default_values.shn výchozí hodnoty parametrů funkcí, první varianta https://github.com/tisnik/pre­sentations/blob/master/shi­ne/07_default_values.shn
11 08_default_values.shn výchozí hodnoty parametrů funkcí, druhá varianta https://github.com/tisnik/pre­sentations/blob/master/shi­ne/08_default_values.shn
       
12 09_type_checks.shn specifikace typů parametrů funkcí https://github.com/tisnik/pre­sentations/blob/master/shi­ne/09_type_checks.shn
13 10_variable_types.shn specifikace typů proměnných, korektní typy https://github.com/tisnik/pre­sentations/blob/master/shi­ne/10_variable_types.shn
14 11_variable_types.shn specifikace typů proměnných, nekorektní typy https://github.com/tisnik/pre­sentations/blob/master/shi­ne/11_variable_types.shn
15 12_variable_types_in_function.shn specifikace typů parametrů lokálních proměnných https://github.com/tisnik/pre­sentations/blob/master/shi­ne/12_variable_types_in_fun­ction.shn
       
16 13_local_variables.lua globální vs. lokální proměnné, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/13_local_variables.lua
17 13_local_variables.shn globální vs. lokální proměnné, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/13_local_variables.shn
18 14_local_variable.shn lokální proměnná, použití modifikátoru local https://github.com/tisnik/pre­sentations/blob/master/shi­ne/14_local_variable.shn
19 14_local_variables.lua lokální proměnná, použití modifikátoru local https://github.com/tisnik/pre­sentations/blob/master/shi­ne/14_local_variables.lua
20 15_global_and_local_variable.shn globální i lokální proměnná stejného jména, varianta s local https://github.com/tisnik/pre­sentations/blob/master/shi­ne/15_global_and_local_va­riable.shn
21 16_global_and_local_variable.shn globální i lokální proměnná stejného jména, varianta bez local https://github.com/tisnik/pre­sentations/blob/master/shi­ne/16_global_and_local_va­riable.shn
       
22 17_counter1.lua čítač vytvořený s využitím uzávěru, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/17_counter1.lua
23 17_counter1.shn čítač vytvořený s využitím uzávěru, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/17_counter1.shn
24 18_counter1.shn zjednodušený zápis předchozího příkladu https://github.com/tisnik/pre­sentations/blob/master/shi­ne/18_counter1.shn
25 19_counter2.lua čítač s konfigurovatelným krokem, varianta pro jazyk Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/19_counter2.lua
26 19_counter2.shn čítač s konfigurovatelným krokem, varianta pro jazyk Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/19_counter2.shn
       
27 20_varargs.shn zpracování funkce s proměnným počtem parametrů https://github.com/tisnik/pre­sentations/blob/master/shi­ne/20_varargs.shn
28 21_varargs.shn zpracování funkce s proměnným počtem parametrů (jeden z parametrů je povinný) https://github.com/tisnik/pre­sentations/blob/master/shi­ne/21_varargs.shn
       
29 22_table_type.shn parametr funkce typu table https://github.com/tisnik/pre­sentations/blob/master/shi­ne/22_table_type.shn
30 23_array_type.shn parametr funkce typu array https://github.com/tisnik/pre­sentations/blob/master/shi­ne/23_array_type.shn
31 24_default_var_varargs.shn kombinace funkce s výchozí hodnotou parametru a proměnným počtem parametrů https://github.com/tisnik/pre­sentations/blob/master/shi­ne/24_default_var_varargs­.shn
       
32 25_table1.lua běžné tabulky v jazyce Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/25_table1.lua
33 25_table1.shn běžné tabulky v jazyce Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/25_table1.shn
34 26_table2.lua tabulky a hodnoty nil v jazyce Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/26_table2.lua
35 26_table2.shn tabulky a hodnoty nil v jazyce Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/26_table2.shn
36 27_table3.lua zápis tabulek na více řádků, varianta pro jazyk Lua (nekorektní) https://github.com/tisnik/pre­sentations/blob/master/shi­ne/27_table3.lua
37 27_table3.shn zápis tabulek na více řádků, varianta pro jazyk Lua (korektní) https://github.com/tisnik/pre­sentations/blob/master/shi­ne/27_table3.shn
38 28_array1.lua tabulka obsahující jen pole (jazyk Lua) https://github.com/tisnik/pre­sentations/blob/master/shi­ne/28_array1.lua
39 28_array1.shn skutečné pole v jazyku Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/28_array1.shn
       
40 29_array_push_pop.shn pole a operace typu push a pop https://github.com/tisnik/pre­sentations/blob/master/shi­ne/29_array_push_pop.shn
41 30_array_shift_unshift.shn pole a operace typu shift a unshift https://github.com/tisnik/pre­sentations/blob/master/shi­ne/30_array_shift_unshift­.shn
42 31_array_join.shn pole a operace typu join https://github.com/tisnik/pre­sentations/blob/master/shi­ne/31_array_join.shn
       
43 32_string.lua základní operace s řetězci v jazyce Lua https://github.com/tisnik/pre­sentations/blob/master/shi­ne/32_string.lua
44 32_string.shn odlišné chování operátoru .. při práci s řetězci v jazyce Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/32_string.shn
45 33_string.shn korektní způsob spojení řetězců v jazyce Shine https://github.com/tisnik/pre­sentations/blob/master/shi­ne/33_string.shn
46 34_interpolation.shn https://github.com/tisnik/pre­sentations/blob/master/shi­ne/34_interpolation.shn
47 35_interpolation.shn https://github.com/tisnik/pre­sentations/blob/master/shi­ne/35_interpolation.shn
       
48 36_expression1.shn výraz, který lze naparsovat a převést na AST https://github.com/tisnik/pre­sentations/blob/master/shi­ne/36_expression1.shn
49 37_expression2.shn výraz, který lze naparsovat a převést na AST https://github.com/tisnik/pre­sentations/blob/master/shi­ne/37_expression2.shn

19. Odkazy na relevantní články a seriály na Rootu

S technologiemi souvisejícími s programovacím jazykem Lua, LuaJITem, ale i s jazyky postavenými nad ekosystémem Luy (viz například výše zmíněný Moonscript) jsme se již na stránkách Roota několikrát setkali. Následují odkazy na více či méně relevantní články k dnes probíranému tématu:

  1. Seriál Programovací jazyk Lua
    https://www.root.cz/seria­ly/programovaci-jazyk-lua/
  2. Seriál Torch: framework pro strojové učení
    https://www.root.cz/serialy/torch-framework-pro-strojove-uceni/
  3. Skriptovací jazyk Lua v aplikacích naprogramovaných v Go
    https://www.root.cz/clanky/skriptovaci-jazyk-lua-v-aplikacich-naprogramovanych-v-go/
  4. Interpretry, překladače, JIT překladače a transpřekladače programovacího jazyka Lua
    https://www.root.cz/clanky/interpretry-prekladace-jit-prekladace-a-transprekladace-programovaciho-jazyka-lua/
  5. LuaJIT – Just in Time překladač pro programovací jazyk Lua
    https://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua/
  6. LuaJIT – Just in Time překladač pro programovací jazyk Lua (2)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-2/
  7. LuaJIT – Just in Time překladač pro programovací jazyk Lua (3)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-3/
  8. LuaJIT – Just in Time překladač pro programovací jazyk Lua (4)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-4/
  9. LuaJIT – Just in Time překladač pro programovací jazyk Lua (5 – tabulky a pole)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-5-tabulky-a-pole/
  10. LuaJIT – Just in Time překladač pro programovací jazyk Lua (6 – překlad programových smyček do mezijazyka LuaJITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-6-preklad-programovych-smycek-do-mezijazyka-luajitu/
  11. LuaJIT – Just in Time překladač pro programovací jazyk Lua (7 – dokončení popisu mezijazyka LuaJITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-7-dokonceni-popisu-mezijazyka-luajitu/
  12. LuaJIT – Just in Time překladač pro programovací jazyk Lua (8 – základní vlastnosti trasovacího JITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-8-zakladni-vlastnosti-trasovaciho-jitu/
  13. LuaJIT – Just in Time překladač pro programovací jazyk Lua (9 – další vlastnosti trasovacího JITu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-9-dalsi-vlastnosti-trasovaciho-jitu/
  14. LuaJIT – Just in Time překladač pro programovací jazyk Lua (10 – JIT překlad do nativního kódu)
    http://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua-10-jit-preklad-do-nativniho-kodu/
  15. Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua
    https://www.root.cz/clanky/moonscript-jazyk-inspirovany-coffeescriptem-urceny-pro-ekosystem-jazyka-lua/
  16. Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua (2)
    https://www.root.cz/clanky/moonscript-jazyk-inspirovany-coffeescriptem-urceny-pro-ekosystem-jazyka-lua-2/
  17. Moonscript: jazyk inspirovaný CoffeeScriptem určený pro ekosystém jazyka Lua (dokončení)
    https://www.root.cz/clanky/moonscript-jazyk-inspirovany-coffeescriptem-urceny-pro-ekosystem-jazyka-lua-dokonceni/
  18. Použití nástroje RQ (Redis Queue) pro správu úloh zpracovávaných na pozadí
    https://www.root.cz/clanky/pouziti-nastroje-rq-redis-queue-pro-spravu-uloh-zpracovavanych-na-pozadi/
  19. Proudy (streams) podporované systémem Redis
    https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis/
  20. Proudy (streams) podporované systémem Redis (dokončení)
    https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis-dokonceni/
  21. Jazyk Shine: „lepší“ Lua s novými jazykovými konstrukcemi a vylepšeními
    https://www.root.cz/clanky/jazyk-shine-lepsi-lua-s-novymi-jazykovymi-konstrukcemi-a-vylepsenimi/

20. Odkazy na Internetu

  1. Repositář projektu Shine
    https://github.com/richardhundt/shine
  2. Languages that compile to Lua
    https://github.com/hengestone/lua-languages?tab=readme-ov-file#languages-that-compile-to-lua
  3. Repositář projektu Lua Fun
    https://github.com/luafun/luafun
  4. Lua Functional 0.1.3 documentation
    https://luafun.github.io/re­ference.html
  5. Lua Profiler (GitHub)
    https://github.com/luafor­ge/luaprofiler
  6. Lua Profiler (LuaForge)
    http://luaforge.net/projec­ts/luaprofiler/
  7. ctrace
    http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/
  8. The Lua VM, on the Web
    https://kripken.github.io/lu­a.vm.js/lua.vm.js.html
  9. Lua.vm.js REPL
    https://kripken.github.io/lu­a.vm.js/repl.html
  10. lua2js
    https://www.npmjs.com/package/lua2js
  11. lua2js na GitHubu
    https://github.com/basicer/lua2js-dist
  12. Lua (programming language)
    http://en.wikipedia.org/wi­ki/Lua_(programming_langu­age)
  13. LuaJIT 2.0 SSA IR
    http://wiki.luajit.org/SSA-IR-2.0
  14. The LuaJIT Project
    http://luajit.org/index.html
  15. LuaJIT FAQ
    http://luajit.org/faq.html
  16. LuaJIT Performance Comparison
    http://luajit.org/performance.html
  17. LuaJIT 2.0 intellectual property disclosure and research opportunities
    http://article.gmane.org/gma­ne.comp.lang.lua.general/58908
  18. LuaJIT Wiki
    http://wiki.luajit.org/Home
  19. LuaJIT 2.0 Bytecode Instructions
    http://wiki.luajit.org/Bytecode-2.0
  20. Programming in Lua (first edition)
    http://www.lua.org/pil/contents.html
  21. Lua 5.2 sources
    http://www.lua.org/source/5.2/
  22. REPL
    https://en.wikipedia.org/wi­ki/Read%E2%80%93eval%E2%80%93prin­t_loop
  23. The LLVM Compiler Infrastructure
    http://llvm.org/ProjectsWithLLVM/
  24. clang: a C language family frontend for LLVM
    http://clang.llvm.org/
  25. LLVM Backend („Fastcomp“)
    http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html#llvm-backend
  26. Lambda the Ultimate: Coroutines in Lua,
    http://lambda-the-ultimate.org/node/438
  27. Coroutines Tutorial,
    http://lua-users.org/wiki/CoroutinesTutorial
  28. Lua Coroutines Versus Python Generators,
    http://lua-users.org/wiki/LuaCorouti­nesVersusPythonGenerators

Byl pro vás článek přínosný?