aboutsummaryrefslogtreecommitdiffstats
path: root/doc/project.mg
diff options
context:
space:
mode:
Diffstat (limited to 'doc/project.mg')
-rw-r--r--doc/project.mg321
1 files changed, 0 insertions, 321 deletions
diff --git a/doc/project.mg b/doc/project.mg
deleted file mode 100644
index 013fb5c..0000000
--- a/doc/project.mg
+++ /dev/null
@@ -1,321 +0,0 @@
-.ps +1
-.vs +1
-.start
-.ds C \f[B]C\f[]
-.title "Проект по компютърни системи за управление на роботи"
-.title "Език за улесняване на програмиране на вградени устройства"
-.author "Галин Симеонов Ф.Н. 81635" "gtsimeonov@uni-sofia.bg"
-.heading "Увод"
-.paragraph
-При програмирането на вградени устройства,
-някои от проблемите се моделират чрез автомати.
-Също е практика да се програмира на езици от ниско ниво, като \*[C],
-при които ръчното имплементиране на автомати с каквито и да е размери
-често е неинтуитивно, предразполагащо към грешки и трудоемко.
-С цел да помогна разработването на програми, чийто модел е ориентиран околу
-състоянията на системата, предлагам и имплементирам експериментален миниатюрен език транспилиращ до \*[C].
-.paragraph
-За цели имам той да е прост, интуитивен и евентуално лесен за генериране от инстурменти с графичен интернфейс
-.footnote
-Макар, че директното генериране на код без този език да действа като посредник би било по-смислено.
-.footnote end
-\&.
-.heading "Описание на езика"
-.heading "Общ поглед" 2
-Една 'програма' съдържа един или повече 'машини', които действат като контейнери за състояния,събития и преходи.
-Всяка машина си има име и има отделно пространство за имена на състояния и събития.
-Чрез преходите може да се извикват външни функции.
-Ето най-простият пример за това как изглежда кодът:
-
-.code
-machine light_bulb
-[
- states [ ON , OFF ];
- events [ TURN_ON , TURN_OFF , SWITCH_STATE ];
- starting on OFF;
- transitions
- [
- from ON to OFF on event TURN_OFF;
- from ON to OFF on event SWITCH_STATE;
-
- from OFF to ON on event TURN_ON;
- from OFF to ON on event TURN_ON;
- ];
-
-];
-.code end
-
-След транспилация се генерират 3 файла - xxx.h xxx.c и xxx_external.h, който съответно съдържат
-декларациите на служебните функции, тяхната имплементация и декларациите на външните функции, които са използвани от някой преход.
-Подаването на събития към тези 'автомати' става посредством служебната функция - \f[B]push_event_to_machine\f[]
-
-Горният пример не е много функционален, защото комуникацията е само в една посока.
-За да може да връща информация и да има функционалност, на всеки преход може да се сложат функции, които да бъдат изпълнени преди преходът да е завършил
-.footnote
-Това свойство е важно и авторът се е стремил да го запази. Това позволява, например, да се подават събития от функции изпълнени по време на преход
-.footnote end
-\&.
-Taка горният пример може да бъде преработен да вика функция, която действително да включва и изключва някаква лампа:
-
-.code
-machine light_bulb
-[
- states [ ON , OFF ];
- events [ TURN_ON , TURN_OFF , SWITCH_STATE ];
- starting on OFF;
- transitions
- [
- from ON to OFF on event TURN_OFF
- execute light "off";
- from ON to OFF on event SWITCH_STATE
- execute light "off";
-
- from OFF to ON on event TURN_ON
- execute light "on";
- from OFF to ON on event TURN_ON
- execute light "on";
- ];
-
-];
-.code end
-
-Тук също е демонстрирано как се подават аргументи към тези функции.
-Символните низове са избрани като единствен начин да се подават аргументи, защото е предвидено да се транспилира до езици, различни от \*[C],
-а въвеждането на типова система или нещо, което да описва различните аргументи би натоварило езикът твърде много и би донесло само минимална печалба.
-.paragraph
-Възможно е да има повече от една 'машина' в кодът. Например, нека към горния пример добавим:
-
-.code
-machine light_controler
-[
- states [ STATIC , BLINKING ];
- events [ SIGNAL , GO_STATIC, START_BLINKING ];
- starting on STATIC;
- transitions
- [
- from STATIC to BLINKING on event START_BLINKING;
- from BLINKING to STATIC on event GO_STATIC;
-
- from BLINKING to BLINKING on event SIGNAL
- execute prod_light_bulb;
-
- ];
-
-];
-
-machine timer
-[
- states [ ON , OFF ];
- events [ TICK , START , STOP ];
- starting on OFF;
- transitions
- [
- from ON to OFF on event STOP;
- from OFF to ON on event START
- execute prod_timer;
- from ON to ON on event TICK
- execute prod_timer | prod_light_controler;
- ];
-
-];
-.code end
-
-Тук може да се види и 'навързване' на различни функции.
-timer 'машината' праща сигнал до себе си и до light_controler, а light_controler праща сигнал до light_bulb.
-Тук можем да прескочим предаването на събития между 'машините' чрез използването на \f[B]if\f[].
-Променяме третия преход от timer:
-
-.code
- from ON to ON on event TICK
- if(light_controler.BLINKING)
- execute prod_timer | prod_light_bulb;
-
-.code end
-
-Това е условно изпълнение на командите, преходът се случва и състоянието е променено независимо от истинността на условието.
-За реализацията на условен преход, в езикът има \f[B]granted\f[] ключовата дума.
-Горното може да се опитаме да имплементираме по следния начин:
-
-.code
- from ON to ON on event TICK granted (light_controler.BLINKING)
- execute prod_timer | prod_light_bulb;
-.code end
-
-Тук има проблема, че timer спира да работи ако light_controler не е в състояние BLINKING,
-защото преходът няма да се случи и \f[B]execute prod_timer\f[] няма да се изпълни.
-.footnote
-Това, че този пример може да бъде имплементиран на \*[C] под 10 реда, е забелязано от автора.
-.footnote end
-.paragraph
-\f[B]prod_timer\f[],\f[B]prod_light_bulb\f[],\f[B]prod_timer\f[] и \f[B]light\f[] са функции, чиято имплементация трябва да бъде предоставена от програмиста.
-Всички външни функции се събират и се записват в генерирания xxxx_exter.h файл. Този пример би генерирал:
-
-.code
-#ifndef XXXX_EXTERN_H
-#define XXXX_EXTERN_H XXXX_EXTERN_H
-
-extern machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input);
-extern machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input);
-extern machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input);
-extern machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input);
-
-#endif
-
-.code end
-
-Ето и една примерна тяхна импелементация заедно с \f[B]main\f[] функцията:
-
-.code
-machine_buffer_t* light(machine_buffer_t *arguments,machine_buffer_t *input)
-{
- printf("light %s\n",arguments->buffer);
- return NULL;
-}
-machine_buffer_t* prod_light_bulb(machine_buffer_t *arguments,machine_buffer_t *input)
-{
- push_event_to_machine(light_bulb,light_bulb_EVENT_SWITCH_STATE,NULL);
- return NULL;
-}
-machine_buffer_t* prod_light_controler(machine_buffer_t *arguments,machine_buffer_t *input)
-{
- push_event_to_machine(light_controler,light_controler_EVENT_SIGNAL,NULL);
- return NULL;
-}
-machine_buffer_t* prod_timer(machine_buffer_t *arguments,machine_buffer_t *input)
-{
- push_event_to_machine(timer,timer_EVENT_TICK,NULL);
- sleep(1);
- return NULL;
-}
-int main()
-{
- push_event_to_machine(light_controler,light_controler_EVENT_START_BLINKING,NULL);
- push_event_to_machine(timer,timer_EVENT_START,NULL);
- return 0;
-}
-
-.code end
-Това ни дава изхода:
-.code
-light on
-light off
-light on
-light off
-light on
-light off
-light on
-light off
-light on
-\&...
-\&...
-.code end
-
-.heading "Формално описание на езика" 2
-Със затъмнените думи и символи обозначавам думи и символи, които трябва да се интерпретират директно.
-.heading "Програма" 3
-.right
-.nf
-програма : машина [ програма ]
-.fi
-.right end
-Програмата е поредица от машини. Всяка машина има уникално име.
-.heading "Машина" 3
-.right
-.nf
-машина : \f[BI]machine\f[] име \f[BI][\f[] вътрешна част на машината \f[BI] ] ; \f[]
-вътрешна част на машината : \f[BI]states [\f[] поредица от състояния \f[BI] ] ; \f[] [ вътрешна част на машината ]
- \f[BI]events [\f[] поредица от събития \f[BI] ] ; \f[] [ вътрешна част на машината ]
- \f[BI]transitions [\f[] поредица от преходи \f[BI] ] ; \f[] [ вътрешна част на машината ]
- \f[BI]starting on \f[] име на състояние \f[BI];\f[] [ вътрешна част на машината ]
-.fi
-.right end
-
-В една машина може да се срещне само веднъж декларация на състоянията, събитията, преходите и посочване на стартиращо състояние.
-Декларацията на стартиращо състояние трябва да е след декларацията на състоянията. То трябва да е сред декларираните състояния.
-Декларацията на преходите трябва да е след декларациите на състоянията и на събитията.
-Сред декларираните състояния и събития не трябва да има повтарящи се.
-Сред преходите не трябва да има две различни, които излизат от едно състояние и имат за етикет едно събитие.
-.heading "Преход" 3
-.right
-.nf
-преход : \f[BI] from \f[] име-на-състояние
- \f[BI] to \f[] име-на-състояние \f[BI] on \f[] име-на-събитие [ опашка-на-прехода ] \f[BI];\f[]
-опашка-на-прехода : [ \f[BI] granted \f[] израз ] [ условно-изпълнение ]
-условно-изпълнение : \f[BI] if \f[] израз условно-изпълнение [ \f[BI] else \f[] условно-изпълнение ]
-условно-изпълнение : \f[BI] execute \f[] опашка на изпълнението
-опашка-на-изпълнението : име-на-външна-функция \f[BI]"\f[]символен-низ\f[BI]"\f[] [ \f[BI] | \f[] опашка-на-изпълнението ]
-.fi
-.right end
-
-Ако изразът след \f[BI]granted\f[] е истина то преходът се реализира и командите в условното изпълнение се изпълняват спрямо семантиката,
-иначе преходът не се изпълнява и опашката на преходът не се изпълнява.
-Ако изразът след \f[BI]if\f[] е истина то условното изпълнение след изразът се изпълнява, иначе, ако има \f[BI]else\f[]
-съответстващ на \f[BI]if\f[]-а то условното узпълнение след \f[BI]else\f[] се изпълнява.
-Ако условното изпълнение е от типа започващ с \f[BI]execute\f[] то външните функции се изпълняват в ред на срещане
-като изходът на всяка се подава на следващата. Изходът на последната изпълнена функция се изхвърля.
-.heading "Израз" 3
-.right
-.nf
-израз : израз-или
-израз-или : израз-и [ \f[BI]|| \f[] израз-или ]
-израз-и : израз-не [ \f[BI]&& \f[] израз-и ]
-израз-не : [\f[BI]!\f[]]базов-израз
-базов-израз : име-на-машина\f[BI].\f[]име-на-състояние | \f[BI](\f[]израз\f[BI])\f[]
-.fi
-.right end
-
-Израз може да се оцени до истина или лъжа.
-Логическите оператори имат обичайната семантика.
-В базовия израз е позволено да се посочват състояния на други машини, но не е позволено да се посочват състояния на машината,
-в която се намира изразът. Тези посочвания се оценяват до истина ако посочената машина е заела посоченото състояние.
-Могат да се посочват имена на машини, които са декларирани след сегашната, но те трябва да съществуват. Това важи и за състоянията, те трябва също и да принадлежат на посочената машина.
-
-.heading "Детайли на имплементацията"
-За да се реализира обмена на информация между генерирания код и написания,
-е дефинирана структура \f[B]machine_buffer_t\f[], в която се записват данните и техният размер.
-Генерират се и няколко помощни функции, които улесняват работата с такива структури.
-За да се запази свойството - командите на преходът да се изпълнят преди състоянието да се смени,
-се използва опашка, в която се записват
-.heading "Описание на командните аргументи"
-Имплементацията на този език предадена от автора приема следните аргументи.
-
-.code
---print-tokens
-.code end
-Извежда разпознатите лексеми
-.code
---print-ast
-.code end
-Извежда разпознатите структури в текста. ( Абстрактното синтактично дърво )
-.code
--o име-на-файл | --output име-на-файл
-.code end
-Посочва префиксът на генерираните файлове. Например \f[B]xxxx.h xxxx.c xxxx_external.h\f[].
-.code
---extern-mutex
-.code end
-Добавя мутекс преди и след подаването на събитие. Този мутекс трябва да се имплементира външно.
-.code
---extern-queue
-.code end
-Дава възможност на програмиста да даде собствена имплементация на опашката използвана при задържането на събития.
-.code
---extern-buffer
-.code end
-Дава възможност на програмиста да даде собствена имплементация на структурата използвана за пренос на данни.
-
-.heading "Забележки"
-За имплементацията е използвана само стандартната \*[C] библиотека, което би помогнало този транспилатор да бъде
-компилиран до много операционни системи.
-.heading "Бъдещи насоки"
-.list
-.item
-Да се добави ключова дума \f[B]signal\f[] която да праща сигнал до определена машина, за да не трябва да го имплементира програмистът.
-.item
-Да се добави семанитка за състояния и събития, като например - 'при пристигане до това състояние изпълни ... '.
-.item
-Да се направи така, че отделните машини да могат да бъдат на различни физически устройства, т.е. да бъде направен разпределен.
-.item
-Да се направи на пълен език за програмиране.
-.list end
-.finish