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ů
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
14. Zobrazení naparsovaného zdrojového kódu převedeného do formy stromu
16. Zobrazení pseudokódu používaného virtuálním strojem s JITem
18. Repositář s demonstračními příklady
19. Odkazy na relevantní články a seriály na Rootu
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)
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 sum z Table 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
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
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)
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}!
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říklad19. 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:
- Seriál Programovací jazyk Lua
https://www.root.cz/serialy/programovaci-jazyk-lua/ - Seriál Torch: framework pro strojové učení
https://www.root.cz/serialy/torch-framework-pro-strojove-uceni/ - Skriptovací jazyk Lua v aplikacích naprogramovaných v Go
https://www.root.cz/clanky/skriptovaci-jazyk-lua-v-aplikacich-naprogramovanych-v-go/ - 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/ - LuaJIT – Just in Time překladač pro programovací jazyk Lua
https://www.root.cz/clanky/luajit-just-in-time-prekladac-pro-programovaci-jazyk-lua/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - 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/ - Proudy (streams) podporované systémem Redis
https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis/ - Proudy (streams) podporované systémem Redis (dokončení)
https://www.root.cz/clanky/proudy-streams-podporovane-systemem-redis-dokonceni/ - 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
- Repositář projektu Shine
https://github.com/richardhundt/shine - Languages that compile to Lua
https://github.com/hengestone/lua-languages?tab=readme-ov-file#languages-that-compile-to-lua - Repositář projektu Lua Fun
https://github.com/luafun/luafun - Lua Functional 0.1.3 documentation
https://luafun.github.io/reference.html - Lua Profiler (GitHub)
https://github.com/luaforge/luaprofiler - Lua Profiler (LuaForge)
http://luaforge.net/projects/luaprofiler/ - ctrace
http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/ - The Lua VM, on the Web
https://kripken.github.io/lua.vm.js/lua.vm.js.html - Lua.vm.js REPL
https://kripken.github.io/lua.vm.js/repl.html - lua2js
https://www.npmjs.com/package/lua2js - lua2js na GitHubu
https://github.com/basicer/lua2js-dist - Lua (programming language)
http://en.wikipedia.org/wiki/Lua_(programming_language) - LuaJIT 2.0 SSA IR
http://wiki.luajit.org/SSA-IR-2.0 - The LuaJIT Project
http://luajit.org/index.html - LuaJIT FAQ
http://luajit.org/faq.html - LuaJIT Performance Comparison
http://luajit.org/performance.html - LuaJIT 2.0 intellectual property disclosure and research opportunities
http://article.gmane.org/gmane.comp.lang.lua.general/58908 - LuaJIT Wiki
http://wiki.luajit.org/Home - LuaJIT 2.0 Bytecode Instructions
http://wiki.luajit.org/Bytecode-2.0 - Programming in Lua (first edition)
http://www.lua.org/pil/contents.html - Lua 5.2 sources
http://www.lua.org/source/5.2/ - REPL
https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop - The LLVM Compiler Infrastructure
http://llvm.org/ProjectsWithLLVM/ - clang: a C language family frontend for LLVM
http://clang.llvm.org/ - LLVM Backend („Fastcomp“)
http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html#llvm-backend - Lambda the Ultimate: Coroutines in Lua,
http://lambda-the-ultimate.org/node/438 - Coroutines Tutorial,
http://lua-users.org/wiki/CoroutinesTutorial - Lua Coroutines Versus Python Generators,
http://lua-users.org/wiki/LuaCoroutinesVersusPythonGenerators