Compiler Explorer: až nečekaně užitečný nástroj pro vývojáře

6. 9. 2022
Doba čtení: 16 minut

Sdílet

 Autor: Depositphotos
Seznámíme se s užitečným projektem, který se nazývá Compiler Explorer. Jedná se o webovou aplikaci, která dokáže přeložit zdrojové kódy napsané v různých jazycích buď do assembleru zvoleného procesoru nebo (pro určité jazyky) do bajtkódu.

Obsah

1. Compiler Explorer – až nečekaně užitečný nástroj

2. Překlad zdrojových kódů do assembleru

3. Zkoumání specifických vlastností některých mikroprocesorů

4. Podpora historických CPU

5. Porovnání dvou či více variant překladu

6. Zobrazení bajtkódu u vybraných programovacích jazyků

7. Transformace zdrojového kódu do AST

8. Zobrazení AST v Compiler Exploreru

9. Překlad do mezikódu (intermediate representation)

10. Přímá podpora assemblerů

11. Zajímavosti na konec: detekce memset z programové smyčky a překlad pro osmibitové čipy

12. Seznam podporovaných jazyků

13. Seznam integrovaných překladačů

14. Odkazy na Internetu

1. Compiler Explorer – až nečekaně užitečný nástroj

V dnešním článku se, jak již ostatně bylo zmíněno v perexu, seznámíme se zajímavým a mnohdy i velmi užitečným projektem. Tento projekt se jmenuje Compiler Explorer a za jeho vývojem a provozem stojí Matt Godbolt. Jedná se o webovou aplikaci dostupnou na adrese https://godbolt.org/, která dokáže přeložit zdrojové kódy napsané v různých programovacích jazycích buď do assembleru zvoleného mikroprocesoru nebo (pro určité vybrané jazyky) do bajtkódu příslušného virtuálního stroje. Překlad je přitom proveden vybraným překladačem (podle zvoleného jazyka existuje jen jeden překladač nebo i několik desítek překladačů), který je navíc nabízen v různých verzích, takže je například možné porovnat, jak se způsob překladu postupně měnil. V dalších kapitolách si ve stručnosti ukážeme některé způsoby použití tohoto zajímavého nástroje.

Obrázek 1: Úvodní stránka nástroje Compiler Explorer.

Poznámka: z uživatelského pohledu je Compiler Explorer realizován formou webové aplikace, na které se osobně dívám s nedůvěrou (špatné zkušenosti s jejich nároky na systémové prostředky, kvalitu UX a efektivitu resp. většinou spíše neefektivitu používání), ovšem na tomto místě je nutné říci, že samotný Compiler Explorer se chová velmi svižně a i paměťové nároky nejsou (s ohledem na způsob tvorby „moderních“ aplikací) nijak velké. O tom se ostatně můžeme velmi snadno přesvědčit:

Obrázek 2: Compiler Explorer má na straně klienta (tedy prohlížeče) vlastně velmi malé paměťové nároky, dokonce menší, než například samotná stránka Roota a mnohem menší, než stránka s pozastaveným videem na Youtube nebo dokonce samotného Task Manažeru webového prohlížeče :-)

Compiler Explorer si můžete spustit i lokálně s využitím kódu a konfigurace získaného z tohoto repositáře.

2. Překlad zdrojových kódů do assembleru

Již název projektu Compiler Explorer naznačuje, že umožňuje překládat zdrojové kódy napsané v některém z překládaných (kompilovaných) jazyků do assembleru s možností prohlédnutí výsledného vygenerovaného kódu. To je operace, kterou pochopitelně dokáže provést prakticky jakýkoli překladač, ovšem Compiler Explorer programátorům nabízí především velký výběr překládaných programovacích jazyků (včetně C, C++, Rustu a Go) a taktéž velký výběr překladačů, včetně různých verzí těchto překladačů (v případě C a C++ je to GCC, LLVM, MSVC, překlad do WebAssembly apod.). Navíc je nabízeno velké množství cílových platforem, pro které je možné provést překlad, od historických osmibitových mikroprocesorů, až po moderní x86–64, ARMv8 či RISC-V. Ovšem Compiler Explorer uživatelům navíc nabízí možnost specifikovat parametry překladu, tedy většinou zapínat a vypínat optimalizace (prováděné s ohledem na rychlost či velikost cílového strojového kódu), popř. zapínat a vypínat různá rozšíření instrukční sady či určit typ procesoru, což je v současnosti důležité pro všechny tři výše zmíněné platformy: x86–64, ARM a taktéž RISC-V.

Obrázek 3: Takto vypadá překlad zdrojového kódu zapsaného v Rustu (demonstrační příklad s jednoduchým pattern matchingem) do assembleru. Korespondující řádky zdrojového kódu a instrukcí assembleru jsou v tomto případě zvýrazněny odlišnou barvou podkladu.

Poměrně důležitou vlastností Compiler Exploreru je fakt, že se překlad provádí (z pohledu uživatele) na pozadí, a to i v průběhu editace. Je tak možné vlastně „naživo“ vidět, jak se projeví změna algoritmu na efektivitě výsledného strojového kódu. Odpovídající si řádky zdrojového kódu a assembleru jsou přitom zvýrazněny různými barvami, takže je zřejmé, jak se jednotlivé řádky překládají (což pochopitelně nebude vždy zcela funkční, zejména při zapnutí optimalizací).

Poznámka: překlad v průběhu editace byl použit i v ideovém prapředkovi Compiler Exploreru. Jednalo se o tmux, přičemž v jednom okně běžel textový editor (vi) a ve druhém okně se zobrazoval generovaný assembler.

Dále je možné ve zkoumaných kódech používat různé knihovny. Seznam předinstalovaných knihoven lze najít na adrese https://godbolt.org/admin/li­braries.html.

Obrázek 4: Překlad prográmku napsaného v jazyce F# do assembleru x86–64 s využitím překladače dodávaného v .NETu. Povšimněte si, že v tomto konkrétním případě neexistuje vazba mezi řádky zdrojového kódu a assemblerem.

Poznámka: pěknou ukázkou „live“ náhledu na generovaný kód v assembleru je toto video.

3. Zkoumání specifických vlastností některých mikroprocesorů

Asi nejzajímavější je použití Compiler Exploreru pro zkoumání různých instrukčních sad a jejich rozšíření. Například jsme se na stránkách Roota ve stručnosti seznámili s rozšířením instrukční sady procesorů ARM, které se jmenuje NEON (což je jedna z mnoha variant implementace SIMD – Single Instruction Multiple Data). I na běžném desktopu a bez nutnosti instalace jakéhokoli (cross) překladače je možné zjistit, jak fungují takzvané intrinsic, tedy konstrukce zapsané v jazyku C či C++, které vedou k překladu kódu s využitím právě instrukcí NEON, i když původně C/C++ sémantiku NEONu neobsahuje (tedy neobsahuje možnost specifikovat například požadavek „tento kód ať je vykonán po 16bitových slovech zpracovaných ve čtyřech paralelních ALU“. Viz například NEON Intrinsics Quick Guide:

Obrázek 5: Překlad kódu zapsaného v jazyku C, v němž se využívají „intrinsic“ vektorové instrukční sady NEON.

Poznámka: samozřejmě se nejedná pouze o NEON, ale podobně lze zkoumat různé doplňky instrukční sady RISC-V nebo ARMv8, nemluvě o x86–64, kde těchto rozšíření existuje celá řada.

Obrázek 6: V Compiler Exploreru jsou podporovány i některé méně známé či méně často používané překladače, například tcc.

4. Podpora historických CPU

V Compiler Exploreru jsou nabízeny (typicky pro programovací jazyk C) i překladače některých historických mikroprocesorů. Příkladem je překladač cc65 určený pro známý osmibitový čip MOS 6502 i pro všechny jeho varianty (viz též https://cc65.github.io/doc/cc65­.html). Jedná se o poměrně dobrou pomůcku při vysvětlování, v čem se tyto starší mikroprocesory odlišují od jejich moderních protějšků. Příkladem je nutnost rozkladu operací s 16bitovými a 32bitovými operandy (nemluvě o číslech s plovoucí řádovou čárkou) na sekvenci osmibitových operací. Tato znalost je pochopitelně důležitá i jinde, například při práci s osmibitovými mikrořadiči.

Obrázek 7: Součet dvou celých šestnáctibitových čísel není na osmibitovém čipu MOS 6502 zcela triviální operací. Je nutné ji rozložit na součet spodních bajtů následovaných součtem vyšších bajtů, navíc je nutno brát ohled na přenos (carry) při prvním součtu.

Obrázek 8: Naproti tomu součet dvou osmibitových celých čísel je na tomtéž čipu již triviální – pokud překladači cc65 odpustíme zcela neefektivní způsob překladu (ten lze ovšem do určité míry ladit – a to použitím přepínačů překladače).

5. Porovnání dvou či více variant překladu

V mnoha diskusích se vývojáři snaží o porovnávání kvality různých překladačů, typicky z hlediska optimalizace generovaného strojového kódu. Popř. se vedou diskuse o tom, zda je například v případě překladače GCC pro určitou aplikaci (nebo i pro jádro operačního systému) lepší zapnout optimalizaci -O2 nebo -O3 atd. Při použití Compiler Exploreru je možné v rámci jednoho tabu v prohlížeči zobrazit výstup z několika překladačů (a to i pro různé platformy), několika verzí překladačů nebo například překlad v rámci jedné verze překladače, ale s odlišnými příznaky (flags). A stále platí, že modifikace ve zdrojovém kódu vede k prakticky okamžitému překladu se zobrazením všech nakonfigurovaných výstupů v assembleru:

Obrázek 9: Porovnání překladu s využitím různých variant Rustu.

Obrázek 10: Porovnání překladu s využitím stejného překladače, ale s odlišnými přepínači (flags).

Obrázek 11: Překlad stejného kódu na tři zcela odlišné platformy: MOS 6502, x86–64 a 32bitový ARM.

Obrázek 12: Porovnání překladu stejného kódu pomocí MSVC a icc.

6. Zobrazení bajtkódu u vybraných programovacích jazyků

Na stránkách Roota jsme se podrobně zabývali studiem bajtkódu některých programovacích jazyků (viz odkazy na konci článku). Projekt Compiler Explorer některé z těchto bajtkódů taktéž podporuje. Týká se to především Pythonu a taktéž Javy, resp. přesněji řečeno jazyků postavených nad virtuálním strojem Javy (JVM). Ovšem některé další jazyky a jejich bajtkódy (alespoň prozatím) podporovány nejsou; což je konkrétně případ programovacího jazyka Lua či technologie Parrot. Z novějších bajtkódů je pravděpodobně nejzajímavější WebAssembly, tedy bajtkód, který lze interpretovat či JITovat v moderních prohlížečích (což po odstranění podpory JVM může vypadat jako snaha o znovuobjevení kola :-) ). Pro zajímavost se podívejme na několik jednoduchých příkladů, konkrétně na překlad do bajtkódu JVM, dále na překlad do bajtkódu Pythonu a konečně překlad do bajtkódu WebAssembly:

Obrázek 13: Překlad konstruktoru třídy Square a metody square naprogramovaného v Javě do bajtkódu virtuálního stroje Javy (JVM). Barevně jsou odlišeny bloky instrukcí implicitního konstruktoru a bloky instrukcí z metody (ty by byly dále rozděleny na jednotlivé řádky).

Obrázek 14: Překlad jednoduché funkce napsané v Pythonu do bajtkódu Pythonu. V tomto případě existuje vazba mezi řádkem zdrojového kódu a blokem v bajtkódu; z tohoto důvodu jsou jednotlivé vazby zvýrazněny odlišným barevným pozadím.

Obrázek 15: Překlad výpočtu zapsaného v jazyku C do WebAssembly.

7. Transformace zdrojového kódu do AST

Současné překladače rozdělují překlad zdrojových kódů do několika kroků. Dnes bývá typické hlavní dělení na front end a back end překladače (někdy se zavádí i pojem middle end, což je poněkud zvláštní označení). V rámci frontendu překladače se postupně provádí jednotlivé dílčí kroky, a to jak v klasických překladačích (C, Rust, Go), tak i v jazycích, které provádí překlad „jen“ do bajtkódu s jeho pozdější interpretací (Python) nebo JITováním (Java). Díky rozdělení celého zpracování do několika konfigurovatelných kroků je zajištěna velká flexibilita a možnost případného relativně snadného rozšiřování o další syntaktické prvky, existuje možnost použití jediné sady nástrojů více jazyky, lze přidat podporu pro různé výstupní formáty (překlad do nativního kódu nebo do WebAssembly atd.), podporu speciální filtry apod. (nehledě na to, že každá činnost je založena na odlišné teorii a mohou na nic pracovat jiní vývojáři). Celý průběh zpracování vypadá při určitém zjednodušení následovně:

  1. Na začátku zpracování se nachází takzvaný lexer, který postupně načítá jednotlivé znaky ze vstupního řetězce (resp. ze vstupního souboru) a vytváří z nich lexikální tokeny. Teoreticky se pro každý programovací jazyk používá odlišný lexer a samozřejmě je možné v případě potřeby si napsat lexer vlastní. V případě Pythonu můžeme použít například standardní modul tokenizer, nebo lze alternativně použít například projekt Pygments, jenž obsahuje lexery pro mnoho dalších programovacích jazyků.
  2. Výstup z lexeru může procházet libovolným počtem filtrů sloužících pro odstranění nebo (častěji) modifikaci jednotlivých tokenů; ať již jejich typů či přímo textu, který tvoří hodnotu tokenu. Díky existenci filtrů je například možné nechat si zvýraznit vybrané bílé znaky, slova se speciálním významem v komentářích (TODO:, FIX:) apod. Některé lexery obsahují filtr přímo ve svém modulu.
  3. Sekvence tokenů tvoří základ pro syntaktickou analýzu. Nástroj, který syntaktickou analýzu provádí, se většinou nazývá parser a proto se taktéž někdy setkáme s pojmem parsing (tento termín je ovšem chybně používán i v těch případech, kdy se provádí „pouze“ lexikální analýza). Výsledkem činnosti parseru je vhodně zvolená datová struktura, typicky abstraktní syntaktický strom (AST); někdy též strom derivační. V případě Pythonu vypadá postupné zpracování vstupního zdrojového textu takto: lexer → derivační strom (parse tree) → AST.

Obrázek 16: AST s vizualizací výrazu 1+2*3.

Poznámka: některé jazyky navíc obsahují preprocesor, který se spouští před klasickým lexerem (i když samotný preprocesor může lexer obsahovat).

Obrázek 17: AST s vizualizací výrazu (1+2)*3.

8. Zobrazení AST v Compiler Exploreru

Vzhledem k tomu, jak je AST důležitý pro front end překladače, může být užitečné mít možnost si prohlédnout i tuto datovou strukturu. Dostupná je pouze pro některé překladače, typicky pro ty, které skutečně striktně rozdělují jednotlivé fáze zpracování a dokážou produkovat výstup z každé této fáze. Dobrým příkladem takového typu překladače je Clang, který si později zaslouží samostatný článek. Tento překladač může (pochopitelně kromě dalších výstupů) generovat i výstup z parseru, a to právě ve formě AST:

Obrázek 18: AST vygenerovaný překladačem Clang.

Poznámka: v současnosti pouze nepatrná část překladačů, které jsou v Compiler Exploreru integrovány, tuto funkci podporuje.

9. Překlad do mezikódu (intermediate representation)

Některé typy překladačů, mezi nimi i již výše zmíněný Clang v první fázi překladu (front end) vygenerují mezikód), který je nezávislý na konkrétním typu procesoru. Teprve na tento mezikód jsou aplikovány různé (obecné) optimalizace a následně je provedena transformace do strojového kódu zvoleného mikroprocesoru. V případě, že zvolený překladač dokáže vygenerovat a především vyexportovat mezikód, je tato volba dostupná i v Compiler Exploreru, o čemž se opět můžeme velmi snadno přesvědčit:

Obrázek 19: Výstup do assembleru a mezikód, který k tomuto výstupu vedl na architektuře x86–64.

Obrázek 20: Tentýž program, tentýž mezikód, ovšem tentokrát přeložený pro ARMv7.

Poznámka: opět platí, že pouze nepatrná část překladačů integrovaných do Compiler Exploreru tuto funkci podporuje.

10. Přímá podpora assemblerů

Výsledkem překladu je typicky strojový kód popř. v některých případech (Python, Java, Lua) bajtkód. To platí i pro assemblery, které jsou Compiler Explorerem taktéž podporovány, takže je možné si nechat zobrazit, jak se zdrojový kód v „symbolickém“ assembleru překládá do strojového kódu, který je pro lepší čitelnost zobrazen s využitím disassembleru (což znamená oproti původnímu kódu ztrátu informací). Díky této podpoře si můžete snadno vyzkoušet různé assemblery, které se liší svou syntaxí, a to i tehdy, pokud jsou určeny pro stejnou platformu (viz například rozdíly mezi GNU Assemblerem, NASMem, assemblerem integrovaným do LLVM atd.):

Obrázek 21: Kostra programu napsaného pro AArch64 (ARMv8) s běžícím Linuxem.

Obrázek 22: Můžeme si nechat zobrazit i kódy instrukcí, tedy vlastní strojový kód.

Obrázek 23: „Hello world“ v assembleru i386.

11. Zajímavosti na konec: detekce memset z programové smyčky a překlad pro osmibitové čipy

Clang obsahuje některé zajímavé optimalizace, například dokáže rozpoznat, že programátor zapsal smyčky sémanticky odpovídající standardní funkci memset:

Obrázek 24: Volba -O1 zajistí, že Clang nahradí celou smyčku voláním standardní funkce memset.

Tentýž příklad, ovšem přeložený GCC (kde jsem se snažil přesvědčit překladač, aby smyčku alespoň rozbalil):

Obrázek 25: Překlad stejného příkladu, nyní ovšem s využitím GCC.

Příklad překladu zdrojového programu naprogramovaného v céčko do strojového kódu pro osmibitový mikrořadič, konkrétně pro ATmega328:

Obrázek 26: Kód získaný při vypnutí optimalizací není příliš dobrý…

bitcoin_skoleni

12. Seznam podporovaných jazyků

Seznam podporovaných jazyků lze získat přes REST API:

Id             | Name
csharp         | C#
fsharp         | F#
vb             | Visual Basic
go             | Go
c              | C
c++            | C++
fortran        | Fortran
assembly       | Assembly
circle         | C++ (Circle)
circt          | CIRCT
cppx           | Cppx
crystal        | Crystal
hlsl           | HLSL
dart           | Dart
erlang         | Erlang
carbon         | Carbon
cppx_blue      | Cppx-Blue
cppx_gold      | Cppx-Gold
mlir           | MLIR
cuda           | CUDA C++
analysis       | Analysis
python         | Python
ruby           | Ruby
typescript     | TypeScript Native
ada            | Ada
cpp_for_opencl | C++ for OpenCL
openclc        | OpenCL C
llvm           | LLVM IR
d              | D
rust           | Rust
ispc           | ispc
jakt           | Jakt
java           | Java
kotlin         | Kotlin
nim            | Nim
pony           | Pony
scala          | Scala
solidity       | Solidity
clean          | Clean
pascal         | Pascal
haskell        | Haskell
ocaml          | OCaml
swift          | Swift
zig            | Zig

13. Seznam integrovaných překladačů

I seznam podporovaných překladačů je možné získat přes REST API. Celkem se v současnosti jedná o 1489 kombinací platforma+překladač+verze:

Compiler Name                              | Name
dotnet601csharp                            | .NET 6.0.101
dotnet601fsharp                            | .NET 6.0.101
dotnet601vb                                | .NET 6.0.101
386_gltip                                  | 386 gc (tip)
386_gl114                                  | 386 gc 1.14
386_gl115                                  | 386 gc 1.15
386_gl116                                  | 386 gc 1.16
386_gl117                                  | 386 gc 1.17
386_gl118                                  | 386 gc 1.18
386_gl119                                  | 386 gc 1.19
cc65_217                                   | 6502 cc65 2.17
cc65_218                                   | 6502 cc65 2.18
cc65_219                                   | 6502 cc65 2.19
cc65_trunk                                 | 6502 cc65 trunk
...
...
...
zcxx060                                    | zig c++ 0.6.0
zcxx070                                    | zig c++ 0.7.0
zcxx071                                    | zig c++ 0.7.1
zcxx080                                    | zig c++ 0.8.0
zcxx090                                    | zig c++ 0.9.0
zcxxtrunk                                  | zig c++ trunk
zcc060                                     | zig cc 0.6.0
zcc070                                     | zig cc 0.7.0
zcc071                                     | zig cc 0.7.1
zcc080                                     | zig cc 0.8.0
zcc090                                     | zig cc 0.9.0
zcctrunk                                   | zig cc trunk
ztrunk                                     | zig trunk

14. Odkazy na Internetu

  1. Stránka projektu Compiler Explorer
    https://godbolt.org/
  2. The LLVM Compiler Infrastructure
    https://llvm.org/
  3. GCC, the GNU Compiler Collection
    https://gcc.gnu.org/
  4. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mobilefish.com/tu­torials/java/java_quickgu­ide_jvm_instruction_set.html
  5. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  6. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  7. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  8. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  9. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  10. Inside The Python Virtual Machine
    https://leanpub.com/insidet­hepythonvirtualmachine
  11. module-py_compile
    https://docs.python.org/3­.8/library/py_compile.html
  12. Given a python .pyc file, is there a tool that let me view the bytecode?
    https://stackoverflow.com/qu­estions/11141387/given-a-python-pyc-file-is-there-a-tool-that-let-me-view-the-bytecode
  13. The structure of .pyc files
    https://nedbatchelder.com/blog/200804/the_str­ucture_of_pyc_files.html
  14. Python Bytecode: Fun With Dis
    http://akaptur.github.io/blog/2013/08/14/pyt­hon-bytecode-fun-with-dis/
  15. Python's Innards: Hello, ceval.c!
    http://tech.blog.aknin.na­me/category/my-projects/pythons-innards/
  16. Byterun
    https://github.com/nedbat/byterun
  17. Python Byte Code Instructions
    http://document.ihg.uni-duisburg.de/Documentation/Pyt­hon/lib/node56.html
  18. Python Byte Code Instructions
    https://docs.python.org/3­.2/library/dis.html#python-bytecode-instructions
  19. dis – Python module
    https://docs.python.org/2/li­brary/dis.html
  20. Comparison of Python virtual machines
    http://polishlinux.org/ap­ps/cli/comparison-of-python-virtual-machines/
  21. O-code
    http://en.wikipedia.org/wiki/O-code_machine
  22. ARM GCC Inline Assembler Cookbook
    http://www.ethernut.de/en/do­cuments/arm-inline-asm.html
  23. Extended Asm – Assembler Instructions with C Expression Operands
    https://gcc.gnu.org/online­docs/gcc/Extended-Asm.html
  24. ARM inline asm secrets
    http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/
  25. The ARMv8 instruction sets
    http://infocenter.arm.com/hel­p/index.jsp?topic=/com.ar­m.doc.den0024a/ch05s01.html
  26. A64 Instruction Set
    https://developer.arm.com/pro­ducts/architecture/instruc­tion-sets/a64-instruction-set
  27. The ARM Instruction Set
    http://simplemachines.it/doc/ar­m_inst.pdf
  28. ARM Architecture (Wikipedia)
    http://en.wikipedia.org/wi­ki/ARM_architecture
  29. The GNU Assembler Tutorial
    http://tigcc.ticalc.org/doc/gnu­asm.html
  30. The GNU Assembler – macros
    http://tigcc.ticalc.org/doc/gnu­asm.html#SEC109
  31. 6502 – the first RISC µP
    http://ericclever.com/6500/
  32. ca65 Users Guide
    https://cc65.github.io/doc/ca65.html
  33. cc65 Users Guide
    https://cc65.github.io/doc/cc65.html
  34. Adventures with ca65
    https://atariage.com/forum­s/topic/312451-adventures-with-ca65/
  35. Assembly Language Misconceptions
    https://www.youtube.com/wat­ch?v=8_0tbkbSGRE
  36. How Machine Language Works
    https://www.youtube.com/wat­ch?v=HWpi9n2H3kE
  37. Instrukční sada AArch64: technologie NEON
    https://www.root.cz/clanky/instrukcni-sada-aarch64-technologie-neon/
  38. Seriál Programovací jazyk Go
    https://www.root.cz/seria­ly/programovaci-jazyk-go/
  39. Seriál Programovací jazyk Rust
    https://www.root.cz/seria­ly/programovaci-jazyk-rust/
  40. Instrukční sada procesorových jader s otevřenou architekturou RISC-V
    https://www.root.cz/clanky/instrukcni-sada-procesorovych-jader-s-otevrenou-architekturou-risc-v/
  41. 64bitové mikroprocesory s architekturou AArch64
    https://www.root.cz/clanky/64bitove-mikroprocesory-s-architekturou-aarch64/
  42. Jak se zrodil procesor?
    https://www.root.cz/clanky/jak-se-zrodil-procesor/
  43. Cross assemblery a cross překladače pro platformu osmibitových domácích mikropočítačů Atari
    https://www.root.cz/clanky/cross-assemblery-a-cross-prekladace-pro-platformu-osmibitovych-domacich-mikropocitacu-atari/
  44. CppCon 2016: Jason Turner “Rich Code for Tiny Computers: A Simple Commodore 64 Game in C++17”
    https://www.youtube.com/wat­ch?v=zBkNBP00wJE
  45. Vektorové procesory aneb další pokus o zvýšení výpočetního výkonu počítačů
    https://www.root.cz/clanky/vektorove-procesory-aneb-dalsi-pokus-o-zvyseni-vypocetniho-vykonu-pocitacu/
  46. Intermediate representation
    https://en.wikipedia.org/wi­ki/Intermediate_representa­tion
  47. Abstract syntax tree
    https://en.wikipedia.org/wi­ki/Abstract_syntax_tree
  48. Lexical analysis
    https://en.wikipedia.org/wi­ki/Lexical_analysis
  49. Parser
    https://en.wikipedia.org/wi­ki/Parsing#Parser
  50. Parse tree
    https://en.wikipedia.org/wi­ki/Parse_tree
  51. Derivační strom
    https://cs.wikipedia.org/wi­ki/Deriva%C4%8Dn%C3%AD_strom
  52. Python doc: ast — Abstract Syntax Trees
    https://docs.python.org/3/li­brary/ast.html
  53. Python doc: tokenize — Tokenizer for Python source
    https://docs.python.org/3/li­brary/tokenize.html
  54. Mikropočítač KIM-1: jeden ze zvěstovatelů osmibitové revoluce
    https://www.root.cz/clanky/mi­kropocitac-kim-1-jeden-ze-zvestovatelu-osmibitove-revoluce/
  55. Compiler Explorer Libraries
    https://godbolt.org/admin/li­braries.html
  56. Stav jednotlivých překladačů v Compiler Exploreru
    https://compiler-explorer.github.io/compiler-workflows/build-status
  57. WebAssembly
    https://webassembly.org/
  58. Clang
    https://clang.llvm.org/
  59. Clang: Assembling a Complete Toolchain
    https://clang.llvm.org/doc­s/Toolchain.html

Autor článku

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