Czwarty (język programowania)
Paradygmat | konkatenacyjne ( oparte na stosie ), proceduralne , refleksyjne , niektóre implementacje są zorientowane obiektowo |
---|---|
Zaprojektowany przez | Charlesa H. Moore'a |
Po raz pierwszy pojawiły się | 1970 |
Dyscyplina pisania | Bez typu |
Rozszerzenia nazw plików | .fs, .fth, .4th, .f, .forth [ potrzebne źródło ] |
Strona internetowa | |
Główne wdrożenia | |
SwiftForth (Forth, Inc.) Gforth (Projekt GNU) VFX Forth (Inżynieria mikroprocesorowa) | |
Influenced | |
Factor , Joy , PostScript , RPL , REBOL , STOIC |
Forth to proceduralny , zorientowany na stos język programowania i interaktywne środowisko zaprojektowane przez Charlesa H. „Chucka” Moore'a i po raz pierwszy użyte przez innych programistów w 1970 roku. Chociaż nie jest akronimem , nazwa języka we wczesnych latach była często pisana wielkimi literami jako DALEJ . Implementacje FORTH-79 i FORTH-83, które nie zostały napisane przez Moore'a, stały się de facto standardami, a oficjalna standaryzacja języka została opublikowana w 1994 roku jako ANS Forth. Szeroka gama pochodnych Forth istniała przed i po ANS Forth.
Forth zazwyczaj łączy kompilator ze zintegrowaną powłoką poleceń, w której użytkownik wchodzi w interakcje za pomocą podprogramów zwanych word . Słowa można definiować, testować, ponownie definiować i debugować bez ponownej kompilacji lub ponownego uruchamiania całego programu. Wszystkie elementy syntaktyczne, w tym zmienne i podstawowe operatory, są zdefiniowane jako słowa. Stos służy do przekazywania parametrów między słowami, co prowadzi do stylu odwrotnej notacji polskiej .
Przez większą część istnienia Forth standardową techniką była kompilacja do kodu wielowątkowego , który można interpretować szybciej niż kod bajtowy . Jedną z pierwszych zalet Forth był rozmiar: całe środowisko programistyczne - w tym kompilator, edytor i programy użytkownika - mogło zmieścić się w pamięci w 8-bitowym lub podobnie ograniczonym systemie. Nie są już ograniczone przestrzenią, istnieją nowoczesne implementacje, które generują zoptymalizowany kod maszynowy, podobnie jak inne kompilatory języków.
Forth jest używany w programie ładującym Open Firmware , w aplikacjach kosmicznych , takich jak statek kosmiczny Philae , oraz w innych systemach wbudowanych, które wymagają interakcji ze sprzętem. Względna prostota tworzenia podstawowego systemu Forth doprowadziła do wielu osobistych i zastrzeżonych wariantów, takich jak niestandardowy Forth używany do implementacji bestsellerowej gry wideo Starflight z 1986 roku firmy Electronic Arts . Implementacja wolnego oprogramowania Gforth jest aktywnie utrzymywana, podobnie jak kilka systemów wspieranych komercyjnie.
Moore później opracował serię mikroprocesorów do bezpośredniego wykonywania skompilowanego kodu podobnego do Forth i eksperymentował z mniejszymi językami opartymi na koncepcjach Forth, w tym cmForth i colorForth .
Używa
Forth ma niszę w zastosowaniach astronomicznych i kosmicznych, a także historię systemów wbudowanych . Boot ROM Open Firmware używane przez Apple , IBM , Sun i OLPC XO-1 zawierają środowisko Forth.
Forth był często używany do wprowadzania nowego sprzętu. Forth był pierwszym rezydentnym oprogramowaniem na nowym chipie Intel 8086 w 1978 roku, a MacFORTH był pierwszym rezydentnym systemem programistycznym dla Macintosha 128K w 1984 roku.
Firma Atari, Inc. wykorzystała skomplikowaną animowaną wersję demonstracyjną napisaną w języku Forth, aby zaprezentować możliwości komputerów Atari 400 i 800 w domach towarowych. Trzy domowe gry komputerowe firmy Electronic Arts , wydane w latach 80., zostały napisane w Forth: Worms? (1983), Gwiezdny lot (1986) i Władcy podboju (1986).
Canon Cat (1987) używa Forth do programowania systemu.
Rockwell wyprodukował jednoukładowe mikrokomputery z rezydentnymi jądrami Forth: R65F11 i R65F12. ASYST był czwartym rozszerzeniem do pomiarów i sterowania na komputerach PC.
Historia
Forth wyewoluował z osobistego systemu programowania Charlesa H. Moore'a , który był w ciągłym rozwoju od 1968 roku. Forth po raz pierwszy zetknął się z innymi programistami na początku lat 70., zaczynając od Elizabeth Raczej w United States National Radio Astronomy Observatory (NRAO). Po pracy w NRAO, Charles Moore i Elizabeth Attraction założyli FORTH, Inc. w 1973 roku, udoskonalając i przenosząc systemy Forth na dziesiątki innych platform w następnej dekadzie.
Forth jest tak nazwany, ponieważ w 1968 roku „plik zawierający interpreter był oznaczony jako CZWARTY, dla oprogramowania czwartej (następnej) generacji, ale system operacyjny IBM 1130 ograniczył nazwy plików do pięciu znaków”. Moore postrzegał Fortha jako następcę języków programowania trzeciej generacji typu „ kompiluj-łącz-go ” lub oprogramowania dla sprzętu „czwartej generacji”.
MicroFORTH firmy FORTH, Inc. został opracowany dla mikroprocesorów Intel 8080 , Motorola 6800 , Zilog Z80 i RCA 1802 , począwszy od 1976 r. MicroFORTH był później używany przez hobbystów do generowania systemów Forth dla innych architektur, takich jak 6502 w 1978 r. Grupa Forth Interest powstała w 1978 roku. Promowała i rozpowszechniała własną wersję języka FIG-Forth dla większości komputerów domowych.
Forth był popularny na początku lat 80., ponieważ dobrze pasował do ograniczonej pamięci mikrokomputerów . Łatwość implementacji języka doprowadziła do wielu wdrożeń. Brytyjski komputer domowy Jupiter ACE ma Forth w swoim systemie operacyjnym rezydentnym w pamięci ROM . Insoft GraFORTH to wersja Forth z rozszerzeniami graficznymi dla Apple II.
Powszechna praktyka została skodyfikowana w de facto standardach FORTH-79 i FORTH-83 odpowiednio w latach 1979 i 1983. Normy te zostały ujednolicone przez ANSI w 1994 roku, powszechnie określane jako ANS Forth.
Od 2018 roku źródło oryginalnej wersji FORTH 1130 zostało odzyskane i jest teraz aktualizowane, aby działało na przywróconym lub emulowanym systemie 1130.
Przegląd
Forth kładzie nacisk na użycie małych, prostych funkcji zwanych słowami . Słowa dla większych zadań odwołują się do wielu mniejszych słów, z których każde wykonuje odrębne zadanie podrzędne. Duży program Forth to hierarchia słów. Te słowa, będące odrębnymi modułami, które komunikują się niejawnie za pośrednictwem mechanizmu stosu, mogą być prototypowane, budowane i testowane niezależnie. Najwyższy poziom kodu Forth może przypominać anglojęzyczny opis aplikacji. Forth został nazwany językiem metaaplikacji : językiem, który może być używany do tworzenia języków zorientowanych na problemy .
Forth opiera się na wyraźnym użyciu stosu danych i odwrotnej notacji polskiej , która jest powszechnie stosowana w kalkulatorach firmy Hewlett-Packard . W RPN operator jest umieszczany po swoich operandach, w przeciwieństwie do bardziej powszechnej notacji wrostkowej , w której operator jest umieszczany między swoimi operandami. Notacja postfiksowa ułatwia analizowanie i rozszerzanie języka; Elastyczność Forth sprawia, że statyczna BNF jest nieodpowiednia i nie ma monolitycznego kompilatora. Rozszerzenie kompilatora wymaga jedynie napisania nowego słowa, zamiast modyfikowania gramatyki i zmiany podstawowej implementacji.
Korzystając z RPN, można uzyskać wynik wyrażenia matematycznego (25 * 10 + 50)
w ten sposób:
25 10 * 50 + CR . 300 ok
Najpierw układa się na stosie liczby 25 i 10.
Słowo *
pobiera dwie najwyższe liczby ze stosu, mnoży je i umieszcza iloczyn z powrotem na stosie.
Następnie na stos kładzie się liczbę 50.
Słowo +
dodaje dwie najwyższe wartości, przesuwając sumę. CR
( powrót karetki ) rozpoczyna wyjście w nowej linii. Wreszcie, .
drukuje wynik. Ponieważ wszystko zakończyło się pomyślnie, system Forth drukuje OK
.
Nawet funkcje strukturalne Forth są oparte na stosie. Na przykład:
: FLOOR5 ( n -- n' ) DUP 6 < JEŚLI UPUST 5 ELSE 1 - TO ;
Dwukropek wskazuje początek nowej definicji, w tym przypadku nowego słowa (ponownie, słowo jest terminem używanym dla podprogramu) o nazwie FLOOR5
. Tekst w nawiasach jest komentarzem informującym, że to słowo oczekuje liczby na stosie i zwróci ewentualnie zmienioną liczbę (na stosie).
Podprogram wykorzystuje następujące polecenia: DUP
duplikuje liczbę na stosie; 6
wypycha 6 na wierzch stosu; <
porównuje dwie najwyższe liczby na stosie (6 i wejście DUP
ed) i zastępuje je wartością prawda lub fałsz; JEŻELI
przyjmuje wartość prawda-lub-fałsz i wybiera wykonanie polecenia bezpośrednio po nim lub przejście do ELSE
; DROP
odrzuca wartość ze stosu; 5
wkłada 5 na wierzch stosu; i TO
kończy tryb warunkowy.
Słowo FLOOR5
jest odpowiednikiem tej funkcji napisanej w języku programowania C przy użyciu operatora trójskładnikowego „?:”
int podłoga5 ( int v ) { return ( v < 6 ) ? 5 : ( v - 1 ); }
Ta funkcja jest napisana bardziej zwięźle jako:
: PIĘTRO5 ( n -- n' ) 1- 5 MAKS ;
Można to uruchomić w następujący sposób:
1 PIĘTRO5 CR . 5 ok 8 PIĘTRO5 CR . 7 ok
Najpierw odkładana jest liczba (1 lub 8) na stos, wywoływany jest FLOOR5
, który ponownie podnosi liczbę i przesuwa wynik. CR
przenosi dane wyjściowe do nowej linii (ponownie, tutaj jest to tylko dla czytelności). Na koniec wezwanie do .
wyskakuje wynik i drukuje.
Udogodnienia
Gramatyka Fortha nie ma oficjalnej specyfikacji. Zamiast tego jest zdefiniowany przez prosty algorytm. Interpreter odczytuje linię wejścia z urządzenia wejściowego użytkownika, która jest następnie analizowana pod kątem słowa, używając spacji jako ogranicznika ; niektóre systemy rozpoznają dodatkowe białe znaki. Gdy tłumacz znajdzie słowo, sprawdza je w słowniku . Jeśli słowo zostanie znalezione, interpreter wykonuje kod powiązany ze słowem, a następnie wraca, aby przeanalizować resztę strumienia wejściowego. Jeśli słowo nie zostanie znalezione, zakłada się, że słowo to jest liczbą i podejmowana jest próba przekształcenia go w liczbę i odłożenia na stos; jeśli się powiedzie, interpreter kontynuuje analizowanie strumienia wejściowego. W przeciwnym razie, jeśli zarówno wyszukiwanie, jak i konwersja liczb nie powiedzie się, interpreter drukuje słowo, po którym następuje komunikat o błędzie informujący, że słowo nie zostało rozpoznane, opróżnia strumień wejściowy i czeka na nowe dane wprowadzone przez użytkownika.
Definicja nowego słowa zaczyna się od słowa :
(dwukropek) i kończy na słowie ;
(średnik). Na przykład,
: X DUP 1+ . . ;
skompiluje słowo X
i sprawi, że nazwę będzie można znaleźć w słowniku. Wykonane przez wpisanie 10 X
w konsoli spowoduje to wydrukowanie 11 10
.
Większość systemów Forth zawiera asembler do pisania słów przy użyciu funkcji procesora. Czwarte asemblery często używają odwrotnej polskiej składni, w której parametry instrukcji poprzedzają instrukcję. Typowy polski asembler przygotowuje operandy na stosie, a mnemonik kopiuje całą instrukcję do pamięci jako ostatni krok. Asembler Forth jest z natury asemblerem makr, więc łatwo jest zdefiniować alias dla rejestrów zgodnie z ich rolą w systemie Forth: np. "dsp" dla rejestru używanego jako wskaźnik stosu danych.
System operacyjny, pliki i wielozadaniowość
Większość systemów Forth działa pod systemem operacyjnym hosta, takim jak Microsoft Windows , Linux lub wersja Unix i używa systemu plików systemu operacyjnego hosta dla plików źródłowych i danych; ANSI Forth Standard opisuje słowa używane dla wejścia/wyjścia. Wszystkie nowoczesne systemy Forth używają zwykłych plików tekstowych jako źródła, nawet jeśli są one osadzone. System wbudowany z rezydentnym kompilatorem pobiera swoje źródło przez łącze szeregowe.
Klasyczne systemy Forth tradycyjnie nie używają ani systemu operacyjnego , ani systemu plików . Zamiast przechowywać kod w plikach, kod źródłowy jest przechowywany w blokach dysku zapisywanych na fizyczne adresy dysków. Słowo BLOCK
służy do translacji numeru bloku miejsca na dysku o wielkości 1K na adres bufora zawierającego dane, który jest zarządzany automatycznie przez system Forth. Używanie bloków stało się rzadkością od połowy lat 90. W systemie hostowanym te bloki również są przydzielane w normalnym pliku.
Wielozadaniowość , najczęściej kooperacyjne planowanie okrężne , jest zwykle dostępna (chociaż słowa i obsługa wielozadaniowości nie są objęte standardem ANSI Forth). Słowo PAUZA
służy do zapisania kontekstu wykonania bieżącego zadania, zlokalizowania następnego zadania i przywrócenia kontekstu wykonania. Każde zadanie ma swoje własne stosy, prywatne kopie niektórych zmiennych kontrolnych i obszar zdrapek. Zamiana zadań jest prosta i wydajna; w rezultacie wielozadaniowość Forth jest dostępna nawet na bardzo prostych mikrokontrolerach , takich jak Intel 8051 , Atmel AVR i TI MSP430 .
Inne niestandardowe udogodnienia obejmują mechanizm wysyłania wywołań do systemu operacyjnego hosta lub systemów okienkowych , a wiele z nich zapewnia rozszerzenia, które wykorzystują planowanie zapewniane przez system operacyjny. Zazwyczaj mają większy i inny zestaw słów niż samodzielne PAUSE Fortha
do tworzenia zadań, zawieszania, niszczenia i modyfikowania priorytetu.
Samodzielna kompilacja i kompilacja krzyżowa
W pełni funkcjonalny system Forth z całym kodem źródłowym skompiluje się sam, technika powszechnie nazywana meta-kompilacją lub self-hostingiem przez programistów Forth (chociaż termin ten nie dokładnie pasuje do meta-kompilacji, jak jest zwykle definiowana). Zwykłą metodą jest ponowne zdefiniowanie kilku słów, które umieszczają skompilowane bity w pamięci. Słowa kompilatora używają specjalnie nazwanych wersji pobierania i przechowywania, które można przekierować do obszaru bufora w pamięci. Obszar bufora symuluje lub uzyskuje dostęp do obszaru pamięci rozpoczynającego się pod innym adresem niż bufor kodu. Takie kompilatory definiują słowa dostępu zarówno do pamięci komputera docelowego, jak i pamięci komputera hosta (kompilującego).
Po ponownym zdefiniowaniu operacji pobierania i przechowywania dla przestrzeni kodu, kompilator, asembler itp. są rekompilowane przy użyciu nowych definicji pobierania i przechowywania. To skutecznie ponownie wykorzystuje cały kod kompilatora i interpretera. Następnie kompilowany jest kod systemu Forth, ale ta wersja jest przechowywana w buforze. Bufor w pamięci jest zapisywany na dysku i zapewnia sposoby tymczasowego ładowania go do pamięci w celu przetestowania. Kiedy wydaje się, że nowa wersja działa, jest nadpisywana nad wersją poprzednią.
Istnieje wiele odmian takich kompilatorów dla różnych środowisk. W przypadku systemów wbudowanych kod można zamiast tego zapisać na innym komputerze, techniką znaną jako kompilacja krzyżowa , przez port szeregowy lub nawet pojedynczy bit TTL , zachowując nazwy słów i inne niewykonujące się części słownika w oryginalnej kompilacji komputer. Minimalne definicje takiego kompilatora Forth to słowa, które pobierają i przechowują bajt, oraz słowo, które nakazuje wykonanie słowa Forth. Często najbardziej czasochłonną częścią pisania zdalnego portu jest zbudowanie początkowego programu do implementacji pobierania, przechowywania i wykonywania, ale wiele nowoczesnych mikroprocesorów ma zintegrowane funkcje debugowania (takie jak Motorola CPU32), które eliminują to zadanie.
Struktura języka
Podstawową strukturą danych Forth jest „słownik”, który odwzorowuje „słowa” na wykonywalny kod lub nazwane struktury danych. Słownik jest ułożony w pamięci jako drzewo połączonych list z linkami przechodzącymi od ostatniego (ostatnio) zdefiniowanego słowa do najstarszego, aż do znalezienia wartości wartowniczej , zwykle wskaźnika NULL. Zmiana kontekstu powoduje, że przeszukiwanie listy zaczyna się od innego liścia. Wyszukiwanie połączonej listy jest kontynuowane, gdy gałąź łączy się z głównym pniem, prowadząc ostatecznie z powrotem do wartownika, korzenia. Słowników może być kilka. W rzadkich przypadkach, takich jak metakompilacja, słownik może być izolowany i samodzielny. Efekt przypomina zagnieżdżanie przestrzeni nazw i może przeciążać słowa kluczowe w zależności od kontekstu.
Zdefiniowane słowo zazwyczaj składa się z nagłówka i treści , przy czym nagłówek składa się z pola nazwy (NF) i pola łącza (LF), a treść składa się z pola kodu (CF) i pola parametru (PF).
Nagłówek i treść hasła słownika są traktowane oddzielnie, ponieważ mogą nie być ciągłe. Na przykład, gdy program Forth jest ponownie kompilowany na nową platformę, głowa może pozostać na komputerze kompilującym, podczas gdy ciało przechodzi na nową platformę. W niektórych środowiskach (takich jak systemy wbudowane ) głowice niepotrzebnie zajmują pamięć. Jednak niektóre kompilatory krzyżowe mogą umieszczać głowy w celu, jeśli oczekuje się, że sam cel będzie obsługiwał interaktywny Forth.
Wpis w słowniku
Dokładny format wpisu słownika nie jest określony, a implementacje są różne. Jednak niektóre komponenty są prawie zawsze obecne, chociaż dokładny rozmiar i kolejność mogą się różnić. Opisany jako struktura, wpis słownika może wyglądać w ten sposób:
struktury : flaga \ długość nazwy słowa char-array: nazwa \ nazwa długość czasu wykonania nie jest znana w czasie kompilacji adres: poprzedni \ pole linku, wstecz ptr do poprzedniego słowa adres: słowo kodowe \ ptr do kodu wykonania tego słowa dowolne -tablica: pole parametru \ nieznana długość danych, słów lub kodów operacji słowo końcowe struktury końcowej
Pole nazwy zaczyna się od długości nazwy słowa, po której następuje znakowa reprezentacja nazwy.
Pole łącza zawiera wskaźnik do wcześniej zdefiniowanego słowa. Wskaźnik może być względnym przesunięciem lub adresem bezwzględnym wskazującym na następny najstarszy element rodzeństwa.
Wskaźnik pola kodu będzie albo adresem słowa, które wykona kod lub dane w polu parametru, albo początkiem kodu maszynowego, który procesor wykona bezpośrednio. W przypadku słów zdefiniowanych dwukropkiem wskaźnik pola kodu wskazuje słowo, które zapisze bieżący wskaźnik instrukcji Forth (IP) na stosie zwrotnym i załaduje adres IP z nowym adresem, z którego ma być kontynuowane wykonywanie słów. Jest to to samo, co robią instrukcje call/return procesora.
Struktura kompilatora
Sam kompilator nie jest monolitycznym programem. Składa się z Forth słów widocznych dla systemu i możliwych do wykorzystania przez programistę. Pozwala to programiście na zmianę słów kompilatora do specjalnych celów.
Flaga „czasu kompilacji” w polu nazwy jest ustawiona dla słów z zachowaniem „czasu kompilacji”. Większość prostych słów wykonuje ten sam kod, niezależnie od tego, czy są wpisywane w wierszu poleceń, czy osadzone w kodzie. Podczas ich kompilacji kompilator po prostu umieszcza kod lub wskaźnik wątkowy do słowa.
Klasycznymi przykładami słów używanych w czasie kompilacji są struktury kontrolne , takie jak IF
i WHILE
. Prawie wszystkie struktury kontrolne Forth i prawie cały jego kompilator są zaimplementowane jako słowa kompilacyjne. Oprócz niektórych rzadko używanych przepływu sterowania , które można znaleźć tylko w kilku implementacjach, takich jak warunkowe słowo zwrotne ?EXIT użyte w preForth Ulricha Hoffmanna, wszystkie słowa przepływu sterowania Forth są wykonywane podczas kompilacji w celu skompilowania różnych kombinacji prymitywnych słów wraz z ich gałęzią adresy. Na przykład JEŻELI
i WHILE
oraz pasujące do nich słowa ustawiają ROZGAŁĘZIĘ
(rozgałęzienie bezwarunkowe) i ?Rozgałęzienie
(zdejmują wartość ze stosu i rozgałęziają się, jeśli jest fałszywa). Słowa przepływu sterowania zliczaną pętlą działają podobnie, ale konfigurują kombinacje słów pierwotnych, które działają z licznikiem i tak dalej. Podczas kompilacji stos danych jest używany do obsługi równoważenia struktury kontrolnej, zagnieżdżania i łatania wstecznego adresów rozgałęzień. Fragment:
... DUP 6 < JEŚLI UPUŚĆ 5 W PRZECIWNYM PRZYPADKU 1 - TO ...
zostanie skompilowany do następującej sekwencji wewnątrz definicji:
... DUP LIT 6 < ?GAŁĘZIA 5 DROP LIT 5 ROZDZIAŁ 3 LIT 1 - ...
Liczby po BRANCH
reprezentują względne adresy skoku. LIT
jest prymitywnym słowem służącym do umieszczania „dosłownej” liczby na stosie danych.
Stan kompilacji i stan interpretacji
Słowo :
(dwukropek) analizuje nazwę jako parametr, tworzy wpis w słowniku ( definicję dwukropka ) i wchodzi w stan kompilacji. Interpreter kontynuuje odczytywanie słów oddzielonych spacjami z urządzenia wejściowego użytkownika. Jeśli słowo zostanie znalezione, interpreter wykonuje semantykę kompilacji skojarzoną z tym słowem, zamiast semantyki interpretacji . Domyślna semantyka kompilacji słowa polega na dołączeniu jego semantyki interpretacji do bieżącej definicji.
słowo ;
(średnik) kończy bieżącą definicję i powraca do stanu interpretacji. Jest to przykład słowa, którego semantyka kompilacji różni się od domyślnej. Semantyka interpretacji ;
(średnik), większość słów sterujących przepływem i kilka innych słów jest niezdefiniowanych w ANS Forth, co oznacza, że muszą być używane tylko wewnątrz definicji, a nie w interaktywnym wierszu poleceń.
Stan interpretera można zmienić ręcznie za pomocą słów [
(lewy nawias) i ]
(prawy nawias), które wprowadzają odpowiednio stan interpretacji lub stan kompilacji. Tych słów można użyć ze słowem LITERAL
, aby obliczyć wartość podczas kompilacji i wstawić obliczoną wartość do bieżącej definicji dwukropka. LITERAL
ma semantykę kompilacji, aby pobrać obiekt ze stosu danych i dołączyć semantykę do bieżącej definicji dwukropka, aby umieścić ten obiekt na stosie danych.
W ANS Forth aktualny stan interpretera można odczytać z flagi STATE ,
która zawiera wartość true w stanie kompilacji i false w przeciwnym przypadku. Pozwala to na implementację tak zwanych słów state-smart , których zachowanie zmienia się w zależności od aktualnego stanu tłumacza.
Natychmiastowe słowa
Słowo IMMEDIATE
oznacza najnowszą definicję dwukropka jako słowo bezpośrednie , skutecznie zastępując jego semantykę kompilacji semantyką interpretacji. Natychmiastowe słowa są zwykle wykonywane podczas kompilacji, a nie kompilowane, ale programista może to zmienić w dowolnym stanie. ;
jest przykładem bezpośredniego słowa. W ANS Forth słowo POSTPONE
przyjmuje nazwę jako parametr i dołącza semantykę kompilacji nazwanego słowa do bieżącej definicji, nawet jeśli słowo zostało oznaczone jako natychmiastowe. Forth-83 zdefiniował osobne słowa COMPILE
i [COMPILE]
, aby wymusić kompilację odpowiednio słów nie-bezpośrednich i bezpośrednich.
Nienazwane słowa i tokeny wykonania
W ANS Forth nienazwane słowa można zdefiniować za pomocą słowa :NONAME
, które kompiluje następujące słowa aż do następnego ;
(średnik) i pozostawia token wykonania na stosie danych. Token wykonania zapewnia nieprzejrzysty uchwyt dla skompilowanej semantyki, podobnie jak wskaźniki funkcji języka programowania C.
Tokeny wykonania mogą być przechowywane w zmiennych. Słowo EXECUTE
pobiera token wykonania ze stosu danych i wykonuje powiązaną semantykę. Słowo COMPILE
(kompilacja-przecinek) pobiera token wykonania ze stosu danych i dołącza powiązaną semantykę do bieżącej definicji.
Słowo '
(tick) przyjmuje nazwę słowa jako parametr i zwraca token wykonania powiązany z tym słowem na stosie danych. W stanie interpretacji ' RANDOM-WORD EXECUTE
jest równoważne z RANDOM-WORD
.
Analizowanie słów i komentarzy
Słowa :
(dwukropek), POSTPONE
, '
(tick) to przykłady parsowania słów , które pobierają argumenty z urządzenia wejściowego użytkownika zamiast ze stosu danych. Innym przykładem jest słowo (
(paren), które czyta i ignoruje następujące słowa do następnego prawego nawiasu włącznie i służy do umieszczania komentarzy w definicji dwukropka. Podobnie słowo \
(ukośnik odwrotny) jest używane do komentarzy, które nadal koniec bieżącego wiersza. Aby poprawnie przeanalizować, (
(paren) i \
(ukośnik odwrotny) muszą być oddzielone białymi znakami od następującego tekstu komentarza.
Struktura kodu
W większości systemów Forth treść definicji kodu składa się albo z języka maszynowego , albo z kodu wielowątkowego . Oryginalny Forth, który jest zgodny z nieformalnym standardem FIG (Forth Interest Group), to TIL (Threaded Interpretive Language). Jest to również nazywane kodem z wątkami pośrednimi, ale Forths z wątkami bezpośrednimi i podprogramami również stały się popularne w czasach współczesnych. Najszybsze nowoczesne Forths, takie jak SwiftForth, VFX Forth i iForth, kompilują Forth do natywnego kodu maszynowego.
Obiekty danych
Gdy słowo jest zmienną lub innym obiektem danych, system CF wskazuje na kod wykonawczy powiązany ze słowem definiującym, które je utworzyło. Słowo definiujące ma charakterystyczne „zachowanie definiujące” (tworzenie wpisu w słowniku oraz ewentualnie przydzielanie i inicjowanie przestrzeni danych), a także określa zachowanie instancji klasy słów skonstruowanych przez to słowo definiujące. Przykłady obejmują:
ZMIENNA
- Nazywa niezainicjowaną, jednokomórkową lokalizację pamięci. Zachowanie instancji
ZMIENNEJ
zwraca jej adres na stosie. CONSTANT
- Nazywa wartość (określoną jako argument dla
CONSTANT
). Zachowanie instancji zwraca wartość. CREATE
- Nazywa lokalizację; miejsce może być przydzielone w tej lokalizacji lub może być ustawione tak, aby zawierało ciąg znaków lub inną zainicjowaną wartość. Zachowanie instancji zwraca adres początku tej przestrzeni.
Forth zapewnia również funkcję, dzięki której programista może definiować nowe słowa definiujące specyficzne dla aplikacji, określając zarówno niestandardowe zachowanie definiujące, jak i zachowanie instancji. Niektóre przykłady obejmują bufory cykliczne, nazwane bity na porcie we/wy i automatycznie indeksowane tablice.
Obiekty danych zdefiniowane przez te i podobne słowa mają zasięg globalny. Funkcję zapewnianą przez zmienne lokalne w innych językach zapewnia stos danych w Forth (chociaż Forth ma również rzeczywiste zmienne lokalne). Czwarty styl programowania używa bardzo niewielu nazwanych obiektów danych w porównaniu z innymi językami; zazwyczaj takie obiekty danych są używane do przechowywania danych, które są używane przez wiele słów lub zadań (w implementacji wielozadaniowej).
Forth nie wymusza spójności użycia typów danych ; programista jest odpowiedzialny za użycie odpowiednich operatorów do pobierania i przechowywania wartości lub wykonywania innych operacji na danych.
Przykłady
"Witaj świecie!"
: WITAJ (-) CR ." Witaj świecie! " ;
CZEŚĆ Witaj świecie!
Słowo CR
(Carriage Return) powoduje wyświetlenie następującego wyniku w nowym wierszu. Parsujące słowo ."
(kropka-cytat) odczytuje łańcuch rozdzielony podwójnym cudzysłowem i dołącza kod do bieżącej definicji, dzięki czemu przeanalizowany ciąg będzie wyświetlany podczas wykonywania. Spacja oddzielająca słowo . "
z łańcucha Witaj, świecie!
nie jest częścią łańcucha. Jest to potrzebne, aby parser rozpoznał .”
jako Czwarte słowo.
Standardowy system Forth jest również interpreterem i ten sam wynik można uzyskać, wpisując następujący fragment kodu w konsoli Forth:
CR . ( Witaj świecie!)
.(
(kropka-nawias) jest natychmiastowym słowem, które analizuje łańcuch rozdzielony nawiasami i wyświetla go. Podobnie jak w przypadku słowa ." znak
spacji oddzielający .(
od Hello, World!
nie jest częścią ciągu.
Słowo CR
pojawia się przed tekstem do wydrukowania. Zgodnie z konwencją, interpreter Forth nie rozpoczyna wyjścia w nowej linii. Zgodnie z konwencją, interpreter czeka na wejście na końcu poprzedniego wiersza, po ok
. W CR
firmy Forth nie ma dorozumianej akcji „opróżniania bufora” , jak to czasami ma miejsce w innych językach programowania.
Mieszanie stanów kompilacji i interpretacji
Oto definicja słowa EMIT-Q
, które po wykonaniu emituje pojedynczy znak Q
:
: EMIT-Q 81 ( wartość ASCII dla znaku 'Q' ) EMIT ;
Ta definicja została napisana w celu bezpośredniego użycia wartości ASCII znaku Q
(81). Tekst w nawiasach jest komentarzem i jest ignorowany przez kompilator. Słowo EMIT
pobiera wartość ze stosu danych i wyświetla odpowiedni znak.
Poniższa redefinicja EMIT-Q
wykorzystuje słowa [
(lewy nawias), ]
(prawy nawias), CHAR
i LITERAL
, aby tymczasowo przełączyć się w stan interpretera, obliczyć wartość ASCII znaku Q
, powrócić do stanu kompilacji i dołączyć obliczoną wartość do bieżącej definicji dwukropka:
: EMIT-Q [ ZNAK Q ] LITERAL EMIT ;
Słowo analizujące CHAR
przyjmuje słowo rozdzielane spacjami jako parametr i umieszcza wartość pierwszego znaku na stosie danych. Słowo [CHAR]
jest bezpośrednią wersją CHAR
. Używając [CHAR]
przykładową definicję EMIT-Q
można przepisać w następujący sposób:
: EMIT-Q [ZNAK] Q EMIT ; \ Wyemituj pojedynczy znak „Q”
W tej definicji użyto \
(ukośnik odwrotny) dla komentarza opisującego.
Zarówno CHAR,
jak i [CHAR]
są predefiniowane w ANS Forth. Używając IMMEDIATE
i POSTPONE
, [CHAR]
można zdefiniować w następujący sposób:
: [CHAR] CHAR POSTPONE LITERAL ; NATYCHMIASTOWY
Kompletny program szyfrujący RC4
W 1987 r. Ron Rivest opracował system szyfrowania RC4 dla RSA Data Security, Inc. Jego opis jest następujący:
Mamy tablicę 256 bajtów, wszystkie różne. Za każdym razem, gdy używana jest tablica, zmienia się ona poprzez zamianę dwóch bajtów. Zamiany są kontrolowane przez liczniki i oraz j , każdy początkowo 0. Aby otrzymać nowe i , dodaj 1. Aby otrzymać nowe j , dodaj bajt tablicy w nowym i . Wymień bajty tablicy w i i j . Kod jest bajtem tablicy jako sumą bajtów tablicy w i oraz j . Jest to XORowane z bajtem tekstu jawnego do zaszyfrowania lub tekstem zaszyfrowanym do odszyfrowania. Tablica jest inicjowana przez ustawienie jej najpierw na wartości od 0 do 255. Następnie przejdź przez nią, używając i i j , uzyskując nowy j przez dodanie do niej bajtu tablicy w i i bajtu klucza oraz zamianę bajtów tablicy w i i j . Ostatecznie i i j są ustawione na 0. Wszystkie dodatki są modulo 256.
Poniższa wersja Standard Forth używa tylko słów Core i Core Extension.
0 0
0 0
0 0
0
wartość ii wartość jj wartość KeyAddr wartość KeyLen utwórz SArray 256 allot \ state tablica 256 bajtów : KeyArray KeyLen mod KeyAddr ; : get_byte + c@ ; : set_byte + c! ; : as_bajt 255 i ; : reset_ij TO ii TO jj ; : i_update 1 + as_byte TO ii ; : j_update ii SArray get_byte + as_byte TO jj ; : swap_s_ij jj SArray get_byte ii SArray get_byte jj SArray set_byte ii SArray set_byte ; : rc4_init ( KeyAddr KeyLen -- ) 256 min TO KeyLen TO KeyAddr 256 DO i i SArray set_byte LOOP reset_ij BEGIN ii KeyArray get_byte jj + j_update swap_s_ij ii 255 < WHILE ii i_update REPEAT reset_ij ; : rc4_byte ii i_update jj j_update swap_s_ij ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor ;
Jest to jeden z wielu sposobów testowania kodu:
0
hex utwórz AKey 61 c, 8 A c, 63 c, D2 c, FB c, : test cr DO rc4_byte . PĘTLA cr ; AKey 5 rc4_init 2 C F9 4 C EE DC 5 test \ wyjście powinno być: F1 38 29 C9 DE
Implementacje
Ponieważ Forth jest prosty do wdrożenia i nie ma standardowej implementacji referencyjnej, istnieje wiele wersji tego języka. Oprócz obsługi standardowych odmian systemów komputerów stacjonarnych ( POSIX , Microsoft Windows , macOS ), wiele z tych systemów Forth jest również przeznaczonych dla różnych systemów wbudowanych . Wymieniono tutaj niektóre systemy, które są zgodne z normą ANS Forth z 1994 roku.
- ASYST, podobny do Forth system do zbierania i analizy danych
- Gforth , przenośna implementacja ANS Forth z Projektu GNU
- noForth , implementacja ANS Forth (o ile to możliwe) dla mikrokontrolerów Flash (MSP430 i Risc-V)
- Open Firmware , program ładujący i standard oprogramowania układowego oparty na ANS Forth
- pForth , przenośny Forth napisany w C
- SP-Forth , ANS Forth wdrożenie z rosyjskiej Forth Interest Group (RuFIG)
- Swift Forth, implementacja generująca kod maszynowy firmy Forth, Inc.
- VFX Forth, optymalizacja natywnego kodu Forth
Zobacz też
- RTX2010 , procesor z natywną obsługą Forth
Notatki
Dalsza lektura
- Biancuzzi Federico; Strażnik, Shane (2009). „4. [Rozmowa z Chuckiem Moore'em]”. Mistrzowie programowania, Rozmowy z twórcami głównych języków programowania . O'Reilly. ISBN 978-0-596-51517-1 .
- Brodie, Lew (1987). Zaczynając od przodu (wyd. 2). Prentice Hall. ISBN 978-0-13-843079-5 .
- Brodie, Leo (2007). Marcela Hendrixa (red.). Zaczynając od przodu . Marlin Ouverson (red. Internet). FORTH, Inc. Źródło 2007-09-29 .
- Brodie, Leo (2004). Paysan, Bernd (red.). Myślenie naprzód (książka PDF online) . ISBN 978-0-9764587-0-8 . Źródło 2008-09-15 .
- Conklin, Edward K.; Raczej Elżbieta D.; i in. (8 września 2007). Czwarty podręcznik programisty (wyd. 3). Wydawnictwo BookSurge. P. 274. ISBN 978-1-4196-7549-2 .
- Raczej Elizabeth D. (2000). Czwarte techniki aplikacji (spiralne) . Naprzód Inc. str. 158. ISBN 978-0-9662156-1-8 .
- Pelc, Stephen F. (2005). Programowanie do przodu (po spirali) . MicroProcessor Engineering Sp. 188.
- Kelly, Mahlon G.; Szpiedzy, Mikołaj (1986). DALEJ: Tekst i odnośniki . Prentice Hall. ISBN 978-0-13-326331-2 .
- Koopman, Jr, Philip J. (1989). Komputery stosowe: nowa fala . Ellisa Horwooda. ISBN 978-0-7458-0418-7 .
- Pountain, Dick (1987). Zorientowany obiektowo Forth: Implementacja struktur danych . Harcourt Brace Jovanovich. ISBN 978-0-12-563570-7 .
- Payne, William (19 grudnia 1990). Wbudowany kontroler dla rodziny 8051 . Elsevier. P. 528. ISBN 978-0-12-547570-9 .
- Winfield, Alan (1983). Kompletna Czwarta . Johna Wileya. ISBN 978-0471882350 .
- Baglioni, Gio Federico (1983). Czwarty dla VIC20 i CBM64 . Jacksona. ISBN 978-88-7056-141-8 .
Linki zewnętrzne
- Programowanie języka zorientowanego na problemy , niepublikowana książka, Charles H. Moore, czerwiec 1970
- Oprogramowanie z 1970 roku
- Konkatenatywne języki programowania
- Rozszerzalne języki programowania składni
- Czwarta rodzina języków programowania
- Języki programowania
- Języki programowania stworzone w 1970 roku
- Języki programowania zgodne ze standardem ISO
- Maszyny wirtualne oparte na stosie
- Języki programowania systemów