dc: kalkulator jako język programowy dla programistów
dc to klasyczny kalkulator z Unix, starszy niż język C, wchodzący w skład standardowych dystrybucji większości systemów, w tym macOS. Za fasadą prostego narzędzia kryje się pełnoprawny język programowania stosowy z rejestrami, makrami, konstrukcjami warunkowymi i rekurencją. Podstawowy model to stos: liczby i ciągi znaków są umieszczane na stosie za pomocą poleceń, operatory pobierają górne elementy, wykonują działanie i zwracają wynik.
Pierwsze obliczenie: dla sumy 2 + 2 wprowadź 2 2 + p. Tutaj 2 2 umieszcza liczby na stosie wiersz po wierszu, + sumuje dwa górne elementy, p wypisuje wynik.
2 2 +
p
4
Stos to kluczowy element: każdy literał (liczba lub [ciąg znaków]) wrzuca wartość na wierzch. Komentarze zaczynają się od #.
Praca z rejestrami i zmiennymi
dc zapewnia 256 rejestrów (a-z, 0-9 i inne znaki), przechowujących liczby lub ciągi znaków. Polecenia sR zapisują wierzchołek stosu do rejestru R, lR pobierają go z powrotem. Rejestry zachowują stan niezależnie od głównego stosu.
Przykład zapisania i przywrócenia ciągu znaków:
[Witaj świecie!] sx
lx
p
Witaj świecie!
Rejestry nadają się do zmiennych globalnych. Liczby w rejestrach są manipulowane tak samo jak na stosie: li do załadowania i na stos.
Makra jako funkcje
Funkcje w dc to makra: ciągi znaków w rejestrach, wykonywane poleceniem lRx, gdzie x to rejestr. Makra definiuje się jako [kod] sR.
Przykład funkcji sumującej rejestry a i b:
[la lb +] sS
1 sa
2 sb
lSx
p
3
Makra obsługują rekurencję i mogą wywoływać się nawzajem, tworząc podprogramy.
Konstrukcje warunkowe
Rozgałęzienia opierają się na porównaniach dwóch górnych elementów stosu. Operatory: =, >, <, != i inne. Jeśli warunek jest prawdziwy, wykonywane jest makro z określonego rejestru.
[[Równe] p] sE
[[Nierówne] p] sN
1 0
=E
1 0
!=N
Nierówne
Porównania zużywają dwa elementy ze stosu, wynik (0 lub 1) pozostaje.
Rekurencyjne pętle
Pętli nie ma, ale rekurencja jest realizowana przez samowywołanie makra. Przykład wypisywania liczb od 1 do 10:
[
li p
1 + si
li 11 >C
] sC
1 si
lCx
Makro C wypisuje i, zwiększa i rekurencyjnie wywołuje się, dopóki i < 11. Bieżące i jest już na stosie przy wejściu.
- Zalety rekurencji w dc: prostota, brak jawnych pętli.
- Ograniczenia: ryzyko przepełnienia stosu przy głębokiej rekurencji.
- Alternatywy: rekurencja ogonowa minimalizuje użycie stosu.
FizzBuzz w dc
Implementacja FizzBuzz do 100 demonstruje połączenie makr, warunków i rekurencji. Kluczowe polecenia: P (drukowanie bez nowej linii), c (czyszczenie stosu).
Pełny kod:
[[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: flaga d określa, czy drukować liczbę. Makro W sprawdza podzielność przez 3/5, ustawiając Fizz/Buzz. P z 10 (LF) dla nowej linii.
Zaawansowane zastosowania: Peg Solitaire
dc pozwala rozwiązywać złożone zadania, takie jak Peg Solitaire – łamigłówka ze skokami kołków na planszy. Stan planszy jest kodowany liczbą binarną, manipulacje odbywają się przez arytmetykę i operacje bitowe (dostępne przesunięcia, maski).
Formuły walidacji ruchów w RPN wyglądają skomplikowanie z powodu sprawdzeń bitowych, ale zapewniają pełną grę: od początkowej konfiguracji do końcowego kołka.
Takie podejście pokazuje dc jako narzędzie do prototypowania algorytmów bez kompilacji.
Co jest ważne
- Stos to podstawa wszystkich operacji: literały wrzucają, operatory pobierają/wrzucają wyniki.
- Rejestry (256 szt.) dla stanów, makra – dla podprogramów z
lRx. - Warunki zużywają stos, rekurencja zastępuje pętle.
p/Pdo wypisywania,cdo czyszczenia,%do modulo.- Nadaje się do skryptowania, prototypów, nauki RPN.
— Editorial Team
Brak komentarzy.