User:Oksana Hristova/sandbox/Forth BG

Forth

Структура на кода

edit

В повечето Форт системите, тялото на дадена кодова дефиниция се състои или от машинен език или от някаква форма на нишков код. Оригиналния Форт, които следва неформалния FIG стандарт (Forth Interest Group), е нишковотълкователен език. Това се нарича индиректнонишков код, но директнонишкови и подпрограмнонишкови Форт кодове също са станали популярни в днешно време. Най-бързите и модерни Форт кодове използват подпрограмни нишки, вмъкват просто думи като макроси и изпълняват шпионкова оптимизация или други оптимизиращи стратегии, за да направят кода по-малък и бърз. [1]

Обекти от данни

edit

Когато една дума е променлива или друг обект от данни, кодовото поле сочи към кода, изпълняван по време на работа, който е свързан с дефиниращата дума, която я е създала. Дефиниращата думата има характерно "дефиниращо поведение" (създавайки речник и евентуално заделяйки и инициализирайки пространство в паметта) и също така определя поведението на дадена инстанция от класа от думи, създадени от дефиниращата дума. Примери включват:

VARIABLE
Наименува неинициализирана едноклетъчна локация в паметта. Инстанционното поведение на дадена променлива VARIABLE връща нейния адрес в стека.
CONSTANT
Наименува стойност (уточнена като аргумент към константата CONSTANT). Инстанционното поведение връща стойността.
CREATE
Наименува локация; мястото може да бъде заделеното на дадената локация или може да бъде направено да съдържа низ или друга инициализирана стойност.

Инстанционното поведение връща адресът на началото на това място.

Форт също така предоставя инструмент, чрез който програмиста може да дефинира нови, специфични за дадена апликация, дефиниращи думи, посочвайки както специфично дефиниращото поведение, така и инстанционното поведение. Някои примери включват кръгови буфери, наименувани битове на даден I/O порт и автоматично индексирани масиви.

Обектите от данни, дефинирани от тези и подобни думи, са с глобален обхват. Функцията, която се осигурява от локалните променливи в други езици, е осигурена от купчината от данни във Форт (въпреки че Форт също разполага с реални локални променливи). Стилът на програмиране на Форт използва много малко наименувани обекти от данни в сравнение с други езици; обикновено подобни обекти от данни се използват за съдържането на информация, която се използва от множество думи и обекти (в една многообектна имплементация). [2]

Форт не налага последователност в употребата на обектите от данни; програмистът носи отговорност да използва подходящите оператори да взима и запазва стойност или да изпълнява други операции с информацията.

Програмиране

edit

Думите, написани на Форт, се компилират в изпълним файл. Класическите реализации с "индиректни нишки" компилират списъци на адреси на думи, които да бъдат изпълнени последователно; много съвременни системи генерират реален машинен код (включително повиквания към някои външни думи и код за други, разширени в място). Някои системи притежават оптимизиращи компилатори. Най-общо казано, програма, написана на Форт, се записва като образ на паметта на компилираната програма с една единствена команда (например, RUN), който се изпълнява, когато компилираната версия е заредена.

По време на разработката, програмистът използва преводача в режим REPL за изпълнение и тестване на всеки малък детайл, докато се разработва. Поради това повечето програмисти на Форт препоръчват свободен дизайн отгоре-надолу, и разработка отдолу-нагоре с непрекъснато тестване и интеграция. [3]

Дизайнът отгоре-надолу обикновено представлява разделяне на програмата в "речници", които след това се използват като комплекти от инструменти на високо равнище за написване на окончателната програма. Една добре проектирана Форт програма се чете като естествен език, и имплементира не само едно-единствено решение, но и инструменти за атакуване на свързани проблеми. [4]

Примери за код

edit

Примерът "Здравей, свят!"

edit

В този пример на конзолен екран се извежда текстът „Здравей, свят!“:

Една възможна имплементация:

: HELLO  ( -- )  CR ." Hello, world!" ; 
HELLO <cr>
Hello, world!

Думата CR (Carriage Return) кара следващия изход да се изведе на нов ред. Думата, правеща разбор ." (дот-цитат) чете двоен цитат от разграничена низ и добавя код към настоящото определение, така че обработеният низ ще бъдат показан по време на изпълнение. Интервалния писмен знак, делящ думата ." от низа Hello, World! не е включен като част от низа. Той е необходим, така че парсера разпознава ." като Форт дума.

Една стандартна Форт система играе ролята и на преводач, и същия изход може да се получи, като въведете следния фрагмент от код в Форт конзолата:

CR .( Hello, world!)

.( (дот-скобата) е непосредствена дума, която прави разбор на низ, който е разграничен чрез скоби, и го показва на екрана. Както при думата ." интервалният писмен знак .( от Hello, World! не е част от низа.

Думата CR се използва преди текста за печат. По установена практика, Форт преводачът не изкарва изхода на нов ред. Друга установена практика е преводачът да изчаква входа в края на предишния ред, след ok диалог. Не съществува имплицитно "флъш-буфер" действие в думата CR на Форт, както е понякога в други езици за програмиране.

Смесване на състояния на компилиране и интерпретация

edit

Ето дефиницията на думата EMIT-Q, която при изпълнение издава единствената буква Q:

: EMIT-Q   81 ( the ASCII value for the character 'Q' ) EMIT ;

Това определение е написано, за да използва ASCII стойността на Q (81) директно. Текстът между скобите е коментар и се игнорира от компилатора. Думата EMIT приема стойност от стека от данни и показва съответния символ.

Следващото предефиниране на EMIT-Q използва думите [ (лява скоба), ] (дясна скоба), CHAR и LITERAL, за да смени състоянието интерпретатора временно, да изчисли ASCII стойността на Q символа, да се върне към състояние на компилация и да добави изчислената стойност към настоящата двуеточна дефиниця:

: EMIT-Q   [ CHAR Q ]  LITERAL  EMIT ;

Думата за разбор CHAR приема разделена чрез интервали дума като параметър и поставя стойността на първия й символ на стека от данни. Думата [CHAR] е пряка версия на CHAR. Използвайки [CHAR] , примерната дефиниция на EMIT-Q може да бъде пренаписана по следния начин:

: EMIT-Q   [CHAR] Q  EMIT ; \ Emit the single character 'Q'

Това определение използва \ (обратна наклонена черта) за описване на коментара.

И двете CHAR и [CHAR] са предварително определени ANS Форт. Използвайки IMMEDIATE и POSTPONE , [CHAR] може да се дефинира по следния начин:

: [CHAR]   CHAR  POSTPONE LITERAL ; IMMEDIATE

Пълна RC4 шифър програма

edit

През 1987 г. Рон Ривест разработва RC4 шифър-системата за RSA Data Security, Inc. Кодът е изключително прост и може да бъде написан от повечето програмисти, следвайки описанието:

Имаме масив от 256 байта, от които всички са различни. Всеки път, когато масива се използва, той се променя, като размества два байта. Размените се контролират от броячи i и j, като всеки първоначално е 0. За да получите новия i, добавете 1. За да получите новия j, добавете байт масивa на новото i. Разменете байт масивите на i и j. Кодът е байт масив от сумата от байт масивите на i и j. После се използва метода на изключване с един байт от обикновения текст, за да се кодира, или от шифър текста за декриптиране. Масивът се инициализира като се прави да бъде равен на 0 до 255. След това се преминава през него, използвайки i и j, получавайки новото j, като се добавя към него байт масива на i и ключов байт, и разменяйки байтовете на масиви на i и j. Накрая, i и j се правят да бъдат равни на 0. Всички прибавяния са по модул от 256.

Следната стандартна Форт версия използва само основни и основни разширени думи.

0 value ii        0 value jj
0 value KeyAddr   0 value KeyLen
create SArray   256 allot   \ state array of 256 bytes
: KeyArray      KeyLen mod   KeyAddr ;

: get_byte      + c@ ;
: set_byte      + c! ;
: as_byte       255 and ;
: reset_ij      0 TO ii   0 TO jj ;
: i_update      1 +   as_byte TO ii ;
: j_update      ii SArray get_byte +   as_byte TO jj ;
: swap_s_ij
    jj SArray get_byte
       ii SArray get_byte  jj SArray set_byte
    ii SArray set_byte
;

: rc4_init ( KeyAddr KeyLen -- )
    256 min TO KeyLen   TO KeyAddr
    256 0 DO   i i SArray set_byte   LOOP
    reset_ij
    BEGIN
        ii KeyArray get_byte   jj +  j_update
        swap_s_ij
        ii 255 < WHILE
        ii i_update
    REPEAT
    reset_ij
;
: rc4_byte
    ii i_update   jj j_update
    swap_s_ij
    ii SArray get_byte   jj SArray get_byte +   as_byte SArray get_byte  xor
;

Това е един от многото начини за тестване на кода:

hex
create AKey   61 c, 8A c, 63 c, D2 c, FB c,
: test   cr   0 DO  rc4_byte . LOOP  cr ;
AKey 5 rc4_init
2C F9 4C EE DC  5 test   \ output should be: F1 38 29 C9 DE

Имплементации

edit

Поради това, че виртуалната машина на Форт е лесна за имплементация и няма стандартна референтна имплементация, има множество реализации на езика. В допълнение към поддръжката на стандартните видове десктоп компютърни системи (POSIX, Microsoft Windows, bg:Mac OS X/Mac OS X), много от тези Форт системи също така са насочени към различни вградени системи. Изброени са някои от най-важните системи, които съответстват на 1994 ANS Forth стандарта.

  • Gforth - преносима ANS Forth имплементация от проекта GNU
  • SwiftForth - настолни и вградени Форт системи от Forth, Inc., инициаторите на езика;
  • VFX Forth - високооптимизиращ естествен Форт код
  • SP-Forth - портативно Форт изпълнение от Russian Forth Interest Group
  • Open Firmware - буутлоудър и BIOS стандарт, базиран на ANSI Forth

References

edit
  1. ^ Ertl, M. Anton; Gregg, David. "Implementation Issues for Superinstructions in Gforth" (PDF). Archived from the original (PDF) on 2006-06-25. Retrieved 2006-06-19.
  2. ^ Brodie, Leo (1987). "Under The Hood". Starting Forth (2nd ed.). Prentice-Hall. p. 241. ISBN 0-13-843079-9. To summarize, there are three kinds of variables: System variables contain values used by the entire Forth system. User variables contain values that are unique for each task, even though the definitions can be used by all tasks in the system. Regular variables can be accessible either system-wide or within a single task only, depending upon whether they are defined within OPERATOR or within a private task. {{cite book}}: External link in |title= (help)
  3. ^ Brodie, Leo (1984). Thinking Forth. Prentice-Hall. ISBN 0-13-917568-7. {{cite book}}: External link in |title= (help)
  4. ^ The classic washing machine example describes the process of creating a vocabulary to naturally represent the problem domain in a readable way.
edit