Arabski jest językiem Raju? W jakim języku mówił Adam i dlaczego w raju jest fajnie? Jakim językiem mówi się w raju?
Opracowany adaptacyjny język PARADISE interaktywnego systemu programowania DSSP Moskovsky Uniwersytet stanowy Wydział Matematyki Obliczeniowej i Cybernetyki N.P. Brusentsov, V.B. Zakharov, I.A. Rudnev, S.A. Sidorov, N.A. Chanyshev Moskwa, 1987
Ogólny opis języka PARA
Cel i cel rozwoju języka
PARA (Evolved Adaptive Language) jest podstawowym językiem systemu konwersacyjnego DSSP dla programowania strukturalnego. Podstawowy - oznacza będący podstawą wszelkich dalszych konstrukcji realizowanych w DSSP poprzez rozwijanie (rozwijanie, wzmacnianie) języka bazowego i być może adaptację tych stworzonych w ten sposób narzędzia językowe do konkretnego zastosowania. W przeciwieństwie do tzw. języków wysoki poziom, PARADISE nie dostarcza gotowych typów danych i operacji, a jedynie elementy i prymitywy do efektywnego definiowania wymaganych typów. Na przykład oryginalne formaty danych to bajt 8-bitowy, słowo 16-bitowe i słowo długie 32-bitowe, które są interpretowane w zależności od wykonywanych na nich operacji jako liczby całkowite, wektory logiczne, kody znaków, wartości logiczne, dane i procedury wskaźniki. W takim przypadku można z jednej strony manipulować pojedynczymi bitami bajtów i słów, a z drugiej tworzyć złożone jednostki danych (słowa o wielu długościach, wektory, tablice, wiersze tekstu itp.), ustalenie dla nich takiej lub innej interpretacji wprowadzenie odpowiednich operacji. Można więc wprowadzić liczby rzeczywiste o wymaganej długości i zakresie wartości, liczby zespolone i inne obiekty, a wersja języka skupiona na danej aplikacji będzie zawierała obiekty i środki tkwiące w tej aplikacji i nie będzie zawierała tego, co nie dotyczy do niego - język zostanie dostosowany (dostosowany) do aplikacji. Rozwój DSSP miał na celu stworzenie ogólnodostępnego i wydajnego narzędzia do programowania mikrokomputerów, tj. komputery oparte na mikroprocesorach. Istotną cechą architektury mikroprocesorów jest elementarność typów danych i operacji, co oznacza z jednej strony uniwersalność, az drugiej złożoność programowania. Ze względu na swoją wszechstronność mikroprocesory i oparte na nich mikrokomputery mają potencjalnie nieograniczone zastosowania. Praktyczna realizacja tych możliwości polega jednak przede wszystkim na złożoności opracowania niezbędnych programów użytkowych. Co więcej, zadowalający programy użytkowe można stworzyć tylko przy głębokiej i subtelnej znajomości specyfiki poszczególnych aplikacji, tj. powinny być opracowywane nie tylko przez programistów, ale przez wysoko wykwalifikowanych specjalistów z danej dziedziny. Dlatego system programowania powinien nie tylko w dużym stopniu zwiększać produktywność programistów, ale także być na tyle prosty, aby mógł go opanować i efektywnie wykorzystywać nieprofesjonalni programiści.
Radykalnym rozwiązaniem tego problemu byłoby najwyraźniej znaczne uproszczenie architektury komputerowej. Niestety, architektura mikrokomputerów rozwija się w diametralnie odwrotnym kierunku - na ścieżce rosnącej złożoności i wyrafinowania, więc profesjonalnemu programiście nie jest dziś łatwo opanować język składania mikrokomputerów. Języki programowania systemów, takie jak C czy PL/M, w pewnym (choć dalece niewystarczającym) ograniczyły złożoność wytwarzania oprogramowania, ale trudno je polecić osobom, które nie mają doświadczenia w branży programistycznej. Szeroko dostępny język powinien oczywiście być prostszy i bardziej naturalny, powinien opierać się na najzwyklejszych, znanych wyobrażeniach o istocie i technice programowania.
Oprócz dostępności i znacznego zmniejszenia złożoności tworzonych programów w porównaniu do programowania w asemblerze, DSSP wymagało uniwersalności języka, takiej samej jak asemblera, dużej wydajności maszyny (tj. zwartości i szybkości kodu) , niezawodność weryfikowalności tworzonych programów oraz ich serwisowalność i modyfikowalność, a także mobilność (przenośność) systemu i opracowanych w nim programów na maszyny o różnych architekturach.
programowanie proceduralne
Programowanie w języku PARADISE jest dość podobne do tak rozpowszechnionych typów ludzka aktywność jak planowanie i organizowanie powiązanych ze sobą działań, prac, procesów czy projektowanie złożonych obiektów materialnych - maszyn, jednostek, konstrukcji. Jak konstruktor realizujący swój projekt przez agregację części składowe(bloki, węzły, części) programista syntetyzuje wymaganą złożoną akcję z prostych akcji dostarczanych przez język. Można też powiedzieć, że programowanie (konstrukcja) polega na stopniowym rozkładzie (dekompozycji) zaimplementowanego obiektu na coraz mniejsze komponenty.
W języku RAJ głównym "konstruktywnym" jest procedura - nazwane działanie. Język opiera się na ograniczonym zestawie najprostszych procedur (prymitywów) reprezentowanych przez własne nazwy (notacje). Na przykład: + oznacza "dodaj", NEG oznacza "odwrócony znak", VCTR oznacza "utwórz wektor". W szczególności istnieją prymitywne: i; (dwukropek i średnik), pozwalające na wprowadzenie nowej procedury np. o nazwie P, definiując ją jako ciąg procedur P1, P2, ..., PN w postaci
: P P1 P2 ... PN ;
Jeżeli procedura P reprezentuje akcję, którą powinien wykonać stworzony program, to konstrukcja tego programu za pomocą języka PARA sprowadza się do sekwencyjnego uszczegóławiania procedur P1, P2, ..., PN. Oznacza to, że każda z tych procedur musi być zdefiniowana przez sekwencję mniejszych procedur, które następnie są definiowane przez sekwencje jeszcze mniejszych procedur i tak dalej, aż do uzyskania definicji składających się tylko z prymitywów.
Taka konstrukcja programu, zaczynając od określonego celu i stopniowo rozkładając stosowane procedury do poziomu podstawowych cech języka, nazywana jest programowaniem odgórnym. Jest to główny sposób na uzyskanie programów w języku PARADISE do rozwiązywania pojedynczych, dobrze zdefiniowanych zadań. Przeciwieństwem jest programowanie oddolne - budowanie w oparciu o podstawowy język systemu stopniowo rozszerzanych procedur skoncentrowanych na określonym obszarze problemowym. W ten sposób realizowany jest rozwój języka i jego adaptacja do konkretnego zastosowania.
W obu przypadkach niezbędna jest staranna struktura tworzonych programów: każdy program i każda jego część musi składać się z niewielkiej liczby oddzielnych części, z których każda pełni określoną funkcję i umożliwia autonomiczną weryfikację. W odniesieniu do języka PARA oznacza to w szczególności, że definicje procedur powinny być krótkie: sekwencja definiująca z reguły nie powinna zawierać więcej niż 5-7 członów. Strukturyzacja zapewnia zrozumiałość, testowalność i modyfikowalność programu, znacznie zmniejsza złożoność jego tworzenia i utrzymania.
Powyższy przykład zdefiniowania procedury P jest uproszczony. W rzeczywistości sekwencja definiująca może zawierać jako człony nie tylko nazwy procedur, ale także nakazy (polecenia) składające się z więcej niż jednego słowa. Nazwa procedury, używana bez kombinacji z innymi słowami, jest poleceniem wykonania wyznaczonej przez nią procedury. Sekwencja nazw procedur instruuje wykonanie tych procedur w kolejności ich nazw jedna po drugiej (w porządku liniowym). Aby ustawić inne sekwencje wykonywania, PARA zapewnia specjalne słowa (przedrostki), które nakazują wykonanie procedur nazwanych w połączeniu z nimi, w zależności od określonego warunku, a także wielokrotne (cykliczne) wykonywanie procedury.
Na przykład sekwencja liniowa P0 P1 powoduje wykonanie procedury P0, a następnie wykonanie procedury P1. Jeżeli procedura P1 nie musi być zawsze wykonywana, a tylko wtedy, gdy w wyniku wykonania P0 uzyskana zostanie liczba dodatnia, to zamiast P1 zapisywana jest komenda wykonania zgodnie z warunkiem: JEŻELI + P1, tj. zamiast P0 P1 będzie to P0 JEŻELI+P1. PARA zawiera zestaw prefiksów-warunków, które pozwalają skutecznie wyrazić wykonanie warunku, a także wybór dwóch, trzech lub więcej procedur.
Wielokrotne wykonanie procedury jest określane za pomocą prefiksu RP. Tak więc komenda RP P powoduje, że procedura P jest wykonywana raz za razem, aż zostaną stworzone warunki, w których wyzwalane jest EX zawarte w ciele tej procedury - wyjście z pętli, po czym wykonywane jest kolejne polecenie w kolejności liniowej . Warunkiem wyjścia z pętli może być np. równość do zera jakiejś zmiennej X, co wyraża się jako:
Procedura, której nazwa jest zawarta w definicji innej procedury, nazywana jest w niej zagnieżdżoną. Procedura zagnieżdżona, jeśli nie jest pierwotną, może z kolei zawierać procedury zagnieżdżone, tj. zagnieżdżenie może być wielokrotne. Ponadto reguły języka PARA nie zabraniają umieszczania w definicji procedury własnej nazwy lub nazwy procedury zawierającej tę nazwę, tj. PARA umożliwia rekurencję.
Wielokrotnie wykonywana procedura może być również zagnieżdżona w wielokrotnie wykonywanej procedurze. W takim przypadku ma miejsce zagnieżdżanie pętli. PARADISE umożliwia wielokrotne zagnieżdżanie pętli.
Liniowa sekwencja poleceń, zagnieżdżanie, warunkowe i cykliczne zagnieżdżanie procedur – to wyczerpuje możliwości konstruowania programów w języku RAYA. Niedobór, jednorodność i naturalność tych środków jest kluczem do łatwości opanowania i posługiwania się językiem. Jednocześnie jest to rygorystyczny, ustrukturyzowany język programowania, który zapewnia znaczne zmniejszenie złożoności tworzenia i niezawodności programów.
Procedury i dane
Wszystko, co zostało powiedziane do tej pory, jest cechą charakterystyczną języka RAJ jako środka zapisywania działań, konstruowania dowolnych działań ze skończonego zbioru operacji pierwotnych. Drugą stroną języka są sposoby przedstawiania obiektów, na których działania, środki prezentacja i organizacja danych.
Niezwykle prostym elementem danych jest element dwuwartościowy - bit. Bity to elementy składowe wszystkich innych formatów i typów danych. W języku PARADISE jako podstawowe formaty akceptowane są 8-bitowe bajty, 16-bitowe słowo i 32-bitowe słowo długie. W zależności od wykonywanych na nich operacji bajty, słowa i longwordy podlegają wielu interpretacjom, m.in. może służyć jako podstawa różne rodzaje dane. Ponadto są początkowymi elementami do tworzenia formatów i typów kompozytowych.
Właściwie PARADISE nie zawiera ani prostych, ani złożonych typów danych - są tylko podstawowe formaty (bajt, słowo, długie słowo) oraz środki do konstruowania z nich formatów złożonych: wektory i tablice wielowymiarowe. W tym przypadku te same bajty (słowa, długie słowa), w zależności od wykonanych na nich operacji, są interpretowane jako wektory bitów, lub jako binarne liczby całkowite ze znakiem lub bez, lub jako litery alfabetu wejścia/wyjścia itp. Typy danych i związane z nimi ograniczenia i kontrole można wprowadzać w rozszerzeniach językowych specyficznych dla domeny.
W języku bazowym deklaracja nazw danych pełni jedynie funkcję udostępniania danych po nazwie: z nazwą powiązana jest liczba komórek pamięci wymaganych przez deklarację oraz mechanizm dostępu do nich. Operacje testowania i transformacji nie są bezpośrednio stosowane do nazwanych danych. Operacje te są definiowane na stosie operandów, który jest sekwencją 32-bitowych słów (elementów stosu) dynamicznie modyfikowaną poprzez dodawanie (wypychanie) nowych elementów na jego koniec, a także usuwanie elementów z tego samego końca (wyskakiwanie z stos). Elementy są wycofywane w kolejności odwrotnej do tej, w jakiej zostały wysłane: ostatni wysłany jest wycofywany jako pierwszy. Dane do przetestowania lub przekształcenia są wysyłane na stos, gdzie wykonywane są na nich określone operacje, po czym wyniki przetwarzania można usunąć ze stosu.
Na przykład, jeśli istnieje zmienna X zadeklarowana jako słowo o długości 32 bitów, to bezpośrednio na niej można wykonać tylko dwie operacje:
1) wypychanie jej wartości na stos, co następuje automatycznie za każdym razem, gdy wymieniana jest nazwa X,
2) przypisanie go do zespołu! Wartość X ostatniego (górnego) elementu do usunięcia ze stosu.
Jeśli, powiedzmy, chcesz podwoić wartość X, dodając ją do siebie, możesz to zrobić, wykonując następujące polecenia jedno po drugim:
Dwa wystąpienia wartości X zostaną wepchnięte na stos, następnie polecenie + usunie je, zsumuje i wrzuci wynikową ilość na stos, po czym polecenie! X wycofa tę kwotę i przypisze jej wartość do zmiennej X.
Zwykłe dla języków wysokiego poziomu pisanie podanego przykładu w postaci X:=X+X jest bardziej znane programiście, ale nie jest bezpośrednim odzwierciedleniem sekwencji poleceń wykonywanych przez procesor, ale jest rodzaj wzoru matematycznego. Jest to wygodne przy programowaniu problemów obliczeniowych, jednak w języku bazowym ważniejsza wydaje się korespondencja jeden-do-jednego z wykonywanymi poleceniami, ponieważ program można sprawdzić polecenie po poleceniu bezpośrednio w języku programowania i na ogół nie jest wymagana znajomość języka innego niż język procesora.
Jednak szczególnie cenną korzyścią ze stosu danych jest to, że procedury testowania i transformacji mogą być definiowane i implementowane niezależnie od danych, do których są stosowane. Operacje testowania i transformacji są formułowane nie w odniesieniu do identyfikatorów danych (lub nazw stałych i zmiennych, parametrów formalnych), ale w odniesieniu do elementów stosu, do których wartości operandów muszą być przypisane do czasu wykonania operacji. Na przykład operacja dodawania dwóch liczb, wykonywana poleceniem + (dodaj), polega na pobraniu dwóch górnych elementów (górnego i dolnego) jako sum ze stosu, obliczeniu ich sumy i wysłaniu na stos. Aby dodać dwie liczby, musisz wysłać ich wartości na stos i wykonać polecenie +, wynik będzie na szczycie stosu.
Procedurę test-transformację z dowolną liczbą parametrów wejściowych i wyjściowych można zatem zdefiniować po prostu jako nazwaną akcję (bez listy parametrów) wykonywaną na stosie zawierającym wartości argumentów w określonej kolejności, a po wykonaniu wartości wynikowe . Aby zastosować taką procedurę do jednego lub drugiego zestawu określonych danych, konieczne jest przesłanie tych danych w odpowiedniej kolejności na stos. Po ich spożyciu procedura pozostawi na stosie (również ułożonym w określonej kolejności) swoje wyniki.
Innymi słowy, nazwy procedur w języku PARA są używane w taki sam sposób jak znaki operacji i są w istocie symbolami operacji o dowolnej liczbie argumentów. Zgodnie z zasadą działania stosu, operacje zapisywane są w postaci postfiksowej, tj. Nazwa operacji jest umieszczana po liście nazw lub wartości jej operandów. Na przykład, jeśli oznaczymy operację uzyskania sumy trzech liczb symbolem ++, to suma liczb A, 5 i B zostanie wyrażona w następujący sposób:
Byłoby możliwe ustalenie formalnych reguł języka postfiksowego i kierowanie się nimi podczas pisania programów, ale łatwiej i bardziej niezawodnie człowiekowi radzić sobie nie z regułami, ale z modelem procesora stosu, tj. z modelem maszyny, dla której tworzone są programy i która je wykona. W przypadku języka PARA taką maszyną jest procesor DSSP - zestaw sprzętu i programów realizujących czynności zalecone w tym języku.
Procesor DSSP
Fizycznie procesor DSSP może być zaimplementowany w postaci mikroprocesora o tej prostej i wydajnie programowalnej architekturze, która umożliwiłaby jak najlepsze rozwiązanie problemu oprogramowania mikrokomputerowego. Ale taki mikroprocesor nie został jeszcze stworzony, a jego architektura musi być emulowana na istniejących mikrokomputerach w celu poprawy ich programowalności. Oczywiście emulacja wiąże się z kosztami – wymaga pamięci i czasu komputera, ale w przypadku emulacji procesora PRSP koszty te są stosunkowo niewielkie.
Z punktu widzenia programisty cechą procesora jest jego architektura, czyli informacje o tym, jaki jest ten procesor jako narzędzie do przetwarzania danych, jakie są możliwości prezentacji danych na wejściu i wewnątrz procesora, jakie są operacje testowania i konwersji danych, jak zorganizowana jest własna pamięć procesora, a także dostęp do pamięci głównej i zewnętrznej, jakie są kontrolki przebieg programu, interakcja z otoczenie zewnętrzne, reakcja na wyjątkowe wydarzenia itp. Mistrzostwo architektury to warunek konieczny sensowne (nieformalne) programowanie, które znacznie zmniejsza liczbę błędów i zwiększa niezawodność programów.
Centralnym elementem procesora DSSP jest wspomniany już stos operandów. W rzeczywistości przetwarzanie odbywa się w stosie i z reguły dane są przesyłane przez stos. Poszczególne polecenia i krótkie sekwencje poleceń nad stosem można wykonać, dostarczając je do wejścia procesora bezpośrednio z klawiatury terminala. W tym przypadku procesor DSSP imituje działanie kalkulatora postfiksowego. Liczby wprowadzane z klawiatury oraz mnemoniczne kody operacji są oddzielone spacjami. Wprowadzony tekst jest wyświetlany jako ciąg znaków na ekranie terminala. Sygnałem zakończenia wprowadzania i poleceniem do procesora „Wykonaj wprowadzoną instrukcję” jest naciśnięcie klawisza
Na przykład, aby obliczyć wyrażenie (2-5)*3 i wyświetlić wynik, wprowadź:
2 5 - 3 * .
Po naciśnięciu klawisza
* 2 5 - 3 * . -90
Gwiazdka na początku linii jest wysyłana przez procesor jako sygnał, że oczekuje na dane wejściowe.
W rozważanym przykładzie procesor postrzegał i przetwarzał wprowadzone liczby jako liczby dziesiętne. W rzeczywistości, podczas wprowadzania, liczby te były konwertowane na binarny kod komplementarny, a podczas wyprowadzania były konwertowane z powrotem na dziesiętny. Procesor PRSP umożliwia również tryby binarne, ósemkowe i szesnastkowe we/wy. Aby przejść do żądanego trybu, musisz wykonać odpowiednio jedno z poleceń B2, B8, B10, B16.
Naciskanie klawiszy powoduje wprowadzenie kodów procesora reprezentujących litery wskazane na tych klawiszach (litery, cyfry, znaki interpunkcyjne, symbole operacji). Sekwencja znaków wejściowych tworzy ciąg wejściowy - łańcuch bajtów zawierający kody znaków, jeden bajt na znak. Maksymalna długość ciągu wejściowego to 80 znaków.
Przetwarzając ciąg wejściowy, procesor wyodrębnia z niego słowa - kombinacje liter oddzielonych od siebie spacjami i interpretuje je. Jeżeli przetwarzanym słowem jest znana procesorowi nazwa operacji (procedury) lub podana nazwa, to procesor wykonuje akcje, które z definicji ta nazwa powinna wywołać. Jeśli słowo nie jest znane procesorowi, próbuje zinterpretować je jako liczbę, biorąc pod uwagę ustawiony tryb wejścia / wyjścia.
Liczby to słowa składające się z cyfr akceptowanych w danym systemie liczbowym i być może zawierające znak minus jako pierwszą literę. W szesnastkowym trybie wejścia/wyjścia ważne są również litery łacińskie A, B, C, D, E, F. Odebrana liczba jest konwertowana na kod dopełniający do dwóch i wysyłana do stosu argumentów jako słowo o długości 32 bitów. W takim przypadku, jeśli wartość liczby znajduje się poza zakresem reprezentowalnych wartości-2147483648: 2147483647, to jest ona zastępowana wartością porównywalną modulo 2**32 z tego zakresu.
W przypadku, gdy przetwarzane słowo nie jest znane procesorowi i nie może zostać zaakceptowane jako liczba, procesor wyświetla komunikat na ekranie terminala: „Nie wiem<обрабатываемое слово>i czeka na dalsze instrukcje.
Wprowadzanie danych w postaci dowolnego tekstu (ciągu bajtów-literałów) odbywa się w postaci literałów tekstowych, które są tekstem ujętym w podwójne cudzysłowy, np.: "Literał tekstowy". Odebranie literału tekstowego na wejściu procesora powoduje, że tekst zawarty między cudzysłowami jest zapisywany do pamięci głównej w postaci ciągu bajtów-litrów. W tym przypadku adres pierwszego bajtu i liczba bajtów (długość tekstu) są odkładane na stos. Literał tekstowy poprzedzony kropką jest interpretowany przez procesor jako polecenie "umieszczenia tekstu między cudzysłowami na ekranie terminala". Na przykład podanie na wejście procesora kombinacji znaków „Brak pamięci” spowoduje pojawienie się na ekranie komunikatu: Brak pamięci.
Kod pojedynczego znaku jest odkładany na stos jako młodszy bajt wierzchołka, gdy ten znak dociera do wejścia procesora, wraz z poprzedzającym go znakiem #. Na przykład kombinacja znaków #L wyśle kod litery L na stos, kombinacja znaków #5 wyśle kod liczby 5. Polecenie TOB do wysłania bajtu do terminala wyświetla znak, którego kod jest zawarte w młodszym bajcie wierzchołka stosu.
Nawet w trybie bezpośredniego wykonywania instrukcji procesor PRSP znacznie przekracza możliwości konwencjonalnego kalkulatora, zapewniając użytkownikowi, oprócz operacji przetwarzania danych, możliwość deklarowania nazwanych danych i definiowania procedur, które mogą być następnie wykorzystywane wraz z podstawowe operacje. Deklarowanie nazw danych i definiowanie procedur odbywa się za pomocą specjalnych poleceń.
Np. aby utworzyć zmienną 16-bitową o nazwie np. TEMP, należy wpisać na klawiaturze i zastosować do wejścia procesora klawiszem
ZMIENNA TEMP
Wraz z deklaracją możesz przypisać zmiennej wartość początkową, na przykład 0:
WAR.TEMP 0 ! TEMP
Teraz pojawienie się nazwy TEMP na wejściu procesora spowoduje, że bieżąca wartość tej zmiennej zostanie wepchnięta na stos, a przypisanie jej nowej wartości, usuniętej ze stosu, można wykonać poleceniem! TEMP.
Definicję procedury wprowadza komenda: (dwukropek) zawierająca nazwę definiowanej procedury i określająca ciąg komend z literą; (średnik) jako znak końca definicji. Zademonstrujmy definicję i zastosowanie procedur na przykładzie obliczenia silni liczby naturalnej N ze wzoru
N!=N*(N-1)*(N-2)*...*2*1, czyli Mnożenie N-1.
Procedura FCT, aby uzyskać pożądany wynik, musi pomnożyć podaną liczbę N przez sukcesywnie malejące liczby, zaczynając od N-1 do 1, tj. tylko N-1 razy. W PARA jest to programowane przez wykonanie procedury P t razy: DO P, gdzie P jest nazwą procedury, t jest bieżącą wartością wierzchołka stosu, wskazującą, ile razy procedura P ma być wykonana.
Załóżmy, że przed zastosowaniem procedury FCT liczba N została wsunięta na stos i znajduje się na jego szczycie. Aby procedura była bardziej zrozumiała, przedstawiamy modyfikowalny mnożnik zmiennej K:
Wprowadzamy definicję procedury FCT w postaci:
FCT [N] ! K K K 1-DO F . [N] ;
Komentarze w nawiasach kwadratowych odzwierciedlają aktualny stan stosu operandów. Zespół! K, który rozpoczyna zdefiniowaną procedurę, przypisuje wartość liczby N pobranej ze stosu do zmiennej K. Następnie K jest dwukrotnie odkładany na stos i odejmując 1 na szczycie stosu, liczbę wykonań powtórzonego powstaje procedura F równa N-1. Po tym następuje polecenie DO F, które przypisuje pętlę, po której wierzchołek stosu będzie zawierał żądaną wartość silni - N!. Zespół. (kropka) wyświetla kopię tej wartości na ekranie terminala. Pozostaje zdefiniować procedurę F, która modyfikuje wartość K poprzez odjęcie 1 i mnożenie przez K częściowego wyniku obliczenia R zawartego na stosie. :
F [R] K 1- ! K [R] K * ;
Poprawność obu procedur sprawdza się wykonując ich definicje komenda po komendzie, po każdym poleceniu wyświetlając zawartość stosu operandu i wartość zmiennej K na ekranie terminala. stos musi zawierać wartość N!, a wartość zmiennej K musi być równa 1.
Sprawdzone i poprawione (jeśli w procesie weryfikacji wykryto błędy) procedury są testowane przez zastosowanie ich do poszczególnych wartości liczby N. Ponieważ procedura F jest zagnieżdżona w FCT, jej testowanie odbywa się automatycznie w procesie testowania ten ostatni. Należy pamiętać, że wartości wynikowe nie powinny przekraczać maksymalnej liczby dodatniej reprezentowanej w kodzie dopełniającym do dwójki przez 32-bitowe słowo: 2147483647, czyli FCT daje poprawne wyniki tylko dla N=1, ..., 13.
Używanie FCT nie różni się od używania instrukcji procesora natywnego: aby uzyskać wynik, musisz określić wartość operandu i wpisać nazwę procedury:
5 FCT
7 FCT
Powyższa implementacja procedury FCT wymagała wprowadzenia zmiennej pomocniczej K, jednakże procedurę równoważną funkcjonalnie można przeprowadzić bez zmiennej pomocniczej, wykorzystując operację C, która wypycha kopię jej wierzchołka na stos, a operacje E2 i E3, które wymieniają wierzchołek odpowiednio z drugim i trzecim elementem stosu. Definicja tej procedury jest następująca.
: FCTA [N] C 1- C DO FA D . ;
: POWIERZCHNIA E3 * E2 1- ;
Zaletą takiej procedury „czystego stosu” jest jej pełna autonomia: podobnie jak podstawowe operacje procesora na stosie, jest ona wykonywana tylko na stosie operandów, nie wymagając dodatkowej pamięci i nie powodując żadnych zmian w innych elementach procesora.
Nazwy definiowanych procedur i deklarowane dane są wprowadzane do słownika procesora, który ustanawia związek między tymi nazwami a nazwanymi obiektami, czyli z ciałami procedur znajdujących się w pamięci głównej oraz z elementami tego pamięć przydzielona do przechowywania zadeklarowanych danych. Przetwarzając następne słowo ze strumienia wejściowego, procesor przegląda słownik i po znalezieniu w nim pasującego słowa wykonuje działania związane z tym słowem. Jeśli wyszukiwanie okazało się nieudane, to, jak już wspomniano, podjęto próbę interpretacji numerycznej danego słowa, a jeśli to się nie powiedzie, to pojawia się komunikat, że procesor nie zna tego słowa.
W wyniku kompilacji definicji procedury do słownika wprowadzana jest nazwa tej procedury oraz wskaźnik (adres) jej ciała, który jest ciągiem wskaźników procedur i danych składających się na definicję. Innymi słowy, wewnętrzną reprezentację ciała procedury uzyskuje się przez zastąpienie nazw procedur i danych w jej definicji wskaźnikami do odpowiednich ciał, które z kolei są tymi samymi sekwencjami wskaźników, a w przypadku prymitywów łańcuchy instrukcji maszynowych. Nazywamy tę wewnętrzną reprezentację kodu proceduralnego programu.
Gdy wraz z kompilacją definicji procedury P kompilowane są również definicje wszystkich nieznanych wcześniej procedur zagnieżdżonych, powstaje pełna hierarchia wskaźników, która zapewnia możliwość wykonania procedury P poprzez podanie tylko jej nazwy do wejście procesora. W tym przypadku nazwy procedur zagnieżdżonych skompilowano w związku z definicją P, jeśli nie trzeba osobno uzyskiwać dostępu do tych procedur, nie ma sensu przechowywać ich w słowniku. W wielu przypadkach właściwe okazuje się zablokowanie dostępu do tej lub innej części słownika, pozostawiając być może możliwość wykonywania tylko niektórych procedur.
Aby spełnić te wymagania, słownik zaimplementowany jest jako zbiór podskryptów, na których definiowane są operacje umożliwiające tworzenie i niszczenie podskryptów i ich części, usuwanie nazw, zamykanie i otwieranie dostępu do określonych podskryptów. Każdy podsłownik ma nazwę, która jest używana w powiązanych z nim poleceniach. Nazwy słowników muszą zaczynać się od litery $, na przykład: $PRIME, $EDIT, $FLOAT, $TEXTPROC, $GRAPHICS.
Podsłownik $PRIME, zawierający podstawowy zestaw słów PRSP, jest otwierany po uruchomieniu procesora zarówno w celu dostępu do zawartych w nim słów, jak i uzupełnienia nowymi słowami. Nowe wprowadzone do niego słowa, jeśli to konieczne, mogą zostać usunięte wraz z powiązanymi z nimi treściami za pomocą polecenia FORGET $PRIME. Następnie możliwość dalszego dodawania słów do tego podsłownika jest zapewniona przez wykonanie polecenia GROW $PRIME, które pozwala ponownie rozwinąć podsłownik $PRIME, a wszystko, co w nim wpisane, może zostać ponownie usunięte za pomocą polecenia FORGET $PRIME itp. . W tym trybie PRSP jest używany podczas eksperymentowania z małymi fragmentami programów, pojedynczymi przykładami, szacunkami, a także, jeśli to konieczne, do dołączania nowych słów do podsłownika $PRIME w kolejności rozwoju języka systemu.
W przypadku tworzenia osobnego programu tworzą dla niego własny podsłownik, a osiąga się to dzięki temu, że tekst programu zaczyna się od polecenia
PROGRAM $<имя программы>
Osoba odbiera to polecenie jako nagłówek, po którym następuje komentarz w nawiasach kwadratowych, opisujący w kilku słowach funkcję realizowaną przez program. Dla procesora jest to odpowiednik sekwencji instrukcji
ZAPOMNIJ $<имя>WZROST$<имя>
Dlatego każde odebranie tekstu programu na wejściu procesora spowoduje jego usunięcie Poprzednia wersja i otworzy w ten sposób oczyszczony słownik do wprowadzenia Nowa wersja program o tej samej nazwie. Jest to wygodne przy wprowadzaniu poprawek do stworzonego programu, a także przy jego późniejszej modyfikacji.
Tekst projektowanego programu nie jest wprowadzany bezpośrednio z klawiatury na wejście procesora, lecz tworzony jest w buforze edytora tekstu. Polecenie E (Edit - edit) ustawia tryb edycji, w którym słowa wpisywane na klawiaturze nie są już postrzegane przez procesor jako polecenia do natychmiastowego wykonania, ale są po prostu zapisywane do bufora i jednocześnie wyświetlane na ekranie tekstu. Za pomocą specjalnych klawiszy sterujących ruchem wskaźnika aktualnej pozycji (kursora) na ekranie, a także edycji poleceń wydawanych przez naciśnięcie innych klawiszy, wprowadzany tekst można poprawiać i zmieniać poprzez dokonywanie usunięć i wstawek, przesuwanie jego fragmentów z miejsca na miejsce itp.
Po zakończeniu wpisywania i edycji tekstu edytor wyłączamy naciskając klawisz E jednocześnie z (dokładniej z wcześniej wciśniętym) klawiszem
Po zakończeniu ładowania procedury i dane są dostępne do wglądu po nazwach wpisanych z klawiatury, a poprawność działania programu można sprawdzić wykonując procedury w kolejności rosnącej, tj. zaczynając od tych, których definicje nie zawierają niesprawdzonych procedur. Zanim zaczniesz sprawdzać, dobrze jest upewnić się, że Twój program nie używa niezdefiniowanych nazw. Procesor wyświetla je na ekranie za pomocą polecenia UNDEF. Aby uzupełnić tekst programu o definicje tych nazw, a także poprawić inne błędy wykryte podczas procesu weryfikacji, należy wywołać edytor poleceniem E i dokonać odpowiedniej modyfikacji tekstu źródłowego programu znajdującego się w buforze edytora, a następnie przełączyć procesor w tryb główny i załadować zawartość bufora poleceniem PF.
Po sprawdzeniu i przetestowaniu programu jego kod źródłowy można skopiować z bufora edytora na dysk poleceniem OE f, gdzie f jest nazwą pliku, w którym program zostanie zapisany na dysk. W przyszłości zawartość pliku będzie można wczytać na wejście procesora poleceniem LOAD f, a także skopiować do bufora edytora jako dodatek do tekstu w nim zawartego poleceniem IE f. Domyślnie pliki mają rozszerzenie .DSP. Bufor można wstępnie wyczyścić za pomocą polecenia KE. Możliwe jest również wydrukowanie zawartości bufora za pomocą polecenia LPE.
Po załadowaniu programu gotowego do wykonania można wyczyścić utworzony dla niego podsłownik $.<имя>polecenie WYCZYŚĆ $<имя>. Wykonując to polecenie, procesor usuwa nienaprawione nazwy z nazwanego słownika, tj. wszystkie nazwy z wyjątkiem tych, których definicje poprzedzone są przedrostkiem mocującym:: (dwa dwukropki). W takim przypadku usuwane są tylko same nazwy (wpisy słownika), podczas gdy ciała procedur i powiązane z nimi dane są zachowywane i dostępne podczas wykonywania programu poprzez wewnętrzne odniesienia ustanowione podczas kompilacji, ale nie są już dostępne z zewnątrz. Aby przywrócić możliwość dostępu z zewnątrz, na przykład w przypadku konieczności skompilowania jakiegoś dodatku lub zmiany, należy przeładować kod źródłowy programu.
Nazwy można uczynić niedostępnymi z zewnątrz, bez usuwania ich ze słownika, za pomocą polecenia SHUT $<имя>, co zamyka dostęp do wszystkich słów z podsłownika w nim wymienionego. Otwarcie słownika w celu użycia jego słów odbywa się za pomocą polecenia USE $<имя>. Istnieje również TYLKO polecenie $<имя>, który zamyka wszystkie podsłowniki z wyjątkiem wymienionego, oraz polecenie ANULUJ, które anuluje to ograniczenie. Powyższe polecenia pozwalają kontrolować użycie słownika w czasie kompilacji i limitu niezbędne minimum zestaw nazw dostępnych dla użytkownika programu.
Wyszukiwanie nazwy w słowniku odbywa się poprzez przeglądanie jej słów w odwrotnej kolejności, w jakiej zostały wprowadzone do słownika, tj. zaczynając od ostatniego wpisu. Dlatego dla nazwy zdefiniowanej więcej niż raz w słowniku obowiązuje najnowsza definicja. Jeśli podsłownik zawierający tę ostatnią definicję zostanie zamknięty, wyszukiwanie będzie kontynuowane do pierwszego dostępnego wpisu słownika o podanej nazwie i zostanie użyta definicja określona przez ten wpis.
Kilka słów o wprowadzaniu i wyprowadzaniu danych. Jak już wspomniano, procesor próbuje zinterpretować słowo wykonywanego programu, którego nie ma w słowniku, jako liczbę i, jeśli się powiedzie, odkłada binarny odpowiednik tej liczby na stos. Włożenie numeru na stos można wykonać za pomocą polecenia TIN, które wymaga wpisania numeru wejściowego na klawiaturze. Są też komendy, które powodują, że znak wpisany z klawiatury jest wypychany na stos: TIB - z wyświetlaczem, TRB - bez wyświetlania tego znaku na ekranie. W tym przypadku kod znaku jest reprezentowany przez młodszy bajt 32-bitowego słowa wysyłanego na stos, którego starsze 3 bajty są równe zeru.
Wprowadzanie odpowiednio zawartości wierzchołka stosu jest możliwe w formie cyfry oraz w formie litery. Polecenie TON powoduje wyświetlenie wartości liczbowej podwęzła na ekranie w polu wyjściowym, którego szerokość jest określona przez wierzchołek, w układzie reprezentacji liczb ustalonym w momencie jego wykonania. Polecenie TOB wyświetla znak, którego kod jest zawarty w młodszym bajcie wierzchołka stosu. W obu przypadkach po wyjściu następuje usunięcie argumentów ze stosu.
Procesor DSSP posiada aparaturę do przerwań zewnętrznych i wewnętrznych (polecenia) oraz zapewnia: następujące środki ich przetwarzanie. Procedura przeznaczona do obsługi przerwania zewnętrznego jest zdefiniowana w taki sam sposób jak normalna procedura, ale z przedrostkiem INT dodanym przed dwukropkiem. Nazwa takiej procedury jest powiązana z adresem wektora przerwań z poleceniem:
<адрес вектора>POŁĄCZYĆ<имя процедуры>
Przerwanie polecenia to nazwana operacja wywołująca procedurę odpowiedzi. Nazwę tej operacji określa komenda TRAP, która kojarzy się z nią tzw. procedura ostatecznej odpowiedzi, która jest wykonywana w przypadku, gdy końcowa reakcja nie zostanie zastąpiona inną procedurą odpowiedzi za pomocą komendy ON lub EON. Wszystkie trzy polecenia mają ten sam format:
PUŁAPKA<имя вызова> <процедура реагирования>
NA<имя вызова> <процедура реагирования>
wieczność<имя вызова> <процедура реагирования>
Procedura odwzorowana na nazwę wywołania przez instrukcję EON jest wykonywana po wyjściu z ciała procedury zawierającej instrukcję EON iz wartością operandowego wskaźnika stosu, który był na miejscu w czasie wykonywania EON.
Składnia języka PARA
Alfabet języka PARADISE obejmuje łacinę i rosyjski, małe i wielkie litery, cyfry dziesiętne, znaki matematyczne i inne znaki specjalne. Elementy (członki) alfabetu nazywane są literami. Zewnętrzną reprezentacją litery jest jej wydrukowany obraz (drukowany znak). Wewnątrz procesora PRSP każdy drukowany znak jest reprezentowany przez bajt, którego wartością jest kod binarny tego znaku. Transformacja reprezentacji zewnętrznej na wewnętrzną i odwrotnie jest realizowana przez urządzenie wejścia / wyjścia (klawiatura, wyświetlacz, drukarka). Dla wygody wartość liczbowa kodu jest wyrażona w systemie dziesiętnym, szesnastkowym lub ósemkowym, nazywając odpowiednią liczbę kodem znaku dziesiętnego, szesnastkowego lub ósemkowego.
Wszystkie obiekty języka PARADISE są zbudowane z liter i są liniowymi łańcuchami liter o skończonej długości, zwanych słowami. Ogranicznikiem kolejnych słów jest znak niedrukowalny (spacja). Ciąg spacji jest równoważny pojedynczej spacji. Dodatkowo funkcję separatora wyrazów pełni polecenie „Przejdź na początek następnego wiersza”, oznaczone na klawiaturach urządzeń wejściowych symbolem
Przykładowe słowa: CLEAR NOP STEK2 & 1+ -366 X Probe.
Procesor PRSP rozróżnia słowa po pierwszych siedmiu literach, rozpoznając je przez porównanie politerminalne ze słowami ze swojego słownika. Słownik zawiera słowa będące nazwami (oznaczeniami) własnych operacji procesora, zwanych operacjami podstawowymi lub prymitywami, które mogą być uzupełnione nazwami obiektów (danych, procedur) zdefiniowanych przez użytkownika. Zatem słowa zawarte w słowniku są albo nazwami akcji (operacji, procedur) albo nazwami danych (stałe, zmienne, tablice).
Gdy rozpoznawalne słowo nie znajduje się w słowniku, procesor próbuje przypisać je do jednego z następujących przypadków:
literał numeryczny, tj. ciąg cyfr, prawdopodobnie rozpoczynający się znakiem minus, na przykład: 0, 4096, -25;
literał literał: słowo rozpoczynające się od znaku #, co powoduje, że procesor otrzymuje jako dany kod znak bezpośrednio po nim następujący, na przykład: #A - literał dużej litery łacińskiej A, #5 - literał liczby 5 , # - literał spacji, ## - litery literału #;
literał tekstowy: dowolny tekst ujęty w podwójne cudzysłowy i oddzielony separatorami wyrazów, na przykład: „Tekst”, „Plik wejściowy N3”;
polecenie wysłania komunikatu tekstowego na wyświetlacz: tekst komunikatu wyjściowego, oddzielony z lewej strony kombinacją znaków kropka-podwójny cudzysłów i podwójnego cudzysłowu z prawej strony i oddzielony separatorami wyrazów, na przykład: „Stos jest pusty”;
komentarz: dowolny tekst ujęty w nawiasy kwadratowe i oddzielony ogranicznikami, na przykład: .
Literały i polecenie wysłania komunikatu na wyświetlacz pełnią rolę obiektów języka PRSP wraz ze słowami rozpoznawanymi ze słownika, natomiast komentarze są całkowicie ignorowane przez procesor PRSP - przeznaczone są dla osoby, a nie dla maszyny. Jeśli słowo nie zostanie znalezione w słowniku i nie jest powiązane z wymienionymi konstrukcjami, procesor wydaje komunikat: „Nie wiem<неопознанное слово>".
Ze względu na szczególne znaczenie nadane literom #, „i kombinacji”. na początku słowa, tj. po separatorze, a także litera " przed separatorem, nie mogą być używane na określonych pozycjach w słowach zdefiniowanych do włączenia do słownika.
Sekwencja słów na wejściu procesora jest interpretowana jako sekwencja instrukcji wykonywanych przez procesor. Istnieją trzy rodzaje słów:
1) wykonywane samodzielnie, tj. reprezentowanie poleceń jednowyrazowych (monosłów);
2) wykonywane w połączeniu z jednym lub kilkoma kolejnymi słowami, tj. istnienie początkowe słowa(przedrostki) komendy dwu-, trzy- lub wielowyrazowe;
3) poprzedzające polecenie jako wyjaśnienie lub wskazanie specjalnego trybu wykonania (prefiksy).
Monosłowa obejmują literały, nazwy danych, większość operacji we/wy, testów i konwersji danych na stosie oraz procedury zdefiniowane przez użytkownika. Na przykład: 1987 - literał numeryczny, #5 - literał cyfry 5, "Lista schematów" - literał tekstowy, LENGTH - nazwa zmiennej, TOB, NEG, +, &,<, = - имена (обозначения) операций, SORT, CONVERT, ЧИСТКА, СНЯТЬ - имена процедур пользователя.
Przedrostki są nieodłącznym elementem poleceń służących do opisywania danych i definiowania procedur, a także do manipulowania nazwanymi danymi, warunkowego i wielokrotnego wykonywania procedur oraz zarządzania słownikami. Przykłady poleceń z przedrostkami:
VAR SUM - utwórz zmienną SUM,
: NIEPARZYSTE [x] 1 & ; - stworzyć procedurę ODD, która zastępuje liczbę nieparzystą 1, a parzystą 0,
0 X - przypisz wartość 0 do zmiennej X,
BR+ P1 P2 - jeśli wartość jego wierzchołka pobranego ze stosu jest dodatnia, wykonaj P1, w przeciwnym razie wykonaj P2,
RP CHECK - powtarzaj procedurę CHECK,
USE $REAL - otwiera podsłownik $REAL do użytku.
Z reguły dany prefiks wymaga po sobie określonej liczby słów. Tak więc w podanych przykładach prefiksy VAR, !0 i USE wymagają jednego słowa, podczas gdy prefiks BR+ wymaga dwóch słów. Jednak przedrostek: (dwukropek) umożliwia utworzenie polecenia o dowolnej długości, zaczynając od trzech słów. Koniec polecenia to słowo; (średnik). Dowolna długość jest również charakterystyczna dla deskryptora poleceń stałych CNST A1 ... AJ ; i procedury polecenia wielokrotnego wyboru BR A1 P1 ... AJ PJ ELSE PN.
Przedrostki to specjalne słowa, które po dodaniu na początku polecenia modyfikują jego zawartość lub definiują specjalny tryb wykonania. Na przykład polecenie VAR X bez prefiksu jest instrukcją utworzenia 16-bitowej zmiennej X. Jeśli dodamy do niej prefiks BYTE, otrzymamy polecenie BYTE VAR X, które nakazuje utworzenie 8-bitowej zmienna (bajt) o nazwie X. Jeżeli używamy przedrostka LONG, to otrzymujemy LONG VAR X - instrukcję tworzenia 32-bitowej zmiennej o nazwie X.
Prefiks innego typu, a mianowicie: (dwa dwukropki) informuje o wyniku wykonania polecenia stabilności względem procedury CLEAR, która usuwa luźne słowa ze słownika. Nazwy wprowadzone do słownika podczas budowy programu przy pomocy poleceń opisu danych i definicji procedury, po utworzeniu i przetestowaniu programu, mogą być usuwane ze słownika, za wyjątkiem kilku niezbędnych do utrzymania gotowego programu. Usuwanie odbywa się za pomocą polecenia CLEAR $<имя подсловаря>, nakazujący wyczyszczenie podsłownika związanego z programem, zapisując w nim tylko te słowa, których definicje zawierają przedrostek::. Przykłady poleceń generujących nieusuwalne słowa:
:: BYTE CNST LITCODE # #0 #A ;
:: : MOD / [cel(a,b),reszta(a,b)] E2 D [reszta(a,b)] ;
Jak pokazuje drugi przykład zawierający przedrostki :: i BYTE, w poleceniu może być więcej niż jeden przedrostek.
Tak więc polecenie w DSSP może być albo jednym słowem (monosłowo) albo frazą (frazą), która zaczyna się od prefiksu i zawiera liczbę słów ustawioną dla tego prefiksu, a jeśli prefiks pozwala na dowolną liczbę słów, to ma słowo ograniczające na końcu lub może to być fraza poprzedzona specjalnymi słowami prefiksowymi.
Podstawowy język DSSP nie zawiera bardziej złożonych konstrukcji składniowych niż polecenie i nie zawiera innych konstrukcji niż omówione powyżej. Nawet tak niezbędne rzeczy w językach programowania jak wyrażenie i funkcja są nieobecne w języku bazowym i mogą być wprowadzone, jeśli to konieczne, dopiero w trakcie jego rozwoju.
Program w języku podstawowym to po prostu zbiór poleceń wykonywanych w kolejności, w jakiej pojawiają się w tekście. Co więcej, każde polecenie, z wyjątkiem tych zawierających tylko prymitywy, w procesie jego wykonywania obejmuje sekwencję poleceń, które definiują zawarte w nim słowa. Zaangażowane polecenia mogą z kolei zawierać słowa oznaczające łańcuchy poleceń, które mogą również zawierać słowa odnoszące się do powiązanych z nimi łańcuchów i tak dalej. do poziomu, na którym polecenia zawierają tylko prymitywy.
Ogólny opis języka PARA, który stanowił treść tego rozdziału, został poświęcony scharakteryzowaniu struktury tego języka oraz podstawowego (wstępnego) zbioru jego komend, który jest zbiorem komend wbudowanych (prymitywów). procesora PRSP. Dalszy rozwój języka i odpowiadający mu wzrost możliwości procesora odbywa się poprzez wprowadzanie nowych procedur, poleceń, formatów i typów danych, konstruowanych przy użyciu podstawowych narzędzi. Z reguły takie opracowanie ma charakter problemowy i odbywa się w postaci pakietów procedur ładowanych na wejściu procesora oprócz systemu bazowego.
Z drugiej strony system podstawowy można uzupełnić o zaimplementowane na jego podstawie narzędzia specjalne zwiększające wydajność maszyny programów DSSP. Narzędzia te obejmują możliwość definiowania poszczególnych procedur bezpośrednio w kodzie komend używanej maszyny. Sposób zdefiniowania procedury nie ma wpływu na jej dalsze wykorzystanie: nazwy wszystkich procedur są wprowadzane do wspólnego słownika i są całkowicie równe. Szereg programów bibliotecznych umożliwia korzystanie z procedur lub całych programów napisanych w innych językach.
Opis operacji i poleceń
Operacje wykonywane na stosie
Stos operandów jest jednym z głównych elementów architektury procesora PRSP. Większość instrukcji procesora używa stosu, zużywając z niego potrzebne operandy i wysyłając do niego wyniki. Interpretacja danych na stosie zależy od istoty rozwiązywanego problemu, czyli ostatecznie jest to odpowiedzialność programisty. Z uwagi na to, że wartość, która trafiła na stos faktycznie traci swoją nazwę, trudno z tekstu programu określić, do którego operandu jest zastosowana ta lub inna operacja, jakie są jej skutki. Dlatego, aby jednoznacznie wskazać operandy i wyniki procedur w języku PARA, używane są komentarze. W takim przypadku nie jest wymagane (i nie zawsze możliwe) opisanie całej zawartości stosu. Komentowanie górnej części stosu, na którą ma wpływ wykonywana na niej procedura, jest absolutnie konieczne, ponieważ bez tego traci się widoczność programu, a jego weryfikacja jest trudna.
Aby osiągnąć jednolitość programu, komentarze te należy pisać z uwzględnieniem kilku prostych zasad. Jak każdy komentarz, opis danych na stosie jest ujęty w nawiasy kwadratowe. Ten opis to lista operandów, które znajdują się na stosie w danym punkcie programu. Każdy element listy charakteryzuje zawartość jednej pozycji na stosie, przecinek jest używany jako separator. Wartości pozycji stosu są wymienione od lewej do prawej, zaczynając od najgłębszego elementu i kończąc na szczycie stosu. Opis pojedynczego operandu może być liczbą, nazwą, wyrażeniem lub inną sensowną notacją wyjaśniającą znaczenie wartości na stosie. Czasami możesz określić kilka możliwych wartości dla określonej pozycji na stosie. W tym przypadku wartości są oddzielone ukośnikiem.
Oto przykład komentarza odzwierciedlającego stan stosu operandów:
[rozpocznij dr,N+1,1/0]
W momencie w programie, w którym znajduje się ten komentarz, stos argumentów musi zawierać co najmniej trzy pozycje, a na górze może być 1 lub 0, na dole - wartość liczbowa równa N + 1, a pod nią - trochę numer interpretowany jako adres początkowy.
Dla wygody określenia wymaganej pozycji stosu posłużymy się pojęciem głębokości występowania. Założymy, że szczyt stosu znajduje się na głębokości 1, dół na głębokości 2 i tak dalej. W szczególności wartość oznaczona w przykładzie jako „start.adr”. leży na głębokości 3.
Naszą naukę podstawowego języka PRSP rozpoczniemy od instrukcji wpychania wartości na stos. Najprostszym (i najczęściej używanym) poleceniem tego typu jest literał numeryczny, czyli wyraźne wskazanie stałej, która ma być odłożona na stos. Niech na przykład chcemy odłożyć na stos liczby 28, -5 i 11. W tym celu wpisujemy linię z klawiatury:
28 -5 11 i naciśnij klawisz
Aby wyświetlić całą zawartość stosu na ekranie, DSSP ma polecenie .. (dwie kropki). Po jego wykonaniu na ekranie pojawia się następujący wiersz:
Jak widać, formularz wydruku jest zgodny z przyjętymi konwencjami komentowania stanu stosu (z wyjątkiem stosowania spacji zamiast przecinka). Polecenie .. nie zmienia zawartości stosu.
Słowo 32-bitowe (4 bajty) jest używane do reprezentowania jednej pozycji stosu w pamięci maszyny, liczby są reprezentowane w uzupełnieniu do dwóch. W związku z tym procesor PRSP może poprawnie postrzegać tylko liczby całkowite z zakresu od -2147483648 do 2147483647. Jeśli wprowadzona liczba nie może być reprezentowana w 32 bitach (biorąc pod uwagę znak), to najbardziej znaczące bity, które nie pasują, są odrzucane.
W rozważanych przykładach przyjęto, że procesor PRSP jest w trybie dziesiętnego wprowadzania/wyprowadzania liczb. Do ustawienia tego trybu w języku PARADISE służy komenda B10.
W wielu zadaniach wymagane jest interpretowanie przetwarzanych danych nie jako liczby, ale jako kody binarne, czyli 32-składowe wektory bitowe. W DSSP możliwa jest praca z kodami prezentowanymi w systemie liczb binarnych, ósemkowych lub szesnastkowych. Aby ustawić żądany tryb, wystarczy wykonać jedno z trzech poleceń: B2, B8 lub B16, po czym procesor zaakceptuje i wydrukuje wszystkie wprowadzone kody w określonym systemie liczbowym.
Ta funkcja może służyć do konwersji liczb dziesiętnych na podstawy 2, 8 i 16. Na przykład, aby przekonwertować liczbę 29, wprowadź i wykonaj następujący wiersz:
B10 29 B2 . B8. B16. W rezultacie procesor wyświetli na ekranie serię liczb: 0000000035 0000001D, które są reprezentacją liczby dziesiętnej 29 w trzech wskazanych systemach liczbowych. Zwróć uwagę, że kody są drukowane w ich reprezentacji maszynowej, tj. z wiodącymi zerami i bez znaków „+”, „-”. Podczas wykonywania linii B10 -2 B8 . zwróci liczbę 377777777776, która jest ósemkową reprezentacją uzupełnienia -2.
Podczas pracy z kodami szesnastkowymi mogą wystąpić kolizje między literałami liczbowymi a nazwami poleceń procesora PRSP. Na przykład słowo B8 w szesnastkowym trybie we/wy może być interpretowane jako polecenie ustawienia trybu ósemkowego i jako stała szesnastkowa. Aby uniknąć niejednoznaczności, literały numeryczne powinny zaczynać się od nieznaczącego zera, takiego jak 0B8.
Podstawą systemu poleceń procesora DSSP są operacje transformacji danych znajdujące się na stosie. Ogólną zasadą rządzącą tymi operacjami jest to, że każda operacja zużywa (usuwa) wymagane operandy ze stosu i odkłada wartości wyników (jeśli występują) na ich miejsce.
Rozważmy instrukcje procesora, które implementują cztery operacje arytmetyczne: dodawanie, odejmowanie, mnożenie i dzielenie liczb całkowitych. Dla ich wizerunku w języku PARADISE użyto odpowiednio słów: +, -, * i /. Aby otrzymać sumę dwóch liczb na stosie, na przykład 123 i 45, musisz odłożyć te liczby na stos i wykonać polecenie +. Aby to zrobić, wystarczy wpisać z klawiatury następujący wiersz (zakładając, że ustawiony jest dziesiętny tryb wejścia / wyjścia):
123 45 +
Jeśli teraz wyświetlimy zawartość stosu na ekranie (za pomocą polecenia ..), to wynik dodawania stanie się widoczny:
W podobny sposób działa przemienna operacja mnożenia.
Podczas wykonywania nieprzemiennych operacji odejmowania i dzielenia, wierzchołek podrzędny stosu jest traktowany jako odjemna (dzielna), a wierzchołek jest używany jako podrzędna (dzielnik). Na przykład, aby obliczyć różnicę 151-68, musisz wykonać linię:
151 68 -
Program do wykonywania operacji arytmetycznych w języku PARA charakteryzuje się tym, że operacja znajduje się po odpowiadających jej argumentach. Taka notacja wyrażeń arytmetycznych nazywana jest notacją postfiksową (lub polską odwrotną) i jest szeroko stosowana w kalkulatorach stosu. Niech na przykład musimy obliczyć wartość wyrażenia arytmetycznego ((127+81)*15-(31+117)*21)*3
W notacji postfiksowej to wyrażenie będzie wyglądać tak:
127 81 + 15 * 31 117 + 21 * - 3 *
Ta linia (w której słowa są oddzielone od siebie spacjami) to gotowy program do obliczania naszego wyrażenia przez procesor PRSP.
Dzielenie/polecenie różni się od innych operacji arytmetycznych tym, że daje w wyniku dwie wartości – iloraz i resztę. Iloraz znajduje się na dole stosu, a reszta na górze. Iloraz jest ujemny, jeśli dzielna i dzielnik mają różne znaki. Pozostała część zawsze ma znak dywidendy. Oto kilka przykładów użycia polecenia dzielenia.
125 7 / [-17,-6] / / /
Podczas wykonywania obliczeń mogą wystąpić sytuacje błędne: przepełnienie i dzielenie przez zero. Procesor DSSP w żaden sposób na nie nie reaguje (w szczególności przy dzieleniu przez zero zawartość stosu nie ulega zmianie), a kontrola nad poprawnym wykorzystaniem operacji jest przypisana programiście.
Podczas programowania często konieczne jest zwiększanie lub zmniejszanie wartości o 1 i 2. Do języka PARADISE wprowadzono specjalne polecenia, które wykonują określone akcje na szczycie stosu. Oznaczone są słowami: 1+, 1-, 2+, 2-. Wykonanie tych poleceń jest równoznaczne z włożeniem żądanej stałej (1 lub 2) na stos, po której następuje wykonanie wymaganej operacji arytmetycznej (+ lub -). Na przykład 2+ jest równoważne słowu pair 2 + . Wprowadzenie do języka tych poleceń jest spowodowane względami wydajnościowymi.
Ponadto, aby poprawić wydajność, język bazowy procesora DSSP zawiera polecenia T0 i T1, które zastępują wartość wierzchołka stosu odpowiednio przez 0 i 1, niezależnie od tego, jaka wartość znajdowała się na szczycie przed określonym poleceniem. Przykłady:
Polecenia NEG, ABS i SGN są również przeznaczone do pracy z danymi numerycznymi. Instrukcja NEG odwraca znak wierzchołka stosu, ABS zastępuje wartość wierzchołka stosu jego wartością bezwzględną, SGN - pobiera wartość liczbową z wierzchołka stosu i umieszcza w jej miejsce: -1 - jeśli liczba jest ujemna, 1 - jeśli jest dodatnia, 0 - jeśli równa się zero. Na przykład:
5 NEG [-5] ABS SGN
Polecenia MIN i MAX w języku podstawowym pozwalają znaleźć minimum i maksimum dwóch liczb całkowitych. Argumentami tych instrukcji są dwie liczby na górze i na dole stosu. Instrukcja MIN pozostawia minimalną liczbę parametrów na stosie, MAX maksymalną z nich. Na przykład:
5 0 15 MIN [-5,0] MAKS
Aby znaleźć minimum (maksimum) z trzech liczb na stosie, wystarczy dwukrotnie zastosować polecenie MIN (MAX):
MIN MIN [-2]
Instrukcja SEG sprawdzająca, czy liczba znajdująca się na szczycie stosu mieści się w określonym zakresie od a do b (włącznie z granicami) pozostawia w wyniku na stosie następującą flagę: 1 jeśli liczba jest w zakresie, a 0 Jeżeli nie jest:
SEG [znak] na przykład:
Oprócz instrukcji do pracy z danymi liczbowymi, zestaw instrukcji dla procesora DSSP zawiera szereg operacji przeznaczonych do konwersji kodów 32-bitowych. Operacje te traktują element stosu jako 32-składnikowy wektor bitów, którego składniki są ponumerowane od prawej do lewej w taki sposób, że skrajny lewy bit to liczba 31, a skrajny prawy numer to 0. Numeracja malejąca składników powtarza się numeracja bitów słowa maszynowego przyjęta dla wielu mikroprocesorów.
Instrukcje bit-vector zawierają przede wszystkim operacje bitowe algebry Boole'a:
bitowa inwersja wierzchołka stosu INV, zmiana wartości każdego bitu wierzchołka, tj. zamiana 0 na 1 i 1 na 0;
koniunkcja bitowa góry i dołu stosu &, ustawianie i-tego bitu wyniku, i=31,30,...,0, na 1, jeśli i-te bity obu argumentów wynoszą 1, a w przeciwnym razie ustawienie i-tego bitu na 0;
alternatywa bitowa góry i dołu stosu &0, ustawianie i-tego bitu wyniku, i=31,30,...,0, na 0, jeśli i-te bity obu operandów są równe 0, a w przeciwnym razie ustawienie i-tego bitu na 1;
dodawanie bitowe (nierównoważność) „+” góry i dołu, ustawienie i-tego bitu wyniku na 0, jeśli i-te bity obu operandów mają te same wartości, oraz ustawienie i-tego bitu argumentu wynik do 1, jeśli wartości i-tych bitów operandów są różne.
525 INV 722 i 136 i 0 325 "+"
Sprzężenie bitowe jest często używane do resetowania (czyszczenia) bitów słowa. Aby to zrobić, oryginalne słowo łączy się z maską zawierającą zera w tych bitach, które muszą zostać wyczyszczone, i jedynki w pozostałych bitach. Na przykład, jeśli chcesz zresetować bity 3 do 5 w jakimś słowie X, musisz wykonać jego bitową koniunkcję z maską 377777777707. Dla X=235 otrzymujemy:
Rozdzielczość bitowa może być użyta do wstawienia żądanej kombinacji bitów do wcześniej wyczyszczonej grupy bitów słowa. Niech na przykład musisz umieścić kombinację binarną 010 w bitach od 3 do 5 słowa pozostałego na stosie w wyniku ostatniego przykładu. Można to zrobić w ten sposób:
Operacje manipulacji bitami obejmują również logiczne instrukcje przesunięcia:
przesunięcie w lewo SHL - każdy bit wierzchołka stosu, począwszy od 31., przyjmuje wartość następnego w kolejności malejącej liczb, a ostatni, zerowy bit przyjmuje wartość 0;
przesunięcie w prawo SHR - każdy bit wierzchołka stosu, zaczynając od 0, przyjmuje wartość następnego w rosnącej kolejności liczb, a 31 bit przyjmuje wartość 0;
top shift SHT - górny element jest usuwany ze stosu i traktowany jako liczba całkowita N, wskazująca ile przesunięć i w jakim kierunku należy wykonać na wierzchołku stosu: gdy N>0 następuje przesunięcie w lewo, gdy N<0 - вправо.
B8 125 SHR SHL -2 SHT
Operacje przesunięcia w lewo mogą być używane do mnożenia liczb przez 2 do potęgi N, gdzie N jest liczbą naturalną, która określa liczbę przesunięć. Na przykład pomnożenie liczby -5 przez 8 można wykonać przesuwając tę liczbę o 3 cyfry w lewo:
B10 -5 3 SHT [-40]
W takim przypadku należy wziąć pod uwagę możliwość przepełnienia.
Przesunięcie w prawo może być używane jako operacja dzielenia liczb całkowitych przez 2 do potęgi N tylko dla liczb dodatnich, ponieważ najbardziej znaczący bit (znaku) jest ustawiony na zero podczas przesunięć w prawo. Na przykład:
natomiast
Obróć wierzchołek stosu o 1 bit w prawo ROR i lewy ROL są podobne do instrukcji przesunięcia logicznego, z wyjątkiem tego, że wypchnięty bit krawędzi nie znika, ale jest wpychany do pustej przestrzeni z przeciwległego końca 32 -nieco długie słowo. Na przykład (liczby szesnastkowe):
Polecenia procesora DSSP SWB i SWW są również przeznaczone do przetwarzania kodów binarnych. Funkcja SWB służy do zamiany bajtów dolnej połowy wierzchołka stosu, a funkcja SWW do zamiany połówek wierzchołka stosu. Zilustrujmy, jak te polecenia działają w trybie szesnastkowym we/wy (w tym trybie każdy bajt jest reprezentowany przez dwie cyfry szesnastkowe):
B16 0ABCD SWB SWB
0ABCDEF12 SWW SWB
Polecenia manipulacji stosem odgrywają ważną rolę w języku PARA. Nie zmieniają wartości danych na stosie, a jedynie zmieniają ich położenie, ułatwiając dostęp do operandów znajdujących się głęboko w stosie.
Istnieją trzy polecenia do usuwania elementów stosu: D, DD, DS (Drop - odrzuć). Polecenie D usuwa jeden (górny) element ze stosu, DD - dwa elementy, np.:
D DD D DS usuwa wszystkie elementy ze stosu (czyści stos):
Polecenie skopiowania wierzchołka stosu C (Kopiuj) wypycha kopię bieżącej wartości jego wierzchołka na stos. Jest to równoważne powielaniu górnego elementu stosu: stary wierzchołek staje się podrzędnym, a jego kopia staje się nowym wierzchołkiem. Przykład:
Przedstawimy zastosowanie tego polecenia na przykładzie obliczenia wielomianu p(x)=3*x**2+4*x-5 według schematu Hornera: p(x)=(3*x+4)* x-5. Zakładamy, że wartość x znajduje się na szczycie stosu.
[x] C 3 * 4 + * 5 -
Wraz z poleceniem skopiowania wierzchołka stosu w języku PARADISE istnieją również polecenia C2, C3, C4, które kopiują elementy znajdujące się na głębokości 2, 3, 4. Ich działanie można wytłumaczyć następującymi przykładami:
C2 C4
Istnieje również polecenie CT do kopiowania elementu na głębokość określoną na szczycie stosu. Podczas wykonywania CT procesor usuwa górny element ze stosu, używa jego wartości jako wskaźnika głębokości kopiowanego elementu i odkłada kopię ostatniego elementu na stos. Tak więc kopiowanie elementu znajdującego się na głębokości 5 jest określone przez parę 5 instrukcji CT, po wykonaniu których procesor wrzuci liczbę 5 na stos, a następnie wykona instrukcję CT. Wykonanie przekładnika prądowego o parametrach 1, 2, 3, 4 jest równoważne odpowiednio poleceniom C, C2, C3, C4.
Polecenia wymiany E2, E3, E4 (Wymiana - wymiana) permutują odpowiednio pierwszy (górny) element stosu z 2., 3., 4., tj. z elementem znajdującym się na głębokości 2, 3, 4. Na przykład:
E3 E2
Do wymiany na większych głębokościach stosuje się instrukcję ET, która podobnie jak CT wykorzystuje wartość wierzchołka stosu jako wskaźnik głębokości wymienianego elementu z pierwszym elementem. Na przykład:
5ET
Polecenie ET z parametrami 2, 3, 4 jest równoważne poleceniom E2, E3, E4.
Aby zilustrować użycie poleceń kopiowania i wymiany, rozważ problem szkoleniowy. Na stosie są trzy liczby. Wymagane, aby wejść na stos: . Możemy zaproponować następujący program, którego znaczenie wynika z komentarzy.
C3 C3 C3+
E4+E4
Ten przykład dobrze pokazuje, jak wielką rolę odgrywają komentarze, odzwierciedlając stan stosu operandów.
Programy często muszą porównywać ze sobą wartości liczbowe i wykonywać różne procedury w zależności od wyników porównania. Język RAYA ma polecenia porównania<, =, >. Są one definiowane przez liczby i w rezultacie dają wartości liczbowe 0 i 1. Tak więc polecenie< потребляет из стека два элемента и засылает в стек число 1, если значение нижнего элемента оказалось меньше значения верхнего, а в противном случае засылает 0. Например, в результате выполнения последовательности 5 -20 < в стек будет заслан 0. Команда = засылает 1 в случае равенства потребленных ею элементов. Команда >wysyła 1, gdy dolny element jest większy niż górny. Aby zaprogramować nieścisłe porównania (mniejsze lub równe, większe lub równe), używane jest polecenie NIE, które zastępuje wartość wierzchołka stosu, która nie jest równa zero zerem, a równa zero zerem jeden. Na przykład obliczenie wyrażenia logicznego x>=5, gdzie x jest pewną liczbą na szczycie stosu, można określić w następujący sposób:
[x]5< NOT
Dalsze rozszerzenie możliwości warunków programowania zapewnia zastosowanie, wraz z poleceniami porównania, operacji logicznych koniunkcji & (logiczne AND) oraz alternatywy &0 (logiczne OR). Niech na przykład wymagane jest uzyskanie 1 na stosie, jeśli liczba x na wierzchołku należy do półsegmentu C 5< NOT C2 10 <
& E2 2 = &0
Narzędzia do zarządzania programem w zależności od wyników porównania zostaną omówione później.
Definicja procedur
Jako podstawowa technika programowania PRSP daje użytkownikowi możliwość definiowania nazwanych sekwencji operacji zwanych procedurami. Niech będzie wymagane np. obliczenie wartości trójmianu kwadratowego 3*x**2-4*x+9 dla podanych wartości x. W takim przypadku należy zdefiniować procedurę, która implementuje wzór trójmianowy i wyprowadza wynik do terminala, a następnie zastosować tę procedurę do określonych wartości x. Pożądana procedura, nazwijmy ją PX, jest zdefiniowana następująco: : PX [x] C 3 * 4 - * 9 + . D; Dwukropek oznacza operację „zdefiniuj procedurę”, z nazwą procedury po dwukropku po spacji oddzielającej. Definiująca sekwencja poleceń (treść procedury) następuje po nazwie procedury i kończy się średnikiem. W skrócie procedura jest określona w postaci:
: <имя процедуры> <тело процедуры> ;
W języku PARADISE wymagane jest skomentowanie stanu stosu operandów na początku i na końcu procedury. W treści procedury komentarze są umieszczane według uznania programisty w miejscach, które są trudne do zrozumienia.
Komentarze pomagają człowiekowi zrozumieć i wykorzystać procedurę, podczas gdy procesor po prostu ignoruje wszystko w nawiasach. Dlatego przy wprowadzaniu definicji pojedynczej procedury z terminala można pominąć komentarze.
Po wejściu w definicję procedury i naciśnięciu klawisza
*2PX
*3PX
*4PX
Zdefiniujmy ogólniejszą procedurę obliczania trójmianu postaci a2*x**2+a1*x+a0, która pozwala na ustalenie wartości zarówno x jak i a0, a1, a2. Nazwijmy to PXA:
: PXAC E4 E3 * + * + ;
Podczas korzystania z PXA wartości a0, a1, a2, x muszą być w wymaganej kolejności na stosie. Na przykład: a0=1, a1=2, a2=-3, x=4
* 1 2 -3 4 PXA . D
W treści procedury, wraz z podstawowymi operacjami procesora, mogą znajdować się procedury zdefiniowane przez użytkownika. Na przykład można zdefiniować procedurę P, która oprócz obliczeń wykonywanych przez PXA, wyda kopię wyniku na terminal i usunie wynik ze stosu.
:PXA. D;
W szczególności treść procedury może zawierać nazwę definiowanej procedury, to znaczy procedura może być rekurencyjna. Na przykład:
: CZAS [t] 1- CZAS ;
Ta procedura zmniejsza wartość szczytu stosu o 1 i ponownie odnosi się do siebie, czyli działa jako licznik czasu.
Licznik CZASU w zasadzie nie może się zatrzymać: odejmowanie jedynki będzie wykonywane w kółko podczas pracy procesora. Ale w DSSP są narzędzia, które pozwalają kontrolować przebieg procesu w zależności od uzyskanych wyników - operacja zarządzania przebiegiem programu.
Warunkowe wykonanie i powtórzenie
Program, który jest sekwencją poleceń wykonywanych w kolejności, w jakiej znajdują się jedna po drugiej w swoim rekordzie, nazywamy liniowym. Aby program był dobrze widoczny (czytelny) i zrozumiały, dzieli się go na nazwane części, które mają określone znaczenie - procedury, z których każda jest zdefiniowana przez własną sekwencję procedur, które z kolei są zdefiniowane przez sekwencje mniejszych procedur itp. do procedur zdefiniowanych bezpośrednio przez sekwencje poleceń PRSP. Taki program, napisany jako hierarchia definicji procedur, nazywa się ustrukturyzowanym. Metoda konstruowania programu strukturalnego, polegająca na stopniowym rozkładaniu problemu do rozwiązania na coraz mniejsze podzadania, nazywa się programowaniem strukturalnym.
Tworzenie metodą programowania strukturalnego nie tylko liniowych, ale również dowolnych programów jest możliwe w obecności operacji wykonania procedury według warunku, powtórzenia procedury i wyjścia z powtórzonej procedury. Zestaw tego typu poleceń dostępny w DSSP daje możliwość ustrukturyzowanej konstrukcji dowolnego programu.
Warunki wykonania lub niewykonania procedury są formułowane w stosunku do znaku liczby, a dokładniej w stosunku do znaku wartości, którą aktualnie ma wierzchołek stosu. Główne polecenie warunkowego wykonania procedury - BRS (BRanch on Sign - gałąź po znaku) nakazuje wykonanie jednej z trzech procedur nazwanych od BRS, w zależności od znaku aktualnej wartości wierzchołka stosu. Wykonując BRS, procesor usuwa górny element ze stosu, testuje jego wartość i jeśli jest ujemna, to wykonuje pierwszą z powyższych procedur, jeśli jest zero, to drugą, a jeśli dodatnią, to trzecią. Więc zespół
spowoduje usunięcie jednego elementu ze stosu i wykonanie procedury N, jeśli usunięta wartość jest ujemna, wykonanie procedury P, jeśli jest dodatnia, i wykonanie procedury Z, jeśli jest równa zero.
Przykładem użycia komendy BRS jest poniższa definicja procedury SGN
: SGN [X] BRS -1 0 1 ;
Ta procedura zastępuje wartość X na szczycie stosu przez -1, jeśli X<0, числом 0, если X=0, и числом 1, если X>0. Procedura SGN jest dostępna w PRSP jako podstawowa operacja procesorowa.
Polecenie BRS wraz z wyborem jednej procedury z trzech danych daje możliwość zaimplementowania operatorów dwuwartościowych w postaci JEŻELI-WTEDY i JEŻELI-WTEDY-ELSE . Na przykład instrukcja if x>0 to P1 else P0 odpowiada poleceniu BRS P0 P0 P1, a instrukcja if x<>0 to P - komenda BRS P NOP P, gdzie NOP jest nazwą pustej operacji. Ale w DSSP jest bardziej wydajna implementacja warunków dwuwartościowych - komendy IF-, IF0, IF+, BR-, BR0, BR+.
Polecenia grupy IF odpowiadają instrukcji IF-THEN. Na przykład polecenie IF-P nakazuje usunąć górny element ze stosu i przetestować jego znak, a jeśli ten element ma znak minus, wykonaj procedurę P. Polecenia IF0 P i IF+ P nakazują wykonanie procedury P , odpowiednio w przypadku, gdy usuwany element ma wartość zero, a jego wartość jest dodatnia.
Jako przykład ilustrujący użycie poleceń grupy IF podamy definicję polecenia języka bazowego ABS, które oblicza moduł wierzchołka stosu.
: ABS [X] C JEŚLI-NEG [|X|] ;
Polecenia BR-, BR0 i BR+ odpowiadają instrukcji IF-THEN-ELSE, która nakazuje wybrać jedną z dwóch procedur wywołanych po nich. Jeżeli znak elementu usuwanego ze stosu jest zgodny ze znakiem w oznaczeniu polecenia, to wykonywana jest procedura o nazwie pierwsza, a jeśli nie pasuje, wykonywana jest druga procedura. Na przykład polecenie BR0 P0 P1 nakazuje wykonanie procedury P0 w przypadku, gdy element usunięty ze stosu wynosi zero, a jeśli warunek ten nie jest spełniony, należy wykonać procedurę P1.
Rozważane polecenia pozwalają ekonomicznie zaprogramować wykonanie procedury w zależności od zadanych warunków. Najczęstsze warunki postaci x<0, x=0, x>0 są bezpośrednio implementowane przez polecenia grupy IF. Warunki x<=0, x<>0, x>=0 są programowane za pomocą instrukcji BR-, BR0, BR+ przy użyciu pustej operacji NOP jako pierwszej procedury. Na przykład zdanie jeśli x<=0 then P соответствует команда BR+ NOP P. Примером использования команд группы BR может служить следующая реализация команды базового языка NOT, заменяющей нулевое значение вершины стека единицей, а ненулевое - нулем.
: NIE [x] BR0 1 0 ;
Rozgałęzienie programu jest często wykonywane po komendach porównawczych (<, =, >), które dają wartość logiczną 1 lub 0 w zależności od wyniku porównania dwóch liczb. Na przykład polecenie języka bazowego MAX można zaprogramować w następujący sposób:
: MAX C2 C2< IF+ E2 D ;
W grupie instrukcji rozgałęźnych znajduje się również instrukcja wyboru BR, która zapisana jest jako:
BR A1 P1 A2 P2 ... AK PK ... AN PN ELSE P0
Implementując tę instrukcję, procesor najpierw wykonuje procedurę wskaźnika A1 i porównuje wartość, którą włożył na stos z wartością poprzedniego wierzchołka stosu poniżej. Jeśli wartości są zgodne, to dwa górne elementy są usuwane ze stosu i wykonywana jest procedura P1 powiązana ze wskaźnikiem A1, po czym następuje przejście do instrukcji następującej po instrukcji BR (czyli w powyższym wpisie, program po słowie P0 w tekście). Jeśli porównywane wartości się nie zgadzają, jeden górny element jest usuwany ze stosu (tj. Wynik A1) i te same działania są wykonywane z parą A2 P2, a następnie, jeśli dopasowanie nie wyszło, to z parą A3 P3 itd. do AN PN włącznie. W przypadku, gdy żadna z prób nie dała dopasowania, wykonywana jest procedura P0 nazwana od słowa ELSE. Zwykle stałe numeryczne działają jak procedury wskaźników, na przykład:
[x] C BR 5 UJEM -3 ABS 0 NIE JESZCZE T0 [y]
W wyniku wykonania tej linii wartość y=-5 zostanie uzyskana na szczycie stosu, jeśli x=5; y=3 jeśli x=-3; y=1 jeśli x=0 i y=0 w przeciwnym wypadku.
Mówiąc ogólnie, procedura wskaźnika może być nie tylko stałą numeryczną, ale także zmienną lub inną procedurą, która spełnia prosty warunek, że nie zdejmuje niczego ze stosu i odkłada na stos pojedynczą wartość.
Jako ilustrację wykorzystania warunkowych operacji wykonania procedury, zmodyfikujmy procedurę TIME w poprzedniej sekcji tak, aby licznik zatrzymywał się po spełnieniu danego warunku:
: CZAS [t] 1- C JEŻELI+ CZAS ;
Teraz ta procedura TIME wywołuje się tylko wtedy, gdy wierzchołek stosu jest dodatni. Licznik będzie działał dokładnie N razy, jeśli na początku pierwszego wykonania CZAS wierzchołek zawiera liczbę dodatnią N. Na przykład, aby uzyskać 7 zliczeń, musisz określić
7 razy<ВК>
Ponieważ JEŻELI+ w definicji CZAS, jak każda operacja warunkowa, usuwa badany element ze stosu, a ten element jest niezbędny do kolejnych operacji, należy go zduplikować umieszczając operację C (Kopiuj) przed JEŻELI+.
Rekurencja nie jest podstawowym sposobem wielokrotnego wykonywania procedury. Do programowania cykli w języku PARADISE dostępne są komendy RP (Repeat - repeat) i DO (Do - do, perform).
Polecenie RP W nakazuje wykonywanie procedury W w kółko nieograniczoną liczbę razy. Aby powtórzenia się zatrzymały, ciało procedury W musi zawierać operację EX (Exit - exit), która jest wykonywana w określonych warunkach. Operacja EX przeskakuje do wykonania procedury następującej po tekście programu po powtórzeniu procedury zawierającej tę operację EX. Zatem licznik, zaimplementowany powyżej jako rekurencyjna procedura CZAS, może być zaprogramowany jako powtórzenie procedury W, która jest zdefiniowana następująco:
: W [t] 1- C IF0 EX ;
Aby licznik działał 25 razy, musisz wykonać linię
Wraz z operacją EX, która jest używana w warunkowych instrukcjach wykonania, istnieją warunkowe operacje wyjścia EX-, EX0, EX+, które mają taki sam efekt jak instrukcje IF-EX, IF0 EX, IF+ EX, tj. zużywają wierzchołek elementu który testuje swój znak i kończy działanie, jeśli znak jest zgodny z określonym w oznaczeniu operacji. Operacje EX, EX-, EX0, EX+ mogą być użyte niekoniecznie w treści najczęściej powtarzanej procedury (w naszym przypadku W), ale także w procedurach, których dotyczy.
Jako przykład rozważmy problem znalezienia największego wspólnego dzielnika dwóch liczb naturalnych metodą euklidesową. Istota metody polega na tym, że konieczne jest odejmowanie mniejszej liczby od większej, aż liczby się zrównają. Po osiągnięciu równości zostanie znaleziony największy wspólny dzielnik.
Programowanie będzie realizowane metodą odgórnego rozwoju. Najpierw definiujemy procedurę GCD, która ustala ogólny schemat algorytmu. Parametrami tej procedury są dwie liczby M i N na stosie, dla których znajduje się największy wspólny dzielnik. W treści procedury GCD należy określić cykliczny proces konwersji wartości w stosie. W wyniku tego procesu na stosie powinny pozostać dwie równe liczby - dowolna z nich może być uznana za największy wspólny dzielnik. Mając to na uwadze, procedurę GCD można zdefiniować w następujący sposób.
: gcd RP STEP [węd(M,N),węd(M,N)] D [węd(M,N)] ;
Teraz konieczne jest zaprogramowanie jednego kroku procesu iteracyjnego, tj. zdefiniować procedurę STEP. Jego parametrami są dwie liczby na stosie. Musisz porównać te liczby i wyjść z pętli, jeśli są równe, w przeciwnym razie odejmij mniejszą od większej. Można to zrobić na przykład tak:
: ETAP C2 C2 - BRS NOP EX E2 C2 - ;
Teraz w programie nie ma już niezdefiniowanych procedur i możesz zacząć go testować. Sprawdzenie należy przeprowadzić od dołu do góry, tj. najpierw musisz upewnić się, że procedura STEP działa poprawnie, a dopiero potem - GCD.
Operacja DO w języku bazowym powoduje, że nazwana po niej procedura jest powtarzana N razy, gdzie N jest liczbą znajdującą się na szczycie stosu w momencie wykonania DO. Na przykład, aby procedura P została wykonana 8 razy, należy podać
8 DOP
Jeżeli w ciele procedury P znajduje się co najmniej jedna operacja wyjścia i warunek jej wykonania zostanie spełniony przed wystąpieniem określonej liczby powtórzeń, to powtórzenia zostaną zakończone poprzez wyjście z procedury, tak jak ma to miejsce w przypadku operacja RP. Na przykład, jeśli DO powtórzy powyższą procedurę W, której definicja zawiera IF0 EX, napisanie [T] 30 DO W spowoduje 30 powtórzeń W, jeśli wartość T>=30. Jeśli 0 Jeśli do czasu wykonania operacji DO wierzchołek stosu ma wartość zero lub ujemną, to procedura następująca po DO nie zostanie wykonana ani razu. Aby zilustrować użycie operacji DO, definiujemy procedurę NUM, która zlicza liczbę niezerowych bitów w 32-bitowym słowie x podanym na szczycie stosu. Licznik liczby jednostek zostanie umieszczony na szczycie stosu. Liczenie jednostek będzie polegało na 32-krotnym powtórzeniu procedury NUMI, w której zbadamy jeden bit słowa x. Po wyjściu z pętli żądana liczba powinna znajdować się na szczycie stosu. : LICZ [x] 0 E2 32 DO LICZ D [N] ; Do zliczania niezerowych bitów wykorzystujemy fakt, że jednostka w najwyższym (31.) bicie słowa jest znakiem liczby ujemnej. Jeśli badane słowo jest przeczące, należy je dodać do N. Pod koniec procedury NUMI musisz przesunąć badane słowo o jeden bit w lewo. : NUMI C JEŚLI- N+ SHL ; Implementacja procedury N+ jest dość prosta: musisz dodać jedną na wierzchu stosu bez zmiany wierzchołka. : N+ E2 1+ E2 ; Procedury powtarzalne mogą zawierać w swoich ciałach operacje RP i DO, co prowadzi do zagnieżdżonych pętli, przy czym dozwolona jest dowolna głębokość zagnieżdżania. W tym przypadku istnieje operacja EXT umożliwiająca wyjście z zagnieżdżonej pętli, wskazująca głębokość zagnieżdżenia na szczycie stosu. Na przykład wyjście z dwóch zagnieżdżonych pętli można określić w następujący sposób: Należy pamiętać, że użycie polecenia EXT wymaga większej ostrożności, ponieważ podczas modyfikacji programu głębokość zagnieżdżenia pętli może się zmienić, a odpowiednia stała przed EXT będzie musiała zostać zmieniona. Stos operandów jest głównym, ale nie jedynym mechanizmem manipulacji danymi w PRSP. Możliwe jest również, wraz z definicjami procedur, deklarowanie elementów i standardowych zbiorów elementów danych (tzw. struktur), które są następnie dostępne do użycia według ich nazw. Realizując deklaracje danych, procesor rezerwuje pamięć niezbędną do ich przechowywania i zapewnia niezbędne mechanizmy dostępu do tej pamięci. Podstawowy język PRSP zawiera kilka słów dyrektyw omówionych poniżej do deklarowania zmiennych i tablic. W celu rozszerzenia języka systemu można wprowadzić do niego inne tego rodzaju słowa, a co za tym idzie inne elementy i struktury danych. Słowo VAR deklaruje 16-bitową zmienną liczbową. Na przykład wpis deklaruje zmienną X, to znaczy mówi procesorowi, że nazwa X jest nazwą zmiennej. Procesor kojarzy z tą nazwą 16-bitową lokalizację pamięci, która będzie przechowywać wartość tej zmiennej. Instrukcja przypisania wartości do zmiennej X, która jest zawarta na szczycie stosu argumentów, to Wykonując to polecenie, procesor usuwa górny element ze stosu i zapisuje jego wartość do komórki przydzielonej dla zmiennej X. Komenda składająca się tylko z nazwy zmiennej, przed którą nie ma litery !, powoduje odłożenie wartości tej zmiennej na stos, a wgrywanie odbywa się poprzez skopiowanie zawartości odpowiedniej komórki pamięci, czyli wartości zmiennej pozostaje bez zmian. Zatem każde wystąpienie nazwy zmiennej X w programie, jeśli nie jest bezpośrednio poprzedzone słowem określającym inną akcję, spowoduje odłożenie na stos bieżącej wartości tej zmiennej, podobnie jak bezpośrednio podane liczby (literale numeryczne) są popychane. Jako przykład podajemy inną wersję procedury GCD omówionej powyżej, w której używane są dwie zmienne robocze. : NIE! X! Y RP KROK X [GCD] ; : ETAP X Y = EX+ X Y BR+ X-Y Y-X ; : X-Y X Y - ! X; : Y-X Y X - ! Y ; Jak widać, program nieco się wydłużył, ale jego klarowność wzrosła. Słowo VCTR deklaruje jednowymiarową tablicę (wektor) 16-bitowych komórek, a numer najwyższego elementu tej tablicy określa wartość wierzchołka. Na przykład w wyniku pisania 9 VCTR ROW, procesor rezerwuje 10 kolejno adresowalnych 16-bitowych słów pamięci, tworząc wektor ROW (0:9). Najpierw liczba 9 jest wypychana na stos, a następnie wykonywana jest procedura VCTR, wykorzystująca górny element stosu do określenia długości tworzonego wektora ROW. Włożenie na stos wartości j-tego elementu wektora ROW, 0<=j<=9, задается командой [j]ROW Używając numeru elementu na stosie jako parametru, nazwa wektora ROW powoduje zastąpienie tego numeru wartością odpowiedniego elementu. Jeśli bezpośrednio przed nazwą wektora ROW znajduje się słowo!, to elementowi tego wektora wskazanemu przez wierzchołek jest przypisywana wartość subvertexa, a głębokość stosu jest zmniejszona o 2. Na przykład można zresetować piąty element wektora ROW w następujący sposób: Istnieje również możliwość łączenia wektorów stałych, tj. wektory liczb 16-bitowych, których wartości są zdefiniowane w momencie zadeklarowania i nie zmieniają się w przyszłości. Zatem wektor stałych 16-bitowych VC o długości L+1 jest deklarowany przy użyciu słowa CNST w postaci: CNST VC k0 k1 ... kL ; gdzie k0, k1, ... kL są poleceniami wrzucającymi jedną wartość na stos. Najczęściej są to tylko literały numeryczne, ale mogą też występować nazwy zmiennych, procedur, a także komendy składające się z par słów, jak np. omówione poniżej polecenie wysłania adresu zmiennej „X”. Dostęp do elementów wektora stałego odbywa się w taki sam sposób jak do składowych wektorów regularnych, na przykład: Wielowymiarowa tablica słów 16-bitowych jest deklarowana słowem ARR, poprzedzonym maksymalnymi wartościami indeksu dla każdego wymiaru oraz liczbą wymiarów. Na przykład trójwymiarowa tablica TIR(0:8,0:2,0:24) jest zadeklarowana w następujący sposób: Liczba 3 bezpośrednio przed ARR wskazuje wymiar zadeklarowanej tablicy. Pchnięcie elementu tablicy na stos jest osiągane przez podanie indeksu tego elementu, po którym następuje nazwa tablicy. Na przykład polecenie wypychania elementu TIR(0,2,2) na stos jest wyrażone jako W związku z tym przypisanie bieżącej wartości wierzchołka stosu do tego elementu jest podawane przez polecenie Wszystkie rozważane przykłady ilustrowały tworzenie struktur ze słów 16-bitowych. Jednak język umożliwia również definiowanie struktur 32-bitowych słów i 8-bitowych bajtów. W tym celu słowo określające strukturę jest poprzedzone odpowiednio LONG lub BYTE. Na przykład, 5 BYTE VCTR X - definicja 6-składnikowego wektora bajtowego X; BAJT CNST Y 65 66 67 ; - definicja 3-składnikowej bajtowej stałej wektora Y; 10 20 2 LONG ARR MTRX - definicja macierzy długich słów MTRX(0:10,0:20). Odczytywanie elementów struktur słownych i bajtowych odbywa się dokładnie tak samo jak w przypadku 16-bitowych struktur słownych. Jeśli długość elementu jest mniejsza niż 32 bity, wyodrębniona wartość jest umieszczana w młodszym słowie lub bajcie wierzchołka stosu, a górna część wierzchołka jest ustawiana na zero. Młodsze słowo lub bajt 32-bitowego długiego słowa na stosie jest również przyjmowane jako wartość przypisana do elementu struktury słowa lub bajtu. Chociaż domyślnie przy definiowaniu danych używany jest 16-bitowy format słowa, ma on również zapis WORD. Wskazane jest używanie tego prefiksu, gdy program ma być przeniesiony na inne maszyny, na których zaimplementowano również DSSP i domyślny może być inny. Struktury danych bajtowych są najczęściej używane do przechowywania i przetwarzania informacji tekstowych. Wynika to z faktu, że jeden bajt jest przydzielany w pamięci komputera do zakodowania jednego znaku. Do ustawiania kodów znaków w języku PARADISE służy konstrukcja #l, gdzie l jest dowolnym znakiem dostępnym na klawiaturze komputera. Procesor DSSP postrzega tę konstrukcję jako polecenie wepchnięcia litery l na stos. Na przykład: Ta konstrukcja wykonuje te same czynności, co literał numeryczny równy kodowi określonego znaku, ale jej użycie jest bardziej preferowane, ponieważ po pierwsze eliminuje potrzebę zapamiętywania kodów, a po drugie sprawia, że programy są bardziej zrozumiałe. W szczególności można podać następującą definicję wektora stałego Y: BYTE CNST Y #A #B #C ; Często wygodnie jest używać notacji symbolicznej dla stałej numerycznej w programie. Aby zapewnić taką możliwość, istnieje słowo definiujące WARTOŚĆ: To polecenie zdejmuje górny element ze stosu i tworzy słowo o nazwie bezpośrednio po VALUE. Użycie tego słowa jest równoznaczne z użyciem stałej liczbowej. Na przykład: Rozważane narzędzia dają możliwość nazywania danych i manipulowania danymi niezależnie od systemu adresowego komputera. Ale język podstawowy zawiera również narzędzia, które pozwalają manipulować adresami elementów pamięci. Adres zmiennej lub elementu tablicy X jest odkładany na stos przez polecenie W przypadku elementu tablicy, polecenie to jest poprzedzone wartością indeksu(ów). Podstawowa instrukcja języka @ zastępuje adres długiego słowa pamięci na szczycie stosu wartością, którą zawiera długie słowo. Na przykład wartość zmiennej Y można odłożyć na stos, wykonując następujący wiersz: Instrukcja @B zastępuje adres wartością odpowiedniego bajtu, zakładając, że starsze bajty wierzchołka stosu wynoszą zero, a instrukcja @L zastępuje adres słowem 32-bitowym. Istnieją również instrukcje dotyczące zapisywania wartości do pamięci. Polecenie !T zapisuje 16-bitową wartość podrzędną pod adresem wyjętym ze szczytu stosu. Polecenie !TB powoduje podobny zapis młodszego bajtu podwęzła do bajtu adresowanego przez węzeł, a !TL zapisuje 32-bitowe słowo podwęzła do słowa adresowanego przez węzeł. Na przykład, możesz przypisać wartość 15 do piątego elementu wektora bajtów BV(0:5) za pomocą następujących poleceń: 15 5" B.V.!TB Konieczność pracy z pamięcią pod fizycznymi adresami zwykle pojawia się przy tworzeniu programów zależnych od architektury konkretnego komputera, na przykład przy tworzeniu sterowników wejścia/wyjścia. W celu uzyskania większej wydajności i zwartości programów w języku PARA wprowadzono następujące operacje: 0 <имя переменной>- zresetuj zmienną; 1 <имя переменной>- przypisać jednostkę do zmiennej; 1- <имя переменной>- zmniejszyć wartość zmiennej o jeden; 1+ <имя переменной>- zwiększ wartość zmiennej o jeden; !- <имя переменной>- odejmij wartość wierzchołka stosu od zmiennej; !+ <имя переменной>- dodaj do zmiennej wartość wierzchołka stosu. Każdą z tych operacji można łatwo zaprogramować za pomocą poleceń odczytu i zapisu zmiennych. Na przykład, 0 X jest równoważne 0 ! X 1+ X jest równoważne X 1+ ! X X jest równoważne X E2 - ! X Wykorzystanie tych operacji zwiększa wydajność i widoczność programów. W praktyce często konieczne jest przypisanie jednej wartości do wszystkich elementów tablicy. Jest na to operacja w języku PARADISE!!!<имя массива>. Jego działanie polega na przypisaniu wartości wierzchołka stosu do wszystkich składników określonej tablicy. Operacja!!! ma zastosowanie do tablic z elementami dowolnego formatu. Przykład użycia: kod znaku "spacja" jest zapisywany do wszystkich elementów tablicy bajtów BUF. Często konieczne jest uzyskanie informacji o strukturze danych kryjącej się za nazwą w programie. Para poleceń ROZMIAR? - podać format elementu danych: 1, 2 lub 4 bajty oraz DIM? - zwraca liczbę elementów danych w strukturze. Na przykład, jeśli dane są zadeklarowane 3 4 2 DŁUGI SZR Z wtedy w stosunku do nich te polecenia dadzą następujący wynik (liczby dziesiętne): ROZMIAR? ROZMIAR X? TAK ROZMIAR? Z CIEMNY? X WYMIAR? TAK WYGASZONY? Z Zestaw instrukcji procesora DSSP zawiera dodatkowo cztery instrukcje, które umożliwiają odczytywanie i zapisywanie poszczególnych bitów komórek pamięci komputera. Są to polecenia @BI, !BI, !BI0, !BI1. Parametrami dla każdego z nich są adres słowa pamięci na stosie i liczba bitów w tym słowie (przypomnijmy, że bity są numerowane od prawej do lewej, zaczynając od zera). Polecenie !BI zakłada również obecność na stosie i wartość bitu do zapisania. Komenda @BI zastępuje podane parametry wartością wybranego bitu (0 lub 1), komendy !BI0 i!BI1 przypisują odpowiednio wartość 0 i 1 do wybranego bitu, usuwając ich parametry ze stosu, a Polecenie !BI ustawia wybrany bit na najmniej znaczący bit trzeciego elementu stosu i usuwa wszystkie trzy jego parametry ze stosu. Na przykład, jeśli wartością zmiennej X jest liczba binarna 101101, to wyniki wymienionych operacji będą następujące: " X [adres X] 3 @BI - trzeci bit X, 0 " X 3 !BI - X to 100101, " X [addr.X] 0 !BI0 - X to 100100, " X [addr.X] 1 !BI1 - X to 100110. Język PARADISE posiada również udogodnienia do pracy z ciągami bajtów znajdujących się w pamięci. Aby określić ciąg bajtów, dwa parametry są odkładane na stos: adres początkowy ciągu (tj. adres jego pierwszego bajtu) i długość ciągu (liczba bajtów w nim zawartych). Polecenie !!!MB służy do przypisania wszystkich bajtów ciągu do jednej (podanej na stosie) wartości. Pobiera trzy parametry ze stosu: , gdzie b jest wartością do przypisania, a i l są odpowiednio adresem początkowym i długością ciągu bajtów. Niech na przykład musisz wyzerować elementy od 3 do 10 tablicy bajtowej TXT(0:20). Aby to zrobić, możesz uruchomić następującą linię: 0 3" TXT 8 !!! MB w rezultacie osiem kolejnych elementów określonej tablicy, zaczynając od trzeciego, otrzyma wartość 0. Podobne polecenie!!!MW ma za zadanie wypełnić ciąg 16-bitowych słów tą samą wartością (liczbą słów jest wskazany na górze stosu), a polecenie !!M - do wypełnienia ciągu długich słów. Polecenie !SB wysyła ciągi bajtów. Jego parametrami są: , gdzie a1 i l są adresem początkowym i długością przekazywanego ciągu, a2 jest adresem początkowym ciągu, do którego wykonywane jest przekazywanie. W wyniku wykonania polecenia!SB w pamięci z adresu a2 zostanie umieszczony ciąg bajtów o długości l, który jest dokładną kopią ciągu znajdującego się pod adresem a1 przed wykonaniem transferu. Ciąg źródłowy i docelowy mogą się pokrywać. Niech na przykład chcesz przesunąć elementy tablicy bajtów M(0:10) w następujący sposób: M(10):=M(9), M(9):=M(8), ..., M(1):= M(0). Aby to zrobić, możesz użyć polecenia!SB: 0" M 10 C2 1+ !SB w rezultacie ciąg 10 bajtów zostanie przesunięty o jeden bajt w kierunku zwiększania adresów pamięci. Polecenie!SB jest wygodne do pracy z ciągami znaków (przypomnij sobie, że każdy znak jest zakodowany przez jeden bajt). Pozwala na przykład na przypisanie do tablicy bajtów wartości jawnie podanego ciągu literowego. Do określenia takiego ciągu służy literał tekstowy, tj. cytowana sekwencja znaków, np. „TEKST DOSŁOWA”. Ta konstrukcja, napotkana w programie, powoduje umieszczenie na stosie adresu początkowego i długości ciągu bajtów zawierającego tekst w cudzysłowie. Te opcje mogą być następnie użyte z poleceniem !SB. Na przykład fragment "TABLE" 0 " TN !SB spowoduje przeniesienie literału "TABLE" do tablicy TN. Polecenie SRCHB wyszukuje podany bajt w ciągu. Parametry: , gdzie b jest bajtem, którego pierwsze wystąpienie ma zostać znalezione, a i n ustawiają odpowiednio adres początku i długość szukanego ciągu. Jeżeli n>0, to wyszukiwanie odbywa się od adresu a do adresu a + n-1 (w kierunku rosnących adresów), jeżeli n<0, то поиск ведется с адреса a до адреса a+n+1 (в сторону убывания адресов). В результате выполнения этой команды в стеке оказывается значение d, равное смещению относительно адреса a до первого вхождения байта b. Если такое вхождение не обнаружено, то d=n. Примеры: #T „TEKST” SRCHB #A „TEKST” SRCHB #E "TEKST" [#E,a,4] 1- + -4 [#E,a+3,-4] SRCHB [-2] Kończąc przegląd sposobów pracy z danymi, zajmijmy się zagadnieniem związanym z przechowywaniem danych w pamięci zewnętrznej komputera, tj. na dyskach magnetycznych. Język PARADISE ma polecenie ZAPISZ<имя файла>Instruuje przechowywanie kopii pamięci głównej systemu na dysku wraz z obiektami zdefiniowanymi przez użytkownika. W takim przypadku obszary pamięci przydzielone dla danych przez operacje VAR, VCTR, ARR nie są wyświetlane na dysku. W rezultacie, gdy zapisany system jest ładowany z dysku, wartości określonych danych nie są zdefiniowane (muszą być określone podczas wykonywania programu). W większości przypadków jest to uzasadnione, ponieważ nie ma potrzeby wydawania miejsca na dysku na przechowywanie zmiennych roboczych, buforów itp. Istnieją jednak dane, których wartości należy określić natychmiast po uruchomieniu systemu z dysku. Przykładem jest zmienna przechowująca prędkość wymiany danych z jakimś urządzeniem zewnętrznym. Przy przejściu na inny kurs wystarczy zmienić wartość tej zmiennej bez dokonywania jakichkolwiek korekt w programie. Wskazaniem dla procesora, że wartości elementów jakiejś struktury danych powinny być zapisywane na dysku w poleceniu ZAPISZ to prefiks FIX umieszczony przed definicją struktury, np. FIX VAR SPEED 20 FIX BYTE VCTR TABL Praca z tak zdefiniowanymi strukturami danych nie różni się od pracy ze strukturami zdefiniowanymi w zwykły sposób. W języku PARADISE istnieje niewielka grupa poleceń przeznaczonych do sterowania procesorem PRSP, a raczej emulatorem procesora PRSP. Polecenie RESTART powoduje ponowne uruchomienie procesora. W takim przypadku stos jest wyczyszczony, wyświetlany jest komunikat Wersja DSSP XX.XX.XX Bezpłatnie XXXXW i procesor przechodzi w tryb oczekiwania na wprowadzanie poleceń. To polecenie jest przydatne podczas debugowania programów. Jest również wykonywany w przypadku wystąpienia błędów: indeks poza granicami tablicy, wyczerpanie wolnej pamięci itp. Polecenie \G służy do kontynuowania wykonywania programu po zatrzymaniu się na niezdefiniowanym słowie. Jeżeli podczas wykonywania procedury procesor napotka odwołanie do niezdefiniowanego słowa, wydaje komunikat: przestań nie wiem<слово> . gdzie kropka jest zachętą procesora PRSP, sygnalizującą, że procesor jest w stanie zatrzymania na niezdefiniowanym słowie. W tym trybie możesz wykonywać dowolne polecenia procesora, tak jak w normalnym trybie, gdy gwiazdka jest znakiem zachęty. Z tego trybu można wyjść na dwa sposoby - albo przez wykonanie polecenia \G (wtedy procesor będzie kontynuował wykonywanie przerwanej procedury, pomijając niezdefiniowane słowo), albo przez polecenie RESTART. Polecenie EXEC nakazuje procesorowi wykonanie procedury, której adres znajduje się na szczycie stosu. Aby uzyskać adres procedury, użyj polecenia „” (dwa apostrofy), po którym następuje nazwa procedury. Na przykład w wyniku wykonania polecenia adres procedury ABS zostanie umieszczony na stosie. Te polecenia umożliwiają przekazanie procedury jako parametru do innej procedury. Wspomniana już operacja SAVE należy do grupy poleceń sterujących procesorem.<имя файла>, nakazujące zapisanie kopii systemu na dysku, a także komendy określające źródło wejściowe informacji tekstowych dostarczanych do procesora. Początkowo tym źródłem jest klawiatura wyświetlacza. WCZYTAJ polecenie<имя файла>przełącza dane wejściowe na plik dyskowy o określonej nazwie. Polecenie PF - nakazuje wprowadzanie poleceń z bufora edytora tekstu. Polecenie TEXEC wysyła na wejście procesora ciąg tekstowy, którego parametry są określone na stosie. Gdy polecenia zawarte w określonych źródłach są wykonywane, wejście automatycznie przełącza się na klawiaturę wyświetlacza. Wejściowy strumień instrukcji odbierany przez procesor może w szczególności zawierać instrukcje do definiowania procedur i danych, powodujące kompilację w wewnętrzną reprezentację i przechowywanie ciała procedury lub przydzielanie pamięci dla określonych danych, a także wprowadzanie nazwy skompilowanej procedury lub struktury danych do słownika PRSP. Słownik ustala korespondencję pomiędzy zewnętrznymi (używanymi w tekście programu) nazwami a adresami obiektów odpowiadającymi tym nazwom w reprezentacji wewnętrznej. Przetwarzając definicję procedury lub opis podanego nazwanego, procesor buduje słownik, tworząc w nim nowy wpis słownikowy zawierający nazwę (dokładniej 7 pierwszych znaków nazwy) i adres ciała procedury lub deskryptor danych powiązany z tą nazwą. W programowaniu zstępującym ciała procedur mogą zawierać odniesienia do obiektów, które nie zostały jeszcze zdefiniowane. W tym przypadku w słowniku powstają hasła słownikowe (nagłówki), oznaczone znakiem nieokreśloności. Użyj polecenia UNDEF, aby wyświetlić wszystkie niezdefiniowane nazwy. W trakcie rozwoju słownika możliwe jest tworzenie podsłowników - nazwanych zbiorów haseł słownikowych. Podsłownik zazwyczaj łączy procedury i struktury danych związane z tym samym zadaniem. Aby uniknąć pomyłek między nazwami podskryptów a innymi obiektami programu, nazwa podsłownika musi zaczynać się od litery $. Dostęp do słowników podrzędnych w celu ich rozwoju lub używania można otwierać i zamykać za pomocą specjalnych poleceń, które obejmują następujące (nazwa $v oznacza dowolny poprawny podsłownik). GROW $v - powiększa podsłownik $v, to znaczy, o ile nie określono inaczej, umieszcza nazwy wszystkich skompilowanych procedur i danych w podsłowniku $v; USE $v - otwarty do użycia (w celu wyszukania w nim nazw) $v subskrypcja; ZAMKNIJ $v - zamyka możliwość korzystania z podsłownika $v; TYLKO $v - udostępnia do użytku tylko podsłownik $v; ANULUJ - anuluj TYLKO ostatnie. Istnieje również polecenie ?$, które wypisuje na wyświetlaczu nazwy wszystkich słowników podrzędnych ich stanu - niezależnie od tego, czy podsłownik wyszukiwania jest otwarty czy zamknięty. Podsłownik, którego nazwa jest wydrukowana na górze, jest zawsze zwiększany. Podstawowe procedury PRSP stanowią podsłownik o nazwie $PRIME, który jest domyślnie otwarty do użytku i rozwoju, to znaczy, jeśli nie było polecenia, aby nakazać wzrost innemu podsłownikowi. Niech, na przykład, operacja?$ wypisze następny stan słowników podrzędnych. $PRG otwarte $PRIME otwarte $EDIT zamknięte $PRIME otwarte SYSTEM zamknięty Oznacza to, że $PRG jest obecnie otwarty do zwiększania i używania, $PRIME jest tylko do użytku, a $EDIT i SYSTEM są niedostępne. Pamiętaj, że podsłownik może składać się z kilku sekcji o tej samej nazwie. Istnieją polecenia do usuwania ze słownika jednego lub drugiego zestawu haseł słownikowych i, być może, powiązanych z nimi obiektów wewnętrznych. Tak więc polecenie FORGET $v usuwa wszystkie nazwy wprowadzone do słownika (nie tylko podsłownik $v) od ostatniego wykonania polecenia GROW $v, wraz z obiektami oznaczonymi tymi nazwami i cofa wzrost $v subskrypcja, którą ustawił. Polecenie PROGRAM $v wykonuje te same czynności, co sekwencyjne polecenia FORGET $v GROW $v. Obecność takiego polecenia na początku dowolnego programu prowadzi do tego, że podczas ponownej kompilacji programu jego stara kopia zostanie usunięta i zostanie utworzony podsłownik do przechowywania obiektów nowej kopii programu. Np. wykonując operację FORGET $PRIME na słowniku, którego stan został pokazany powyżej, otrzymujemy nowy stan: $EDIT zamknięte $PRIME otwarte SYSTEM zamknięty Podczas wykonywania polecenia ZAPOMNIJ wyświetlane są nazwy sekcji do usunięcia. Zauważ, że nazwa podsłownika SYSTEM nie zaczyna się od $. Jest to dozwolone, ale prowadzi do tego, że zastosowanie poleceń FORGET i RPOGRAM do tego podsłownika nie powoduje żadnych działań (podsłownik SYSTEM wydaje się dla nich nie istnieć). W związku z tym, że zdecydowana większość procedur w gotowym programie nie wymaga dostępu poprzez nazwę zewnętrzną, istnieje możliwość usunięcia ich nazw ze słownika z zachowaniem skojarzonych z nimi obiektów wewnętrznych. Polecenie CLEAR $v usuwa wszystkie nazwy ze wszystkich sekcji podsłownika $v, z wyjątkiem tych poprzedzonych w tekście programu (gdy zostały zdefiniowane) przedrostkiem:: (dwa dwukropki). Na przykład w wyniku wykonania przez procesor następującego fragmentu programu: :: : X+ Y !+ X ; WYCZYŚĆ $EXAM tylko nazwy X i X+ pozostaną w podsłowniku $EXAM, wpis słownikowy Y zostanie usunięty (chociaż zmienna odpowiadająca słowu Y w reprezentacji wewnętrznej pozostanie). Głównym środkiem interakcji użytkownika z DSSP jest terminal, który zwykle jest wyświetlaczem katodowym z klawiaturą. Z terminala odbywa się wstępne wprowadzanie, edytowanie i debugowanie programów, przygotowywanie danych i całe zarządzanie systemem. Programy i dane, a także sam PRSP są przechowywane jako pliki na dyskach i można je wydrukować na drukarce. Do sterowania wejściami/wyjściami zestaw podstawowych procedur PRSP zawiera narzędzia opisane poniżej. Programowanie działania terminala umożliwiają polecenia wprowadzania i wyprowadzania liczb, pojedynczych liter i ciągów liter (łańcuchów znaków), a także kilka dodatkowych poleceń. Polecenie TIB (Terminal Input Byte) inicjuje pętlę oczekiwania na naciśnięcie klawisza na klawiaturze terminala. Po naciśnięciu klawisza 8-bitowy kod odpowiedniego znaku jest odkładany na stos jako młodszy bajt góry, przy czym górne 3 bajty zawierają zera. Na wyświetlaczu pojawi się kopia wprowadzonego w ten sposób znaku. Istnieje również komenda TRB (Terminal Read Byte), która różni się od TIB tym, że przesłanie kodu wprowadzonego znaku na stos nie wiąże się z wyświetleniem tego znaku na wyświetlaczu. Polecenie TIN (Terminal Input Number) inicjuje cykl wprowadzania danych do stosu i wyświetlania na wyświetlaczu numeru wpisanego z klawiatury. Numer wejściowy musi być sekwencją cyfr, która może zaczynać się znakiem minus i kończyć się znakiem Każde polecenie TIN wprowadza jedną liczbę. Jeśli chcesz wpisać ciąg cyfr w jednym wierszu, należy je rozdzielić, naciskając klawisz Sekwencja zawierająca n znaków wpisanych z klawiatury wprowadzana jest do pamięci komputera w postaci n bajtów umieszczonych pod kolejno rosnącymi adresami, począwszy od adresu a, za pomocą polecenia TIS (Terminal Input String), przed którym adres a i liczba n znaków jest odkładanych na stos . Niech na przykład zostanie zadeklarowany wektor bajtów X o wystarczającej długości. Musisz wprowadzić 9 znaków, przypisując ich wartości elementom tego wektora, zaczynając od elementu zerowego: Podobnie, używając polecenia TOS, określa się wynik sekwencji n bajtolitrów o adresie początkowym a: Wyprowadzenie na terminal elementów tekstowych bezpośrednio zawartych w programie zapewnia konstrukcja ."<текст>" Na przykład, aby tekst WPISZ NUMER WARIANTU pojawił się na wyświetlaczu po wykonaniu określonego fragmentu programu, fragment musi zawierać wpis „WPISZ NUMER WARIANTU”. Polecenie TON (Terminal Output Number) wyświetla liczbę, która ma zostać ściągnięta ze szczytu stosu, a długość pola wyjściowego musi być określona na górze. Numer wyjściowy jest wyrównany do prawej krawędzi pola, puste pozycje po lewej stronie są wypełniane spacjami, a jeśli długość liczby przekracza określoną długość pola, to po lewej następuje odcięcie. W trybie dziesiętnym we/wy liczby ujemne zaczynają się od znaku minus. Polecenie TOB (bajt wyjścia terminala) drukuje znak, którego kod jest podany przez młodszy bajt wierzchołka stosu. Głębokość stosu zmniejsza się o 1. Istnieją również polecenia, które bezpośrednio sterują kursorem wyświetlania: CR - skok na początek nowej linii, SP - spacja, czyli przesuń się o jedną pozycję w prawo. Polecenie BELL powoduje krótki dźwięk („dzwonek”). Czasami podczas komunikacji z terminalem może być konieczne sprawdzenie, czy klawisz został już naciśnięty i czy wyświetlacz wykonał już poprzednie polecenie wyjścia. Można to zrobić za pomocą poleceń TTI (Terminal Test Input) i TTO (Terminal Test Output), które pozostawiają flagę 1 na stosie, jeśli wystąpiło określone zdarzenie, i 0 w przeciwnym razie. Polecenia wyjścia drukarki są podobne do poleceń wyjścia terminala i są oparte na podobnym mnemoniku, w którym litery LP (drukarka wierszowa) zastąpiono TO lub dodano jako wiodące. Np. LPCR - przejście na początek nowej linii, LPSP - spacja, LPN - wyprowadzenie liczby z subvertexa w polu określonym przez wierzchołek, LPB - wyprowadzenie znaku, LPS - wyprowadzenie ciągu znaków . Istnieje również polecenie [N] LPT, które przesuwa głowicę drukującą do pozycji N drukowanej linii, oraz polecenie LPFF, które podaje arkusz papieru. Aby wydrukować wyraźny tekst, wygodnie jest użyć literału tekstowego i polecenia LPS, na przykład: „TABELA WARTOŚCI FUNKCJI” LPS Podczas programowania urządzeń peryferyjnych konieczna staje się obsługa przerwań. W DSSP to przetwarzanie jest zaprogramowane w następujący sposób. Program przeznaczony do obsługi przerwania to zwykła procedura PRSP, przed definicją której znajduje się przedrostek INT, na przykład INT: A !1+ I ; Prefiks INT zapewnia, że stan procesora jest zapisywany po przerwaniu i przywracany po zakończeniu przerwania. Polecenie LINK służy do łączenia procedury z określonym przerwaniem: <адрес вектора>POŁĄCZYĆ<имя процедуры>podczas którego, zgodnie z odpowiednim wektorem, rejestrowane jest wywołanie procedury obsługi przerwania. Instrukcja LINK może wykonywać zarówno statyczne łączenie procedury z przerwaniem, które występuje w czasie kompilacji programu, jak i dynamicznie, gdy program jest wykonywany. Przerwanie procesora to sposób, w jaki zdarzenie, które wystąpiło w świecie zewnętrznym, jest zgłaszane do systemu. W programie mogą również wystąpić zdarzenia wymagające natychmiastowego przetworzenia. Nazywane są sytuacjami wyjątkowymi. Przykłady takich sytuacji: dzielenie przez zero, błąd komunikacji z urządzeniem, koniec pliku wejściowego itp. W DSSP wyjątkowe sytuacje są naprawiane za pomocą przerwań poleceń. Przerwanie polecenia to nazwana operacja wywołania procedury odpowiedzi i jest zadeklarowana w następujący sposób: PUŁAPKA<имя вызова> <конечная реакция> Na przykład: PUŁAPKA S1 .Sytuacja S1. W pierwszym przypadku ostateczną reakcją na przerwanie S jest procedura X, w drugim przypadku, gdy wystąpi przerwanie S1, na terminalu zostanie wyświetlony komunikat: Sytuacja S1. Program, który prawdopodobnie spowoduje przerwanie, może ustawić na nie odpowiedź poleceniem catch. W PRSP istnieją dwa rodzaje przechwycenia: ON i EON. Polecenia przechwytywania mogą być używane tylko wewnątrz procedur i mają format: NA<имя прерывания> <реакция> wieczność<имя прерывания> <реакция>Na przykład: : A ... ON S "Przerwanie S" ... ; : A1 ... EON S1 ABC ... ; ON i EON ustalają różne typy reakcji. Jeżeli komendą ON podana zostanie nowa reakcja, to w przypadku wystąpienia przerwania wykonywana jest procedura reakcji, po czym przerwany program kontynuuje działanie. Jeżeli reakcja jest ustawiona komendą EON, to najpierw stos operandów przyjmuje głębokość jaką miał w momencie wykonania EON, następnie reakcja jest wykonywana, a gdy się kończy, wykonanie procedury, w której EON użyte polecenie zatrzymuje się natychmiast. Rozważ przykłady. Procedura M wprowadza znaki z klawiatury terminala i sprawdza czy jest to cyfra. Jeżeli wprowadzony znak nie jest cyfrą, podnoszone jest przerwanie ND. TRAP ND "Nie liczba." : MRP M1 ; : M1 TRB [B] C #0< C2 #9 >&0 JEŻELI+ ND [B] TOB ; Ostateczną odpowiedzią na przerwanie ND jest komunikat: Brak cyfry. Jeśli M jest wywoływane z procedury P1, która ma własną odpowiedź na przerwanie ND: P1 ON ND PR1 M ; : PR1 [B] CR "Błąd." D#0 [#0] ; wówczas po wpisaniu znaku niecyfrowego przerwanie ND zostanie przetworzone przez program reakcyjny PR1 typu ON, co spowoduje wysłanie komunikatu z nowej linii: Błąd. Wprowadzony znak zostanie zastąpiony znakiem 0, po czym M będzie nadal działać. Jeśli M jest wywoływane z procedury P2: P2 EON ND PR2 M ; : PR2 CR "Błąd. Koniec wpisu." ; wówczas po wpisaniu znaku nie będącego cyfrą przerwanie ND zostanie przetworzone przez program reakcyjny PR2 typu EON, co spowoduje wysłanie komunikatu z nowej linii: Błąd. Koniec wejścia, po którym P2 wyjdzie. Stos argumentów będzie wtedy pusty. W razie potrzeby przerwanie może być reaktywowane w programie reakcji, rozszerzając je w ten sposób na programy wyższego poziomu. W takim przypadku przerwanie zostanie obsłużone przez program określony w poleceniu przechwycenia w procedurze obejmującej lub ostateczną reakcję. Na przykład, jeśli zmodyfikujesz PR2 w następujący sposób: : PR2 CR "Błąd. Koniec wprowadzania." N.D.; wówczas komunikat wyświetlany na terminalu będzie miał postać: Błąd. Koniec wprowadzania. Nie liczba. DSSP ma kilka wbudowanych przerwań poleceń, na które odpowiedź można dostarczyć w programach użytkownika. PYTANIE:
Assalam alejkum tak! Tam natknąłem się na ten artykuł. Jeśli się nie mylę, napisałeś coś przeciwnego. Jeśli nie jest to trudne, możesz ponownie skomentować ten artykuł. Muzułmański. Arabski jest językiem Koranu. Został wybrany spośród wszystkich języków świata i ma niezwykłe właściwości. Ten język jest również językiem Proroka Mahometa (niech pokój i błogosławieństwo będą z nim). Ten język jest bogaty i żaden z języków świata nie może z nim konkurować. Ma duchowy i fizyczny wpływ na osobę mówiącą tym językiem. Arabowie organizowali konkursy poetyckie, ale kiedy Prorok (saw) otrzymał Objawienie, Arabowie byli tak zdumieni tak wspaniałą ekspresją języka, a nawet niektórzy myśleli, że Koran ma magiczną wpływ na osobę. Jeśli ktoś chce poprawić jedno słowo lub literę z Koranu, cała harmonia Boskiej księgi zostanie zerwana. Ani jedno słowo Koranu nie powinno być zmieniane, w przeciwnym razie zmieni się znaczenie i fonetyka. Wiemy, że niektóre słowa z czasem stają się przestarzałe i nie używamy ich. A język Koranu nie stracił na aktualności od 1439 lat... Uczę Koranu od ponad 10 lat i do dziś nie widziałem, aby jeden z moich uczniów zadawał mi pytanie: „Dlaczego studiujemy Koran? Skąd to się wzieło? Jakie to ma zalety? Jaka jest jego osobliwość od czytania od lewej do prawej? Z dnia na dzień rośnie liczba chętnych do nauki alfabetu arabskiego i zasad tajuid, aby później mogli czytać Koran z oryginału. Ale niewiele osób myśli o odpowiedzi na powyższe pytania. I w końcu, kiedy wyjaśniam im zalety Koranu, jego zalety, wielu zaczyna się w to zagłębiać. Arabski ma 29 liter. Dźwięki powstają na granicy krtani, pośrodku krtani, klatki piersiowej, między korzeniem języka a jamą ustną. Dźwięki języka arabskiego „czyszczą” jamę ustną i są mniej podatne na choroby. Język arabski jest również dobrym logopedą. Leczy seplenienie i błędną wymowę litery „r”. Ten język pomaga również osobom z zaburzeniami widzenia. Ponieważ czytanie tekstu arabskiego od lewej do prawej poprawia aparat wzrokowy człowieka i go rozluźnia. Owalny, okrągły kształt liter również dobrze wpływa na psychikę. Wszystkie litery alfabetu arabskiego są spółgłoskami. Nie ma specjalnych liter dla samogłosek. Są krótkie i długie samogłoski. Samogłoski krótkie są przekazywane na piśmie za pomocą samogłosek - znaków w indeksie górnym i dolnym. Ponadto na 28 liter 22 litery są połączone po obu stronach, a 6 liter jest połączonych tylko z prawej strony. Koran dotarł do nas bez zniekształceń przez 23 lata. Koran jest ostatnią Boską księgą i nie będzie po nim innych ksiąg. Jest zesłany na całą ludzkość. Prawa Koranu pozostaną w mocy aż do Dnia Sądu i nie ulegną zmianie. Koran jest wiecznym, wielkim cudem Wszechmogącego, danym Prorokowi Mahometowi (niech pokój będzie z nim). Czytanie Koranu to kult. Radzę wszystkim codziennie czytać tę nieporównywalnie wspaniałą książkę i znać jej znaczenie. Pospiesz się, aby nauczyć się czytać i rozmawiać ze swoim Stwórcą. Niech Allah pozwoli nam być mieszkańcami Jannat i mówić językiem arabskim, który Sam wybrał. Dilyarom Bektaeva, ustaz z Aktobe regional Centralny meczet „Nur Gasyr” http://nurgasyr.kz/index.php/ma-alar/1826-yazyk-zhitelej-dzhannata
ODPOWIADAĆ:
wa alaikum assalaam bracie! Tacy jak ona, wychowani w domu i nieświadomi „fałszywi ustaze” muszą być odepchnięci od muzułmanów, aby ich nie wprowadzać w błąd. Ponieważ takie bzdury szerzą się w meczecie w Aktobe, a nieświadomi nauczyciele są trzymani, być może dlatego w tym mieście jest tak wielu ekstremistycznych sekciarzy. Ani w Koranie, ani w Sunny nie ma nawet odległej wskazówki, że język arabski będzie wspólnym językiem dla wszystkich mieszkańców Raju. Zastanów się, jak przedstawiciele innych narodowości będą się ze sobą komunikować w Raju, jeśli nie znają arabskiego?!! Wcześniej odpowiedziałem na podobne pytanie: 1. To opowieść o tym, jak ludzie przestali się rozumieć i pojawiły się liczne języki współczesnego świata. Jak popularny jest ten mit wśród różnych narodów i jakie są jego interpretacje? 2. Mit Wieży Babel opiera się nie tylko na przekonaniu, że początkowo cała ludzkość mówiła tym samym językiem, ale także na tym, że język ten był „idealny”: nazwy przedmiotów oddawały ich prawdziwą istotę. Czy przedstawiciele innych kultur podzielają te poglądy i uważają, że ich język jest najbliższy oryginalnemu? Odpowiedź na pierwsze pytanie znajduje się w Księdze Rodzaju 11:1-9 Starego Testamentu, gdzie jest powiedziane, że Bóg postanowił ukarać ludzkość, nakładając na nią przekleństwo pomieszania języków. Odpowiedź na drugie pytanie znajduje się w Księdze Rodzaju 2:19. W tej części Bóg przyprowadził wszystkie zwierzęta i ptaki do Adama, aby usłyszeć, jak Adam je nazwie, a „jak człowiek nazywa każdą żywą istotę, tak się nazywa”. Zaimprowizowana wycieczka kulturalna pozwoli nam zobaczyć, jak omawiane są te kwestie. W odniesieniu do pierwszego z nich wielu zgadza się ze Starym Testamentem: różnorodność języków jest karą Pana, a przynajmniej wynikiem jakiegoś niekorzystnego czynnika. Legenda jednego z plemion australijskich opowiada o jedzeniu starych ludzi. Plemiona, które zjadały samo ciało, mówiły „czystym” językiem, a te, które jadły narządy wewnętrzne, mówiły „nieczystym”. Afrykańscy Kabile wierzą, że w wyniku konfliktu ludzie zaczęli mówić różnymi językami. Według plemienia z Assam pomieszanie języków wynikało z faktu, że kiedyś troje dzieci polowało na szczura. Jedno z plemion amazońskich jest zdania, że Bóg podzielił ludzi i ich języki, aby byli Mu bardziej posłuszni. Wśród rdzennej ludności Ameryki, w plemieniu Maidu (Kalifornia), uważa się, że początkowo ludzie mówili tym samym językiem, ale pewnego dnia podczas ceremonii pogrzebowej język ten przestał być jednym. Irokezi uważają, że separacja języków była spowodowana kłótnią rodzinną, która doprowadziła do śmierci dziecka. Ale założenie, że wielojęzyczność jest przekleństwem, nie jest tak powszechne, jak się wydaje. Na świecie istnieje wiele wersji, według których separacja nastąpiła w wyniku naturalnych procesów. Starożytny indyjski hymn „Rigveda” wspomina, że kiedyś istniało Vak („słowo”) i bogowie podzielili je na wiele form. Ludy Półwyspu Indochińskiego opowiadają o sześciu rasach, z których każda miała swój własny język w postaci łodygi, wijącej się z tykwy. Plemię Quiche (Gwatemala) ma mit, że ludzie żyli razem i mówili tym samym językiem, dopóki nie zostali podzieleni na grupy. Każda wybrała sobie boga i zaczęła mówić własnym językiem. Mit stworzenia południowoamerykańskiego plemienia Navajo opowiada o „Zmieniającej się kobiecie” i pojawieniu się prawdziwych ludów, które mówiły jej językiem. Stworzyła więc sąsiednie ludy - Pueblo, meksykańskich tubylców i inne, a oni mówili własnymi językami, rozprzestrzeniając je w różnych kierunkach. W islamie Koran naucza, że Adam nie wymyślił imion ani niczego innego, ale wszystkiego nauczył go Allah. Różnorodność języków jest całkowicie naturalna i jest przejawem mocy Allaha. Wszyscy ludzie są w stanie zrozumieć objawienia Koranu, niezależnie od tego, w jakim języku są napisane. System mitologiczny wielu narodów świata nie ma wyjaśnienia dla pomieszania języków, które jest po prostu uważane za oczywiste i dlatego nie może odpowiedzieć na nasze pytanie. Jednak w prawie wszystkich kulturach świata pojawia się wzmianka o języku „idealnym” (pytanie 2). Powyżej wspomnieliśmy o plemieniu australijskim, które wierzy, że niektórzy ludzie (żywiący się ludzkim ciałem) mówią „czystym” językiem, który przekazuje prawdziwą istotę rzeczy. Według starożytnych Egipcjan bóg Ptah nadawał wszystkie nazwy, dzięki czemu język stał się darem bogów. W Chinach „właściwego” języka nauczali mityczni cesarze. Koran traktuje różnorodność języków jako podział jednego języka, który obejmuje wszystkie inne. Wszędzie ludzie próbują zrozumieć, jak nazwa przedmiotu ujawnia swoją istotę. Zakłada się, że albo „idealny” język, który opisuje prawdziwą istotę przedmiotu, istnieje dzisiaj, albo pozostał w przeszłości. Drugie założenie jest warunkiem poszukiwania prawdy i harmonii w świecie. Wydaje się, że w naszych umysłach tkwią idee związku języka ze światem rzeczywistym i ludzką egzystencją. W związku z tym nasuwa się pytanie, które po raz pierwszy pojawiło się w dialogu Platona „Kratylos” i od tego czasu jest przedmiotem nieustannej debaty: czy związek między nazwą a obiektywną istotą rzeczy jest naturalny (powstający w subiektywnej świadomości native speakera). ) czy to połączenie jest warunkowe i losowe? 18 grudnia obchodzimy Światowy Dzień Języka Arabskiego. Święto zostało ustanowione przez ONZ w 2010 roku i jest jednym z sześciu oficjalnych języków ONZ. Według najnowszych danych na świecie jest 300 milionów ludzi mówiących po arabsku i jego dialektach. Co więcej, za 240 milionów jest rodzimy. Język arabski i religia islamu są ze sobą nierozerwalnie związane. Jedno jest nie do pomyślenia bez drugiego, ponieważ od półtora tysiąclecia muzułmanie na całym świecie czytają modlitwy po arabsku pięć razy dziennie. Został na nią zesłany Święty Koran i przemówił Prorok Muhammad (niech spoczywa w pokoju). Duchowni z Groznego na swój sposób uczcili tę doniosłą datę. Imam Meczetu Serca Czeczenii Magomed Dadakhaev zwrócił się do mieszkańców miasta. Wyjaśnił rolę języka arabskiego w życiu muzułmanina: Bez znajomości języka arabskiego człowiek nie może nauczyć się islamu. Dlatego wśród muzułmanów język ten od niepamiętnych czasów był bardzo szanowany. Niezbędnym warunkiem studiowania religii Proroka (niech spoczywa w pokoju) jest analiza tekstów arabskich, z których prawie wszystkie zostały napisane bardzo dawno temu. We współczesnym arabskim jest ponad 12 milionów słów (dla porównania jest ich 131 000 w języku rosyjskim i około miliona w języku angielskim ...). To bardzo bogaty i złożony język. Kiedy studiowałem na islamskim uniwersytecie w Syrii, nasz nauczyciel, filolog, podał nam taki przykład: w języku arabskim liczba synonimów jednego słowa „wielbłąd” sięga sześciu tysięcy! Jego gramatyka jest również bardzo złożona i wieloaspektowa. Jego badanie wymaga sporego wysiłku intelektualnego i wolicjonalnego. Dlatego wśród tłumaczy Koranu i Hadisów Proroka (niech spoczywa w pokoju) nie ma amatorów. Jest prawie niemożliwe zrozumienie znaczenia świętego tekstu bez solidnego arabskiego leksykonu i znajomości składni, semantyki i fonetyki tego języka. Czasami są ludzie, którzy nazywają siebie ekspertami od Koranu. Cytują z Orędzia Wszechmogącego, udzielają rad ludziom. Ale jeśli zapytasz ich o źródło wiedzy, otrzymasz odpowiedź: „Czytam tłumaczenie”. Tacy ludzie są bardzo niebezpieczni dla islamu, ponieważ nie wiedząc, co robią, mogą wprowadzić zamieszanie i nieścisłości w interpretacji przesłania Wszechmogącego. W islamskich instytucjach edukacyjnych szeroko praktykowana jest następująca metodologia nauczania: od kilku lat uczniowie szkół podstawowych studiują wyłącznie filologię arabską. I dopiero po opanowaniu w wystarczającym stopniu niezbędnej ilości materiału, uzyskują dostęp do studiowania tekstów Koranu. Tak więc język arabski jest rodzajem trampoliny do opanowania informacji o islamie. Ponadto język arabski będzie używany przez mieszkańców Raju. Chwała niech będzie Allahowi za uczynienie nas muzułmanami! Co dało nam piękny, bogaty język arabski, aby zrozumieć naszą wolę! W szkołach, aby uczyć się podstaw algorytmizacji, tzw. szkolny język algorytmiczny (edukacyjny język algorytmiczny), używając słów zrozumiałych dla ucznia w języku rosyjskim. W przeciwieństwie do większości języków programowania, język algorytmiczny nie jest związany z architekturą komputera, nie zawiera szczegółów związanych z urządzeniem maszyny. Algorytm w języku algorytmicznym w ujęciu ogólnym zapisany jest w postaci: Podczas pisania algorytmu słowa kluczowe były zazwyczaj podkreślane lub wyróżniane pogrubieniem. Wcięcia użyto do wyróżnienia bloków logicznych, a pary słów początku i końca bloku były połączone pionową kreską. Przykład obliczenia sumy kwadratów: Aby wzmocnić teoretyczne studia nad programowaniem w języku algorytmicznym, w 1985 roku specjaliści z Mechmatu Moskiewskiego Uniwersytetu Państwowego stworzyli edytor-kompilator "E-warsztat"(„E” - na cześć Erszowa), który pozwala wprowadzać, edytować i wykonywać programy w języku algorytmicznym. W 1986 roku został wydany zestaw światów treningowych (wykonawców) dla „E-praktyki”: „Robot”, „Drafter”, „Dwunożny”, „Pojazd terenowy”, które pozwalają po prostu wprowadzić koncepcje algorytmu. "E-warsztat" został zaimplementowany na komputerach: Yamaha, Corvette, UKNC i był szeroko stosowany. Ten język programowania był stale ulepszany, a opis późniejszej wersji „E-warsztatu” pojawił się w podręczniku z 1990 roku. System programowania „KuMir” („Zestaw światów edukacyjnych”), który obsługuje ten podręcznik, został wydany przez przedsiębiorstwo InfoMir w 1990 roku. Język tego systemu jest również nazywany „KuMir”. W 1995 roku „KuMir” został rekomendowany przez Ministerstwo Edukacji Federacji Rosyjskiej jako główny materiał edukacyjny do kursu „Podstawy informatyki i inżynierii komputerowej” na podstawie podręcznika A.G. Kushnirenko, G.V. Lebiediewa i RA Svorenyi. . Należy jednak zauważyć, że język algorytmiczny, z braku szczegółów łączących go bezpośrednio z architekturą komputerową, niemniej jednak odwołując się do języków podobnych do Algolo, domyślnie uczy dzieci w wieku szkolnym polegania na architekturze maszyn von Neumanna. (Architektura Von Neumanna jest praktyczną realizacją wcześniejszej idei zwanej Maszyną Turinga. Poza ideą Turinga istnieją inne pomysły. Najpopularniejsza z nich to Rachunek Lambda: pracował nad nią Alonzo Church. Maszyna Lisp to architektura oparta na Lambdzie - rachunek.) Fundacja Wikimedia. 2010 . Język algorytmiczny to język formalny używany do pisania, wdrażania lub badania algorytmów. Każdy język programowania jest językiem algorytmicznym, ale nie każdy język algorytmiczny nadaje się do użycia jako język ... ... Wikipedia Termin ten ma inne znaczenia, patrz Smok (znaczenia). Przykład schematu blokowego algorytmu w języku smoka DRAKON w schemacie DRAKON (przyjazny rosyjski język algorytmiczny zapewniający widoczność) wizualny ... ... Wikipedia Termin ten ma inne znaczenia, patrz Język algorytmiczny. Uczący się język algorytmiczny to język formalny używany do pisania, wdrażania i uczenia się algorytmów. W przeciwieństwie do większości języków programowania nie jest związany z ... Wikipedia Język algorytmiczny (również rosyjski język algorytmiczny, RAYA) to język programowania używany do pisania i badania algorytmów. Studiując informatykę w szkołach, studiować podstawy algorytmizacji, tzw. szkoła algorytmiczna ... ... Wikipedia Edukacyjny język programowania to język programowania przeznaczony do nauczania programowania specjalistów. Taki język musi spełniać główny wymóg: prostotę. Im prostsze, tym szybciej początkujący go opanuje. Możliwości takich ... ... Wikipedia Przykład schematu blokowego algorytmu w smoczych diagramach języka DRAKON DRAKON (Przyjazny Rosyjski Język Algorytmiczny Który Zapewnia Widoczność) to wizualny język algorytmiczny stworzony w ramach programu kosmicznego Buran. Rozwój tego języka ... WikipediaNazwane dane
Praca z pamięcią według adresów fizycznych
Dodatkowe operacje na danych i pamięci
Polecenia sterujące procesorem
Polecenia zarządzania słownikiem
Polecenia we/wy
Obsługa przerwań i wyjątków
Przykłady
E-warsztat
Krytyka
Spinki do mankietów
Zobacz, co „rosyjski język algorytmiczny” znajduje się w innych słownikach: