Język programowania Revomer

Oficjalna specyfikacja - wersja 0.9

Krzysztof Piecuch

Tomasz Jędrzejewski


Spis treści

Przedmowa
1. Założenia
1.1. Przykładowy program
1.2. Szczegóły
1.3. Środowisko
2. Składnia
2.1. Podstawy
2.2. Funkcje
2.2.1. Deklaracja funkcji
2.2.2. almukantarat
2.2.3. conf
2.2.4. rf
2.2.5. charm
2.3. Operatory
2.3.1. ????&
2.3.2. in
2.3.3. @&%^"
2.3.4. *?!
2.3.5. ~].?&*
2.4. Zarządzanie kodem źródłowym
2.4.1. come here
2.4.2. unless
2.4.3. if
2.4.4. real
2.4.5. shuffle
2.5. Pamięć operacyjna
2.5.1. hide
2.5.2. gifs
2.5.3. sars
2.6. Wejście/wyjście
2.6.1. gifts
2.6.2. pos
2.7. Komendy specjalne
2.7.1. nope
2.7.2. rope
3. Pozostałe
3.1. Obsługa pamięci
3.2. Revomerowa Logika
3.3. Interpreter
3.4. W następnych wydaniach
A. Copyright

Spis tabel

2.1. Operator ????&
3.1. Operator ????&

Spis przykładów

1.1. Program "HI UNIVERSE"
2.1. Program "HI UNIVERSE"
2.2. Nawiasy
2.3. Wywołanie funkcji "foo"
2.4. Kopiowanie
2.5. Losowanie liczby
2.6. Wstawianie wartości stałej

Przedmowa

28 sierpnia 2006 roku do LO im. Stanisława Staszica w Lublinie zjechała się z całej Polski grupa młodych informatyków oraz matematyków, aby dzielić się między sobą własną wiedzą i doświadczeniem. Jeszcze przed samym rozpoczęciem zlotu rozmowa zeszła na ezoteryczne języki programowania, które poza nielicznymi wyjątkami nie oferowały nic ponad udziwnioną składnię. Na pierwszym z wykładów dwójka uczestników, Krzysztof Piecuch oraz Tomasz Jędrzejewski, postanowiła tchnąć nowe życie w tę gałąź informatyki, tworząc nowy język programowania oparty na rewolucyjnej idei działania. Tak narodził się projekt Revomer.

W przeciągu pięciu dni trwania zlotu, w spartańskich warunkach, powstawały równocześnie założenia projektowe oraz pierwszy interpreter języka. Prace prowadzone były w godzinach nocnych i porannych na laptopie ulokowanym na sali gimnastycznej, a pierwsza wersja niniejszej specyfikacji została napisana na kilkumetrowej wstędze szarego papieru toaletowego. 1 września o godzinie 10.04 po raz pierwszy udało uruchomić się program wypisujący "HI UNIVERSE".

Nazwa języka to pisane na odwrót angielskie słowo "remover". Odzwierciedla ona podstawowe idee leżące u jego podstaw, które można zawrzeć w prostym skrócie IN-IG (Is Negative-Is Good). Język samą swoją strukturą wymusza zastosowanie nowego punktu widzenia na wiele, zdałoby się, oczywistych i nieodłącznych konstrukcji programistycznych. Mamy głęboką nadzieję, że będzie on istotnym wkładem w rozwój światowej informatyki oraz że kupi go znany wszystkim monopolista z Redmond i zastosuje w swoich produktach.

Rozdział 1. Założenia

W tej części wyjaśniamy podstawowe założenia języka programowania Revomer.

1.1. Przykładowy program

Podany poniżej program jest jednocześnie pierwszym, jaki udało się uruchomić na pierwszym interpreterze Revomera. Powoduje on wypisanie na ekranie napisu "HI UNIVERSE", po czym kończy swoją pracę.

Przykład 1.1. Program "HI UNIVERSE"

almukantarat~
nope~
null%
almukantarat~
come here $1, $1, $3
gifs 3~
hide $3
gifs 29~
hide $2
gifs 29~
hide $1
pos $0~
gifs 69~
pos $0~
gifs 83~
pos $0~
gifs 82~
pos $0~
gifs 69~
pos $0~
gifs 86~
pos $0~
gifs 73~
pos $0~
gifs 78~
pos $0~
gifs 85~
pos $0~
gifs 32~
pos $0~
gifs 73~
pos $0~
gifs 72~
hide $0
%	     

Dokładna analiza kodu źródłowego jest przeprowadzona w dalszej części specyfikacji.

1.2. Szczegóły

Szczegółowe założenia i koncepcje dotyczące Revomera to:

  1. Usuwanie, negowanie, odejmowanie (a nawet dzielenie!) jest cacy. Dodawanie i reszta jest be.
  2. Jeśli już coś uda nam się dodać, musi to być okupione pewnym kosztem, ponieważ jest be.
  3. Działanie programu polega na samomodyfikacji własnego kodu źródłowego w trakcie jego wykonywania.
  4. W kwestiach spornych interpreter próbuje zawsze domyślić się, co programista lub wykonywany program miał na myśli, czyt. wykonuje losową operację.

1.3. Środowisko

Środowisko, w którym pracują programy Revomera składa się z następujących elementów:

  1. Pamięć operacyjna na dane programu podzielona na 1-bajtowe komórki i przechowująca liczby ze znakiem (tj. dodanie oraz ujemne). Interpreter musi gwarantować przynajmniej 64 kB pamięci operacyjnej. Pamięć jest wypełniana w sposób losowy w momencie startu programu.
  2. Pamięć kodu źródłowego - jej struktura leży już w gestii interpretera, jednak musi ona umożliwiać dynamiczną modyfikację źródeł w trakcie wykonywania programu.
  3. Kod źródłowy stanowi lista rozkazów dla interpetera. Każdy z rozkazów może przyjmować do czterech argumentów.
  4. Pamięć operacyjna pełni także rolę rejestrów, dlatego do wszystkich instrukcji można podawać jako argumenty jedynie wskaźniki definiujące, w którym miejscu pamięci znajdują się dane.
  5. Długość argumentów może być zmieniana w trakcie wykonywania programu, aby rozkazy mogły przyjąć z pamięci większe liczby. Dodatkowo zmianie podlega wtedy także starszeństwo bajtów. Szczegóły w rozdziale poświęconemu zarządzaniu pamięcią.
  6. Revomer wykorzystuje własną odmianę logiki klasycznej, zwaną Logiką Revomerową.

Rozdział 2. Składnia

2.1. Podstawy

Wróćmy do naszego przykładu "HI UNIVERSE". Omówimy na jego przykładzie podstawowe koncepcje składni języka Revomer.

Przykład 2.1. Program "HI UNIVERSE"

almukantarat~
nope~
null%
almukantarat~
come here $1, $1, $3
gifs 3~
hide $3
gifs 29~
hide $2
gifs 29~
hide $1
pos $0~
gifs 69~
pos $0~
gifs 83~
pos $0~
gifs 82~
pos $0~
gifs 69~
pos $0~
gifs 86~
pos $0~
gifs 73~
pos $0~
gifs 78~
pos $0~
gifs 85~
pos $0~
gifs 32~
pos $0~
gifs 73~
pos $0~
gifs 72~
hide $0
%	     

Pierwszą i najważniejszą zasadą, której trzeba się nauczyć, jest kierunek czytania listingów. W Revomerze każda linijka może zawierać tylko jeden rozkaz. Linijki numerowane są od początku pliku, ale cały kod wykonywany jest w tył, tj. z dołu do góry. Przy omawianiu poszczególnych komend dostępnych dla programisty będziemy używać pojęć "następna instrukcja" oraz "poprzednia instrukcja" zgodnie z kierunkiem wykonywania programu. Zatem zwrot "skasować następą instrukcję" oznacza, że interpreter skasuje następną instrukcję, jaka się wykona, czyli tę leżącą linijkę wyżej.

Cały kod podzielony jest na funkcje. Deklaracja funkcji rozpoczyna się znakiem %, przed którym podana jest jej nazwa. Funkcja bez nazwy zwana jest funkcją zerową i od niej rozpoczyna się wykonywanie programu. Dopuszcza się tworzenie wielu funkcji o identycznej nazwie - podczas ich wywoływania ta "właściwa" wybierana jest w sposób losowy. Funkcja kończy pracę, gdy po napotkaniu deklaracji następnej funkcji lub komendy almukantarat stwierdzi, że nie zawiera już żadnych rozkazów. W przeciwnym wypadku zaczyna wykonywać się od początku. Program kończy pracę w momencie skasowania z użytej funkcji zerowej ostatniego rozkazu.

Jak wspomnieliśmy, formalnie funkcja kończy się w momencie deklaracji następnej funkcji lub końca listy rozkazów. Jednak interpreter bardzo nie lubi, gdy programista każe mu tam dotrzeć i dlatego jej wykonywanie powinno się "przerywać" wcześniej komendą almukantarat - uwaga, nie wlicza się ona do ostatecznej liczby rozkazów w danej funkcji. Oznacza to, że jeśli w treści funkcji znajduje się np. operacja nope oraz almukantarat, to dla interpretera tylko pierwsza z nich jest licząca się - zatem w funkcji mamy tylko jeden rozkaz i jego skasowanie wystarczy, aby przerwać działanie.

Dalsze reguły dotyczące składni:

  1. Każda komenda w Revomerze musi być zakończona tyldą za wyjątkiem tych komend, które nie mogą. Wyjątkiem od wyjątku jest komenda rope, która dopuszcza oba warianty.
  2. W Revomerze nie ma czegoś takiego, jak komentarze, ponadto białe znaki są ignorowane jedynie z końca linijek. W pozostałych miejscach liczba oraz kolejność każdego znaku odgrywa niezwykle istotne znaczenie.
  3. Listę parametrów oddziela od nazwy komendy jedna spacja.
  4. Parametry separuje przecinek i spacja.
  5. Parametr przeważnie jest adresem odpowiedniej komórki pamięci. Adres składa się ze znaku $ oraz numeru komórki. Revomer dopuszcza tworzenie wskaźników: zapis $$12 oznacza, że w komórce 12 zapisany jest numer komórki, z której trzeba odczytać właściwą wartość. Można także tworzyć jeszcze bardziej rozbudowane łańcuchy wskaźników, np. $$$$$$$$$$$$$$$12. Maksymalna ilość znaków dolara to 255.
  6. Niektóre z komend, zwane maszynowymi, mogą przyjmować inne argumenty, niż adresy komórek pamięci. Dozwolone pozostałe rodzaje to: liczba naturalna lub nazwa.
  7. Niektóre komendy wymagają podania parametrów w nawiasach. W Revomerze nawias otwierający to }, a nawias zamykający to #. Pomiędzy nawiasami a argumentami nie ma żadnych spacji. Przykład takiej komendy:

    Przykład 2.2. Nawiasy

    unless}$3#

2.2. Funkcje

Rozdział ten opisuje komendy związane z tworzeniem, wywoływaniem i zarządzaniem funkcjami.

2.2.1. Deklaracja funkcji

nazwa%
		

Rozpoczyna nową funkcję o podanej nazwie. Jeśli nazwa nie jest podana, tworzona jest funkcja zerowa. Jeżeli w trakcie wykonywania programu interpreter dotrze do takiej komendy, wykonuje identyczą czynność, jak almukantarat, jednak przedtem wykonuje także za karę operację rope.

Komenda nie jest zakończona tyldą.

2.2.2. almukantarat

almukantarat~
		

Jeżeli aktualnie wykonywana funkcja nie zawiera już żadnych innych instrukcji, przerywa jej wykonywanie i pozwala powrócić do miejsca wywołania. W przeciwnym wypadku rozpoczyna wykonywanie funkcji od początku. Nazwa tej komendy pochodzi z astronomii, gdzie oznacza koło na sferze niebieskiej, którego punkty leżą na tej samej wysokości nad horyzontem.

2.2.3. conf

conf funkcja1, funkcja2~
		

Zamienia dwie podane funkcje nazwami. Operacja dotyczy także funkcji aktualnie wykonywanych i znajdujących się na stosie. Komenda musi być zakończona tyldą.

2.2.4. rf

rf funkcja~
		

Usuwa z kodu wszystkie funkcje o podanej nazwie. Uwaga: jeżeli usuniemy w ten sposób funkcję zerową, nie spowodujemy przerwania wykonywania programu. Jeśli program nie zawiera funkcji zerowej, interpreter zaczyna w kółko wykonywać komendę rope w nadziei, że kiedyś uda mu się ją odtworzyć. Komenda musi być zakończona tyldą.

2.2.5. charm

charm $1
		

Wywołuje funkcję. Nazwę funkcji do wywołania należy wprowadzić do kolejnych komórek pamięci (malejąco), a następnie podać tutaj jako argument adres komórki zawierającej pierwszą literę. Algorytm pobierania nazwy jest następujący:

  1. Pobierz z aktualnej komórki znak i dodaj go do bufora.
  2. Czy jest funkcja o nazwie znajdującej się w buforze?
  3. Jeśli tak, wywołaj ją.
  4. Jeśli nie, przesuń się na poprzednią komórkę w pamięci i skocz do punktu 1.

Jeżeli osiągnięty zostanie w ten sposób koniec pamięci, interpreter wykonuje operację rope.

Przykład 2.3. Wywołanie funkcji "foo"

almukantarat~
nope~
foo%
almukantarat~
charm $2
gifs 111~
hide $0
gifs 111~
hide $1
gifs 102~
hide $2
%	     

2.3. Operatory

Rozdział ten opisuje operatory dostępne w języku Revomer.

2.3.1. ????&

????& $1, $2
		 

Operator logiczny Logiki Revomerowej wykonuje operacje na bitach komórek $1 oraz $2, a wynik zapisuje do pierwszej z nich. Tabelka logiczna:

Tabela 2.1. Operator ????&

Operator ????&
$1$1 ????& $2$2
0-10
0-1-1
-1-10
-10-1

Wartości inne niż Prawda i Fałsz Revomerowy są redukowane do takowych za pomocą Reduktora Standardowego.

2.3.2. in

in $1
		 

Reduktor IN - jeżeli w podanej komórce pamięci znajduje się liczba ujemna, zapisuje tam Prawdę Revomerową (-1). Jeżeli nieujemna - Fałsz Revomerowy (0).

2.3.3. @&%^"

@&%^" $1, $2
         

Od pierwszego argumentu odejmuje drugi i wynik zapisuje w komórce pamięci podanej w drugim argumencie.

2.3.4. *?!

*?! $1, $2
         

Dzieli pierwszy argument przez drugi i wynik zapisuje w komórce pamięci podanej w pierwszym argumencie. W przypadku dzielenia przez zero wykonywana jest operacja rope.

2.3.5. ~].?&*

~].?&* $1, $2~
         

Kopiuje zawartość pierwszej komórki do drugiej. W przykładzie poniżej wprowadzamy liczbę 52 do komórki $8, a następnie kopiujemy ją do komórki $9 i wyświetlamy.

Przykład 2.4. Kopiowanie

almukantarat~
nope~
null%
almukantarat~
come here $0, $0, $1
gifs 3~
hide $1
gifs 8~
hide $0
pos $9~
~].?&* $8, $9~
gifs 66~
hide $8
%	     

Komenda musi być zakończona tyldą.

2.4. Zarządzanie kodem źródłowym

Rozdział ten opisuje komendy do zarządzania kodem źródłowym.

2.4.1. come here

come here $1[, $2[, $3]]
         

Komenda pozwala przesuwać grupy komend w inne miejsce programu. Jej działanie różni się nieco w zależności od liczby argumentów:

  1. Bierze komendę leżącą $1 niżej i przenosi ją przed siebie.
  2. Dwa podane argumenty oznaczają tym razem całą grupę komend do przeniesienia. $1 nakazuje się cofnąć X linijek w dół (początek zaznaczanego obszaru), a następnie od tego miejsca $1 linijek do góry (koniec zaznaczanego obszaru). Obszar zostaje przeniesiony bezpośrednio przed komendę come here.
  3. Trzeci argument pozwala określić inne miejsce ulokowania przenoszonego bloku kodu, począwszy od come here (ilość linijek liczona do góry).

Uwaga: jeśli nowa lokalizacja bloku komend znajduje się wewnątrz tego bloku, kod źródłowy programu ulega defragmentacji z powodu działania algorytmu przesuwania. Zachowanie wskaźnika programu jest następujące: docelowo jako następna ma się zawsze wykonać instrukcja po come here. Jeżeli jednak come here zawarte jest wewnątrz przenoszonego przez siebie bloku (czyt: instrukcja przenosi samą siebie), jako następna musi być wykonana instrukcja leżąca po przenoszonym bloku (bierzemy pod uwagę sytuację SPRZED przeniesienia!).

2.4.2. unless

unless}$1#
         

Instrukcja warunkowego usuwania kodu. Jeżeli w podanej komórce znajduje się wartość fałszywa, następna linijka kodu źródłowego jest z niego usuwana. Linijka ta wykona się tylko wtedy, gdy w komórce znajduje się Revomerowska Prawda Logiczna (-1).Adres komórki podawany jest w nawiasach.

2.4.3. if

if $1, $2~
         

Dołącza plik, którego nazwa zawarta jest między komórkami pamięci $1 oraz $2, a znajdujące się w nim komendy wstawia w miejsce samego siebie. Wykonywanie dołączonego pliku rozpoczyna się od przedostatniej instrukcji. Jeżeli podany plik nie istnieje, wykonywana jest operacja rope.

2.4.4. real

real $1~
         

Usuwa linijkę leżącą $1 linijek niżej.

2.4.5. shuffle

shuffle $1, $2
         

W losowy sposób miesza kod źródłowy pomiędzy linijkami leżącymi $1 oraz $2 dalej. Przykład: losowanie liczby w zakresie od 1 do 10.

Przykład 2.5. Losowanie liczby

almukantarat~
nope~
null%
almukantarat~
come here $2, $2, $4
gifs 3~
hide $4
gifs 21~
hide $2
pos $0~
gifs 74~
gifs 73~
gifs 72~
gifs 71~
gifs 70~
gifs 69~
gifs 68~
gifs 67~
gifs 66~
gifs 65~
shuffle $1, $2
hide $0
gifs 1~
hide $1
gifs 11~
hide $2
%	     

W przykładzie wskazaliśmy, że wymieszane mają być komendy leżące między 1, a 11 linią wyżej.

2.5. Pamięć operacyjna

Rozdział ten opisuje komendy zarządzania pamięcią operacyjną.

2.5.1. hide

hide $1
         
Przesuwa wskaźnik interpretera na podaną w argumencie komórkę pamięci. Po tej komendzie nie podajemy tyldy.

2.5.2. gifs

gifs wartosc~
         
Wstawia podaną wartość liczbową do komórki pamięci, na której znajduje się aktualnie wskaźnik interpretera. Podany poniżej fragment programu wstawia liczbę "20" do komórki $0:

Przykład 2.6. Wstawianie wartości stałej

gifs 20~
hide $0	     

2.5.3. sars

sars 1|2|4
         

Zmienia długość wszystkich argumentów przekazywanych do komend. Dozwolone długości to 1, 2 lub 4 bajty. Ponadto wraz z wywołaniem sars zmienia się także starszeństwo bajtów. Adresy pamięci zawsze wskazują najstarszy bajt. Jeżeli starszeństwo jest ustawione na big endian, a kolejne bajty odczytywane są z komórek pamięci o rosnących numerach. Dla little endian - adresy komórek z kolejnymi bajtami maleją.

2.6. Wejście/wyjście

Komendy wejścia/wyjścia.

2.6.1. gifts

gifts $1[, $2]
         

Komenda wejścia, wczytuje dane do podanej komórki pamięci. W zależności od wartości w komórce pamięci w argumencie drugim:

  • Dla wartości ujemnych - komenda pozwala ręcznie wpisać liczbę w konsoli interpretera, która zostanie zapisana do komórki. Na ten tryb pracy wpływa komenda sars, zatem można podawać liczby zapisywane na większej liczbie bajtów.
  • Dla 0 i wartości dodanych (domyślne) - do podanej komórki pamięci wczytuje numer kolejnego wprowadzonego znaku ASCII znajdującego się na wejściu.

2.6.2. pos

pos $1~
         

Wyświetla znak ASCII o numerze znajdującym się w podanej komórce pamięci. Wartości dodatnie są traktowane normalnie, natomiast wartości ujemne pozwalają uzyskać znaki o kodach 128..255 według wzoru (-X+127).

2.7. Komendy specjalne

Dodatkowe komendy specjalnej troski i/lub uwagi.

2.7.1. nope

nope~
         

Ta komenda nic nie robi.

2.7.2. rope

rope~
         

Wykonuje losową komendę z losowymi argumentami. rope jest niezwykle ważna dla języka REVOMER, ponieważ służy też do domyślania się, co programista miał na myśli, odwołując się np. do nieistniejącego zasobu lub robiąc błąd składni w danej linijce. Komenda jest zatem wykonywana przy każdej nieprzewidzianej przez interpreter i specyfikację okazji. Jako jedyna także może, ale nie musi posiadać tyldy na końcu.

Rozdział 3. Pozostałe

3.1. Obsługa pamięci

Dodatkowe informacje o pamięci oraz o przechowywaniu danych w języku Revomer.

  1. Do zapisu liczb ujemnych Revomer wykorzystuje kod uzupełnień do dwóch.
  2. Komórka o ujemnej wartości reprezentuje znak ASCII o kodzie -X + 128, gdzie X to wartość w tej komórce.
  3. Kolejność odczytywania i zapisywania liczb większych, niż 8-bitowe (oraz w ogóle zdolność do robienia tego) zależy od ustawień komendy sars oraz aktualnego starszeństwa bajtów, które zmienia się wraz z jej kolejnymi wywołaniami między big endian oraz little endian.
  4. Revomer obsługuje następujące wartości logiczne: prawda (-1) oraz fałsz (0). Wartość logiczną każdej innej liczby określa się w następujący sposób: zapisujemy podaną liczbę słownie w sztucznym języku ferrinckim autorstwa Zyxa (bez użycia znaków diaktrycznych), haszujemy ją algorytmem MD5, bierzemy trzeci bit siedemnastego bajtu i jeśli jest to zwykła prawda (1), zamieniamy ją na Prawdę Revomerową. Aby uzyskać dodatkowe informacje o języku ferrinckim, odwiedź: yermenia.zyxist.com/ferrincki.html.

3.2. Revomerowa Logika

Rozdział ten zawiera podstawowe informacje o systemie logicznym używanym w Revomerze. Jest on ogólnie zbliżony do modelu klasycznego, lecz różni się wieloma istotnymi szczegółami.

Revomerowa Logika operuje na dwóch stanach revomerowych. Fałsz Revomerowy jest równoważny zwykłemu fałszowi i oznaczany jest jako 0. Prawda Revomerowa natomiast, w przeciwieństwie do logiki klasycznej, posiada wartość ujemną: -1.

Logika Revomerowa posiada jeden operator logiczny ????& oraz dwa reduktory pozwalające zredukować każdą inną wartość do Prawdy lub Fałszu Revomerowego. Operator ????& jest dwuargumentowy i daje następujący wynik:

Tabela 3.1. Operator ????&

Operator ????&
$1$1 ????& $2$2
0-10
0-1-1
-1-10
-10-1

Odpowiada on mniej więcej operatorowi NAND w logice klasycznej.

Reduktor Standardowy jest domyślnie używany do redukcji każdej wartości innej niż -1 i 0 do Prawdy lub Fałszu Revomerowego. Redukcji dokonuje następujący algorytm:

  1. Zapisz daną liczbę słownie w sztucznym języku ferrinckim (bez użycia dodatkowych znaków diaktrycznych). Gramatyka języka ferrinckiego dostępna jest pod adresem yermenia.zyxist.com/ferrincki.html
  2. Zakoduj otrzymany ciąg tekstowy algorytmem MD5.
  3. Weź trzeci bit siedemnastego wyrazu otrzymanego ciągu, dokonując redukcji do revomerowych wartości logicznych, jeśli zachodzi taka potrzeba.

Drugi z reduktorów nazywa się IN (Is Negative). Sprawia on, że każda ujemna wartość zostaje zredukowana do Prawdy Revomerowej (-1), a każda nieujemna do fałszu.

3.3. Interpreter

Wskazówki dla interpreterów języka Revomer.

  1. W przypadku nieznalezienia w programie funkcji zerowej interpreter wykonuje w kółko operację rope z nadzieją, że kiedyś uda mu się przez to stworzyć funkcję zerową i się przerwać. Dlatego też w Revomerze można napisać najkrótszy program świata generujący inne programy - wystarczy kazać interpreterowi wykonać pusty plik.
  2. Komenda conf wykonuje zamianę nazw funkcji, ale nie miejsc ich rozpoczęcia oraz innych właściwości, w tym ilości znajdujących się w nich komend. Jeżeli zaczęliśmy więc wykonywać funkcję "foo", po czym zamieniliśmy ją nazwą z funkcją "bar", to zmieniła się tylko jej nazwa. Na stosie wywołań pamiętamy, że wykonujemy funkcję "foo", ale w tym momencie ma już ona właściwości funkcji "bar" (m.in. długość).
  3. Jeżeli z jakiegoś powodu kasacji ulega miejsce, na którym aktualnie znajduje się kursor interpretera, należy go tak przestawić, aby następnym rozkazem był ten, który miał się wykonać jako następny.

3.4. W następnych wydaniach

To nie wszystko! W przyszłych wydaniach język Revomer zostanie wzbogacony o wiele nowych możliwości:

  1. Obsługa plików.
  2. Obsługa strumieni i połączeń sieciowych.
  3. Pełne wsparcie dla konsoli systemowej - twoje programy wzbogacą się o interfejs z prawdziwego zdarzenia!
  4. Wielowyjątkowość
  5. More memory = more problems = more fun

Dodatek A. Copyright

Autorami języka Revomer oraz jego specyfikacji są Krzysztof Piecuch oraz Tomasz Jędrzejewski. To ich dłużnikami będzie świat, jeśli znany monopolista z Redmond rzeczywiście kupi ten język.