User:Oksana Hristova/sandbox/Forth BG
This is not a Wikipedia article: It is an individual user's work-in-progress page, and may be incomplete and/or unreliable. For guidance on developing this draft, see Wikipedia:So you made a userspace draft. Find sources: Google (books · news · scholar · free images · WP refs) · FENS · JSTOR · TWL |
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]- ^ 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.
- ^ 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
(help)|title=
- ^ Brodie, Leo (1984). Thinking Forth. Prentice-Hall. ISBN 0-13-917568-7.
{{cite book}}
: External link in
(help)|title=
- ^ The classic washing machine example describes the process of creating a vocabulary to naturally represent the problem domain in a readable way.
External links
[edit]