User:Dpelovski/sandbox/Forth

5 Структука на езика

5.1 Вписване в речника

5.2 Структура на компилатора

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

5.2.2 Непосредствени думи

5.2.3 Думи без наименование и изпълнение на знаци

Структука на езика

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

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

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

Вписване в речника

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

//grafika

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

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

Структура на компилатора

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

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

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

//графика

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

//графика

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

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

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

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

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

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

Непосредствени думи

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

Думи без наименование и изпълнение на знаци

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

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

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