Forth

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене
Криейтив Комънс - Признание - Споделяне на споделеното Лиценз за свободна документация на ГНУ Тази страница частично или изцяло представлява превод на страницата „Forth“ в Уикипедия на английски. Оригиналният текст, както и този превод, са защитени от Лиценза „Криейтив Комънс - Признание - Споделяне на споделеното“, а за съдържание, създадено преди юни 2009 година — от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната страница, както и на преводната страница. Вижте източниците на оригиналната статия, състоянието ѝ при превода, и списъка на съавторите.  
Форт
Парадигма процедурен, стеково ориентиран, рефлективен, обединяващ език
Реализиране през 1970;
преди 46 години
 (1970)
Автор Чарлз Мур
Типизация на данните нетипизиран
Имплементация SwiftForth (Forth, Inc.)
Gforth (Free software)
VFX Forth (MicroProcessor Engineering)
Повлиян от B5000, Lisp, APL
Повлиява Factor, PostScript, RPL, REBOL
Уебсайт www.forth.com
Форт в Общомедия

Форт (на английски: Forth) е императивна стеково базирана среда за програмиране, създадена от Чарлз „Чък“ Мур. Характеризира се със структурирано програмиране, рефлексия (способността да се модифицира структурата на програмата по време на изпълнението й), свързано програмиране (функциите са подредени една до друга) и гъвкавост (програмиста може да създава нови команди). Въпреки, че не е абревиатура, името на езика понякога се изписва с главни букви FORTH, следвайки обичайно използваната практика от по-ранните години.

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

Форт cе използва за Open Firmware(стандарт, който дефинира интерфейсите на компютърната фърмуер система) boot loader (системен софтуер зареждащ ОС), в космически приложения,[1] като космическия апарат Филе и при различни видове хардуерни системи. Най-продаваната за 1986 игра Starflight, работеща под операционна система DOS, създадена от Electronic Arts, е написана на Форт.[2]

Преглед[редактиране | редактиране на кода]

Средата за разработка на Форт съчетава компилатора с интерактивен потребителски интерфейс, където потребителят определя и изпълнява подпрограми, наречени думи. Думите могат да бъдат тествани, предефинирани, и отстраняването на грешките може да се осъществи без прекомпилиране или рестартиране на цялата програма. Всички синтактични елементи, включително променливи и основни оператори са дефинирани като думи. Форт средите се различават по това как се съхранява получената програма, но в идеалния случай изпълнението на програмата има същия резултат, както повторно да въведеш кода ръчно.

Стекове[редактиране | редактиране на кода]

Повечето среди за разработка с рекурсивни подпрограми използват „стек“ за контрол на потока. Тази структура също съхранява локални променливи, включително и Parameter_ на подпрограмата(Система за извикване по стойност, като например C). Форт често няма локални променливи,нито такива извиквани по стойност. Вместо това във втори „стек“ се съхраняват междинните стойности. Думите действат върху най-горните стойности в първата група. Поради това може да се нарече „стек“ от параметри или „данни“, но по-често се използва просто „стек“. Функцията, която извиква „“ се нарича „връзка“ или връщащ „стек“, с абревиатура “rstack”.  Функциите за манипулиране на стека се осигуряват от ядрото, позволявайки му да бъде използван за временно запазване на думата,в противен случай не може да се използва за подаване на параметри и манипулиране на данни.

Повечето команди са специфицирани по начина си на въздействие върху „стека“. Обикновено параметрите са разположени на върха на „стека“, преди думата да се изпълни.  След изпълнение параметрите се изтриват и заменят от някакви връщани стойности. За аритметични оператори се следва правилото на обратната полска нотация. Вижте по-долу примери, за използването на „стек“.

Поддръжка[редактиране | редактиране на кода]

Форт все още е прост и разширяем език. Неговата модулност и разширяемост позволя писането на програми от високо ниво като CAD системи. Форт е бил използван успешно в създаването на големи,сложни проекти. Разработените приложения, от компетентни и дисциплинирани професионалисти, са доказали в продължение на десетилетия, че са лесни за поддръжка в развиващите се хардуерни платформи.[3] Forth has a niche both in astronomical and space applications.[4] Форт се използва, както в астрономическите,така и в космическите приложения.Днес Форт все още се употребява в много вградени системи (малки компютърни устройства), заради преносимостта му, ефективното използване на паметта, краткото време за развитие, както и бързата скорост на изпълнение.

Вграден е успешно в модерни RISC ,също така са произведени процесори, които използват Форт като машинен език.[5]

Други приложения на Форт включват: boot ROMs използван от Apple_Inc.,, Sun, и OLPC XO-1, FICL- първият етап на зареждане контролера на операционната система .

История[редактиране | редактиране на кода]

Форт еволюира от лична система за програмиране на Чарлз Мур, като се е развивала непрекъснато от 1968г. досега.[6]

За първи път Форт е предоставен на други програмисти през 1970г.,започвайки с Елизабет Радър в националната радио астрономическа обсерватория на САЩ.[6] След работата си в NRAO, Чарлз Мур и Елизабет Радър създават компанията FORTH през 1973 г., усъвършенстват и пренасят Форт системи за десетки други платформи през следващото десетилетие.

Форт е наречен така през 1968г., името на обяснителният файл бил FOURTH, но тъй като IBM_1130 позволява имена на файлове само до 5 знака, той го модифицира на Форт.[7] Мур вижда Форт, като наследник на трето поколение езици за програмиране, или катo софтуер за хардуер "четвърто поколение".

Тъй като Чарлз Мур често е сменявал своята работа през кариерата си, ранният натиск върху развиването на програмния език е бил върху това да се улесни пренасянето му на различни компютърни архитектури. Система Форт често се е използвала за въвеждане на нов хардуер. Например, Форт е първият софтуер на новия чип през 1978 г. и MacFORTH е първата развита система за първия Macintosh през 1984 г.[6]

Форт, microFORTH Inc.  е разработена за , , и   микропроцесори, които започват през 1976 г. MicroFORTH по-късно се използва от любители да произвеждат Форт системи за други архитектури, като 6502 през 1978 г. Широкото разпространение на езика води до неговата стандартизация.Общото приложение е стандартизирано в стандартите Форт-79[8] and FORTH-83[9] и Форт-83, съответно през годините 1979г. и 1983г.. Тези стандарти са обединени от ANSI през 1994 г., обяснени в  ANS Форт.[10][11]


Форт става много популярен през 1980 г.,[12] тъй като е подходящ за малките микрокомпютри по онова време, поради своята компактност и преносимост. Най-малко един домашен компютър, британската Юпитер ACE, е имал заложен Форт в ROM  операционната си система.  използва също Форт за своя система за програмиране. Rockwell, също произвеждат едночипови микрокомпютри с Форт ядра, на R65F11 и R65F12. Пълното „родословно“дърво е в Технически университет- Виена. Insoft Garforth е версия на Форт с графични разширения за . А ASYST е Форт разширение за измерване и контролиране на персонални компютри.[13] ASYST was a Forth expansion for measuring and controlling on PCs.[14] 

Перспектива на програмиста[редактиране | редактиране на кода]

Форт силно разчита на изрично ползване на „стек“ данни и на обратна полска нотация (RPN или постфиксната нотация), често се използва в калкулатори отHewlett-Packard. В RPN операторът се намира след неговите операнди, за разлика от общо използваната инфискна нотация,където операторът се намира между неговите операнди. Postfix нотация прави езика по-лесен за разбор и разширяване. Гъвкавостта на Форт прави статичната БНФ граматика неуместна, и не разполага с монолитен компилатор. Разширяването на компилатора изисква само написването на нова дума, вместо модифициране на граматиката и промяна на основната имплементация.

Използването на RPN, може да намери резултата на математическия израз  (25 * 10 + 50) по този начин:

25 10 * 50 + CR . 300 ok
Stack1.svg

Този команден ред първо слага 10 и 25 в скрития стек,

Forthstack1 5.svg

а думата *умножава двете числа на върха на стека и ги заменя с тяхното произведение.

Forthstack2.svg

След,което числото 50 е сложено в стека.

Forthstack3.svg

Думата +го добавя към произведението. CR премества резултата на нов ред (това е от гледна точка на форматирането и може да бъде пропуснато но – при повечето имплементации без тази дума ще изкарат резултата на един и същи ред с входните данни, поради което ще се наруши четимостта). Накрая командата . отпечатва резултата на потребителския терминал. След, което ако всичко е преминало успешно, текстовия редактор изписва „Ок“ и минава на нов ред, за да вземе още входна информация, без да е нужно изрично да му се дава команда за това.

Дори структурните характеристики на Форт са стеково базирани. Например:

: FLOOR5 ( n -- n' )   DUP 6 < IF DROP 5 ELSE 1 - THEN ;

Този код дефинира нова дума наречена FLOOR5 изполваща следните команди: DUP копира числото в стека; 6 слага 6 в началото на стека; < сравнява първите две числа в стека (6 и копирания вход), и ги заменя с булева стойност „вярно“ или „не вярно“; IF взима тази булева стойност и избира да изпълни командата веднага или да премине към ELSEDROP игнорира стойността на стека. След, което  THEN приключва условието. Текстът в кавичките е коментар, който те подсеща,че тази дума очаква число в стека и ще върне вероятно променено число. Думата FLOOR5 е равностойна на същата функция написана на програмния език “C” използващ тернарен оператор:

int floor5(int v) {
  return (v < 6) ? 5 : (v - 1);
}

Тази функция е написана по сбито по следния начин

: FLOOR5 ( n -- n' ) 1- 5 MAX ;

Можете да изпълните тази думата така:

1 FLOOR5 CR . 5 ok 8 FLOOR5 CR . 7 ok

Първо интерпретатора слага число(1 или 8) в стека, след което вика думата FLOOR5, която изкарва резултата. CR мести изходните данни на нов ред. Накрая „.“ извиква резултата и го принтира на потребителския терминал.

Възможности[редактиране | редактиране на кода]

Форт няма категорична формална граматика. Интерпретатора чете ред от потребителското входно устройство, след което се прави разбор на машинна дума, използвайки разстояние като разграничител, като някои системи разпознават допълнителните празни символа. Когато интерпретатора намери една машинна дума, той я проверява в речника. Ако намери думата, интерпретатора изпълнява кода асоцииран с машинната дума, след което се връща да прави разбора на останалата част от входния поток. Ако не намери машинната дума, се приема че е цифра и прави опит да я превърне в цифра, като я избутва в стека; ако действието е успешно, интерпретатора продължава разбора на входния поток. В противен случай, ако проверката и опита за превръщането и в цифра се провали, интерпретатора отпечатва машинната дума последвана от съобщение за грешка, което показва, че не разпознава машинната дума, премахва я от входния поток и чака за ново въвеждане от потребителя.[15]

Дефинирането на нова машинна дума дума започва с символа : (двоеточие) и завършва с ; (точка и запетая ). Например,

: X DUP 1+ . . ;

ще компилира машинната дума X, и ще направи името откриваемо в речника. Когато операцията се изпълни след като се въведе 10 X, в конзолата ще се отпечата 11 10.[16]

Повечето Форт системи включват асемблер, който позволява да се определят точните думите, щадейки ресурсите на процесора. Обикновено асемблерът ги складира в отделно именно пространство (wordlist), тъй като се ползват рядко от потребителите. Асемблерите на Форт могат да използват обратен полски запис синтаксис в който параметрите на команда предхождат команда, но конструират променлива с широка граница, специфични за Форт имплементатора. Типичния полски запис асемблер подготвя операнди в стека като накрая помага копирането на цялата команда в паметта. Асемблера на Форт в същността си е макро асемблер, така че е лесно да се определят псевдоними на регистри в зависимост от тяхната роля в системата на Форт: например „Datastackpointer“ използван като стек указател(променлива, съдържаща адрес в паметта) за регистъра.[17]

Операционна система, файлове, изпълнение на няколко команди едновременно[редактиране | редактиране на кода]

Повечето Форт системи работят под хост операционни системи като Microsoft Windows, Linux или версия на Unix, като за източник на файлове с данни използва системните файлове на съответната хост операционна система; стандартът на Форт ANSI описва използваните входящи и изходящи компютърни думи. Всичко модерни Форт системи използват нормални текстови файлове за източник, дори ако те са вградени. Вградената система с резидентен компилатор взима своя източник чрез серийна линия.

Класическите Форт системи традиционно не използват операционна система или файлова система. Вместо да се съхранява във файлове, изходния код се складира в дискови блокове, записани на адреса на физическия диск. Машинната дума BLOCK се използва за трансформирането на броя на един1k –размерен блок в дисковото пространство от буфера, който съдържа данните, който се управлява автоматично от Форт системата. Блока започва да се използва от средата на 1990-те години. В хост системите тези блокове също са разпределени в нормален файл.

На разположение е изпълняването на няколко команди едновременно, най-често съвместно циклично планиране. Машинната дума PAUSE най-често се използва за запаметяване на възпроизведения контекст на текущите задачи, за локализиране на следващата задача и за възстановяване на възпроизведения контекст. Всяка задача има свои собствени стекове, собствени копия на някои контролирани променливи и нулева зона. Смяната на задачите е проста и ефективна и в резултат на което изпълняването на няколко команди едновременно при Форт е възможно дори на много обикновени микроконтролери, като Intel 8051, Atmel AVR, и TI MSP430.[18]

Други по-нестандартни устройства разполагат с механизъм за издаване на повиквания до хост операционни системи или windows системи, и много от тях осигуряват разширения, които използват планирането, осигурено от операционната система. Обикновено те имат по-голям и по-различен набор от машинни думи от самостоятелната машинна дума на Форт PAUSE за създаване на задачи, ограничаване, унищожаване и промяна на приоритета.

Собствена компилация и обратна компилация[редактиране | редактиране на кода]

Пълнофункционалната система на Форт с всички изходни кодове ще се обединят, техника която обичайно се нарича мета-компилация от програмистите на Форт (въпреки че термина не отговаря точно на израза мета- компилация). Обичайният метод е да предефинира малката част от машинни думи, които поставят компилираните битове в паметта. Компилираните машинни думи използват специално наименувани версии за извличане и съхраняване, които могат да бъдат пренасочени към буферна зона в паметта. Буферната зона симулира или достъпва до зоната в паметта, която започва с различен адрес от този на буфера на кода. Такива компилатори определят машинни думи за да получат достъп до компютърната памет и тази на хоста.[19]

След извличането и съхраняването операциите са предефинирани за кодовото пространство, компилатора, алемблера и т.н. са прекомпилирани, използвайки новите определения за извличане и съхраняване. Тази ефективна повторна употреба на всички кодове в компилатора и интерпретатора. Така е компилиран системния код на Форд, но тази версия се съхранява в буфера. Буферът в паметта е записан на диск като са осигурени начини да бъде възпроизведен временно в паметта за тестване. Когато новата версия заработи, тя се презаписва върху старата версия.

Множество варианти на такива компилатори съществуват в различни среди. За вградени системи, кодът може вместо това да бъде написан на друг компютър, техника позната като обратна компилация върху серийния порт или дори един единствен бит ТТЛ(транзисторно транзисторна логика), докато запазва имената на машинните думи и други неизпълняващи части от речника в начално компилиращия компютър. Минималните определения за такъв компилатор на Форт са машинните думи които извличат и съхраняват един байт, и машинната дума, която дава командата машинната дума на Форт да бъде изпълнена. Обикновено частта, която отнема най-много време при писането на отдалечен порт е конструирането на главната програма за да въведе извличането, съхраняването и изпълнението, но много модерни микропроцесори имат вградена инструменти за отстраняване на грешки (като при Motorola CPU32), което елиминира тази задача.[20]

Структука на езика[редактиране | редактиране на кода]

Основната структура от данни, която се използва в езика Форт е “речника“. Той преобразува “думи” в код, който може да бъде изпълнен. Речникът е изложен в паметта като дърво на свързани списъци с връзки, преминаващи от най-новата дефинирана дума до най-старата, докато стойността sentinel, която в повечето случай е нулев указател (null pointer), не се появи. Търсенето по свързания списък продължава като клонът продължава да се слива в основата на ствола, като рано или късно се връща обратно към sentinel-а, а именно корена. Може да има повече от един брой речници. В редки случай, като например по време на мета-компилация, речника може да бъде изолиран и самостоятелен. Ефектът наподобява този на вкарване на един namespace в друг, и може да презапише ключови думи в зависимост от контекста.

Дума, която има определение, обикновено се състои от глава и тяло, като главата съдържа полето за име (name field) и полето за връзка (link field), а тялото съдържа областта, в която се намира самия код (code field), както и областта на параметъра (parameter field).

„Главата и тялото“ на даден речник се разглеждат поотделно, тъй като те не могат да си граничат. Например, когато програма написана на Форт се прекомпилира за нова платформа, главата може да остане на компютъра, който компилира, докато тялото преминава на новата платформа. В някои програмни среди (като в областта на вградените системи) главите заемат ненужна памет. Въпреки това, някои компилатори, който работят на няколко платформи, могат да поставят главите в целта, ако целта, сама по себе си, се очаква да поддържа интерактива версия на Форт. [21]

Вписване в речника[редактиране | редактиране на кода]

Няма точен формат при вписване на данни в речника - и реализацията, и имплементацията варират. Въпреки това, някои компоненти са почти винаги налице, но също могат да варират по размер и ред. Ако трябва да го опишем като структура, вписването в речника изглежда по следния начин:[22]

structure
  byte:       flag           \ 3bit flags + length of word's name
  char-array: name           \ name's runtime length isn't known at compile time
  address:    previous       \ link field, backward ptr to previous word
  address:    codeword       \ ptr to the code to execute this word
  any-array:  parameterfield \ unknown length of data, words, or opcodes
end-structure forthword

Полето, което съдържа името, започва с префикс, което се дефинира от дължината на името на думата (обикновено до 32 байта), и няколко допълнителни бита за флагове. Думата се представя като символен низ, след което следва префикса. В зависимост от конкретната имплементация на Форт, може да има един или повече NUL (‘\0’) байта за подравняване.

Полето “link” съдържа указател към предварително определена дума. Указателят може да играе ролята на изместител или на абсолютен адрес, който сочи към следващия най-възрастен събрат.

Структура на компилатора[редактиране | редактиране на кода]

Компилаторът не е монолитна програма. Състои се от Форт “думи”, които са видими за системата, и могат да се използват от програмиста. Това позволява на програмиста да променя думите на компилатора, ако иска да постигне определени цели.

Флагът на времето за компилация в полето “name”, е настроено за думи с “компилационно поведение”. Повечето прости думи, изпълняват един и същ код, независимо дали са писани в конзола, или са изпълнени в среда за разработка. При компилация, компилаторът просто поставя кода, или указател към думата.

Класическите примери за компилационни думи са контролните структури IF и WHILE. Почти всички контролни струрктури на езика Форт и почти всички компилатори са реализирани като компилационни думи. Освен някои рядко изплозвани контролни думи, които имат приложение само в някои имплементации, като например условното връщане. Всичките контролни думи на езика Форт се изпълняват по време на компилация, за да се направят различни комбинации от примитивни думи, заедно с техните разклоняващи се адреси. Например IF и WHILE, и думите, които съответстват с тези, създават BRANCH и ?BRANCH. Броени цикли на контролните думи, работят по подобен начин, но създават комбинации от примитивни думи, които работят с брояч. По време на компилация, стека с данни се използва за подпомагането на контролната структура, влагането, както и за обратно пачване на браншовите адреси. Пример:

... DUP 6 < IF DROP 5 ELSE 1 - THEN ...

Ще бъде компилиран в следната последователност:

... DUP LIT 6 < ?BRANCH 5  DROP LIT 5  BRANCH 3  LIT 1 - ...

Числата след BRANCH представляват относителните адреси. LIT е примитивната дума за бутане на „буквално“ число върху стека от данни.

Състояние на компилацията и състояние на интерпретацията[редактиране | редактиране на кода]

Думата : (двуеточие) парсва дадено име като параметър, вписва данни в речника и влиза в състояние на компилация. Интерпретаторът продължава да чете думи разделени с разстояние от потребителския вход. Ако се намери дума, интерпретаторът осъществавя компилация, свързана с думата, вместо семантичната интерпретация на думата.

Думата ; (точка и запетая) завършва настоящата дефиниция и се връща към състояние на интерпретация. Това е пример за дума, чиято компилационна семантика се различава от стойността по подразбиране на думата. Семантичното тълкуване на ;(точка и запетая), и на някои други думи са неопределени в ANS Forth, което означава, че те трябва да се използват само в рамките на определения, а не чрез интеракция с конзолата.

Състоянието на интерпретатора може да се променя ръчно, чрез думите [ (лява квадратна скоба) и ] (дясна квадратна скоба), които съответно влизат в състояние на интерпретация или в състояние на компилация. Тези думи могат да се използват в комбинация с думата LITERAL за изчисление на стойност по време на компилация, и за вмъкването на тази вече изчислена стойност в конкретната дефиниция на : (многоточие). LITERAL има компилационната семантика да вземе даден обект от стека с данни и да добавя семантика към конкретната дефиниция, за да постави този обект в стека с данни.

В ANS Forth, сегашното състояние на интерпретатора, може да бъде прочетен от флага STATE, който е TRUE по време на компилация и FALSE в противен случай. Това позволява имплементацията на така наречените state-smart words ( пазещи състоянието си думи) с поведение, което се променя според текущото състояние на интерпретатора.

Непосредствени думи[редактиране | редактиране на кода]

Думата IMMEDIATE (непосредствен) маркира последната дефиниция дадена от конкретната дефиниция на : (двуеточие) ,ефективно замествайки неговата компилационна семантика с неговата тълковна семантика.[23] Непосредствените думи обикновено се изпълняват по време на компилация, не напълно компилирани, но това може да бъде презаписано или отхвърлено от програмиста, в което и да е състояние. ; (точка и запетая) е пример за непосредствена дума. В ANS Forth, думата POSTPONE (отлагам), взима дадено име като параметър и добавя компилационната семантика на същата дума към текущата дефиниция, дори и думата да е маркирана като непосредствена. Forth-83 дефинира отделните думи COMPILE (компилирам) и [COMPILE], за да принуди компилирането съответно на непостредсвени думи и на обикновени думи.

Думи без наименование и символи на изпълнение[редактиране | редактиране на кода]

В ANS Forth, думи без наименование могат да бъдат дефиниране с думата :NONAME/ (без име), като се компилират всички думи до следващата ; (точка и запетая), като оставя символи на изпълнение (на английски: execution token )в стека с данни. Този символ на изпълнение осигурява семантичното компилиране, подобно на функционалните указатели на езика за програмиране C.

Символите на изпълнение(execution tokens) могат да се съхраняват в променливи. Думата EXECUTE (изпълнявам) взима даден символ на изпълнение от стека с данни и изпълнява свързаната семантика. Думата COMPILE (компилирам), взима символa на изпълнение (execution token) от стека с данни и добавя към текущата дефиниция свързаната семантика.

Думата (апостроф) взима името на дадена дума като параметър и връща низ от символи, които е свързан с думата в стека с данни. В състояние на интерпретация ‘RANDOM-WORD EXECUTE е равно на RANDOM-WORD.[24]

Правене на разбор на машинни думи и коментари[редактиране | редактиране на кода]

Машинните думи : (двоеточие), POSTPONE, ' (апостроф) са примери за правене на разбор на машинни думи, които прилагат техните аргументи от потребителското входиращо устройство вместо от данните на стека. Друг пример е машинната дума ( (скоба), която чете и игнорира следващите машинни думи до и включително следващата дясна скоба и се използва за да се напишат коментари в двоеточна дефиниция. Също така машинната дума \ (наклонена черта) се използва за коментари, които продължават до края на реда. За да бъде правилно направен разборът ( (скоба) и \(наклонена черта) трябва да бъдат разделени с разстояние от следващия текст на коментара.

Структура на кода[редактиране | редактиране на кода]

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

Обекти от данни[редактиране | редактиране на кода]

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

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

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

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

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

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

Програмиране[редактиране | редактиране на кода]

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

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

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

Примери за код[редактиране | редактиране на кода]

Примерът "Здравей, свят!"[редактиране | редактиране на кода]

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

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

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

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

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

CR .( Hello, world!)

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

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

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

Ето дефиницията на думата 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 шифър програма[редактиране | редактиране на кода]

През 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

Имплементации[редактиране | редактиране на кода]

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

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

Източници[редактиране | редактиране на кода]

  1. NASA applications of Forth (original NASA server no longer running, copy from archive.org)
  2. Starflight. // October 28, 2014.
  3. Forth Success Stories. // Посетен на 2006-06-09.
  4. Space Related Applications of Forth. // Посетен на 2007-09-04.
  5. Forth Chips Page. // с. 54. Посетен на 2006-06-09.
  6. а б в The Evolution of Forth. // ACM SIGPLAN Notices, Volume 28, No. 3. March 1993. ACM SIGPLAN History of Programming Languages Conference, April 1993.
  7. Moore, Charles H. Forth - The Early Years. // 1991. Посетен на 2006-06-03.
  8. The Forth-79 Standard (PDF). //
  9. The Forth-83 Standard. //
  10. Programming Languages: Forth. // ANSI technical committee X3J14, 24 March 1994. Посетен на 2006-06-03.
  11. Standard Forth (ANSI INCITS 215-1994) Reference. // Quartus Handheld Software, 13 September 2005. Посетен на 2013-04-14.
  12. "The Forth Language", BYTE Magazine 5 (8), 1980, http://archive.org/details/byte-magazine-1980-08/ 
  13. GraFORTH II Language Reference (PDF)
  14. Campbell et al, "Up and Running with Asyst 2.0", MacMillan Software Co., 1987
  15. Brodie, Leo. Starting Forth. Second. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 14.
  16. Brodie, Leo. Starting Forth. Second. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 16.
  17. Rodriguez, Brad. B.Y.O.ASSEMBLER. // Посетен на 2006-06-19.
  18. Rodriguez, Brad. MULTITASKING 8051 CAMELFORTH (PDF). // Посетен на 2006-06-19.
  19. Rodriguez, Brad. MOVING FORTH. // July 1995. Посетен на 2006-06-19.
  20. Shoebridge, Peter. Motorola Background Debugging Mode Driver for Windows NT. // 1998-12-21. Посетен на 2006-06-19.
  21. Martin, Harold M.. Developing a tethered Forth model. // ACM Press, March 1991. Посетен на 2006-06-19.
  22. Brodie, Leo. Starting Forth. Second. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 200–202.
  23. Brodie, Leo. Starting Forth. Second. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 273.
  24. Brodie, Leo. Starting Forth. Second. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 199.
  25. Ertl, M. Anton. Implementation Issues for Superinstructions in Gforth (PDF). // Посетен на 2006-06-19.
  26. Brodie, Leo. Under The Hood. // Starting Forth. 2nd. Prentice-Hall, 1987. ISBN 0-13-843079-9. с. 241. 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.
  27. Brodie, Leo. Thinking Forth. Prentice-Hall, 1984. ISBN 0-13-917568-7.
  28. The classic washing machine example describes the process of creating a vocabulary to naturally represent the problem domain in a readable way.

Външни препратки[редактиране | редактиране на кода]