Zpět na domů

dc: programování na zásobníkovém kalkulátoru

dc — zásobníkový kalkulátor Unix jako programovací jazyk s registry, makry a rekurzí. Článek rozebírá zásobníkový model, podmínkové konstrukce, příklady FizzBuzz a Peg Solitaire s kompletním kódem.

Programujeme FizzBuzz na dc: od zásobníku k hře
Advertisement 728x90

dc: kalkulačka jako programovací jazyk pro vývojáře

dc je klasická kalkulačka z Unixu, starší než jazyk C, která je součástí standardní instalace většiny systémů včetně macOS. Za jednoduchým nástrojem se skrývá plnohodnotný zásobníkový programovací jazyk s registry, makry, podmíněnými konstrukcemi a rekurzí. Základním modelem je zásobník: čísla a řetězce se ukládají do zásobníku příkazy, operátory odebírají horní prvky, provádějí akci a vracejí výsledek.

První výpočet: pro součet 2 + 2 zadáte 2 2 + p. Zde 2 2 vloží čísla do zásobníku postupně, + sečte dva horní prvky, p vypíše výsledek.

2 2 +
p
4

Zásobník je klíčový prvek: každý literál (číslo nebo [řetězec]) vloží hodnotu na vrchol. Komentáře začínají znakem #.

Google AdInline article slot

Práce s registry a proměnnými

dc poskytuje 256 registrů (a-z, 0-9 a další znaky), které ukládají čísla nebo řetězce. Příkazy sR uloží vrchol zásobníku do registru R, lR jej načte zpět. Registry si zachovávají stav nezávisle na hlavním zásobníku.

Příklad uložení a obnovení řetězce:

[Ahoj světe!] sx
lx
p
Ahoj světe!

Registry jsou vhodné pro globální proměnné. Čísla v registrech se manipulují stejně jako v zásobníku: li pro načtení i do zásobníku.

Google AdInline article slot

Makra jako funkce

Funkce v dc jsou makra: řetězce v registrech, které se provedou příkazem lRx, kde x je registr. Makra se definují jako [kód] sR.

Příklad funkce pro součet registrů a a b:

[la lb +] sS
1 sa
2 sb
lSx
p
3

Makra podporují rekurzi a mohou se vzájemně volat, čímž tvoří podprogramy.

Google AdInline article slot

Podmíněné konstrukce

Větvení je založeno na porovnání dvou horních prvků zásobníku. Operátory: =, >, <, != a další. Pokud je podmínka pravdivá, provede se makro z uvedeného registru.

[[Stejné] p] sE
[[Různé] p] sN
1 0
=E
1 0
!=N
Různé

Porovnání spotřebuje dva prvky ze zásobníku, výsledek (0 nebo 1) zůstane.

Rekurzivní cykly

Cyklů není, ale rekurze se implementuje pomocí sebevolání makra. Příklad výpisu čísel od 1 do 10:

[
	li p
	1 + si
	li 11 >C
] sC

1 si
lCx

Makro C vypíše i, zvýší ho a rekurzivně se zavolá, dokud i < 11. Aktuální i je již v zásobníku při vstupu.

  • Výhody rekurze v dc: jednoduchost, absence explicitních cyklů.
  • Omezení: riziko přetečení zásobníku při hluboké rekurzi.
  • Alternativy: tail-rekurze minimalizuje využití zásobníku.

FizzBuzz v dc

Implementace FizzBuzz do 100 demonstruje kombinaci maker, podmínek a rekurze. Klíčové příkazy: P (výpis bez nového řádku), c (vyčištění zásobníku).

Celý kód:

[[Fizz] P 0 sd] sF
[[Buzz] P 0 sd] sB
[li 3 % 0 =F li 5 % 0 =B] sW
[10 P] sP
[li p c] sD
[
  1 sd
  lWx
  ld 0 =P
  ld 1 =D
  li 1 + si
  li 101 >M
] sM

1 si
lMx

Logika: příznak d určuje, zda vypsat číslo. Makro W kontroluje dělitelnost 3/5, nastavuje Fizz/Buzz. P s 10 (LF) pro nový řádek.

Pokročilé aplikace: Peg Solitaire

dc umožňuje řešit složité úlohy, jako je Peg Solitaire – hlavolam se skákáním kolíků na hracím poli. Stav pole se kóduje binárním číslem, manipulace probíhá pomocí aritmetiky a bitových operací (dostupné posuny, masky).

Vzorce pro validaci tahů v RPN vypadají složitě kvůli bitovým kontrolám, ale umožňují celou hru: od počáteční konfigurace po finální kolík.

Tento přístup ukazuje dc jako nástroj pro prototypování algoritmů bez kompilace.

Co je důležité

  • Zásobník je základem všech operací: literály vkládají, operátory odebírají/vracejí výsledky.
  • Registry (256 ks) pro stavy, makra – pro podprogramy s lRx.
  • Podmínky spotřebovávají zásobník, rekurze nahrazuje cykly.
  • p/P pro výstup, c pro vyčištění, % pro modulo.
  • Vhodné pro skriptování, prototypy, výuku RPN.

— Editorial Team

Advertisement 728x90

Číst dál