Áàçà çíàíèé ñòóäåíòà. Ðåôåðàò, êóðñîâàÿ, êîíòðîëüíàÿ, äèïëîì íà çàêàç

êóðñîâûå,êîíòðîëüíûå,äèïëîìû,ðåôåðàòû

Èíòåðàêòèâíûé èíòåðïðåòàòîð — Èíôîðìàòèêà, ïðîãðàììèðîâàíèå

ÌÈÍÈÑÒÅÐÑÒÂÎ ÎÁÐÀÇÎÂÀÍÈß ÐÅÑÏÓÁËÈÊÈ ÁÅËÀÐÓÑÜ

Ó×ÐÅÆÄÅÍÈÅ ÎÁÐÀÇÎÂÀÍÈß «ÁÅËÎÐÓÑÑÊÈÉ ÃÎÑÓÄÀÐÑÒÂÅÍÍÛÉ ÓÍÈÂÅÐÑÈÒÅÒ ÈÍÔÎÐÌÀÒÈÊÈ È ÐÀÄÈÎÝËÅÊÒÐÎÍÈÊÈ»

Êàôåäðà èíôîðìàòèêè

 

ÊÓÐÑÎÂÎÉ ÏÐÎÅÊÒ

ïî ïðåäìåòó «Îáúåêòíî-îðèåíòèðîâàííîå ïðîãðàììèðîâàíèå»

íà òåìó «Èíòåðïðåòàòîð ÿçûêà ïðîãðàììèðîâàíèÿ».

 

Âûïîëíèë ñò. ãð.********

************.

 

Ïðîâåðèë

****************.

 

 

ÌÈÍÑÊ 2005

 

          Ñîäåðæàíèå.


Ñîäåðæàíèå. 2

Ââåäåíèå.. 3

Ïîñòàíîâêà çàäà÷è. 4

Îïèñàíèå ðåàëèçîâàííîãî â èíòåðïðåòàòîðå ÿçûêà ïðîãðàììèðîâàíèÿ. 5

Ïðèìåðû ïîëüçîâàòåëüñêèõ ôóíêöèé.. 12

1. Ñîðòèðîâêà ìàññèâà. 12

2. Âû÷èñëåíèå ÍÎÄ ïî àëãîðèòìó Åâêëèäà. 12

3. Ðåêóðñèâíîå âû÷èñëåíèå ôàêòîðèàëà. 13

4. Ïðîâåðêà, ÿâëÿåòñÿ ëè ñòðîêà êîððåêòíûì èäåíòèôèêàòîðîì. 13

5. Âû÷èñëåíèå óãëà òðåóãîëüíèêà ïî òðåì ñòîðîíàì. 14

Ïðîåêòèðîâàíèå è ðåàëèçàöèÿ  ïðîãðàììû-èíòåðïðåòàòîðà   15

Âíóòðåííåå ïðåäñòàâëåíèå è âûïîëíåíèå ïðîãðàììû. 18

Îáðàáîòêà òåêñòà ïðîãðàììû. 24

Ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ. 27

Âçàèìîäåéñòâèå ïîäñèñòåì èíòåðïðåòàòîðà. Êëàññ Facade. 31

Çàêëþ÷åíèå.. 33

Ïðèëîæåíèå. Èñõîäíûé òåêñò (ñîêðàùåííî). 34

1. Êëàññ VarBase. 34

2. Êëàññ ArrayVar. 34

3. Êëàññ InterprEnvironment. 36

4. Êëàññ Namespace. 40

5. Èíòåðôåéñ IÑomputable. 42

6. Êëàññ Call. 42

7. Êëàññ ArgList. 42

8. Êëàññ Expression. 43

9. Êëàññ Operation (ñîêðàùåííî). 49

10. Êëàññ Parser. 50

11. Êëàññ LineCompiler. 56

12. Èíòåðôåéñ IOperator. 60

13. Êëàññ Command. 60

14. Êëàññ ForOperator. 61

15. Êëàññ NextOperator. 62

16. Êëàññ Subroutine. 62

17. Êëàññ Facade. 67

18. Êëàññ SourceBox. 69

19. Êëàññ Form1. 75

Èñïîëüçîâàííàÿ ëèòåðàòóðà è äîêóìåíòàöèÿ. 78


Ââåäåíèå

Ñòàíäàðòíûé «Êàëüêóëÿòîð» Windows ÿâëÿåòñÿ, ïîæàëóé, åäèíñòâåííîé èìåþùåé øèðîêîå ðàñïðîñòðàíåíèå ïðîãðàììîé, ïðåäíàçíà÷åííîé äëÿ ìåëêèõ âû÷èñëåíèé. Åãî íå ìîãóò çàìåíèòü èç-çà ñâîåé ãðîìîçäêîñòè, íè ýëåêòðîííûå òàáëèöû, íè ïðîôåññèîíàëüíûå ìàòåìàòè÷åñêèå ïàêåòû. Íî â òî æå âðåìÿ ýòà ïðîãðàììà èìååò ñóùåñòâåííûå íåäîñòàòêè, ïðè÷èíà êîòîðûõ ïðîñòà – ïîëüçîâàòåëüñêèé èíòåðôåéñ ñäåëàí «ïî îáðàçó è ïîäîáèþ» êàðìàííîãî êàëüêóëÿòîðà, ïîýòîìó çàèìñòâîâàíû âñå íåóäîáñòâà ïîñëåäíåãî. Íàïðèìåð, ïðè ðàáîòå ïîëüçîâàòåëü âèäèò òîëüêî îäíî ÷èñëî è ïîñëå ïîëó÷åíèÿ ðåçóëüòàòà íå ìîæåò ïðîâåðèòü, ïðàâèëüíî ëè áûëè ââåäåíû îïåðàíäû. Âòîðîé ïðîáëåìîé ÿâëÿåòñÿ íåâîçìîæíîñòü äîáàâëåíèÿ ïîëüçîâàòåëüñêèõ ôóíêöèé – åñëè ïðèõîäèòñÿ ïðîèçâîäèòü âû÷èñëåíèÿ ïî îäíîé è òîé æå ôîðìóëå ñòî ðàç, ñòî ðàç ïðèõîäèòñÿ íàæèìàòü ñîîòâåòñòâóþùóþ êíîïêó äëÿ êàæäîé àðèôìåòè÷åñêîé îïåðàöèè â âûðàæåíèè. Íà ìîå ìíåíèå, íàèáîëåå óäîáíû äëÿ ïîâñåäíåâíîãî èñïîëüçîâàíèÿ â êà÷åñòâå çàìåíû «Êàëüêóëÿòîðó» èíòåðàêòèâíûå èíòåðïðåòàòîðû, ê ÷èñëó êîòîðûõ îòíîñÿòñÿ MatLab è  Python. Íî îñíîâíîå íàçíà÷åíèå ýòèõ ïðîãðàììíûõ ïàêåòîâ ñîâñåì äðóãîå, íåò ñìûñëà óñòàíàâëèâàòü èõ íà êîìïüþòåð ëèøü äëÿ òîãî, ÷òîáû âûïîëíÿòü íåñêîëüêî ñëîæåíèé è óìíîæåíèé ïàðó ðàç â äåíü. Ïîýòîìó ÿ ðåøèë íàïèñàòü íåñëîæíûé èíòåðàêòèâíûé èíòåðïðåòàòîð, íå ãðîìîçäêèé è óäîáíûé äëÿ ìåëêèõ âû÷èñëåíèé.


Ïîñòàíîâêà çàäà÷è.

Òðåáóåòñÿ ðåàëèçîâàòü èíòåðïðåòàòîð îòíîñèòåëüíî íåñëîæíîãî ÿçûêà ïðîãðàììèðîâàíèÿ, ðàáîòàþùèé â èíòåðàêòèâíîì ðåæèìå, òî åñòü âûïîëíÿþùèé ââîäèìûå ïîëüçîâàòåëåì êîìàíäû ñ êëàâèàòóðû. Ïðè ýòîì äîëæíà ïðèñóòñòâîâàòü âîçìîæíîñòü ñîçäàíèÿ ïîëüçîâàòåëüñêèõ ôóíêöèé, â êîòîðûõ ìîãóò ïðèñóòñòâîâàòü îïåðàòîðû óïðàâëåíèÿ òå÷åíèåì ïðîãðàììû – âåòâëåíèÿ, öèêëû è äð., à òàêæå îïåðàòîðû âûâîäà (íà êîíñîëü). Äîëæíû áûòü òàêæå ïðåäóñìîòðåíû âîçìîæíîñòü ñîõðàíåíèÿ ïðîìåæóòî÷íûõ ðåçóëüòàòîâ âû÷èñëåíèÿ (â òîì ÷èñëå ìåæäó ñåàíñàìè ðàáîòû ñ èíòåðïðåòàòîðîì) è âîçìîæíîñòü ïðåðûâàíèÿ âûïîëíåíèÿ çàöèêëèâøåéñÿ ïîëüçîâàòåëüñêîé ôóíêöèè áåç çàâåðøåíèÿ ðàáîòû èíòåðïðåòàòîðà. Äàííûé èíòåðïðåòàòîð äîëæåí áûòü óäîáåí â èñïîëüçîâàíèè êàê çàìåíà ñòàíäàðòíîìó «Êàëüêóëÿòîðó» Windows, ïî êðàéíåé ìåðå, äëÿ ÷åëîâåêà, âëàäåþùåãî ìèíèìàëüíûìè íàâûêàìè ïðîãðàììèðîâàíèÿ.


Îïèñàíèå ðåàëèçîâàííîãî â èíòåðïðåòàòîðå ÿçûêà ïðîãðàììèðîâàíèÿ.

Èíòåðïðåòàòîð ðàáîòàåò â ðåæèìå êîíñîëè è âûïîëíÿåò êîìàíäû, ââîäèìûå ñ êëàâèàòóðû. Ýòè êîìàíäû ìîãóò ñîäåðæàòü âûçîâû ïîëüçîâàòåëüñêèõ ôóíêöèé. Êîä ïîëüçîâàòåëüñêèõ ôóíêöèé ñîçäàåòñÿ ñ ïîìîùüþ îêíà ðåäàêòîðà êîäà èíòåðïðåòàòîðà. Èíòåðïðåòàòîð ïðåäîñòàâëÿåò âîçìîæíîñòü ñîçäàíèÿ, ðåäàêòèðîâàíèÿ è óäàëåíèÿ ïîëüçîâàòåëüñêèõ ôóíêöèé. Ôóíêöèè ñîõðàíÿþòñÿ â ôàéëàõ, èìÿ êîòîðûõ íå èìååò ðàñøèðåíèÿ è ñîâïàäàåò ñ èìåíåì ôóíêöèè. Ôàéëû èñïîëüçóåìûõ ôóíêöèé äîëæíû íàõîäèòüñÿ â ïîäêàòàëîãå subroutines ðàáî÷åãî êàòàëîãà èíòåðïðåòàòîðà. Ñîõðàíåííûå ïîëüçîâàòåëüñêèå ôóíêöèè çàãðóæàþòñÿ àâòîìàòè÷åñêè ïðè çàïóñêå èíòåðïðåòàòîðà. Âñå îïåðàòîðû óïðàâëåíèÿ òå÷åíèåì ïðîãðàììû ìîãóò èñïîëüçîâàòüñÿ òîëüêî â òåêñòå ïîëüçîâàòåëüñêîé ôóíêöèè. Âñå îñòàëüíûå îïåðàòîðû (êîìàíäû) ìîãóò áûòü âûçâàíû íåïîñðåäñòâåííî èç êîíñîëè. Êðîìå òîãî, â êîíñîëè ìîæíî ââåñòè âûðàæåíèå áåç äîïîëíèòåëüíûõ êëþ÷åâûõ ñëîâ, è îíî áóäåò âû÷èñëåíî, åãî çíà÷åíèå áóäåò âûâåäåíî íà ýêðàí. Äëÿ âûâîäà æå äàííûõ èç ôóíêöèè íåîáõîäèìî èñïîëüçîâàòü îïåðàòîðû âûâîäà (ñì. íèæå).

Èäåíòèôèêàòîðîì (èìåíåì) ïåðåìåííîé ñëóæèò ïîñëåäîâàòåëüíîñòü ñèìâîëîâ ïðîèçâîëüíîé äëèíû, ñîñòîÿùàÿ èç áóêâ (ëàòèíñêîãî àëôàâèòà), öèôð è çíàêîâ ïîä÷åðêèâàíèÿ, íå íà÷èíàþùàÿñÿ ñ öèôðû. Òå æå îãðàíè÷åíèÿ ðàñïðîñòðàíÿþòñÿ è íà èìåíà ôóíêöèé. Ðåãèñòð áóêâ èìååò çíà÷åíèå. Âîçìîæíî íàëè÷èå òîëüêî îäíîé ïåðåìåííîé ñ êàæäûì èìåíåì â êàæäîé ôóíêöèè è â ñðåäå êîíñîëè. Íî äîïóñêàåòñÿ ñîâïàäåíèå èìåíè ïåðåìåííîé ñ èìåíåì êàêîé-ëèáî ôóíêöèè. Òàêæå èìåíà ïåðåìåííûõ è ôóíêöèé íå äîëæíû ñîâïàäàòü ñ êëþ÷åâûìè ñëîâàìè ÿçûêà, ê êîòîðûì îòíîñÿòñÿ:

·        call

·        clear

·        else

·        elseif

·        endif

·        error

·        for

·        if

·        loop

·        next

·        print

·        println

·        result

·        return

·        while

Ïðåäâàðèòåëüíîãî îáúÿâëåíèÿ ïåðåìåííûõ íå òðåáóåòñÿ. Ïåðåìåííàÿ ïðèñóòñòâóåò â ïàìÿòè ñ ìîìåíòà ïðèñâîåíèÿ åé çíà÷åíèÿ, ïðè ýòîì òèï ïåðåìåííîé îïðåäåëÿåòñÿ ïî òèïó ïðèñâàèâàåìîãî åé çíà÷åíèÿ. Ìàññèâ òàêæå ñîçäàåòñÿ ïðè ïðèñâàèâàíèè çíà÷åíèÿ êàêîìó-ëèáî åãî ýëåìåíòó. Ïîïûòêà ïîëó÷èòü çíà÷åíèå åùå íå èíèöèàëèçèðîâàííîé ïåðåìåííîé èëè ïîïûòêà ðàññìîòðåòü êàê ìàññèâ ïåðåìåííóþ, íå ÿâëÿþùóþñÿ òàêîâîé, ïðèâîäèò ê îøèáêå. Êàæäàÿ ôóíêöèÿ è ñðåäà êîíñîëè èìåþò ñîáñòâåííûå, íå çàâèñÿùèå äðóã îò äðóãà íàáîðû ïåðåìåííûõ. Îáðàòèòüñÿ èç ôóíêöèè èëè ñðåäû êîíñîëè ê “÷óæîé” ïåðåìåííîé íåâîçìîæíî.

Èìåþòñÿ ñëåäóþùèå òèïû äàííûõ: öåëûé, âåùåñòâåííûé, ñòðîêîâûé, ìàññèâ. Öåëûé, âåùåñòâåííûé è ñòðîêîâûé òèïû íàçûâàþòñÿ ïðîñòûìè â ïðîòèâîïîëîæíîñòü ìàññèâó; âåùåñòâåííûé è öåëûé òèïû íàçûâàþòñÿ ÷èñëîâûìè. Òèï ïåðåìåííîé íå îïèñûâàåòñÿ, íî ìîæåò áûòü îïðåäåëåí ñ ïîìîùüþ ôóíêöèé issingle, isarray, isstring, isnum, isint, isreal. Êðîìå òîãî, âûïîëíåíèå îïåðàöèè íàä àðãóìåíòàìè íåäîïóñòèìûõ òèïîâ ìîæåò ïðèâåñòè ê îøèáêå. Ìàññèâ ìîæåò õðàíèòü ýëåìåíòû ëþáûõ ïðîñòûõ òèïîâ, ïðè÷åì òèïû ðàçíûõ ýëåìåíòîâ îäíîãî è òîãî æå ìàññèâà ìîãóò íå ñîâïàäàòü. Ïî ìåðå çàïîëíåíèÿ ìàññèâà âîçìîæíî ïîÿâëåíèå â íåì «ïóñòûõ ìåñò», íàïðèìåð, ïîñëå êîìàíä a{0}:=1; a{2}:=4; a{4}:=5 (ïðîïóùåíû ýëåìåíòû ñ èíäåêñàìè 1 è 3). Ïîïûòêà ïîëó÷èòü çíà÷åíèå åùå íå èíèöèàëèçèðîâàííîãî ýëåìåíòà ìàññèâà ïðèâîäèò ê îøèáêå. Ïðîâåðèòü, èíèöèàëèçèðîâàí ëè ýëåìåíò ìàññèâà ñ çàäàííûì èíäåêñîì, ìîæíî ñ ïîìîùüþ ôóíêöèè defined.

Ëþáàÿ ïîñëåäîâàòåëüíîñòü ïðîáåëîâ è òàáóëÿöèé, èäóùèõ ïîäðÿä, ñ÷èòàåòñÿ çà îäèí ïðîáåë, åñëè îíà íàõîäèòñÿ ìåæäó ñèìâîëàìè, êîòîðûå ìîãóò âõîäèòü â èäåíòèôèêàòîðû (áóêâû, öèôðû, ïîä÷åðêèâàíèå), èëè èãíîðèðóåòñÿ â ïðîòèâíîì ñëó÷àå. Òàêæå èãíîðèðóþòñÿ èíòåðïðåòàòîðîì êîììåíòàðèè, êîòîðûìè ÿâëÿþòñÿ ñòðîêè èëè îêîí÷àíèÿ ñòðîê, íà÷èíàþùèåñÿ ñ ñèìâîëà ‘#’. Ýòè ïðàâèëà íå ðàñïðîñòðàíÿþòñÿ íà ñòðîêîâûå êîíñòàíòû, çàêëþ÷àåìûå â äâîéíûå êàâû÷êè. Ñòðîêîâîé êîíñòàíòîé íå ÿâëÿåòñÿ ïîñëåäîâàòåëüíîñòü ñèìâîëîâ â êàâû÷êàõ, åñëè îòêðûâàþùàÿ êàâû÷êà íàõîäèòñÿ ïîñëå ñèìâîëà íà÷àëà êîììåíòàðèÿ '#’, íî ýòîò ñèìâîë ìîæåò ïðèñóòñòâîâàòü â ñòðîêîâîé êîíñòàíòå ìåæäó êàâû÷êàìè. Òàê íàïðèìåð, êîìàíäà a :  =    b +   ”#”+c#comment ýêâèâàëåíòíà êîìàíäå a:=b+”#” +    c, íî íå ðàâíîñèëüíà êîìàíäå a:=b+”    #”+c, èëè a+b+” (ïîñëåäíÿÿ êîìàíäà ñèíòàêñè÷åñêè íåâåðíà).

Êàæäàÿ ñòðîêà, ââîäèìàÿ ñ êîíñîëè, ñîäåðæèò îäíó êîìàíäó èëè íè îäíîé (ïóñòàÿ ñòðîêà èëè êîììåíòàðèé) êîìàíäû. Òî æå êàñàåòñÿ è ñòðîê ôàéëà ôóíêöèè, êðîìå ïåðâîé, êîòîðàÿ äîëæíà ñîäåðæàòü îïèñàíèå ôóíêöèè â âèäå: <èìÿ_ôóíêöèè>[<ñïèñîê_ïàðàìåòðîâ>], ãäå ñïèñîê ïàðàìåòðîâ, çàêëþ÷àåìûé â êâàäðàòíûå ñêîáêè, ñîñòîèò èç èìåí ïàðàìåòðîâ, ðàçäåëåííûõ çàïÿòîé (ýòà ñòðîêà òàêæå ìîæåò ñîäåðæàòü è êîììåíòàðèé ïîñëå îïèñàíèÿ ôóíêöèè). Êâàäðàòíûå ñêîáêè ïèøóòñÿ äàæå ïðè ïóñòîì ñïèñêå ïàðàìåòðîâ. Èìåíà ïàðàìåòðîâ (ôîðìàëüíûõ) ïîä÷èíÿþòñÿ òåì æå îãðàíè÷åíèÿì, ÷òî è èìåíà ïåðåìåííûõ, ìàëî òîãî, îíè ðàññìàòðèâàþòñÿ êàê ïåðåìåííûå, îïðåäåëåííûå â äàííîé ôóíêöèè, íî â íà÷àëå âûïîëíåíèÿ ôóíêöèè îíè ïðèíèìàþò çíà÷åíèÿ ñîîòâåòñòâóþùèõ ôàêòè÷åñêèõ ïàðàìåòðîâ. Íóæíî îòìåòèòü, ÷òî ïîïûòêà ïåðåäà÷è â êà÷åñòâå ôàêòè÷åñêîãî ïàðàìåòðà ôóíêöèè ïåðåìåííîé ñ íåîïðåäåëåííûì çíà÷åíèåì âñåãäà ïðèâîäèò ê îøèáêå, äàæå åñëè â ôóíêöèè ê ýòîìó ïàðàìåòðó íåò íè îäíîãî îáðàùåíèÿ.. Òàêæå ïðèâîäèò ê îøèáêå âûçîâ ôóíêöèè ñ ÷èñëîì ôàêòè÷åñêèõ ïàðàìåòðîâ, íå ñîîòâåòñòâóþùèì ÷èñëó ôîðìàëüíûõ ïàðàìåòðîâ. Êðîìå òîãî, â êàæäîé ôóíêöèè èìååòñÿ ïåðåìåííàÿ ñ ïðåäîïðåäåëåííûì èìåíåì result. Åå çíà÷åíèå íà ìîìåíò âûõîäà èç ôóíêöèè è ÿâëÿåòñÿ âîçâðàùàåìûì çíà÷åíèåì ôóíêöèè.  ìîìåíò íà÷àëà âûïîëíåíèÿ ôóíêöèè åå çíà÷åíèå ðàâíî 0 (öåëîå ÷èñëî). Åñëè ïåðåìåííàÿ result áûëà óäàëåíà êîìàíäîé clear è îñòàëàñü íåîïðåäåëåííîé íà ìîìåíò âûõîäà èç ôóíêöèè, âîçíèêàåò îøèáêà.

Çíà÷åíèÿ öåëîãî, âåùåñòâåííîãî è ñòðîêîâîãî òèïà ìîãóò áûòü ïðåäñòàâëåíû â ïðîãðàììå â âèäå êîíñòàíò (ëèòåðàëîâ). Öåëûé ëèòåðàë ïðåäñòàâëÿåò ñîáîé ïîñëåäîâàòåëüíîñòü öèôð. Îí ïðåäñòàâëÿåò ÷èñëî, îáû÷íîé çàïèñüþ êîòîðîãî ÿâëÿåòñÿ. Âåùåñòâåííûé ëèòåðàë ïðåäñòàâëÿåò ñîáîé äåñÿòè÷íóþ èëè ýêñïîíåíöèàëüíóþ çàïèñü âåùåñòâåííîãî ÷èñëà, ïðè ýòîì, â ñëó÷àå ýêñïîíåíöèàëüíîé çàïèñè, áóêâà “å” ìîæåò áûòü êàê ñòðî÷íîé, òàê è ïðîïèñíîé. Íàïðèìåð:12.0, 1.6e87, 2Å-7, 89.0.  ÷èñëîâûõ ëèòåðàëàõ íå ìîæåò ñîäåðæàòüñÿ íà÷àëüíûé ñèìâîë «+» èëè «-», îíè ìîãóò ïðåäñòàâëÿòü òîëüêî ïîëîæèòåëüíîå ÷èñëî. Îòðèöàòåëüíûå çíà÷åíèÿ ìîæíî ïîëó÷èòü ïðèìåíåíèåì îïåðàöèè óíàðíûé ìèíóñ. Öåëàÿ ÷àñòü âåùåñòâåííîãî ÷èñëà íå ìîæåò áûòü îïóùåíà. Äðîáíàÿ ÷àñòü (òî÷êà è õîòÿ áû îäíà öèôðà ïîñëå íåå) äîëæíà ïðèñóòñòâîâàòü, åñëè íå óêàçàí ïîðÿäîê, íàïðèìåð, 11å-6 – äîïóñòèìàÿ çàïèñü, à 11.å-4 è 61. – íåò. Ñòðîêîâûé ëèòåðàë çàêëþ÷àåòñÿ â äâîéíûå êàâû÷êè, åñëè â íåãî íóæíî âêëþ÷èòü äâîéíóþ êàâû÷êó, òî îíà ïèøåòñÿ äâàæäû.

Ñïåöèàëüíûé ëîãè÷åñêèé òèï äàííûõ îòñóòñòâóåò, ëîãè÷åñêèå çíà÷åíèÿ ïðåäñòàâëÿþòñÿ ïåðåìåííûìè öåëîãî, âåùåñòâåííîãî ëèáî ñòðîêîâîãî òèïà – èñòèíå ñîîòâåòñòâóåò ïîëîæèòåëüíîå ÷èñëî ëèáî íåïóñòàÿ ñòðîêà, ëæè – íåïîëîæèòåëüíîå ÷èñëî ëèáî ïóñòàÿ ñòðîêà. Ðåçóëüòàò âñåõ ñòàíäàðòíûõ ëîãè÷åñêèõ îïåðàöèé – öåëûå ÷èñëà 1 (èñòèíà) èëè -1 (ëîæü). Ïðè ïîïûòêå ðàññìîòðåòü ìàññèâ êàê ëîãè÷åñêîå çíà÷åíèå âîçíèêàåò îøèáêà.

Âûðàæåíèåì ÿâëÿåòñÿ:

·        èäåíòèôèêàòîð ïåðåìåííîé;

·        êîíñòàíòà öåëîãî, âåùåñòâåííîãî èëè ñòðîêîâîãî òèïà;

·        îáðàùåíèå ê ýëåìåíòó ìàññèâà ñ çàäàííûì èíäåêñîì, èìåþùåå ñèíòàêñèñ <èäåíòèôèêàòîð ìàññèâà>{<èíäåêñ>} (èíäåêñ çàêëþ÷åí â ôèãóðíûå ñêîáêè). Èíäåêñ äîëæåí áûòü âûðàæåíèåì. Ïåðåä îòêðûâàþùåé ôèãóðíîé ñêîáêîé äîëæíî ñòîÿòü èìÿ ïåðåìåííîé, ÿâëÿþùåéñÿ ìàññèâîì (íî íå äðóãîå âûðàæåíèå, èìåþùåå òèï ìàññèâà).  Çíà÷åíèå èíäåêñà äîëæíî áûòü íåîòðèöàòåëüíûì öåëûì, èíà÷å âîçíèêàåò îøèáêà;

·        ðåçóëüòàò ïðèìåíåíèÿ óíàðíîé îïåðàöèè ê âûðàæåíèþ;

·        ðåçóëüòàò ïðèìåíåíèÿ áèíàðíîé îïåðàöèè ê äâóì âûðàæåíèÿì;

·        âûçîâ ôóíêöèè (áåç êëþ÷åâîãî ñëîâà call).  ýòîì ñëó÷àå ôóíêöèÿ îáÿçàíà âîçâðàùàòü çíà÷åíèå, èíà÷å âîçíèêàåò îøèáêà. Ôàêòè÷åñêèìè ïàðàìåòðàìè ôóíêöèè äîëæíû áûòü âûðàæåíèÿ;

·        âûðàæåíèå, çàêëþ÷åííîå â êðóãëûå ñêîáêè.

Îïåðàöèè, èñïîëüçóåìûå â âûðàæåíèÿõ, è èõ ïðèîðèòåòû (îïåðàíäû îáîçíà÷åíû êàê a è b; äëÿ ñóììû ÷èñåë, ðàçíîñòè è ïðîèçâåäåíèÿ ðåçóëüòàò – öåëîå ÷èñëî, åñëè îáà îïåðàíäà – öåëûå, èíà÷å – âåùåñòâåííîå ÷èñëî)  ïåðå÷èñëåíû â òàáëèöå.



Óðîâåíü ïðèîðèòåòà Ñèíòàêñèñ Òèïû îïåðàíäîâ Ñìûñë Òèï ðåçóëüòàòà
1 ~a ïðîñòîé ëîãè÷åñêîå îòðèöàíèå öåëûé (-1 èëè 1)
-a ÷èñëî óíàðíûé ìèíóñ òîò æå, ÷òî è a
+a ÷èñëî óíàðíûé ïëþñ
2 a*b ÷èñëà ïðîèçâåäåíèå ÷èñëî
a/b ÷èñëà âåùåñòâåííîå äåëåíèå âåùåñòâåííîå
3 a+b ñòðîêè ëèáî  a – ñòðîêà, b - ÷èñëî êîíêàòåíàöèÿ ñòðîê (÷èñëî ïðåîáðàçóåòñÿ â ñòðîêó) ñòðîêà
÷èñëà ñóììà ÷èñëî
a-b ÷èñëà ðàçíîñòü ÷èñëî
4 a=b ïðîñòûå (îáà – ÷èñëà ëèáî ñòðîêè îäíîâðåìåííî) ðàâíî öåëûé (-1 èëè 1)
a<>b íå ðàâíî
a>b áîëüøå
a<b ìåíüøå
a<=b ìåíüøå ëèáî ðàâíî
a>=b áîëüøå ëèáî ðàâíî
5 a&b ïðîñòûå “È”
6 a^b ïðîñòûå èñêëþ÷àþùåå “ÈËÈ”
a~=b ëîãè÷åñêàÿ ýêâèâàëåíòíîñòü
a|b “ÈËÈ”

Âûðàæåíèÿ èíòåðïðåòèðóþòñÿ â ñîîòâåòñòâèè ñ ïðèîðèòåòîì îïåðàöèé è èìåþùèìèñÿ â íèõ êðóãëûìè ñêîáêàìè. Ïðè ýòîì âñå óíàðíûå îïåðàöèè âûïîëíÿþòñÿ ñïðàâà íàëåâî, áèíàðíûå îïåðàöèè îäèíàêîâîãî ïðèîðèòåòà – ñëåâà íàïðàâî. Åñëè â âûðàæåíèè õîòÿ áû îäèí èç îïåðàíäîâ îïåðàöèè íå èìååò òðåáóåìûé òèï, èëè îïåðàöèÿ íå ìîæåò áûòü ïðîèçâåäåíà êîððåêòíî ïî äðóãîé ïðè÷èíå, íàïðèìåð, â ñëó÷àå äåëåíèÿ íà íîëü, òî âîçíèêàåò îøèáêà.

Âûçîâ ôóíêöèè èìååò ñëåäóþùèé ñèíòàêñèñ: <èìÿ ôóíêöèè>[<ôàêòè÷åñêèé ïàðàìåòð 1>,<ôàêòè÷åñêèé ïàðàìåòð 2>,...,<ôàêòè÷åñêèé ïàðàìåòð 3>]. Äàæå åñëè ñïèñîê ïàðàìåòðîâ ïóñò, êâàäðàòíûå ñêîáêè âñå ðàâíî ïèøóòñÿ. Ôàêòè÷åñêèìè ïàðàìåòðàìè ôóíêöèè äîëæíû áûòü âûðàæåíèÿ.

Íàïðèìåð, function1[a,b+c,function2[a,function3[]],56.12e-1]. Ñóùåñòâóåò ðÿä ïðåäîïðåäåëåííûõ ôóíêöèé, ñ èìåíàìè êîòîðûõ íå äîëæíû ñîâïàäàòü èìåíà ïîëüçîâàòåëüñêèõ ôóíêöèé. Èõ ñïèñîê ïðèâåäåí â òàáëèöå.


Ôóíêöèÿ

Âîçâðàùàåìîå

 çíà÷åíèå

Îïèñàíèå
abs[÷èñëî] òîãî æå òèïà, ÷òî è ïàðàìåòð àáñîëþòíàÿ âåëè÷èíà
cos[÷èñëî] âåùåñòâåííîå êîñèíóñ
sin[÷èñëî] ñèíóñ
tg[÷èñëî] òàíãåíñ
arctg[÷èñëî] àðêòàíãåíñ
arcsin[÷èñëî] àðêñèíóñ
arccos[÷èñëî] àðêêîñèíóñ
exp[÷èñëî] ñòåïåíü îñíîâàíèÿ íàòóðàëüíûõ ëîãàðèôìîâ (ýêñïîíåíòà)
pow[÷èñëî, ÷èñëî] ïåðâûé ïàðàìåòð â ñòåïåíè âòîðîé ïàðàìåòð (ïåðâûé ïàðàìåòð äîëæåí áûòü íåîòðèöàòåëüíûì)
ln[÷èñëî] íàòóðàëüíûé ëîãàðèôì
lg[÷èñëî] äåñÿòè÷íûé ëîãàðèôì
log[÷èñëî, ÷èñëî] ëîãàðèôì ïåðâîãî àðãóìåíòà ïî îñíîâàíèþ, çàäàííîìó âòîðûì àðãóìåíòîì
sqrt[÷èñëî] êâàäðàòíûé êîðåíü
pi[] êîíñòàíòà pi (îòíîøåíèå äëèíû îêðóæíîñòè ê äèàìåòðó)
idiv[öåëîå ÷èñëî, öåëîå ÷èñëî] öåëîå ÷àñòíîå öåëî÷èñëåííîãî äåëåíèÿ
imod[öåëîå ÷èñëî, öåëîå ÷èñëî] öåëîå îñòàòîê öåëî÷èñëåííîãî äåëåíèÿ
substr[ñòðîêà, öåëîå ÷èñëî, öåëîå ÷èñëî] ñòðîêà ïîäñòðîêà (ïåðâûé ïàðàìåòð – èñõîäíàÿ ñòðîêà, âòîðîé ïàðàìåòð – èíäåêñ ïåðâîãî ñèìâîëà, òðåòèé – äëèíà ïîäñòðîêè; åñëè ïðîèñõîäèò âûõîä çà ïðåäåëû èñõîäíîé ñòðîêè, òî îøèáêè íåò, íî äëèíà ðåçóëüòàòà – ìåíüøå óêàçàííîé â òðåòüåì ïàðàìåòðå)
strlen[ñòðîêà] öåëîå äëèíà ñòðîêè
strpos[ñòðîêà, ñòðîêà] öåëîå ïîçèöèÿ ïåðâîãî ñèìâîëà ïåðâîãî âõîæäåíèÿ âòîðîé ñòðîêè â ïåðâóþ, ëèáî -1, åñëè ñîâïàäåíèé íåò (íóìåðàöèÿ ñèìâîëîâ ñ íóëÿ)
toint[ïðîñòîé] öåëîå ïðåîáðàçîâàíèå ê öåëîìó (åñëè íåâîçìîæíî – âîçíèêàåò îøèáêà)
toreal[ïðîñòîé] âåùåñòâåííîå ïðåîáðàçîâàíèå ê âåùåñòâåííîìó (åñëè íåâîçìîæíî – âîçíèêàåò îøèáêà)
tostring[ëþáîé] ñòðîêà ïðåîáðàçîâàíèå ê ñòðîêå
issingle[ëþáîé] öåëîå (-1 èëè 1) ÿâëÿåòñÿ ëè çíà÷åíèå âûðàæåíèÿ íå ìàññèâîì
isarray[ëþáîé] ÿâëÿåòñÿ ëè çíà÷åíèå âûðàæåíèÿ ìàññèâîì
isstring[ëþáîé] ÿâëÿåòñÿ ëè çíà÷åíèå âûðàæåíèÿ ñòðîêîé
isnum[ëþáîé] ÿâëÿåòñÿ çíà÷åíèå âûðàæåíèÿ ÷èñëîì
isint[ëþáîé] ÿâëÿåòñÿ ëè çíà÷åíèå âûðàæåíèÿ öåëûì ÷èñëîì
isreal[ëþáîé] ÿâëÿåòñÿ ëè çíà÷åíèå âûðàæåíèÿ âåùåñòâåííûì ÷èñëîì
size[ìàññèâ] ÷èñëî ýëåìåíòîâ ìàññèâà
defined[ìàññèâ, öåëîå] îïðåäåëåí ëè â ìàññèâå ýëåìåíò ñ çàäàííûì èíäåêñîì
iff[ïðîñòîé, ëþáîé, ëþáîé] ëþáîé åñëè ïåðâûé ïàðàìåòð – èñòèíà, òî âîçâðàùàåò çíà÷åíèå âòîðîãî ïàðàìåòðà, èíà÷å - òðåòüåãî

Åñëè ïðè âûçîâå ñòàíäàðòíîé ôóíêöèè òèï õîòÿ áû îäíîãî èç ïàðàìåòðîâ íå ñîîòâåòñòâóåò òðåáóåìîìó, âîçíèêàåò îøèáêà.

Îïåðàòîð âûçîâà call ïîçâîëÿåò âû÷èñëèòü ëþáîå âûðàæåíèå, ïðîèãíîðèðîâàâ åãî çíà÷åíèå, íàïðèìåð, âûçâàòü ôóíêöèþ êàê ïðîöåäóðó. Îí èìååò ñèíòàêñèñ:

call <âûðàæåíèå>

Íàïðèìåð, call procedure1[param1, param2].

Îïåðàòîð ïðèñâàèâàíèÿ èìååò ñèíòàêñèñ <ïåðåìåííàÿ>:=<âûðàæåíèå> èëè <ìàññèâ>{<âûðàæåíèå-èíäåêñ>}:=<âûðàæåíèå>.

 ðåçóëüòàòå ïåðåìåííàÿ èëè ýëåìåíò ìàññèâà ïðèíèìàþò çíà÷åíèå, ðàâíîå çíà÷åíèþ âûðàæåíèÿ â ïðàâîé ÷àñòè îïåðàòîðà ïðèñâàèâàíèÿ, åñëè îíî áûëî âû÷èñëåíî êîððåêòíî.

 Óñëîâíûé îïåðàòîð èìååò âèä:

if <âûðàæåíèå>
                   [îïåðàòîðû]
         [elseif <âûðàæåíèå>]
                   [îïåðàòîðû]
         [elseif <âûðàæåíèå>]
         ...
         [else]
                   [îïåðàòîðû]
         endif

Ïîñëåäîâàòåëüíî ïðîâåðÿþòñÿ âûðàæåíèÿ-óñëîâèÿ â ñòðîêàõ ñ êëþ÷åâûìè ñëîâàìè if è elseif. Êàê òîëüêî ïîëó÷åíî èñòèííîå çíà÷åíèå óñëîâèÿ (ïîëîæèòåëüíîå ÷èñëî èëè íåïóñòàÿ ñòðîêà), òî âûïîëíÿþòñÿ îïåðàòîðû, ñëåäóþùèå çà ñòðîêîé ñ äàííûì óñëîâèåì, çàòåì âûïîëíåíèå ïåðåõîäèò íà ñòðîêó, ñëåäóþùóþ çà endif. Åñëè íè îäíî èç óñëîâèé íå îêàçàëîñü èñòèííûì, òî âûïîëíÿþòñÿ îïåðàòîðû, ðàñïîëîæåííûå ïîñëå else, åñëè ñòðîêà ñ else  èìååòñÿ â äàííîì óñëîâíîì îïåðàòîðå, èíà÷å óïðàâëåíèå ïåðåõîäèò íèæå endif. Óñëîâíûé îïåðàòîð ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèè. Ïðèìåðû:

         1.)

                   if a<0

                            a := abs[a]

                            flag := 1

                   endif

         2.)

                   if (ch=”a”)|(ch=”A”)

                            call proc_a[]

                   elseif (ch=”b”)|(ch=”B”)

                            call proc_b[]

                   elseif (ch=”c”)|(ch=”C”)

                            call proc_c[]

                  else

                            error

                   endif

Îïåðàòîð öèêëà while èìååò âèä:

         while <âûðàæåíèå>

                   [îïåðàòîðû]

         loop

Âûïîëíåíèå áëîêà îïåðàòîðîâ ïîâòîðÿåòñÿ, ïîêà èñòèííî çíà÷åíèå âûðàæåíèÿ-óñëîâèÿ, çàòåì óïðàâëåíèå ïåðåäàåòñÿ íà ñòðîêó, ñëåäóþùóþ çà loop. Ïðè ýòîì, åñëè çíà÷åíèå âûðàæåíèÿ èçíà÷àëüíî ëîæíî, òî îïåðàòîðû íå áóäóò âûïîëíåíû íè ðàçó. Îïåðàòîð öèêëà while ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèè. Ïðèìåð:

         i := 1

         s:=0

         while i<=n

                   s := s+i

                   i := i+1

         loop

Çäåñü ïåðåìåííàÿ s ïîëó÷àåò çíà÷åíèå ñóììû ÷èñåë îò 1 äî n.

Îïåðàòîð öèêëà for èìååò âèä:

         for <ïåðåìåííàÿ-ñ÷åò÷èê> := <âûðàæåíèå1> : <âûðàæåíèå2>

                   [îïåðàòîðû]

         next

 íà÷àëå âûïîëíåíèÿ öèêëà âû÷èñëÿþòñÿ âûðàæåíèå1 è âûðàæåíèå2 (èõ çíà÷åíèÿ äîëæíû áûòü öåëûìè, èíà÷å âîçíèêàåò îøèáêà), çàòåì ïåðåìåííîé-ñ÷åò÷èêó ïðèñâàèâàåòñÿ çíà÷åíèå âûðàæåíèå1 è, åñëè îíî ìåíüøå èëè ðàâíî çíà÷åíèþ âûðàæåíèå2, âûïîëíåíèå ïåðåõîäèò âíóòðü öèêëà, èíà÷å – çà ñòðîêó ñ êëþ÷åâûì ñëîâîì next. Ïîñëå êàæäîé èòåðàöèè öèêëà çíà÷åíèå ñ÷åò÷èêà óâåëè÷èâàåòñÿ íà åäèíèöó è ñðàâíèâàåòñÿ ñî çíà÷åíèåì âûðàæåíèå2 (îíî âû÷èñëÿåòñÿ òîëüêî îäèí ðàç â íà÷àëå), åñëè îíî îêàçûâàåòñÿ ìåíüøèì èëè ðàâíûì çíà÷åíèþ âûðàæåíèå2, òî âûïîëíÿåòñÿ ñëåäóþùàÿ èòåðàöèÿ öèêëà, èíà÷å – öèêë çàâåðøàåòñÿ. Çíà÷åíèå ñ÷åò÷èêà â öèêëå, â ïðèíöèïå, ìîæíî ìåíÿòü, íå åñëè îíî îêàæåòñÿ íå öåëûì íà ìîìåíò îêîí÷àíèÿ î÷åðåäíîé èòåðàöèè, âîçíèêàåò îøèáêà. Îïåðàòîð öèêëà for ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèè. Ïðèìåð:

         for i :=0 : size[a]

                   a{i} := a{i}*2

         next

Îïåðàòîð âîçâðàòà return íåçàìåäëèòåëüíî ïðåðûâàåò âûïîëíåíèå ôóíêöèè (ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèè). Íàïðèìåð,

         if a<b

                   result := 1

                   return

         endif

        

Åñëè ïðè âûïîëíåíèè ôóíêöèè íå âñòðåòèëñÿ îïåðàòîð return, âûõîä èç ôóíêöèè ïðîèñõîäèò êàê òîëüêî óïðàâëåíèå ïåðåõîäèò íèæå ïîñëåäíåé ñòðîêè ôóíêöèè.

Îïåðàòîð error ïðåðûâàåò âûïîëíåíèå ïðîãðàììû – èñêóññòâåííî ãåíåðèðóåòñÿ îøèáêà âðåìåíè âûïîëíåíèÿ. Îí ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèè.

Ïðèìåð:
         a:=toint[str]

         if a<0

                   error

         endif

Äëÿ âûâîäà äàííûõ èñïîëüçóþòñÿ îïåðàòîðû  print è println. Îïåðàòîð print èìååò ñèíòàêñèñ print <âûðàæåíèå>. Çíà÷åíèå âûðàæåíèÿ àâòîìàòè÷åñêè ïðèâîäèòñÿ ê ñòðîêå (ò. å.êîìàíäû println[a] è println[tostring[a]] – ðàâíîñèëüíû). Ýòà ñòðîêà âûâîäèòñÿ íà êîíñîëü. Îïåðàòîð println èìååò àíàëîãè÷íûé ñèíòàêñèñ è íàçíà÷åíèå. Îòëè÷èå çàêëþ÷àåòñÿ â òîì, ÷òî println ïðîèçâîäèò ïåðåâîä íà íîâóþ ñòðîêó ïîñëå âûâîäà, print – íåò. Êðîìå òîãî, åñëè ïðè ðàáîòå â êîíñîëè  ââåäåíî âûðàæåíèå áåç êëþ÷åâûõ ñëîâ è îïåðàòîðà ïðèñâàèâàíèÿ, òî ðåçóëüòàò åãî âû÷èñëåíèÿ âûâîäèòñÿ íà êîíñîëü â îòäåëüíîé ñòðîêå - ýòî ñîêðàùåííàÿ ôîðìà îïåðàòîðà println.

Îïåðàòîð clear ïîçâîëÿåò óäàëèòü ïåðåìåííóþ èç ïàìÿòè, íàïðèìåð, êîìàíäà “clear n” óäàëÿåò èç ïàìÿòè ïåðåìåííóþ n, ïîñëå ÷åãî îíà ñ÷èòàåòñÿ íåîïðåäåëåííîé. Óäàëèòü îòäåëüíûå ýëåìåíòû ìàññèâà íåëüçÿ. Âûïîëíåíèå îïåðàòîðà clear íàä íåîïðåäåëåííîé ïåðåìåííîé íå èìååò íèêàêîãî ýôôåêòà è íå ïðèâîäèò ê îøèáêå. Ñ ïîìîùüþ îïåðàòîðà clear ìîæíî òàêæå óäàëèòü ôàêòè÷åñêèå ïàðàìåòðû ôóíêöèè è äàæå ïåðåìåííóþ result, ÷òî íåîáõîäèìî ïåðåä ðàáîòîé ñ íåé êàê ñ ìàññèâîì. Íî åñëè ïåðåìåííàÿ result íå îïðåäåëåíà íà ìîìåíò âûõîäà èç ôóíêöèè, òî âîçíèêàåò îøèáêà âðåìåíè âûïîëíåíèÿ. Ñèíòàêñèñ îïåðàòîðà clear èìååò âèä:

clear <èìÿ_ïåðåìåííîé1>


Ïðèìåðû ïîëüçîâàòåëüñêèõ ôóíêöèé

1. Ñîðòèðîâêà ìàññèâà.

sort [a]

#ñîðòèðóåò ìàññèâ à ïî âîçðàñòàíèþ.

#ìåòîäîì ïðÿìîãî âûáîðà

if ~isarray[a]

         println “Invalid argument”

         error

endif

 

n:=size[a]

 

for i:=0:n-2

         k:=i

         for j:=i+1:n-1

                   k:=iff[a{j}<a{k}, j, k]

         next

         if i<>k

                   t:=a{i}

                   a{i}:=a{k}

                   a{k}:=t

         endif

next

 

result:=a

2. Âû÷èñëåíèå ÍÎÄ ïî àëãîðèòìó Åâêëèäà

nod [n,m]

#âû÷èñëÿåò íàèìåíüøèé îáùèé äåëèòåëü

#íàòóðàëüíûõ ÷èñåë n è m

#ïî àëãîðèòìó Åâêëèäà

if ~isint[n]|~isint[m]

         println "Invalid arguments"

         error

endif

if (n<0)|(m<0)

         println "Invalid arguments"

         error

endif

 

if n=0

         result:=m

         return

endif

if m=0

         result:=n

         return

endif

 

while m>0

         t:=n

         n:=m

         m:=imod[t,m]

loop

 

result:=n

3. Ðåêóðñèâíîå âû÷èñëåíèå ôàêòîðèàëà.

factor [n]

#ðåêóðñèâíîå âû÷èñëåíèå ôàêòîðèàëà ÷èñëà n

 

if ~isint[n]

         println "Invalid argument"

         error

elseif n<0

         println "Invalid argument"

         error

elseif (n=0)|(n=1)

         result:=1

else

         result:=n*factor[n-1]

endif

4. Ïðîâåðêà, ÿâëÿåòñÿ ëè ñòðîêà êîððåêòíûì èäåíòèôèêàòîðîì.

test_d [str]

#âîçâðàùàåò 1, åñëè ñòðîêà ÿâëÿåòñÿ êîððåêòíûì

#èäåíòèôèêàòîðîì, òî åñòü ñîñòîèò òîëüêî èç

#áóêâ, öèôð, çíàêîâ ïîä÷åðêèâàíèÿ è íà÷èíàåòñÿ

#c öèôðû, ïðè ýòîì èìååò íåíóëåâóþ äëèíó,

#è -1 â ïðîòèâíîì ñëó÷àå

 

if ~isstring[str]

         println "Invalid argument"

         error

endif

n:=strlen[str]

if n=0

         result:=-1

         return

endif

 

ch:=substr[str,0,1]

if (ch>="0")&(ch<="9")

         result:=-1

         return

endif

 

for i:=0:n-1

         ch:=substr[str,i,1]

         if ~(((ch>="0")&(ch<="9"))|((ch>="A")&(ch<="Z"))|((ch>="a")&(ch<="z"))|(ch="_"))

                   result:=-1

                   return

         endif

next

 

result:=1

5. Âû÷èñëåíèå óãëà òðåóãîëüíèêà ïî òðåì ñòîðîíàì.

angle [a,b,c]

#âû÷èñëÿåò óãîë òðåóãîëüíèêà ñî ñòîðîíàìè

#a, b è c ìåæäó ñòîðîíàìè a è b (â ãðàäóñàõ)

if ~isnum[a]|~isnum[b]|~isnum[c]

         println "Invalid arguments"

         error

endif

 

if (a<=0)|(b<=0)|(c<=0)

         println "Not a triangle"

         error

endif

 

cos_alpha:=(a*a+b*b-c*c)/(2*a*b)

if (cos_alpha>=1)|(cos_alpha<=-1)

         println "Not a triangle"

         error

endif

 

alpha:=arccos[cos_alpha]

result:=alpha*180/pi[]


Ïðîåêòèðîâàíèå è ðåàëèçàöèÿ  ïðîãðàììû-èíòåðïðåòàòîðà

Äëÿ ðåàëèçàöèè èíòåðïðåòàòîðà áûëî ðåøåíî èñïîëüçîâàòü ïëàòôîðìó Microsoft .NET v.1.1 è ÿçûê ïðîãðàììèðîâàíèÿ C#. Ýòî ñâÿçàíî ñ òåì, ÷òî ïëàòôîðìà .NET îáåñïå÷èâàåò äîñòàòî÷íî âûñîêóþ ïðîèçâîäèòåëüíîñòü (áûñòðîäåéñòâèå) ïðèëîæåíèé ïðè çíà÷èòåëüíîì óâåëè÷åíèè ñêîðîñòè ðàçðàáîòêè. Ïîñëåäíåå îáåñïå÷èâàåòñÿ çà ñ÷åò íàëè÷èÿ óäîáíûõ âèçóàëüíûõ ñðåäñòâ ðàçðàáîòêè, îáøèðíîé è ìîùíîé ñòàíäàðòíîé áèáëèîòåêè êëàññîâ, èñïîëüçîâàíèÿ àâòîìàòè÷åñêîé ñáîðêè ìóñîðà, êîãäà ïàìÿòü èç-ïîä áîëåå íåèñïîëüçóåìûõ îáúåêòîâ îñâîáîæäàåòñÿ àâòîìàòè÷åñêè. ßçûê C# æå ÿâëÿåòñÿ îñíîâíûì ÿçûêîì ïëàòôîðìû .NET, ïîçâîëÿþùèì ïîëíîñòüþ èñïîëüçîâàòü âñå ïðåèìóùåñòâà òåõíîëîãèè Microsoft .NET, îí èìååò âåñüìà ãèáêèé ñèíòàêñèñ, ïîçâîëÿþùèé ðåàëèçîâûâàòü äîñòàòî÷íî ñëîæíûå àëãîðèòìû ñðàâíèòåëüíî íåáîëüøèìè, íî ëåãêî ÷èòàåìûìè ôðàãìåíòàìè êîäà.

 ïðîãðàììå ìîæíî âûäåëèòü äâå îñíîâíûå ãðóïïû êëàññîâ, äâå ïîäñèñòåìû, îòâåòñòâåííûå çà ëîãèêó ðàáîòû èíòåðïðåòàòîðà è ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ ñîîòâåòñòâåííî. Ïîñêîëüêó ïåðâàÿ ïîäñèñòåìà ñîäåðæèò çíà÷èòåëüíî áîëüøåå ÷èñëî êëàññîâ, ÷åì âòîðàÿ, áûëî ðåøåíî ðàñïîëîæèòü åå â îòäåëüíîì ïðîñòðàíñòâå èìåí logic, âëîæåííîì â êîðíåâîå ïðîñòðàíñòâî èìåí ïðîåêòà. Êëàññû, îòâåòñòâåííûå çà ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ, ðàñïîëîæåíû íåïîñðåäñòâåííî â êîðíåâîì ïðîñòðàíñòâå èìåí ïðîåêòà. Êðîìå òîãî, â ïðîñòðàíñòâå èìåí logic èìååòñÿ äâà âëîæåííûõ ïðîñòðàíñòâà èìåí – operators è vartypes, ñîîòâåòñòâóþùèå äâóì îñíîâíûì èåðàðõèÿì íàñëåäîâàíèÿ â ïðîåêòå – îïåðàòîðàì ïðîãðàììû è òèïàì äàííûõ. Êîðíåâîå ïðîñòðàíñòâî èìåí èìååò èìÿ interpr. Äèàãðàììà ïàêåòîâ ïðîåêòà èçîáðàæåíà íà ðèñ. 1.


        

Ðîëü ïîñðåäíèêà ìåæäó ïîëüçîâàòåëüñêèì èíòåðôåéñîì è ïîäñèñòåìîé, ðåàëèçóþùåé ëîãèêó ðàáîòû èíòåðïðåòàòîðà, âûïîëíÿåò êëàññ Facade (ôàñàä).  Îí òàêæå îòâåòñòâåíåí çà ñîçäàíèå îòäåëüíîãî ïîòîêà äëÿ âûïîëíåíèÿ êîìàíä ïîëüçîâàòåëÿ (ââîäèìûõ ñ êîíñîëè). Âûïîëíÿòü èõ â òîì æå ïîòîêå, ÷òî è îáðàáàòûâàòü ñîîáùåíèÿ ïîëüçîâàòåëüñêîãî èíòåðôåéñà íåëüçÿ òàê êàê â ýòîì ñëó÷àå çàöèêëèâøóþñÿ ïîëüçîâàòåëüñêóþ ôóíêöèþ áóäåò íåâîçìîæíî ïðåðâàòü. Ìíîãèå ìåòîäû êëàññà Facade ñâîäÿòñÿ ê ïðîñòîìó âûçîâó ìåòîäîâ äðóãèõ êëàññîâ èç ïðîñòðàíñòâà èìåí logic. Ýòîò êëàññ â äàëüíåéøåì áóäåò ðàññìîòðåí áîëåå ïîäðîáíî.

Äëÿ îáðàáîòêè îøèáîê ïðèìåíÿåòñÿ ìåõàíèçì ñòðóêòóðíîé îáðàáîòêè èñêëþ÷åíèé. Ïðè ýòîì èñïîëüçóþòñÿ ñëåäóþùèå êëàññû ïîëüçîâàòåëüñêèõ èñêëþ÷åíèé (äëÿ îøèáîê â êëàññàõ ïðîñòðàíñòâà èìåí interpr.logic):

·          CalcException – îøèáêà ïî âèíå ïîëüçîâàòåëÿ (ñèíòàêñè÷åñêàÿ èëè â âû÷èñëåíèÿõ);

·          SyntaxErrorException – ñèíòàêñè÷åñêàÿ îøèáêà, îáíàðóæèâàåìàÿ âî âðåìÿ «êîìïèëÿöèè», ò. å. ïðè çàãðóçêè ôóíêöèè èëè ïðåîáðàçîâàíèÿ ââåäåííîé êîìàíäû âî âíóòðåííèé ôîðìàò. Óíàñëåäîâàí îò CalcException;

·          LineSyntaxException – ñèíòàêñè÷åñêàÿ îøèáêà â êîíêðåòíîì îïåðàòîðå ôóíêöèè. Ñîäåðæèò èíôîðìàöèþ îá ìåñòå îáíàðóæåíèÿ (èìÿ ôóíêöèè, ñòðîêà).

·          OtherException – îøèáêè, ñâÿçàííûå ñ íåêîððåêòíîé ðàáîòîé èíòåðïðåòàòîðà íå ïî âèíå ïîëüçîâàòåëÿ. Êëàññ èñïîëüçóåòñÿ äëÿ îòëàäî÷íûõ öåëåé. Ïðè íîðìàëüíîé ðàáîòå òàêîå èñêëþ÷åíèå íèêîãäà íå äîëæíî ãåíåðèðîâàòüñÿ.

·          LinkedListException – îøèáêà â ìåòîäàõ êëàññà LinkedList. Óíàñëåäîâàí îò êëàññà OtherException.

·          NamespaceSerializationException – óíàñëåäîâàí íåïîñðåäñòâåííî îò System.Exception. Òàêîå èñêëþ÷åíèå – ãåíåðèðóåòñÿ åñëè ïðîñòðàíñòâî èìåí êîíñîëè íå ìîæåò áûòü óñïåøíî âîññòàíîâëåíî.

Ñîîòâåòñòâóþùàÿ äèàãðàììà êëàññîâ èçîáðàæåíà íà ðèñ. 2.


Ìîæíî âûäåëèòü íåñêîëüêî ãðóïï êëàññîâ â ïðîñòðàíñòâå èìåí interpr.logic – êëàññû, îòâåòñòâåííûå çà âû÷èñëåíèå âûðàæåíèé, çà âûïîëíåíèå ïîëüçîâàòåëüñêèõ ôóíêöèé, çà ïðåîáðàçîâàíèå òåêñòà êîìàíä è ïîëüçîâàòåëüñêèõ ôóíêöèé âî âíóòðåííèé ôîðìàò («êîìïèëÿöèþ» òåêñòà ïðîãðàììû), êëàññû, ó÷àñòâóþùèå â îðãàíèçàöèè èíòåðàêòèâíîé ðàáîòû èíòåðïðåòàòîðà. Ýòè ãðóïïû êëàññîâ, ðàâíî êàê è ïîäñèñòåìà ãðàôè÷åñêîãî èíòåðôåéñà ïîëüçîâàòåëÿ, áóäóò ðàññìîòðåíû íèæå.  ïðîñòðàíñòâå èìåí interpr.logic òàêæå èìååòñÿ îäèí êëàññ âñïîìîãàòåëüíîãî íàçíà÷åíèÿ – LinkedList. Îí ïðåäñòàâëÿåò äâóõñâÿçíûé ñïèñîê.  íåì èìåþòñÿ ìåòîäû è ñâîéñòâà äîáàâëåíèÿ è ÷òåíèÿ ýëåìåíòîâ â íà÷àëå è êîíöå ñïèñêà, îïðåäåëåíèÿ ÷èñëà ýëåìåíòîâ ñïèñêà. Ïðè ýòîì, ïðè ïîïûòêå ÷òåíèÿ èç ïóñòîãî ñïèñêà, ãåíåðèðóåòñÿ èñêëþ÷åíèåLinkedListException. Ìåòîä GetIterator(), ñóùåñòâóþùèé â äâóõ ïåðåãðóæåííûõ âåðñèÿõ (äëÿ ïåðâîãî ýëåìåíòà ñïèñêà è äëÿ çàäàííîãî èíäåêñà), âîçâðàùàåò îáúåêò âëîæåííîãî êëàññà LinkedList.Iterator, êîòîðûé ïðåäñòàâëÿåò ñîáîé èòåðàòîð, ïîçâîëÿþùèé ÷èòàòü ýëåìåíòû ñïèñêà, ïåðåìåùàÿñü ïî íåìó îò íà÷àëà ê êîíöó, à òàêæå äâèãàòüñÿ â îáðàòíîì íàïðàâëåíèè. Ýëåìåíò ñïèñêà ïðåäñòàâëÿåòñÿ îáúåêòîì ÷àñòíîãî âëîæåííîãî êëàññà Link, ñîäåðæàùåãî òðè ïîëÿ ñ âèäèìîñòüþ internal – îäíî äëÿ õðàíåíèÿ çíà÷åíèÿ ýëåìåíòà ñïèñêà è äâà äëÿ ññûëîê íà ïðåäûäóùèé è ñëåäóþùèé ýëåìåíòû.

Ñëåäóåò òàêæå îòìåòèòü èíòåðôåéñ interpr.logic.IConsole, ïðåäñòàâëÿþùèé íå÷òî, ÷òî ìîæåò áûòü èñïîëüçîâàíî äëÿ âûâîäà òåêñòà. Îí èìååò äâà ìåòîäà - void Print(string str) è void PrintLn(string str), íàçíà÷åíèå êîòîðûõ ïîíÿòíî èç íàçâàíèÿ.

Îñíîâíûå êëàññû ïðîñòðàíñòâà èìåí interpr.logic ïîêàçàíû íà äèàãðàììå íà ðèñ. 3.



Ðèñ. 3.

Êëàññû ïðîñòðàíñòâà èìåí interpr.logic.

Âíóòðåííåå ïðåäñòàâëåíèå è âûïîëíåíèå ïðîãðàììû.

Áîëüøèíñòâî îïåðàòîðîâ ðåàëèçîâàííîãî ÿçûêà ïðîãðàììèðîâàíèÿ ñîäåðæàò âûðàæåíèÿ. Âûðàæåíèå ïðåäñòàâëÿåò ñîáîé ñîâîêóïíîñòü îïåðàíäîâ è îïåðàöèé íàä íèìè, êîòîðàÿ ìîæåò áûòü âû÷èñëåíà, òî åñòü íà îñíîâàíèè êîòîðîé ìîæíî ïîëó÷èòü íåêîòîðîå çíà÷åíèå-ðåçóëüòàò.  ÿçûêå ïðîãðàììèðîâàíèÿ âûðàæåíèÿ ïðåäñòàâëÿþòñÿ ïîñòðîåííûìè ïî îïðåäåëåííûì òðåáîâàíèÿì ñòðîêàìè. Ïðè îáðàáîòêå òåêñòà ïðîãðàììû (ýòîò ïðîöåññ áóäåò ðàññìîòðåí â ñëåäóþùåì ïàðàãðàôå) ñòðîêîâîå ïðåäñòàâëåíèå âûðàæåíèé ïåðåâîäèòñÿ â ïðåäñòàâëåíèå âíóòðåííåå.  äàííîì èíòåðïðåòàòîðå âíóòðåííåå ïðåäñòàâëåíèå âûðàæåíèé èñïîëüçóåò òàê íàçûâàåìóþ îáðàòíóþ ïîëüñêóþ çàïèñü (ÎÏÇ). Ðàññìîòðèì ÎÏÇ ïîäðîáíåå.

Îáû÷íàÿ ìàòåìàòè÷åñêàÿ çàïèñü àðèôìåòè÷åñêèõ âûðàæåíèé ïðåäñòàâëÿåò ñîáîé òàê íàçûâàåìóþ èíôèêñíóþ çàïèñü, â êîòîðîé çíàêè îïåðàöèé ðàñïîëàãàþòñÿ ìåæäó îïåðàíäàìè. Ïðè ýòîì äëÿ óòî÷íåíèÿ ïîðÿäêà âû÷èñëåíèÿ îïåðàöèé èñïîëüçóþòñÿ ïðèîðèòåòû îïåðàöèé è êðóãëûå ñêîáêè. Òàêàÿ ôîðìà çàïèñè óäîáíà äëÿ ÷åëîâåêà, íî íåóäîáíà äëÿ ÝÂÌ. Ïîýòîìó ÷àñòî èñïîëüçóþò òàê íàçûâàåìóþ ïîñòôèêñíóþ èëè îáðàòíóþ ïîëüñêóþ çàïèñü.  ýòîì ñëó÷àå çíàê îïåðàöèè çàïèñûâàþòñÿ ïîñëå âñåõ åå îïåðàíäîâ, à âû÷èñëåíèå ïðîèçâîäèòñÿ ïî äîâîëüíî ïðîñòîìó àëãîðèòìó: âûðàæåíèå â ÎÏÇ ïîñëåäîâàòåëüíî ïðîñìàòðèâàåì ñëåâà íàïðàâî. Åñëè âñòðå÷àåì îïåðàíä, òî çàíîñèì åãî â ñòåê, åñëè æå âñòðå÷àåì îïåðàöèþ, òî âûáèðàåì åå îïåðàíäû èç ñòåêà, âûïîëíÿåì îïåðàöèþ è çàíîñèì ðåçóëüòàò â ñòåê.  íà÷àëå âû÷èñëåíèÿ âûðàæåíèÿ ñòåê ïóñò. Åñëè âûðàæåíèå çàïèñàíî êîððåêòíî, òî ïðè âûïîëíåíèè êàæäîé îïåðàöèè ÷èñëî ýëåìåíòîâ ñòåêà áóäåò íå ìåíüøå ÷èñëà åå îïåðàíäîâ, è â êîíöå ïðîöåññà â ñòåêå îñòàíåòñÿ ðîâíî îäíî çíà÷åíèå – ðåçóëüòàò âû÷èñëåíèÿ âûðàæåíèÿ. Îñîáåííîñòüþ ÎÏÇ ÿâëÿåòñÿ îòñóòñòâèå íåîáõîäèìîñòè â èñïîëüçîâàíèè ñêîáîê.

Íàïðèìåð, âûðàæåíèå a+(b*c-d)/e â ÎÏÇ èìååò âèä abc*d-e/+. Ïðèìåíèì ê íåìó îïèñàííûé âûøå àëãîðèòì âû÷èñëåíèÿ.

1. Çàíîñèì â ñòåê a.

2. Çàíîñèì â ñòåê b.

3. Çàíîñèì â ñòåê c.

Ñîñòîÿíèå ñòåêà íà ýòîò ìîìåíò: a, b, c – âåðøèíà.

4. Èçâëåêàåì èç ñòåêà îïåðàíäû îïåðàöèè óìíîæåíèÿ – b è c è çàíîñèì â ñòåê ðåçóëüòàò.

Ñòåê: a, b*c.

5. Çàíîñèì â ñòåê d.

Ñòåê:  a, b*c, d.

6. Èçâëåêàåì èç ñòåêà îïåðàíäû, ïðîèçâîäèì âû÷èòàíèå, çàíîñèì â ñòåê ðåçóëüòàò.

Ñòåê: a, b*c-d.

7. Çàíîñèì â ñòåê e.

Ñòåê: a, b*c-d, e.

8. Èçâëåêàåì èç ñòåêà îïåðàíäû, ïðîèçâîäèì äåëåíèå, çàíîñèì â ñòåê ðåçóëüòàò.

Ñòåê: a, (b*c-d)/e.

9. Èçâëåêàåì èç ñòåêà îïåðàíäû, ïðîèçâîäèì ñëîæåíèå, çàíîñèì â ñòåê ðåçóëüòàò.

Èòîãî ïîëó÷àåì â ñòåêå a+(b*c-d)/e, ÷òî è òðåáîâàëîñü.

Äëÿ ïðåäñòàâëåíèÿ âûðàæåíèé â èíòåðïðåòàòîðå èñïîëüçóåòñÿ êëàññ Expression. Îí ñîäåðæèò îáðàòíóþ ïîëüñêóþ çàïèñü âûðàæåíèÿ â âèäå ñâÿçàííîãî ñïèñêà (îäíîíàïðàâëåííîãî). Çâåíî ýòîãî ñïèñêà, ðàâíî êàê è ñòåêà, èñïîëüçóåìîãî ïðè âû÷èñëåíèè âûðàæåíèÿ, ïðåäñòàâëÿåòñÿ îáúåêòîì âëîæåííîãî êëàññà Expression.Element, ñîäåðæàùèì ññûëêè íà ñëåäóþùåå çâåíî è íà îáúåêò, ðåàëèçóþùèé èíòåðôåéñ IComputable, êîòîðûé ñîäåðæèò îäèí ìåòîä logic.vartypes.VarBase Compute() – ïîëó÷èòü çíà÷åíèå. Âû÷èñëåíèå çíà÷åíèÿ âûðàæåíèÿ ïî ðàññìîòðåííîì âûøå àëãîðèòìó ïðîèçâîäèòñÿ â ìåòîäå VarBase Expression.Calculate(). Ñòðîêà, ñîäåðæàùàÿ çàïèñü âûðàæåíèÿ, îáðàáàòûâàåòñÿ â êîíñòðóêòîðå ýòîãî êëàññà. Èíòåðôåéñ IComputable ðåàëèçîâàí òðåìÿ êëàññàìè:

·     VarBase – àáñòðàêòíûé êëàññ, ïðåäñòàâëÿþùèé çíà÷åíèå ëþáîãî òèïà äàííûõ;

·     VarName – ïðåäñòàâëÿåò ïåðåìåííóþ ïî åå èìåíè;

·     Call – ïðåäñòàâëÿåò âûçîâ îïåðàöèè ëèáî ôóíêöèè.

Âíà÷àëå ðàññìîòðèì êëàññû, ïðåäñòàâëÿþùèå çíà÷åíèÿ ðàçëè÷íûõ òèïîâ. Âñå îíè ÿâëÿþòñÿ ïîòîìêàìè òîëüêî ÷òî íàçâàííîãî êëàññà VarBase. Êàê áûëî ñêàçàíî âûøå, â ÿçûêå ñóùåñòâóåò ÷åòûðå òèïà äàííûõ – öåëîå ÷èñëî, âåùåñòâåííîå ÷èñëî, ñòðîêà è ìàññèâ. Ïðè ýòîì ÷èñëîâûå è ñòðîêîâûé òèïû, â ïðîòèâîïîëîæíîñòü ìàññèâó, íàçûâàþòñÿ ïðîñòûìè òèïàìè. Äëÿ ïðîñòûõ çíà÷åíèé áàçîâûì ÿâëÿåòñÿ àáñòðàêòíûé êëàññ SingleVar. Öåëûé è âåùåñòâåííûé òèïû òàêæå îñîáî âûäåëÿþòñÿ êàê ÷èñëîâûå, è äëÿ íèõ ñóùåñòâóåò ñâîé áàçîâûé àáñòðàêòíûé êëàññ NumVar. Íàêîíåö, êàæäîìó èç ÷åòûðåõ òèïîâ äàííûõ ñîîòâåòñòâóåò ñâîé êîíêðåòíûé êëàññ – IntVar, RealVar, StringVar è ArrayVar. Ýòà èåðàðõèÿ êëàññîâ íàõîäèòñÿ â ïðîñòðàíñòâå èìåí interpr.logic.vartypes. Îíà èçîáðàæåíà íà äèàãðàììå íà ðèñ. 4.


Ðèñ. 4.

Êëàññû ïðîñòðàíñòâà èìåí interpr.logic.vartypes.

 

Ìåòîä Compute() êëàññà VarBase ïðîñòî âîçâðàùàåò ññûëêó this. Ìåòîäû IsArray(), IsSingle(), IsString(), IsNum(), IsInt(), IsReal()  ïîçâîëÿþò îïðåäåëèòü òèï çíà÷åíèÿ. Îíè èñïîëüçóþò îïåðàòîð RTTI is ÿçûêà C#.  êëàññå VarBase îáúÿâëåíû àáñòðàêòíûìè óíàñëåäîâàííûå îò System.Object ìåòîäû Clone() è ToString(), ÷òî òðåáóåò îáÿçàòåëüíîãî èõ ïåðåîïðåäåëåíèÿ ó íåàáñòðàêòíûõ ïîòîìêîâ. Àáñòðàêòíûé ìåòîä Serialise() ñîõðàíÿåò îáúåêò (çíà÷åíèå è åãî òèï) â ôàéëå. Êëàññ ArrayVar èìååò ìåòîäû äëÿ ïðèñâîåíèÿ è ïîëó÷åíèÿ çíà÷åíèé îòäåëüíûõ ýëåìåíòîâ ìàññèâà, ïîëó÷åíèÿ ðàçìåðà ìàññèâà, âûÿñíåíèÿ âîïðîñà, îïðåäåëåíî ëè çíà÷åíèå ýëåìåíòà ìàññèâà ñ çàäàííûì èíäåêñîì. Êëàññ SingleVar îïðåäåëÿåò àáñòðàêòíûé ìåòîä ToBool(), âîçâðàùàþùèé ëîãè÷åñêîå çíà÷åíèå îáúåêòà.  êëàññå NumVar òàêæå èìååòñÿ àáñòðàêòíûé ìåòîä ToDouble(), âîçâðàùàþùèé çíà÷åíèå îáúåêòà êàê âåùåñòâåííîå ÷èñëî. Ýòè êëàññû è èõ ïîòîìêè ñîäåðæàò òàêæå ìåòîäû äëÿ âûïîëíåíèÿ íàä çíà÷åíèÿìè àðèôìåòè÷åñêèõ è ëîãè÷åñêèõ îïåðàöèé.

 âèäå îáúåêòîâ êëàññîâ, ïðîèçâîäíûõ îò VarBase, â âûðàæåíèÿõ (ýêçåìïëÿðàõ êëàññà Expression), õðàíÿòñÿ òîëüêî êîíñòàíòíûå çíà÷åíèÿ. Ïåðåìåííûå æå ïðåäñòàâëÿþòñÿ çäåñü îáúåêòàìè êëàññà VarName, ñîäåðæàùèìè èìÿ (èäåíòèôèêàòîð) ïåðåìåííîé. Ñàìè æå çíà÷åíèÿ ïåðåìåííûõ õðàíÿòñÿ â îáúåêòàõ êëàññà Namespace èëè ïðîèçâîäíîãî îò íåãî ConsoleNamespace.

Êëàññ Namespace ïðåäñòàâëÿåò ïðîñòðàíñòâî èìåí (îáëàñòü âèäèìîñòè) ïîëüçîâàòåëüñêîé ôóíêöèè, êëàññ ConsoleNamespace – ñðåäû êîíñîëè. Ïðè ðàáîòå èíòåðïðåòàòîðà ñîçäàåòñÿ ñòåê ïðîñòðàíñòâ èìåí (îáëàñòåé âèäèìîñòè), íà âåðøèíå êîòîðîãî íàõîäèòñÿ ïðîñòðàíñòâî èìåí âûïîëíÿåìîé â äàííûé ìîìåíò ôóíêöèè, íà äíå – ñðåäû êîíñîëè. Êàæäûé ðàç ïðè âûçîâå ôóíêöèè ñîçäàåòñÿ è äîáàâëÿåòñÿ íà âåðøèíó ñòåêà íîâûé îáúåêò Namespace, ïðè âûõîäå èç ôóíêöèè îí óíè÷òîæàåòñÿ. Êëàññ Namespace èìååò ïîëå, ñîäåðæàùåå ññûëêó íà ïðåäûäóùèé ýëåìåíò ñòåêà, ó íàõîäÿùåãîñÿ íà äíå ñòåêà îáúåêòà ConsoleNamespace îíî âñåãäà ñîäåðæèò íóëåâîé óêàçàòåëü.

Ññûëêè íà âåðøèíó è íà äíî ñòåêà ïðîñòðàíñòâ èìåí õðàíÿòñÿ â ïîëÿõ êëàññà InterprEnvironment. Äîñòóï ê òåêóùåìó ïðîñòðàíñòâó èìåí îñóùåñòâëÿåòñÿ ÷åðåç åãî ñâîéñòâî CurrentNamespace. Äëÿ ýòîãî êëàññà ïðè çàïóñêå èíòåðïðåòàòîðà ñîçäàåòñÿ åäèíñòâåííûé îáúåêò, õðàíÿùèéñÿ â åãî ñòàòè÷åñêîì ïîëå è âîçâðàùàåìûé ñòàòè÷åñêèì ñâîéñòâîì òîëüêî äëÿ ÷òåíèÿ Instance. Òàêèì îáðàçîì, çäåñü èñïîëüçîâàí ïàòòåðí Singleton. Êëàññ InterprEnvironment âûïîëíÿåò íåñêîëüêî ðàçëè÷íûõ ôóíêöèé. Ñðåäè íèõ, âî-ïåðâûõ, õðàíåíèå ññûëêè íà îáúåêò IConsole, ñ ïîìîùüþ êîòîðîãî ïðîèçâîäèòñÿ âûâîä. Âî-âòîðûõ – ðàáîòà ñ ïåðåìåííûìè ñðåäû êîíñîëè – èõ ñîõðàíåíèå â ôàéëå, âîññòàíîâëåíèå èç ôàéëà (ïðîèçâîäèòñÿ âî âðåìÿ èíèöèàëèçàöèè îáúåêòà ïðè çàïóñêå èëè ïåðåçàïóñêå èíòåðïðåòàòîðà), ïîëó÷åíèå èõ ñïèñêà. Â-òðåòüèõ – çàãðóçêà è õðàíåíèå ïîëüçîâàòåëüñêèõ ôóíêöèé. Ïîñëåäíÿÿ ôóíêöèÿ áóäåò ðàññìîòðåíà ïîäðîáíåå íèæå.

Ïîñëåäíèé èç êëàññîâ, ðåàëèçóþùèõ èíòåðôåéñ IComputable, – êëàññ Call  ïðåäñòàâëÿåò âûçîâ îïåðàöèè, âñòðîåííîé èëè ïîëüçîâàòåëüñêîé ôóíêöèè â âûðàæåíèè. Îí èìååò äâà ïîëÿ. Ïåðâîå èç íèõ õðàíèò ññûëêó íà îáúåêò êëàññà ArgList, êîòîðûé ñîäåðæèò ñïèñîê îïåðàíäîâ. Îíî èíèöèàëèçèðóåòñÿ ìåòîäîì SetArgList() ïðè êàæäîì âûïîëíåíèè îïåðàöèè èëè ôóíêöèè. Âòîðîå ïîëå ñîäåðæèò ññûëêó íà àáñòðàêòíûé êëàññ Operation, êîòîðûé è ïðåäñòàâëÿåò îïåðàöèþ èëè ôóíêöèþ. Ýòîò êëàññ ñîäåðæèò àáñòðàêòíîå ñâîéñòâî òîëüêî äëÿ ÷òåíèÿ ReqCount, âîçâðàùàþùåå íåîáõîäèìîå ÷èñëî îïåðàíäîâ (àðãóìåíòîâ). Ê ýòîìó ñâîéñòâó îáðàùàåòñÿ ñâîéñòâî êëàññà Call ñ òàêèì æå èìåíåì. Âòîðîé àáñòðàêòíûé ÷ëåí êëàññà Operation, ìåòîä VarBase Perform(ArgList al), âûïîëíÿåò îïåðàöèþ (ôóíêöèþ) íàä àðãóìåíòàìè, ñîäåðæàùèìèñÿ â îáúåêòå ArgList, ïåðåäàâàåìûìè â êà÷åñòâå ïàðàìåòðîâ. Ýòîò ìåòîä âîçâðàùàåò çíà÷åíèå, ÿâëÿþùååñÿ ðåçóëüòàòîì îïåðàöèè (ôóíêöèè). Íèêàêîãî àíàëîãà òèïà void íå ïðåäóñìîòðåíî – îïåðàöèÿ (ôóíêöèÿ) ìîæåò íå âåðíóòü òî èëè èíîå çíà÷åíèå ëèøü â ñëó÷àå îøèáêè. Îò êëàññà Operation óíàñëåäîâàí êëàññ SubName, ïðåäñòàâëÿþùèé ïîëüçîâàòåëüñêóþ ôóíêöèþ ïî åå èìåíè, è ìíîãî÷èñëåííûå êëàññû, ïðåäñòàâëÿþùèå ñòàíäàðòíûå îïåðàöèè è âñòðîåííûå ôóíêöèè. Ïîñëåäíèå ÿâëÿþòñÿ âëîæåííûìè â ñàì êëàññ Operation, ïðèòîì èìåþò ñïåöèôèêàòîð äîñòóïà private. Äëÿ êàæäîãî èç íèõ â êëàññå Operation èìååòñÿ îòêðûòîå ñòàòè÷åñêîå ïîëå òîëüêî äëÿ ÷òåíèÿ, èíèöèàëèçèðóþùååñÿ îáúåêòîì ñîîòâåòñòâóþùåãî òèïà. Ñîçäàíèå äðóãèõ îáúåêòîâ ýòèõ âëîæåííûõ êëàññîâ íåâîçìîæíî. Çäåñü òàêæå èñïîëüçîâàí ïàòòåðí Singleton. Êðîìå òîãî, ìîæíî ãîâîðèòü î ïðèìåíåíèè ïàòòåðíà Strategy – îáúåêò êëàññà Call (êîíòåêñò) êîíôèãóðèðóåòñÿ îáúåêòîì îäíîãî èç êëàññîâ, ïðîèçâîäíûõ îò Operation (ñòðàòåãèÿ), òàêèì îáðàçîì, äëÿ ðàçëè÷íîãî ïîâåäåíèÿ (âûïîëíåíèÿ ðàçëè÷íûõ îïåðàöèé è ôóíêöèé) èñïîëüçóåòñÿ îäèí è òîò æå èíòåðôåéñ. Äèàãðàììà êëàññîâ, ïîÿñíÿþùàÿ ñòðóêòóðó ïàòòåðíà Strategy ïðèìåíèòåëüíî ê äàííîìó ñëó÷àþ, ïðèâåäåíà íà ðèñ. 5.

Ðèñ. 5.

Èñïîëüçîâàíèå ïàòòåðíà Strategy ïðè âûïîëíåíèÿ îïåðàöèé.

Ïîëüçîâàòåëüñêóþ ôóíêöèþ ïðåäñòàâëÿåò îáúåêò êëàññà Subroutine, ñîäåðæàùèé ñïèñîê îïåðàòîðîâ ôóíêöèè. Ýòîò êëàññ ñîäåðæèò âëîæåííûé êëàññ Subroutine.Moment, ñîîòâåòñòâóþùèé òåêóùåé ïîçèöèè âûïîëíåíèÿ â ôóíêöèè; åãî ìåòîäû ïîçâîëÿþò ïåðåäàòü óïðàâëåíèå íà ñëåäóþùèé îïåðàòîð ëèáî íà îïåðàòîð ñ çàäàííûì íîìåðîì, âûïîëíèòü ôóíêöèþ îò íà÷àëà äî êîíöà. Ïðîèçâîëüíûé îïåðàòîð ÿçûêà ïðåäñòàâëÿåòñÿ èíòåðôåéñîì IOperator. Ýòîò èíòåðôåéñ è âñå ðåàëèçóþùèå åãî êëàññû íàõîäÿòñÿ â ïðîñòðàíñòâå èìåí interpr.logic.operators.

Èíòåðôåéñ IOperator èìååò äâà ìåòîäà. Ïåðâûé èç íèõ, GetKind(), âîçâðàùàåò çíà÷åíèå òèïà ïåðå÷èñëåíèÿ OperatorKind, êîòîðîå õàðàêòåðèçóåò âèä îïåðàòîðà. Âòîðîé - void Execute(Subroutine.Moment pos) âûïîëíÿåò îïåðàòîð.  êà÷åñòâå ïàðàìåòðà ïåðåäàåòñÿ îáúåêò Subroutine.Moment, ñ ïîìîùüþ êîòîðîãî óïðàâëåíèå â ôóíêöèè ïåðåäàåòñÿ íà íóæíîå ìåñòî. Íóæíî îòìåòèòü, ÷òî äàæå åñëè äàííûé îïåðàòîð íå íàðóøàåò ëèíåéíîé ïîñëåäîâàòåëüíîñòè âûïîëíåíèÿ, òî âñå ðàâíî îòâåòñòâåííîñòü çà ïåðåõîä íà ñëåäóþùèé îïåðàòîð ëåæèò íà ìåòîäå Execute() îáúåêòà îïåðàòîðà.

Êàê áûëî ñêàçàíî âûøå, ðÿä îïåðàòîðîâ ìîæåò áûòü èñïîëüçîâàí òîëüêî â ôóíêöèÿõ. Ñîîòâåòñòâóþùèå êëàññû ðåàëèçóþò èíòåðôåéñ IOperator íåïîñðåäñòâåííî. Äðóãèå îïåðàòîðû ïðåäñòàâëÿþò ñîáîé êîìàíäû, êîòîðûå ìîãóò áûòü ââåäåíû â êîíñîëè. Îáùèì ñâîéñòâîì òàêèõ îïåðàòîðîâ ÿâëÿåòñÿ òî, ÷òî îíè íå íàðóøàþò ëèíåéíîé ïîñëåäîâàòåëüíîñòè âûïîëíåíèÿ, âñòðåòèâøèñü â ôóíêöèè. Êëàññû, èõ ïðåäñòàâëÿþùèå, ÿâëÿþòñÿ ïîòîìêàìè àáñòðàêòíîãî êëàññà Command, ðåàëèçóþùåãî èíòåðôåéñ IOperator. Ìåòîä Execute() â êëàññå Command èìååò ïåðåãðóæåííóþ âåðñèþ áåç ïàðàìåòðîâ, îáúÿâëåííóþ àáñòðàêòíîé. Âåðñèÿ æå èç èíòåðôåéñà, ïðèíèìàþùàÿ ïàðàìåòð òèïà Subroutine.Moment, â ýòîì êëàññå ðåàëèçîâàíà ñëåäóþùèì îáðàçîì: âûçûâàåòñÿ ìåòîä Execute() áåç ïàðàìåòðîâ, çàòåì óïðàâëåíèå ïåðåäàåòñÿ íà ñëåäóþùèé îïåðàòîð.  êëàññå Command ìåòîä GetKind() âîçâðàùàåò çíà÷åíèå OperatorKind.Plain, ýòîò ìåòîä çäåñü íå ÿâëÿåòñÿ âèðòóàëüíûì è íå ïåðåîïðåäåëÿåòñÿ ó ïîòîìêîâ.

Ðàññìîòðèì òåïåðü îòäåëüíûå êëàññû, ðåàëèçóþùèå èíòåðôåéñ IOperator. Íà÷íåì ñ ïîòîìêîâ êëàññà Command.

Âî ïåðâûõ, ïðèñóòñòâóþò äâå êîìàíäû, îòâå÷àþùèå çà âûâîä íà êîíñîëü – print è println. Îíè ïðåäñòàâëÿþòñÿ êëàññàìè PrintCommand è PrintLnCommand ñîîòâåòñòâåííî. Ñòðóêòóðà ýòèõ êëàññîâ ïîëíîñòüþ àíàëîãè÷íà. Îíè ñîäåðæàò ïîëå m_expr, ñî ññûëêîé íà îáúåêò Expression, ïðåäñòàâëÿþùèé âûðàæåíèå, ðåçóëüòàò âû÷èñëåíèÿ êîòîðîãî äîëæåí áûòü âûâåäåí íà êîíñîëü.  ìåòîäå Execute() ðåçóëüòàò âû÷èñëåíèÿ âûðàæåíèÿ ñíà÷àëà ïðèâîäèòñÿ ê ñòðîêå (âûçûâàåòñÿ ìåòîä ToString), çàòåì âûâîäèòñÿ íà êîíñîëü âûçîâîì ìåòîäîâ îáúåêòà InterprNamespace.CurrentConsole.

Êîìàíäà call ðåàëèçóåòñÿ ñ ïîìîùüþ êëàññà CallCommand, â ìåòîäå execute() êîòîðîãî ïðîñòî âû÷èñëÿåòñÿ âûðàæåíèå èç ïîëÿ m_expr, ðåçóëüòàò æå âû÷èñëåíèÿ âûðàæåíèÿ íèêàê íå èñïîëüçóåòñÿ.

Êîíñòðóêòîðû ýòèõ òðåõ êëàññîâ ïðèíèìàþò îäèí ïàðàìåòð òèïà Expression.

Êëàññ EmptyCommand, ïðåäñòàâëÿþùèé ïóñòóþ êîìàíäó (ïóñòàÿ ñòðîêà ëèáî ñòðîêà êîììåíòàðèÿ), ñîäåðæèò ëèøü ïóñòûå êîíñòðóêòîð áåç ïàðàìåòðîâ è ìåòîä Execute().

Êëàññ ClearCommand ñîäåðæèò ïîëå òèïà string, â êîòîðîì õðàíèòñÿ èìÿ óäàëÿåìîé ïåðåìåííîé. Â ìåòîäå execute() âûçûâàåòñÿ ìåòîä Remove îáúåêòà òåêóùåãî ïðîñòðàíñòâà èìåí.

È, íàêîíåö, êëàññ AssignCommand ïðåäñòàâëÿåò êîìàíäó ïðèñâàèâàíèÿ. Îí èìååò äâà êîíñòðóêòîðà, ïðèíèìàþùèå äâà èëè òðè ïàðàìåòðà ñîîòâåòñòâåííî, äëÿ îïåðàòîðîâ ïðèñâàèâàíèÿ çíà÷åíèÿ ïåðåìåííîé èëè ýëåìåíòó ìàññèâà.  ïåðâîì èç ýòèõ ïàðàìåòðîâ ñîäåðæèòñÿ èìÿ ïåðåìåííîé èëè ìàññèâà â ëåâîé ÷àñòè îïåðàòîðà ïðèñâàèâàíèÿ, â îñòàëüíûõ – ïðèñâàèâàåìîå âûðàæåíèå è, âî âòîðîì ñëó÷àå, èíäåêñíîå âûðàæåíèå. Âûðàæåíèÿ ïåðåäàþòñÿ â èõ ñòðîêîâîé çàïèñè, îíè «êîìïèëèðóþòñÿ» â îáúåêòû êëàññà Expression â êîíñòðóêòîðå ïîñëåäíåãî. Ðàáîòà ñ ïåðåìåííûìè îñóùåñòâëÿåòñÿ ñ ïîìîùüþ îáúåêòà òåêóùåãî ïðîñòðàíñòâà èìåí, âîçâðàùàåìîãî ñâîéñòâîì InterprEnvironment.Instance.CurrentNamespace.

Ê ÷èñëó êëàññîâ, ïðåäñòàâëÿþùèõ îïåðàòîðû óïðàâëåíèÿ ïîñëåäîâàòåëüíîñòüþ âûïîëíåíèÿ, îòíîñÿòñÿ ErrorOperator, ReturnOperator, ForOperator, NextOperator, WhileOperator, LoopOperator, IfOperator, ElseifOperator, ElseOperator, EndifOperator. Äëÿ êàæäîãî èç íèõ èìååòñÿ ñâîå çíà÷åíèå â ïåðå÷èñëåíèè OperatorKind, êîòîðîå è âîçâðàùàåòñÿ ìåòîäîì GetKind ñîîòâåòñòâóþùåãî êëàññà.

Ìåòîä execute() êëàññà ErrorOperator  ñîäåðæèò âñåãî îäíó ñòðîêó - ãåíåðàöèþ èñêëþ÷åíèÿ CalcException. Òàêîé æå êîðîòêèé ìåòîä âûïîëíåíèÿ è â êëàññå ReturnOperator - âûçûâàåòñÿ ìåòîä return() îáúåêòà Subroutine.Moment pos, êîòîðûé íåìåäëåííî ïåðåäàåò âûïîëíåíèå çà êîíåö ôóíêöèè.

Îñòàëüíûå æå èç ðàññìàòðèâàåìûõ îïåðàòîðîâ ðàáîòàþò â ïàðå ñ äðóãèìè îïåðàòîðàìè - while - ñ loop, for - ñ end, if - ñ elseif, else è endif. Ñîîòâåòñòâóþùèå êëàññû èìåþò ïîëÿ, ñîäåðæàùèå íîìåðà (ïîçèöèè) ñîîòâåòñòâóþùèõ ïàðíûõ îïåðàòîðîâ, è ñâîéñòâà äëÿ äîñòóïà ê íèì:

·     â êëàññå ForOperator - ñâîéñòâî NextPos - ïîçèöèÿ îïåðàòîðà next;

·     â êëàññå NextOperator - ñâîéñòâî ForPos - ïîçèöèÿ îïåðàòîðà for;

·     â êëàññå WhileOperator - ñâîéñòâî LoopPos - ïîçèöèÿ îïåðàòîðà loop;

·     â êëàññå LoopOperator - ñâîéñòâî WhilePos - ïîçèöèÿ îïåðàòîðà while;

·     â êëàññàõ IfOperator, ElseIfOperator è ElseOperator - ñâîéñòâî NextPos - ïîçèöèÿ áëèæàéøåãî ñíèçó ñîîòâåòñòâóþùåãî îïåðàòîðà elseif, else èëè endif.

Óñëîâèÿ è ãðàíèöû öèêëîâ òàì, ãäå îíè íóæíû, õðàíÿòñÿ â âèäå îáúåêòîâ òèïà Expression. Ëîãèêà âûïîëíåíèÿ îïåðàòîðîâ ñëåäóþùàÿ:

·     Ïðè âûïîëíåíèè îïåðàòîðà while ìåòîä Execute() êëàññà WhileOperator âû÷èñëÿåò âûðàæåíèå-óñëîâèå è, â çàâèñèìîñòè îò åãî ëîãè÷åñêîãî çíà÷åíèÿ, ïåðåäàåò óïðàâëåíèå ëèáî ñëåäóþùåìó îïåðàòîðó, ëèáî îïåðàòîðó, ñëåäóþùåìó çà îïåðàòîðîì loop. Ìåòîä Execute() êëàññà LoopOperator ïåðåäàåò óïðàâëåíèå íà ñîîòâåòñòâóþùèé îïåðàòîð while.

·     Ïðè âûïîëíåíèè îïåðàòîðà for ìåòîä Execute() êëàññà ForOperator âû÷èñëÿåò çíà÷åíèÿ âûðàæåíèé-ãðàíèö öèêëà, çàïîìèíàåò çíà÷åíèå âåðõíåé ãðàíèöû â ñîîòâåòñòâóþùåì ïîëå êëàññà, çàòåì, åñëè íèæíÿÿ ãðàíèöà áîëüøå âåðõíåé ãðàíèöû, ïåðåäàåò óïðàâëåíèå íà îïåðàòîð, ñëåäóþùèé çà next, èíà÷å - íà ñëåäóþùèé îïåðàòîð. Ïðè âûïîëíåíèè æå îïåðàòîðà next âûçûâàåòñÿ ìåòîä Step() ó îáúåêòà, ïðåäñòàâëÿþùåãî ïàðíûé îïåðàòîð for, êîòîðûé óâåëè÷èâàåò íà åäèíèöó ïåðåìåííóþ-ñ÷åò÷èê öèêëà è, â çàâèñèìîñòè îò ðåçóëüòàòà ñðàâíåíèÿ ïîñëåäíåé ñ âåðõíåé ãðàíèöåé öèêëà, ïðåäàåò óïðàâëåíèå íà îïåðàòîð, ñëåäóþùèé ëèáî çà for, ëèáî çà next. Ïðè ýòîì çà âñå âðåìÿ âûïîëíåíèÿ öèêëà ìåòîä Execute() êëàññà ForOperator âûïîëíÿåòñÿ òîëüêî îäèí ðàç.

·     Ïðè âûïîëíåíèè îïåðàòîðà if ìåòîä Execute() êëàññà IfOperator ïðîñìàòðèâàåò ïîäðÿä ñîîòâåòñòâóþùèå îïåðàòîðû elseif, else è endif äî íàõîæäåíèÿ áëîêà êîäà, â êîòîðûé ñëåäóåò ïåðåäàòü óïðàâëåíèå. Ïðè ýòîì èñïîëüçóþòñÿ ñâîéñòâî NextPos êëàññîâ IfOperator, ElseOperator, ElseifOperator è ìåòîä TestCondition êëàññà ElseifOperator, ïðîâåðÿþùèé ñîäåðæàùååñÿ â îïåðàòîðå óñëîâèå. Äëÿ îïðåäåëåíèÿ âèäà îïåðàòîðà, íà êîòîðûé óêàçûâàåò çíà÷åíèå ñâîéñòâà NextPos î÷åðåäíîãî ðàññìàòðèâàåìîãî îïåðàòîðà, ó ñîîòâåòñòâóþùåãî îáúåêòà âûçûâàåòñÿ âèðòóàëüíûé ìåòîä GetKind.

Äèàãðàììà êëàññîâ ïðîñòðàíñòâà èìåí interpr.logic.operators ïðèâåäåíà íà ðèñ. 6.

Ðèñ. 6.

Êëàññû ïðîñòðàíñòâà èìåí interpr.logic.operators.

Ïîëüçîâàòåëüñêèå ôóíêöèè çàãðóæàþòñÿ ëèáî ïðè çàïóñêå èíòåðïðåòàòîðà, ëèáî ïðè ñîõðàíåíèè èõ â ðåäàêòîðå êîäà. Äëÿ õðàíåíèÿ çàãðóæåííûõ ôóíêöèé èñïîëüçóþòñÿ îáúåêòû êëàññà Subroutine. Ôóíêöèÿ ïðåäñòàâëÿåòñÿ ñïèñêîì îïåðàòîðîâ (êîíòåéíåð ArrayList, â êîòîðîì õðàíÿòñÿ îáúåêòû òèïà èíòåðôåéñà IOperator). Òàêæå â êëàññå èìåþòñÿ ïîëÿ, ñîäåðæàùèå îáùåå ÷èñëî îïåðàòîðîâ, ñïèñîê èìåí ôîðìàëüíûõ ïàðàìåòðîâ ôóíêöèè è èìÿ ôóíêöèè. Êàê áûëî ñêàçàíî âûøå, â êëàññå Subroutine íàõîäèòñÿ âëîæåííûé êëàññ Subroutine.Moment. Îí ïðåäñòàâëÿåò òåêóùóþ ïîçèöèþ âûïîëíåíèÿ â ôóíêöèè è â ñâîèõ ïîëÿõ õðàíèò íîìåð ññûëêó íà îáúåêò Subroutine è íîìåð òåêóùåãî îïåðàòîðà. Åãî ìåòîäû ðàáîòàþò ñ ÷àñòíûìè ïîëÿìè ýêçåìïëÿðà êëàññà Subroutine. Ïîýòîìó íàñëåäîâàíèå îò êëàññà Subroutine ñòàíîâèòñÿ íåæåëàòåëüíûì, è îí îáúÿâëåí êàê sealed.

Çà õðàíåíèå çàãðóæåííûõ ïîëüçîâàòåëüñêèõ ôóíêöèé îòâåòñòâåíåí êëàññ SubroutinesManager, âëîæåííûé (ñî ñïåöèôèêàòîðîì äîñòóïà private) â êëàññ InterprEnvironment. Îí õðàíèò â äâóõ ïîëÿõ òèïà System.Collections.ArrayList ñïèñîê çàãðóæåííûõ ôóíêöèé, êàê ýêçåìïëÿðîâ êëàññà Subroutine, è ñïèñîê èõ èìåí, ñîîòâåòñòâèå ìåæäó ôóíêöèåé è åå èìåíåì óñòàíàâëèâàåòñÿ ïî èíäåêñó â ñïèñêàõ. Singleton-îáúåêò êëàññà InterprEnvironment õðàíèò ññûëêó íà îäèí îáúåêò êëàññà SubroutinesManager. Ê åãî ìåòîäàì îáðàùàþòñÿ ìåòîäû êëàññà InterprEnvironment, ðàáîòàþùèå ñ ïîëüçîâàòåëüñêèìè ôóíêöèÿìè, ñðåäè êîòîðûõ:

·     GetSub(string) – ïîëó÷èòü îáúåêò ôóíêöèè ïî åå èìåíè;

·     LoadSub(string) – çàãðóçèòü ôóíêöèþ ñ çàäàííûì èìåíåì;

·     LoadSubs() – çàãðóçèòü ôóíêöèè èç âñåõ ôàéëîâ â êàòàëîãå subroutines;

·     UnloadSub(string) – âûãðóçèòü ôóíêöèþ ñ çàäàííûì èìåíåì.

 âûðàæåíèÿõ æå ïîëüçîâàòåëüñêèå ôóíêöèè ïðåäñòàâëÿþòñÿ îáúåêòàìè êëàññà VarName, êîòîðûå ñîäåðæàò èìÿ ôóíêöèè, ïî êîòîðîìó âî âðåìÿ âûïîëíåíèÿ ñ ïîìîùüþ ìåòîäà InterprEnvironment.GetSub() ïîó÷àåòñÿ ñîîòâåòñòâóþùèé îáúåêò Subroutine. Ýòî ñâÿçàíî ñ òåì, ÷òî åñëè áû â âûðàæåíèÿõ â îáúåêòàõ Call õðàíèëàñü áû ññûëêà íåïîñðåäñòâåííî íà Subroutine, ôóíêöèÿ, âûçûâàþùàÿ äðóãóþ ôóíêöèþ, íå ìîãëà áû áûòü çàãðóæåíà êîððåêòíî ðàíåå çàãðóçêè ïîñëåäíåé.


Îáðàáîòêà òåêñòà ïðîãðàììû.

Òåêñò ïðîãðàììû ìîæåò ñóùåñòâîâàòü â äâóõ âèäàõ – êîìàíäû, ââîäèìûå ñ êîíñîëè, è ïîëüçîâàòåëüñêèå ôóíêöèè.  îáîèõ ñëó÷àÿõ îäíà ñòðîêà (çà èñêëþ÷åíèåì çàãîëîâêà ôóíêöèè) ïðåîáðàçóåòñÿ â îäèí îïåðàòîð, âîçìîæíî, ïóñòîé.  ïåðâîì ñëó÷àå ýòîò îïåðàòîð äîëæåí ïðåäñòàâëÿòüñÿ îáúåêòîì êëàññà, ïðîèçâîäíîãî îò Command, âî âòîðîì – ëþáûì îáúåêòîì, ðåàëèçóþùèì èíòåðôåéñ IOperator.

Äëÿ ïðåîáðàçîâàíèÿ ñòðîêè òåêñòà ïðîãðàììû â îáúåêò, ðåàëèçóþùèé èíòåðôåéñ IOperator, èñïîëüçóþòñÿ ñòàòè÷åñêèå ìåòîäû êëàññà LineCompiler: Command CompileCommand(string) äëÿ êîìàíäû, ââåäåííîé ñ êîíñîëè è IOperator CompileOperator(string) äëÿ ñòðîêè ôóíêöèè. Êëàññ LineCompiler íå èìååò íåñòàòè÷åñêèõ ÷ëåíîâ, êðîìå çàêðûòîãî êîíñòðóêòîðà, êîòîðûé, çàìåùàÿ êîíñòðóêòîð èç áàçîâîãî êëàññà System.Object, íå äàåò âîçìîæíîñòè ñîçäàâàòü ýêçåìïëÿðû ýòîãî êëàññà. Àëãîðèòì ðàáîòû îáîèõ íàçâàííûõ ìåòîäîâ àíàëîãè÷åí. Âíà÷àëå ïðîâåðÿåòñÿ íàëè÷èå â ñòðîêå ëåêñåìû «:=», ïðèòîì íå ìåæäó äâîéíûìè êàâû÷êàìè (íå â ñòðîêîâîé êîíñòàíòå). Åñëè îíà íàéäåíà, òî äàííàÿ ñòðîêà ðàññìàòðèâàåòñÿ êàê îïåðàòîð ïðèñâàèâàíèÿ. Âíà÷àëå àíàëèçèðóåòñÿ ëåâàÿ ÷àñòü îïåðàòîðà ïðèñâàèâàíèÿ.  çàâèñèìîñòè îò åå âèäà, èñïîëüçóåòñÿ íóæíûé êîíñòðóêòîð êëàññà AssignCommand – äëÿ ïðèñâàèâàíèÿ çíà÷åíèÿ ïåðåìåííîé èëè ýëåìåíòó ìàññèâà. Åìó â êà÷åñòâå îäíîãî èç ïàðàìåòðîâ ïåðåäàåòñÿ ÷àñòü ñòðîêè ñïðàâà îò ñèìâîëîâ «:=», êîòîðàÿ ðàçáèðàåòñÿ êàê âûðàæåíèå â êîíñòðóêòîðå êëàññà Expression. Åñëè æå äàííûé îïåðàòîð íå ÿâëÿåòñÿ îïåðàòîðîì ïðèñâàèâàíèÿ, òî èç ñòðîêè âûäåëÿåòñÿ ïåðâàÿ ëåêñåìà, êîòîðàÿ ïîñëåäîâàòåëüíî ñðàâíèâàåòñÿ ñ êëþ÷åâûìè ñëîâàìè, ñ êîòîðûõ íà÷èíàþòñÿ ðàçëè÷íûå îïåðàòîðû (êîìàíäû). Åñëè ñîâïàäåíèé íå íàéäåíî, òî â ìåòîäå CompileOperator() ãåíåðèðóåòñÿ èñêëþ÷åíèå SyntaxErrorException – ñèíòàêñè÷åñêàÿ îøèáêà, â ìåòîäå æå CompileCommand() â ýòîì ñëó÷àå ñòðîêà ðàññìàòðèâàåòñÿ êàê ñîêðàùåííàÿ ôîðìà êîìàíäû println (òîëüêî âûðàæåíèå). Êàê òîëüêî âèä îïåðàòîðà îïðåäåëåí, îñòàâøàÿñÿ ÷àñòü ñòðîêè àíàëèçèðóåòñÿ ñîîòâåòñòâóþùèì îáðàçîì. Äëÿ ìíîãèõ îïåðàòîðîâ – if, else if, while, print, println – îíà ðàññìàòðèâàåòñÿ êàê îäíî âûðàæåíèå. Ïðè ýòîì íà ëþáîì èç ýòàïîâ àíàëèçà ñòðîêè ïðè îáíàðóæåíèè îøèáêè ìîæåò âîçíèêíóòü èñêëþ÷åíèå SyntaxErrorException.

Äëÿ ëåêñè÷åñêîãî ðàçáîðà ñòðîêè (ðàçáèåíèÿ íà ëåêñåìû) èñïîëüçóåòñÿ êëàññ Parser. Êàæäûé åãî ýêçåìïëÿð èñïîëüçóåòñÿ äëÿ ðàçáîðà îäíîé ñòðîêè. Êëàññ èìååò îäèí êîíñòðóêòîð, êîòîðûé ïðèíèìàåò îäèí ïàðàìåòð òèïà string, ñîäåðæàùèé îáðàáàòûâàåìóþ ñòðîêó.  êîíñòðóêòîðå ñòðîêà ïîäâåðãàåòñÿ ïðåîáðàçîâàíèþ – óäàëÿþòñÿ êîììåíòàðèé, åñëè îí ïðèñóòñòâóåò, è ëèøíèå ïðîáåëû. Êëàññ Parser ðåàëèçóåò ñòàíäàðòíûå èíòåðôåéñû System.IEnumerable è System.IEnumerator. Èíòåðôåéñ IEnumerable ïðåäñòàâëÿåò îáúåêò-ñïèñîê òîãî èëè èíîãî âèäà, êîòîðûé äîïóñêàåò ïîñëåäîâàòåëüíûé ïåðåáîð ýëåìåíòîâ. Îí èìååò åäèíñòâåííûé ìåòîä IEnumerator GetEnumerator(). Èíòåðôåéñ IEnumerator ïðåäñòàâëÿåò îáúåêò, êîòîðûé èñïîëüçóåòñÿ äëÿ ïåðåáîðà ýëåìåíòîâ ñïèñêà.  äàííîì ñëó÷àå ýòó ðîëü âûïîëíÿåò ñàì îáúåêò êëàññà Parser, ïîýòîìó ìåòîä GetEnumerator âîçâðàùàåò ññûëêó this. Ýòîò èíòåðôåéñ ñîäåðæèò ìåòîäû MoveNext() – ïðåéòè íà ñëåäóþùèé ýëåìåíò, Reset() – ñáðîñ íà íà÷àëî ñïèñêà è ñâîéñòâî Current – òåêóùèé ýëåìåíò ñïèñêà.  äàííîì ñëó÷àå îáúåêò Parser ðàññìàòðèâàåòñÿ êàê ñïèñîê ñòðîê-ëåêñåì, âõîäÿùèõ â ñîñòàâ ðàçáèðàåìîé ñòðîêè. Ñâîéñòâî Current äîñòóïíî òîëüêî äëÿ ÷òåíèÿ è åãî áëîê get ñîäåðæèò âûçîâ ìåòîäà private string GetCurrent(), âûäåëÿþùåãî òåêóùóþ ëåêñåìó èç ñòðîêè. Ñòðîêà äåëèòñÿ íà ëåêñåìû ñëåäóþùèõ âèäîâ:

·        ñòðîêîâàÿ êîíñòàíòà;

·        èäåíòèôèêàòîð;

·        ÷èñëî (öåëîå èëè âåùåñòâåííîå, âîçìîæíî, â ýêñïîíåíöèàëüíîé ôîðìå);

·        ñëóæåáíûé ñèìâîë;

·        ñîñòàâíîé ñëóæåáíûé ñèìâîë (‘:=’, ‘<=’, ‘>=’, ‘~=’, ‘<>’).

Ìåòîä GetCurrent() âûäåëÿåò â ñòðîêå  äëèííóþ âîçìîæíóþ ëåêñåìó, íà÷èíàþùóþñÿ ñ òåêóùåé ïîçèöèè.

Êðîìå òîãî, êëàññ Parser èìååò äâà îòêðûòûõ ñòàòè÷åñêèõ ìåòîäà: bool IsID(string) – ÿâëÿåòñÿ ëè äàííàÿ ñòðîêà êîððåêòíûì èäåíòèôèêàòîðîì è bool IsUserID(string) – ÿâëÿåòñÿ ëè äàííàÿ ñòðîêà êîððåêòíûì èäåíòèôèêàòîðîì, íå ñîâïàäàþùèì ñ èìåíåì êàêîé-ëèáî èç âñòðîåííûõ ôóíêöèé.

Ïðåîáðàçîâàíèå âûðàæåíèé â îïèñàííîå ðàíåå âíóòðåííåå ïðåäñòàâëåíèå ïðîèçâîäèòñÿ â êîíñòðóêòîðå êëàññà Expression, êîòîðûé èìååò äâå ïåðåãðóæåííûå âåðñèè, ïðèíèìàþùèå ïàðàìåòðû òèïà string è Parser ñîîòâåòñòâåííî.  îáåèõ âûçûâàåòñÿ private-ìåòîä Analyse(), â êîòîðîì ëåêñåìû èç ñòðîêè çàíîñÿòñÿ â ñïèñîê òèïà LinkedList (ýòîò êëàññ áûë ðàññìîòðåí âûøå), êîòîðûé çàòåì ïåðåäàåòñÿ â êà÷åñòâå ïàðàìåòðà äðóãîìó private-ìåòîäó OPZ().  ïîñëåäíåì è ñîñðåäîòî÷åíà îñíîâíàÿ ÷àñòü àëãîðèòìà ðàçáîðà âûðàæåíèÿ. Ýòîò àëãîðèòì îòíîñèòñÿ ê òàê íàçûâàåìûì âîñõîäÿùèì ìåòîäàì ñèíòàêñè÷åñêîãî ðàçáîðà, â êîòîðûõ äåðåâî ðàçáîðà ñòðîèòñÿ «ñíèçó ââåðõ». Ñèíòàêñè÷åñêèé àíàëèç çäåñü ñîâìåùåí ñ ñåìàíòè÷åñêîé îáðàáîòêîé – ïîñòðîåíèåì îáðàòíîé ïîëüñêîé çàïèñè âûðàæåíèÿ. Ïðåîáðàçîâàíèå âûðàæåíèÿ â ÎÏÇ ïðîèçâîäèòñÿ ñëåäóþùèì îáðàçîì:

·     Âíà÷àëå ñîçäàåòñÿ ïóñòîé ñòåê îïåðàöèé (îáúåêò êëàññà LinkedList).

·     Ïîñëåäîâàòåëüíî ïåðåáèðàþòñÿ ëåêñåìû, âõîäÿùèå â ðàçáèðàåìóþ ñòðîêó. Åñëè âñòðå÷àåòñÿ îïåðàíä – ïåðåìåííàÿ (èäåíòèôèêàòîð, ïîñëå êîòîðîãî íåò îòêðûâàþùåé êâàäðàòíîé èëè ôèãóðíîé ñêîáêè) èëè êîíñòàíòà, òî îí ñðàçó æå äîáàâëÿåòñÿ ê ðåçóëüòàòó, çàòåì, åñëè íà âåðøèíå ñòåêà îïåðàíäîâ èìåþòñÿ óíàðíûå îïåðàöèè, îíè âûòàëêèâàþòñÿ â ðåçóëüòàò.

·     Êàæäàÿ áèíàðíàÿ îïåðàöèÿ èìååò ñâîé ïðèîðèòåò (ìîæíî ïîëó÷èòü â âèäå ÷èñëà ñ ïîìîùüþ private-ôóíêöèè Expression.Priority()).

·     Áèíàðíàÿ îïåðàöèÿ âûòàëêèâàåò èç ñòåêà â ðåçóëüòàò îïåðàöèè ñ áîëüøèì èëè ðàâíûì ïðèîðèòåòîì (ñ âåðøèíû ñòåêà), çàòåì ñàìà çàïèñûâàåòñÿ â ñòåê. Äëÿ ñèìâîëîâ ‘+’ è ‘-’ ïðîèçâîäèòñÿ ïðîâåðêà, ÿâëÿþòñÿ îíè â êàæäîì êîíêðåòíîì ñëó÷àå çíàêîì áèíàðíîé îïåðàöèè èëè óíàðíîé – â ñëó÷àå óíàðíîé îïåðàöèè ïåðåä åå çíàêîì íàõîäèòñÿ îòêðûâàþùàÿ ñêîáêà ëèáî äðóãàÿ îïåðàöèÿ, èëè îïåðàöèÿ íàõîäèòñÿ â íà÷àëå ñòðîêè.

·     Óíàðíàÿ îïåðàöèÿ ñðàçó çàïèñûâàåòñÿ â ñòåê.

·     Îòêðûâàþùàÿ êðóãëàÿ ñêîáêà ñðàçó çàïèñûâàåòñÿ â ñòåê.

·     Çàêðûâàþùàÿ êðóãëàÿ ñêîáêà âûòàëêèâàåò â ðåçóëüòàò âñå îïåðàöèè èç ñòåêà äî îòêðûâàþùåé ñêîáêè, çàòåì ñêîáêè óíè÷òîæàþòñÿ, è âûòàëêèâàþòñÿ ñ âåðøèíû ñòåêà â ðåçóëüòàò óíàðíûå îïåðàöèè, åñëè îíè çäåñü èìåþòñÿ.

·     Åñëè ïîñëå èäåíòèôèêàòîðà â âûðàæåíèè âñòðå÷àåòñÿ îòêðûâàþùàÿ êâàäðàòíàÿ ñêîáêà, òî âûäåëÿþòñÿ ñïèñêè ëåêñåì, èç êîòîðûõ ñîñòîÿò âûðàæåíèÿ-îïåðàíäû ôóíêöèè (îíè ðàñïîëîæåíû â êâàäðàòíûõ ñêîáêàõ è  ðàçäåëåíû çàïÿòûìè; ó÷èòûâàåòñÿ âîçìîæíàÿ âëîæåííîñòü âûçîâîâ ôóíêöèé), äëÿ êàæäîãî èç íèõ ïîñëåäîâàòåëüíî âûçûâàåòñÿ ðåêóðñèâíî ìåòîä Analyse1(), ïðè ýòîì â ðåçóëüòàò äîïèñûâàþòñÿ ðåçóëüòàòû ðàçáîðà ýòèõ âûðàæåíèé, çàòåì, â ðåçóëüòàò äîïèñûâàåòñÿ âûçîâ ôóíêöèè (åå èìÿ – ñòîÿùàÿ ïåðåä îòêðûâàþùåé êâàäðàòíîé ñêîáêîé ëåêñåìà).

·     Åñëè ïîñëå èäåíòèôèêàòîðà âñòðå÷àåòñÿ îòêðûâàþùàÿ ôèãóðíàÿ ñêîáêà, òî ñòîÿùàÿ ïåðåä íåé ëåêñåìà ðàññìàòðèâàåòñÿ êàê èìÿ ìàññèâà (åñëè îíà íå ÿâëÿåòñÿ êîððåêòíûì èäåíòèôèêàòîðîì, òî ýòî ñâèäåòåëüñòâóåò î ñèíòàêñè÷åñêîé îøèáêå). Âûðàæåíèå â ôèãóðíûõ ñêîáêàõ îáðàáàòûâàåòñÿ ðåêóðñèâíûì âûçîâîì Analyse1() (àíàëîãè÷íî ïàðàìåòðó ôóíêöèè), çàòåì â ðåçóëüòàò äîïèñûâàþòñÿ èìÿ ìàññèâà è îïåðàöèÿ îáðàùåíèÿ ê ýëåìåíòó ìàññèâà.

·          Ïîñëå îáðàáîòêè âûçîâà ôóíêöèè èëè îáðàùåíèÿ ê ýëåìåíòó ìàññèâà â ðåçóëüòàò âûòàëêèâàþòñÿ ñ âåðøèíû ñòåêà óíàðíûå îïåðàöèè, åñëè îíè ïðèñóòñòâóþò.

·          Â êîíöå ðàçáîðà â ðåçóëüòàò âûòàëêèâàåòñÿ âñå ñîäåðæèìîå ñòåêà.

·          Êîíñòàíòû çàïèñûâàþòñÿ â ðåçóëüòàò êàê îáúåêòû êëàññîâ, ïðåäñòàâëÿþùèõ ñîîòâåòñòâóþùèå òèïû äàííûõ, ïåðåìåííûå – êàê îáúåêòû VarName, îïåðàöèè è âûçîâû ôóíêöèé – êàê îáúåêòû Call.

Ðàññìîòðèì ïðèìåð. Ïóñòü èìååòñÿ ñòðîêà (a*c+-b{à+ñ})/à. Ïðèìåíèì îïèñàííûé àëãîðèòì.

1.   Âíà÷àëå ñòåê îïåðàíäîâ è ðåçóëüòàò ïóñòû.

2.   Ïåðâàÿ ëåêñåìà – îòêðûâàþùàÿ êðóãëàÿ ñêîáêà. Çàïèñûâàåì åå â ñòåê.

Ñòåê: (Ðåçóëüòàò: <ïóñòî>.

3.   Âòîðàÿ ëåêñåìà – èäåíòèôèêàòîð «à». Çà íèì íåò îòêðûâàþùåé êâàäðàòíîé èëè ôèãóðíîé ñêîáêè, ïîýòîìó çàïèñûâàåì åãî â ðåçóëüòàò.

4.   Ñòåê: (Ðåçóëüòàò: à

5.   Ñëåäóþùàÿ ëåêñåìà – îïåðàöèÿ óìíîæåíèÿ. Çàïèñûâàåì åå â ñòåê. Íà âåðøèíå ñòåêà íåò îïåðàöèé ñ áîëüøèì èëè ðàâíûì ïðèîðèòåòîì, íè÷åãî âûòàëêèâàòü íå íóæíî.

6.   Ñòåê: (*Ðåçóëüòàò: à

7.   Âòîðàÿ ëåêñåìà – èäåíòèôèêàòîð «ñ». Çà íèì íåò îòêðûâàþùåé êâàäðàòíîé èëè ôèãóðíîé ñêîáêè, ïîýòîìó çàïèñûâàåì åãî â ðåçóëüòàò.

Ñòåê: (*Ðåçóëüòàò: àñ

8.   Ñëåäóþùàÿ ëåêñåìà – çíàê «+». Ïåðåä íèì íàõîäèòñÿ èäåíòèôèêàòîð, ïîýòîìó îí ÿâëÿåòñÿ çíàêîì îïåðàöèè ñëîæåíèÿ. Îí âûòàëêèâàåò èç ñòåêà îïåðàöèþ óìíîæåíèÿ êàê èìåþùóþ áîëåå âûñîêèé ïðèîðèòåò, çàòåì  ñàì äîïèñûâàåòñÿ â ñòåê.

9.   Ñòåê: (+ Ðåçóëüòàò: àñ*

10.      Ñëåäóþùàÿ ëåêñåìà – çíàê «ìèíóñ». Ïåðåä íèì íåò íè çàêðûâàþùåé ñêîáêè íè èäåíòèôèêàòîðà, ïîýòîìó îí ÿâëÿåòñÿ çíàêîì îïåðàöèè óíàðíûé ìèíóñ (îáîçíà÷èì åå êàê «_»), çàïèñûâàåì åå â ñòåê.

11.      Ñòåê: (+_Ðåçóëüòàò: àñ*

12.      Ñëåäóþùàÿ ëåêñåìà – èäåíòèôèêàòîð b. Çà íèì ñëåäóåò ôèãóðíàÿ ñêîáêà, ïîýòîìó îí ðàññìàòðèâàåòñÿ êàê èìÿ ìàññèâà.  ôèãóðíûõ ñêîáêàõ íàõîäèòñÿ ñòðîêà «à+ñ», êîòîðàÿ, áóäó÷è ïðåîáðàçîâàííîé ïî ðàññìàòðèâàåìîìó àëãîðèòìó, äàñò â ðåçóëüòàòå «àñ+». Äîïèøåì ýòî â ðåçóëüòàò ðàçáîðà èñõîäíîãî âûðàæåíèÿ. Çàòåì äîïèøåì â ðåçóëüòàò èìÿ ìàññèâà («b») è îïåðàöèþ èíäåêñàöèè (îáîçíà÷èì åå «{}»). È, íàêîíåö, âûòîëêíåì íàõîäÿùóþñÿ íà âåðøèíå ñòåêà îïåðàöèþ óíàðíûé ìèíóñ.

13.      Ñòåê: (+Ðåçóëüòàò: àñ*àñ+b{}_

14.      Ñëåäóþùàÿ (çà çàêðûâàþùåé ôèãóðíîé ñêîáêîé) ëåêñåìà – çàêðûâàþùàÿ êðóãëàÿ ñêîáêà. Îíà âûòîëêíåò èç ñòåêà â ðåçóëüòàò íàõîäÿùóþñÿ ïåðåä îòêðûâàþùåé ñêîáêîé îïåðàöèþ ñëîæåíèÿ, çàòåì îòêðûâàþùàÿ ñêîáêà áóäåò óäàëåíà èç ñòåêà.

Ñòåê; <ïóñòî>Ðåçóëüòàò: ac*ac+b{}_+

15.      Ñëåäóþùàÿ ëåêñåìà – îïåðàöèÿ äåëåíèÿ. Îíà äîïèñûâàåòñÿ â ñòåê (ïåðåä ýòèì ñòåê ïóñò, íè÷åãî âûòàëêèâàòü íå íóæíî).

Ñòåê: /Ðåçóëüòàò: ac*ac+b{}_+

16.      Ïîñëåäíÿÿ ëåêñåìà – èäåíòèôèêàòîð «à». Ïîñëå íåãî íåò íèêàêèõ ñêîáîê, ïîýòîìó îí ñðàçó æå äîáàâëÿåòñÿ ê ðåçóëüòàòó.

Ñòåê: /Ðåçóëüòàò: ac*ac+b{}_+a

17.       êîíöå âûòàëêèâàåì èç ñòåêà îñòàâøóþñÿ â íåì îïåðàöèþ óìíîæåíèÿ â ðåçóëüòàò. Èòîãî ïîëó÷àåì ac*ac+_b{}+a/, ÷òî ÿâëÿåòñÿ îáðàòíîé ïîëüñêîé çàïèñüþ èñõîäíîãî âûðàæåíèÿ.

Ïðè çàãðóçêå ôóíêöèè îáðàáîòêà åå òåêñòà îñóùåñòâëÿåòñÿ â êîíñòðóêòîðå êëàññà Subroutine, êîòîðûé ïðèíèìàåò äâà ïàðàìåòðà – èìÿ ôóíêöèè è òåêñò ôóíêöèè (â âèäå ìàññèâà ñòðîê). Ïðè ýòîì îòäåëüíî ðàññìàòðèâàåòñÿ ïåðâàÿ ñòðîêà – çàãîëîâîê ôóíêöèè. Äëÿ åå àíàëèçà èñïîëüçóåòñÿ private-ìåòîä Subroutine.AnalyseHeader(), â êîòîðîì ïðîâåðÿåòñÿ ñîîòâåòñòâèå ýòîé ñòðîêè òðåáóåìîìó ôîðìàòó è èçâëåêàåòñÿ ñïèñîê ôîðìàëüíûõ ïàðàìåòðîâ. Òàêæå ïðîâåðÿåòñÿ ñîîòâåòñòâèå èìåíè ôóíêöèè â çàãîëîâêå òðåáóåìîìó (ïåðâîìó ïàðàìåòðó êîíñòðóêòîðà). Ïðè ýòîì èñïîëüçóåòñÿ îáúåêò êëàññà Parser. Çàòåì ïî î÷åðåäè ïîäâåðãàþòñÿ ðàçáîðó ñ ïîìîùüþ ìåòîäà LineCompiler.CompileOperator() îñòàëüíûå ñòðîêè, ðåçóëüòàò «êîìïèëÿöèè» êàæäîé èç êîòîðûõ äîáàâëÿåòñÿ â ñïèñîê îïåðàòîðîâ ôóíêöèè. Ïðè ýòîì èñïîëüçóåòñÿ ñòåê âëîæåííîñòè îïåðàòîðîâ (ïðèìåíÿåòñÿ îáúåêò êëàññà System.Collections.Stack). Ïîñëå îáðàáîòêè êàæäîé ñòðîêè ïðîâåðÿåòñÿ òèï ïîëó÷åííîãî îïåðàòîðà ñ ïîìîùüþ ìåòîäà IOperator.GetType(). Åñëè îïåðàòîð îòêðûâàåò áëîê êîäà (if, elseif, else, while, for), òî åãî íîìåð çàíîñèòñÿ â ñòåê. Åñëè îïåðàòîð çàêðûâàåò áëîê êîäà, òî èç ñòåêà èçâëåêàåòñÿ íîìåð ïàðíîãî îïåðàòîðà è ïðèñâàèâàþòñÿ íåîáõîäèìûå çíà÷åíèÿ ñâîéñòâàì NextPos, LoopPos è ò. ä. ñîîòâåòñòâóþùèõ îáúåêòîâ. Îïåðàòîðû elseif è else ðàññìàòðèâàþòñÿ îäíîâðåìåííî è êàê çàêðûâàþùèå ðàñïîëîæåííûé âûøå áëîê êîäà, è êàê îòêðûâàþùèå ñëåäóþùèé. Íóæíî îòìåòèòü, ÷òî â ïåðâûé ýëåìåíò ñïèñêà îïåðàòîðîâ ôóíêöèè (ñ íóëåâûì èíäåêñîì) â îáúåêòå Subroutine ïîìåùàåòñÿ ïóñòîé îïåðàòîð (îáúåêò EmptyCommand), áëàãîäàðÿ ÷åìó êàæäîé ñòðîêå òåêñòà ôóíêöèè ñîîòâåòñòâóåò ýëåìåíò ýòîãî ñïèñêà ñ èíäåêñîì, ðàâíûì íîìåðó ýòîé ñòðîêè. Îñíîâíàÿ ÷àñòü êîäà êîíñòðóêòîðà êëàññà Subroutine íàõîäèòñÿ â áëîêå try, ïðè âîçíèêíîâåíèè èñêëþ÷åíèÿ SyntaxErrorException â êîòîðîì ãåíåðèðóåòñÿ èñêëþ÷åíèå êëàññà LineSyntaxException, îáúåêò êîòîðîãî ñîäåðæèò èíôîðìàöèþ î ìåñòå îøèáêè (èìÿ ôóíêöèè è íîìåð ñòðîêè).


Ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ.

Ãëàâíîé ôîðìå ïðèëîæåíèÿ, êîòîðàÿ èçîáðàæåíà íà ðèñ. 7, ñîîòâåòñòâóåò êëàññ Form1. Îñíîâíóþ ÷àñòü ôîðìû çàíèìàåò êîìïîíåíò ConsoleBox, ñîçäàííûé íà îñíîâå êëàññà UserControl. Îí âêëþ÷àåò â ñåáÿ îäèí ýêçåìïëÿð êîìïîíåíòà RichTextBox, «ðàñòÿíóòûé» ñ ïîìîùüþ ñâîéñòâà Dock íà âñþ äîñòóïíóþ ïëîùàäü. Êîìïîíåíò ConsoleBox ïðåäñòàâëÿåò ñîáîé îêíî êîíñîëè, â êîòîðîé ïîëüçîâàòåëü ââîäèò êîìàíäû, è íà êîòîðóþ âûâîäÿòñÿ ðåçóëüòàòû ðàáîòû êîìàíä. Êëàññ ConsoleBox ÿâëÿåòñÿ åäèíñòâåííûì êëàññîì â îêîí÷àòåëüíîé âåðñèè ïðîåêòà, ðåàëèçóþùèì ðàññìîòðåííûé âûøå èíòåðôåéñ IConsole. Âàæíåéøèå ÷ëåíû êëàññà ConsoleBox:

·     ìåòîäû Print(string)  è PrintLn(string) – ðåàëèçóþò ìåòîäû èíòåðôåéñà IConsole, ïðîèçâîäÿò âûâîä òåêñòà â îêíî êîíñîëè.

·     ìåòîä Prompt() – âûâîäèò ïðèãëàøåíèå êîìàíäíîé ñòðîêè (“>>>”) è ïåðåâîäèò êîíñîëü â ðåæèì îæèäàíèÿ êîìàíäû.

·     ñîáûòèå GetCommand (object sender, ConsoleBoxGetCommandEventArgs e) – âîçíèêàåò, êîãäà â ðåæèìå îæèäàíèÿ êîìàíäû áûëà íàæàòà êëàâèøà Enter. Ïðè ýòîì â ïàðàìåòðå e, èìåþùåì òèï êëàññà ConsoleBoxGetCommandEventArgs, êîòîðûé óíàñëåäîâàí îò System.EventArgs, â ñâîéñòâå Command ñîäåðæèòñÿ ââåäåííàÿ ïîëüçîâàòåëåì êîìàíäà â âèäå ñòðîêè.

Ìåòîäû Print, PrintLn è Prompt ðàññ÷èòàíû íà áåçîïàñíîå èñïîëüçîâàíèå èç äðóãîãî ïîòîêà.  íèõ èñïîëüçóåòñÿ âûçîâ private-ìåòîäîâ ÷åðåç îáúåêò êëàññà System.Windows.Forms.MethodInvoker. Âîçìîæíû äâà ñîñòîÿíèÿ êîìïîíåíòà êîíñîëè – ðåæèì îæèäàíèÿ ââîäà êîìàíäû è ðåæèì ðàáîòû êîìàíäû. Ââîä òåêñòà â ïîëå RichTextBox äîïóñêàåòñÿ òîëüêî â ðåæèìå îæèäàíèÿ ââîäà êîìàíäû è òîëüêî ïîñëå ïîñëåäíåãî ïðèãëàøåíèÿ êîìàíäíîé ñòðîêè, ÷òî îáåñïå÷èâàåòñÿ ñ ïîìîùüþ ñâîéñòâà RichTextBox.SelectionProtected. Âûçîâ ìåòîäà Prompt() ïåðåâîäèò êîíñîëü â ðåæèì îæèäàíèÿ êîìàíäû. Ïðè íàæàòèè Enter â ðåæèìå îæèäàíèÿ êîìàíäû, ïîìèìî ãåíåðàöèè ñîáûòèÿ GetCommand, ïðîèñõîäèò ïåðåõîä èç ðåæèìà îæèäàíèÿ â ðåæèì ðàáîòû êîìàíäû.


        

Ðèñ. 7.

Ãëàâíàÿ ôîðìà.

Ïðè íàæàòèè êíîïêè «Ôóíêöèè» íà ãëàâíîé ôîðìå âûâîäèòñÿ äèàëîãîâîå îêíî, êîòîðîìó ñîîòâåòñòâóåò êëàññ FunctionsForm (ñì. ðèñ. 8).  ýòîì îêíå â âåðõíåì ïîëå îòîáðàæàåòñÿ ñïèñîê óñïåøíî çàãðóæåííûõ ôóíêöèé, â íèæíåì – ôóíêöèé, çàãðóçêà êîòîðûõ ïðîøëà íåóäà÷íî ïî ïðè÷èíå íàëè÷èÿ ñèíòàêñè÷åñêèõ îøèáîê. Êíîïêè ïîçâîëÿþò ðåäàêòèðîâàòü, óäàëèòü (â ýòîì ñëó÷àå òðåáóåòñÿ ïîäòâåðæäåíèå) âûáðàííóþ ôóíêöèþ, ñîçäàòü íîâóþ ôóíêöèþ (â ýòîì ñëó÷àå áóäåò çàïðîøåíî èìÿ ôóíêöèè, è, åñëè îíî íå ÿâëÿåòñÿ êîððåêòíûì èäåíòèôèêàòîðîì, ôóíêöèÿ ñîçäàíà íå áóäåò). Äëÿ çàïðîñà èìåíè ïðè ñîçäàíèè ôóíêöèè èñïîëüçóåòñÿ ôîðìà, îïèñûâàþùàÿñÿ êëàññîì InputForm (ñì. ðèñ. 9). Åñëè ôóíêöèÿ ñîçäàíà óñïåøíî, îíà îòêðûâàåòñÿ äëÿ ðåäàêòèðîâàíèÿ. Ïðè äâîéíîì ùåë÷êå ïî èìåíè ôóíêöèè â ëþáîì èç ñïèñêîâ â îêíå «Ôóíêöèè» òàêæå îíà îòêðûâàåòñÿ äëÿ ðåäàêòèðîâàíèÿ. Îêíî «Ôóíêöèè» ÿâëÿåòñÿ ìîäàëüíûì äèàëîãîì è äîëæíî áûòü çàêðûòî äëÿ ïðîäîëæåíèÿ ðàáîòû ñ èíòåðïðåòàòîðîì. Îíî çàêðûâàåòñÿ ïðè îòêðûòèè ôóíêöèè äëÿ ðåäàêòèðîâàíèÿ. Ïðè ýòîì âìåñòî íåãî íà ýêðàíå ïîÿâëÿåòñÿ îêíî ðåäàêòîðà êîäà.

Ðèñ. 8.

Îêíî «Ôóíêöèè»

        

Ðèñ. 9.

Îêíî ââîäà èìåíè ñîçäàâàåìîé ôóíêöèè.

Îêíó ðåäàêòîðà êîäà ñîîòâåòñòâóåò êëàññ EditorForm (ñì. ðèñ. 10). Êíîïêà «Ñîõðàíèòü» â íåì ñîõðàíÿåò ôóíêöèþ â ôàéëå, ðàñïîëîæåííîì â ïîäêàòàëîãå subroutines ðàáî÷åãî êàòàëîãà èíòåðïðåòàòîðà, ñ èìåíåì, ñîâïàäàþùèì ñ èìåíåì ôóíêöèè (áåç ðàñøèðåíèÿ). Êíîïêà «Âûõîä» - çàêðûâàåò îêíî ðåäàêòîðà (ñ çàïðîñîì íà ñîõðàíåíèå).  ìåòêå ñïðàâà îò êíîïîê îòîáðàæàåòñÿ íîìåð ñòðîêè òåêóùåãî ïîëîæåíèÿ êóðñîðà (íà÷àëà âûäåëåíèÿ) â òåêñòå.  åå òåêñò íîìåð òåêóùåé ñòðîêè çàíîñèòñÿ ïðèáëèçèòåëüíî 10 ðàç â ñåêóíäó, ÷òî îáåñïå÷èâàåòñÿ ñ ïîìîùüþ òàéìåðà (êîìïîíåíò System.Windows.Forms.Timer).Îêíî ðåäàêòîðà êîäà íå ÿâëÿåòñÿ ìîäàëüíûì – â ëþáîé ìîìåíò ðàáîòû ñ èíòåðïðåòàòîðîì ìîæåò áûòü îòêðûòî ñêîëüêî óãîäíî òàêèõ îêîí äëÿ ðàçíûõ ôóíêöèé. Çàáëîêèðîâàíû îòêðûòèå ôóíêöèè âòîðîé ðàç (â äâóõ îêíàõ îäíîâðåìåííî) è âûõîä èç èíòåðïðåòàòîðà äî çàêðûòèÿ âñåõ îêîí ðåäàêòîðà êîäà. Îñíîâíóþ ÷àñòü îêíà ðåäàêòîðà êîäà ñîñòàâëÿåò êîìïîíåíò SourceBox, êîòîðûé òàêæå êàê è ConsoleBox, óíàñëåäîâàí îò  êëàññàUserControl. Îí ñîäåðæèò ýëåìåíò óïðàâëåíèÿ RichTextBox, â êîòîðîì, ñîáñòâåííî, è îñóùåñòâëÿåòñÿ ðåäàêòèðîâàíèå òåêñòà ôóíêöèè, è ýëåìåíò TextBox, ðàñïîëîæåííûé çà RichTextBox íà çàäíåì ïëàíå è íåâèäèìûé äëÿ ïîëüçîâàòåëÿ. Íà íåãî ïåðåêëþ÷àåòñÿ ôîêóñ íà âðåìÿ âûïîëíåíèÿ ñèíòàêñè÷åñêîãî öâåòîâûäåëåíèÿ, òàê êàê äëÿ èçìåíåíèÿ öâåòà ôðàãìåíòà òåêñòà â RichTextBox íåîáõîäèìî ýòîò ôðàãìåíò âûäåëèòü, ÷òî ïðèâîäèëî áû ê çàìåòíîìó ìåðöàíèþ òåêñòà, åñëè áû ôîêóñ ââîäà îñòàâàëñÿ ó ïîëÿ RichTextBox. Òàêîé ïîäõîä ê ðåøåíèþ ïðîáëåìû ïîçâîëÿåò ðåàëèçîâàòü ñèíòàêñè÷åñêîå öâåòîâûäåëåíèå ñ èñïîëüçîâàíèåì ñâîéñòâ êëàññà RichTextBox íåáîëüøèì îáúåìîì êîäà (èíà÷å áû ïðèøëîñü ïðîèçâîäèòü «ðó÷íóþ» ïåðåðèñîâêó ñ íåïîñðåäñòâåííûì èñïîëüçîâàíèåì GDI+). Íî ê ñîæàëåíèþ, çàìåòíî ñíèæàåòñÿ áûñòðîäåéñòâèå, â ñâÿçè ñ ýòèì áûëè ââåäåíû ñëåäóþùèå îãðàíè÷åíèÿ: ñèíòàêñè÷åñêîå öâåòîâûäåëåíèå ïðîèçâîäèòñÿ òîëüêî ïðè èçìåíåíèè íîìåðà ñòðîêè, â êîòîðîé íàõîäèòñÿ êóðñîð, íàïðèìåð, ïðè íàæàòèè Enter, à òàêæå ïðè ùåë÷êå ëåâîé êíîïêîé ìûøè â îêíå ðåäàêòîðà (â RichTextBox). Ïðè ýòîì îáðàáàòûâàþòñÿ òîëüêî ñòðîêè òåêñòà, îòîáðàæàåìûå â äàííûé ìîìåíò âðåìåíè â îêíå. Êîíå÷íî, ýòî íåñêîëüêî íåóäîáíî äëÿ ïîëüçîâàòåëÿ, ïîäîáíîå ìîæíî íàáëþäàòü, íàïðèìåð, â òàêîé ñðåäå ïðîãðàììèðîâàíèÿ, êàê MS Visual Basic 6. Äëÿ âûïîëíåíèÿ ñèíòàêñè÷åñêîãî öâåòîâûäåëåíèÿ èñïîëüçóåòñÿ âëîæåííûé private-êëàññ HighlightParser, êîòîðûé èìååò ìåòîäû äëÿ ðàçáîðà ñòðîêè íà îòäåëüíûå ëåêñåìû, äëÿ îïðåäåëåíèÿ ïîëîæåíèÿ â ñòðîêå è òèïà ýòèõ ëåêñåì. Ïðèìåíèòü êëàññ interpr.logic.Parser çäåñü íåëüçÿ, òàê êàê îí ðàáîòàåò ñ ïðåîáðàçîâàííîé ñòðîêîé (óäàëåíû ëèøíèå ïðîáåëû è êîììåíòàðèè). Êëàññ SourceBox òàêæå èìååò ìåòîäû äëÿ ÷òåíèÿ òåêñòà ôóíêöèè èç ôàéëà è ñîõðàíåíèÿ òåêñòà â ôàéëå.


 

Ðèñ. 10.

Îêíî ðåäàêòîðà êîäà.

        

Ïðè íàæàòèè íà êíîïêó «Ïåðåìåííûå» â ãëàâíîì îêíå èíòåðïðåòàòîðà îòîáðàæàåòñÿ äèàëîãîâîå îêíî ñî ñïèñêîì ïåðåìåííûõ ñðåäû êîíñîëè (ñì. ðèñ. 11). Ïåðåìåííûå îòîáðàæàþòñÿ âìåñòå ñ èõ çíà÷åíèÿìè (ïðèâåäåííûìè ê ñòðîêîâîìó òèïó). Äàííîå îêíî ïîçâîëÿåò óäàëèòü âûáðàííóþ èëè âñå ïåðåìåííûå èç ïàìÿòè. Ýòîìó îêíó ñîîòâåòñòâóåò êëàññ VariablesForm.  Ïðè íàæàòèè êíîïêè «Ïåðåçàïóñê» ïðîèçâîäèòñÿ ïåðåçàïóñê èíòåðïðåòàòîðà (âîçìîæíî, ñ ïðåðûâàíèåì çàöèêëèâøåéñÿ èëè äîëãî ðàáîòàþùåé ïîëüçîâàòåëüñêîé ôóíêöèè). Ïðè ïåðåçàïóñêå íå âîññòàíàâëèâàþòñÿ èçìåíåííûå çíà÷åíèÿ ïåðåìåííûõ ñðåäû êîíñîëè, ïîýòîìó ïðåäóñìîòðåíà âîçìîæíîñòü ñîõðàíåíèÿ çíà÷åíèé ïåðåìåííûõ. Ñîõðàíåíèå ïåðåìåííûõ ïðîèñõîäèò àâòîìàòè÷åñêè ïðè âûõîäå èç èíòåðïðåòàòîðà è âðó÷íóþ ïðè íàæàòèè êíîïêè «Ñîõðàíèòü ïåðåìåííûå». Ïåðåìåííûå ñîõðàíÿþòñÿ â äâîè÷íîì ôàéë variables, êîòîðûé àâòîìàòè÷åñêè ñîçäàåòñÿ â ðàáî÷åì êàòàëîãå èíòåðïðåòàòîðà, è ñ÷èòûâàþòñÿ èç íåãî ïðè çàïóñêå èëè ïåðåçàïóñêå èíòåðïðåòàòîðà. Ñîõðàíÿòü ïåðåìåííûå âðó÷íóþ èìååò ñìûñë ïåðåä çàïóñêîì ïîëüçîâàòåëüñêîé ôóíêöèè, êîòîðàÿ ìîæåò çàöèêëèòüñÿ èëè ñëèøêîì äîëãî ðàáîòàòü, ÷òîáû ìîæíî áûëî ïðåðâàòü åå ðàáîòó, íå îïàñàÿñü ïîòåðÿòü ðåçóëüòàòû ïðåäûäóùèõ âû÷èñëåíèé. Ðàáîòà ñ ïåðåìåííûìè îñóùåñòâëÿåòñÿ ñ ïîìîùüþ ìåòîäîâ êëàññà Facade, îáðàùàþùèõñÿ ê ñîîòâåòñòâóþùèì ìåòîäàì êëàññîâ èç ïðîñòðàíñòâà èìåí interpr.logic.

Êëàññû, îòíîñÿùèåñÿ ê ïîëüçîâàòåëüñêîìó èíòåðôåéñó èíòåðïðåòàòîðà, ïîêàçàíû íà äèàãðàììå íà ðèñ. 12.

        

Ðèñ. 11.

Îêíî «Ïåðåìåííûå».

        



Ðèñ. 12.

Êëàññû, ñâÿçàííûå ñ ãðàôè÷åñêèì èíòåðôåéñîì ïîëüçîâàòåëÿ.


Âçàèìîäåéñòâèå ïîäñèñòåì èíòåðïðåòàòîðà. Êëàññ Facade.

Êàê óæå áûëî ñêàçàíî âûøå, êëàññ Facade ÿâëÿåòñÿ ïîñðåäíèêîì ìåæäó äâóìÿ îñíîâíûìè ïîäñèñòåìàìè – ãðàôè÷åñêèì èíòåðôåéñîì ïîëüçîâàòåëÿ è ëîãèêîé ðàáîòû èíòåðïðåòàòîðà. Çäåñü èñïîëüçîâàí ïàòòåðí Facade. Âñå îáðàùåíèÿ èçâíå ê êëàññàì ïðîñòðàíñòâà èìåí interpr.logic ïðîèçâîäÿòñÿ ÷åðåç âûçîâ ìåòîäîâ êëàññà Facade. Ñàìà æå ïîäñèñòåìà ëîãèêè ðàáîòû èíòåðïðåòàòîðà íå õðàíèò ññûëîê, êàê ýòî òðåáóåò äàííûé ïàòòåðí, íè íà êëàññ Facade, íè íà äðóãèå êëàññû, íå âõîäÿùèå â íåå. Òàêèì îáðàçîì, êëàññ Facade ÿâëÿåòñÿ êàê áû ìîñòîì ìåæäó ïðîñòðàíñòâîì èìåí interpr.logic è êëàññàìè, ðåàëèçóþùèìè ïîëüçîâàòåëüñêèé èíòåðôåéñ.

Ïðè çàïóñêå èíòåðïðåòàòîðà â îáðàáîò÷èêå ñîáûòèÿ Load êëàññà Form1 ïðîèñõîäèò íà÷àëüíàÿ èíèöèàëèçàöèÿ ïðèëîæåíèÿ. Âíà÷àëå âûçûâàåòñÿ ñòàòè÷åñêèé ìåòîä Facade.Create(), êîòîðîìó ïåðåäàåòñÿ ññûëêà íà ýëåìåíò óïðàâëåíèÿ ConsoleBox, ðàñïîëîæåííûé íà ãëàâíîé ôîðìå èíòåðïðåòàòîðà. Òèï ýòîãî ïàðàìåòðà – èíòåðôåéñ IConsole. Ïåðåäàííàÿ ññûëêà íî îáúåêò êîíñîëè ïðèñâàèâàåòñÿ ñâîéñòâó InterprEnvironment.CurrentConsole.  ìåòîäå Facade.Create() ñîçäàåòñÿ åäèíñòâåííûé îáúåêò êëàññà Facade, ê êîòîðîìó â äàëüíåéøåì äîñòóï îñóùåñòâëÿåòñÿ ÷åðåç ñòàòè÷åñêîå ñâîéñòâî òîëüêî äëÿ ÷òåíèÿ Facade.Instance.  Çäåñü èñïîëüçóåòñÿ ïàòòåðí Singleton.

Ïðè ïåðâîì îáðàùåíèè ê ñâîéñòâó InterprEnvironment.Instance âûçûâàåòñÿ êîíñòðóêòîð êëàññà InterprEnvironment,  íåì ñîçäàåòñÿ îáúåêò ConsoleNamespace äëÿ ïðîñòðàíñòâà èìåí êîíñîëè. Çàòåì ïðîèçâîäèòñÿ âîññòàíîâëåíèå ïåðåìåííûõ, ñîõðàíåííûõ â ôàéëå variables â ðàáî÷åì êàòàëîãå èíòåðïðåòàòîðà. Åñëè ýòîò ôàéë îòñóòñòâóåò, òî îí ñîçäàåòñÿ (ïóñòîé) è âîññòàíîâëåíèå íå ïðîèçâîäèòñÿ. Äàííûé ôàéë ÿâëÿåòñÿ äâîè÷íûì.  åãî íà÷àëå çàïèñûâàåòñÿ îáùåå ÷èñëî ïåðåìåííûõ, çàòåì äëÿ êàæäîé èç íèõ ñîõðàíÿåòñÿ èíôîðìàöèÿ î òèïå (îäèí ñèìâîë), èìÿ (ñòðîêà) è çíà÷åíèå. Äëÿ ìàññèâà ïîñëå èìåíè çàïèñûâàåòñÿ îáùåå ÷èñëî ýëåìåíòîâ, çàòåì êàæäûé èç ýëåìåíòîâ â âèäå ïàðû «òèï-çíà÷åíèå». Âîññòàíîâëåíèå ïåðåìåííûõ ïðîèçâîäèòñÿ â ìåòîäå ConsoleNamespace.Restore(). Åñëè âîññòàíîâëåíèå íå ïðîøëî óñïåøíî ïî ïðè÷èíå íåïðàâèëüíîãî ôîðìàòà ôàéëà variables, òî â ìåòîäå Restore() ãåíåðèðóåòñÿ èñêëþ÷åíèå NamespaceSerialisationException. Îíî ïåðåõâàòûâàåòñÿ â êîíñòðóêòîðå êëàññà InterprEnvironment, â ðåçóëüòàòå ÷åãî èçìåíÿåòñÿ çíà÷åíèå ñîîòâåòñòâóþùåãî ïîëÿ, ïîñëå ýòîãî ñâîéñòâî InterprEnvironment.NotRestored, êàê è îáðàùàþùååñÿ ê íåìó ñâîéñòâî Facade.NotRestored, âîçâðàùàåò èñòèíó.  ñëó÷àå, åñëè òàêàÿ îøèáêà ïðîèçîøëà, â îáðàáîò÷èêå Form1.Form1_Load âûäàåòñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå ïîëüçîâàòåëþ.

Íà ñëåäóþùåì øàãå èíèöèàëèçàöèè óñòàíàâëèâàåòñÿ îáðàáîò÷èê äëÿ ñîáûòèÿ Facade.Done (çàâåðøåíèå âûïîëíåíèÿ êîìàíäû). Çàòåì çàãðóæàþòñÿ ïîëüçîâàòåëüñêèå ôóíêöèè ñ ïîìîùüþ ìåòîäà Facade.LoadSubs(), âûçûâàþùåãî ìåòîä InterprEnvironment.LoadSubs(). Åñëè ïðè çàãðóçêå êàêîé-ëèáî ôóíêöèè ïðîèçîøëà îøèáêà, ñîîáùåíèå âûâîäèòñÿ íà êîíñîëü. Íàêîíåö, âûçûâàåòñÿ ìåòîä Prompt() (âûâåñòè ïðèãëàøåíèå è æäàòü ââîäà êîìàíäû) ýëåìåíòà óïðàâëåíèÿ ConsoleBox, ðàñïîëîæåííîãî íà ãëàâíîé ôîðìå.

Êëàññ Facade èìååò öåëûé ðÿä ìåòîäîâ äëÿ ðàáîòû ñ ïîëüçîâàòåëüñêèìè ôóíêöèÿìè è ïåðåìåííûìè ñðåäû êîíñîëè, êîòîðûå âûçûâàþò ñîîòâåòñòâóþùèå ìåòîäû îáúåêòà InterprEnvironment.Instance. Ñðåäè íèõ: LoadSub(), LoadSubs(), GetSubs(), UnloadSub(), GetVariables(), DeleteVariable(), SaveVariables(). ×åðåç ýòè ìåòîäû ïðîèçâîäÿòñÿ îïåðàöèè âî ìíîãèõ îáðàáîò÷èêàõ ñîáûòèé ïîëüçîâàòåëüñêîãî èíòåðôåéñà.

Íî, ïîæàëóé, íàèáîëåå âàæíûì èç ìåòîäîâ êëàññà Facade ÿâëÿåòñÿ ExecuteCommand() – âûïîëíèòü êîìàíäó. Îí âûçûâàåòñÿ â îáðàáîò÷èêå ñîáûòèÿ GetCommand ýëåìåíòà ConsoleBox íà ãëàâíîé ôîðìå.  íåì â îòäåëüíîì ïîòîêå çàïóñêàåòñÿ íà âûïîëíåíèå ÷àñòíûé ìåòîä ThrStart(), â êîòîðîì ââåäåííàÿ ñ êîíñîëè êîìàíäà ñíà÷àëà «êîìïèëèðóåòñÿ» ìåòîäîì LineCompiler.CompileCommand(), çàòåì  âûïîëíÿåòñÿ, ïî îêîí÷àíèè ÷åãî ãåíåðèðóåòñÿ ñîáûòèå Facade.Done(), â îáðàáîò÷èêå êîòîðîãî êîíñîëü ïåðåâîäèòñÿ â ñîñòîÿíèå îæèäàíèÿ ñëåäóþùåé êîìàíäû ìåòîäîì ConsoleBox.Prompt(). È «êîìïèëÿöèÿ» è âûïîëíåíèå êîìàíäû ïðîèçâîäÿòñÿ â áëîêàõ try, â ñëó÷àå âîçíèêíîâåíèÿ èñêëþ÷åíèÿ íà êîíñîëü âûäàåòñÿ ñîîòâåòñòâóþùåå ñîîáùåíèå îá îøèáêå.

Íåîáõîäèìîñòü âûïîëíÿòü êîìàíäû â îòäåëüíîì ïîòîêå ñâÿçàíà ñ òåì, ÷òî òîëüêî â ýòîì ñëó÷àå ìîæíî ïðåðâàòü çàöèêëèâøóþñÿ èëè äîëãî ðàáîòàþùóþ ïîëüçîâàòåëüñêóþ ôóíêöèþ áåç àâàðèéíîãî çàâåðøåíèÿ èíòåðïðåòàòîðà. Äëÿ ïåðåçàïóñêà èíòåðïðåòàòîðà, âîçìîæíî, ñ ïðåðûâàíèåì ðàáîòû ïîëüçîâàòåëüñêîé ôóíêöèè, ïðåäíàçíà÷åí ìåòîä Facade.Restart().  íåì â îòäåëüíîì ïîòîêå çàïóñêàåòñÿ ìåòîä DoRestart(), â êîòîðîì âûïîëíÿþòñÿ ñëåäóþùèå äåéñòâèÿ. Âî-ïåðâûõ, åñëè â äàííûé ìîìåíò âðåìåíè âûïîëíÿåòñÿ êîìàíäà, òî âûçûâàåòñÿ ñòàòè÷åñêèé ìåòîä Subroutine.Moment.Break(). íåì ñ ïîìîùüþ ìåòîäà Interlocked.Exchange() (áåçîïàñíîå ïðè ïàðàëëåëüíîì âûïîëíåíèè ïðèñâàèâàíèå) ñòàòè÷åñêîìó ïîëþ Subroutine.Moment.s_break ïðèñâàèâàåòñÿ çíà÷åíèå 1. Íà êàæäîé èòåðàöèè öèêëà â ìåòîäå Subroutine.Moment.Run(), ïîìèìî âûïîëíåíèÿ î÷åðåäíîãî îïåðàòîðà ôóíêöèè, ïðîâåðÿåòñÿ çíà÷åíèå ýòîãî ïîëÿ. Åñëè îíî ðàâíî åäèíèöå, òî ãåíåðèðóåòñÿ èñêëþ÷åíèå CalcException, òî åñòü âûïîëíåíèå êîìàíäû çàâåðøàåòñÿ ñ îøèáêîé âðåìåíè âûïîëíåíèÿ. Ïîñëå âûçîâà Subroutine.Moment.Break() â ìåòîäå DoRestart() ñëåäóåò öèêë áåç òåëà, êîòîðûé âûïîëíÿåòñÿ äî òåõ ïîð, ïîêà âûïîëíåíèå êîìàíäû íå áóäåò çàâåðøåíî, ÷åãî, êîíå÷íî æå, íå ïðèõîäèòñÿ äîëãî æäàòü. Ïîñëå òîãî, êàê âûïîëíåíèå áóäåò ïðåðâàíî, ïðîèçâîäèòñÿ ïîâòîðíàÿ èíèöèàëèçàöèÿ, àíàëîãè÷íàÿ ïðîèñõîäÿùåé ïðè çàïóñêå èíòåðïðåòàòîðà.

Äëÿ ðåàëèçàöèè ìíîãîïîòî÷íîñòè èñïîëüçóåòñÿ ñòàíäàðòíûé êëàññ System.Threading.Thread. Åãî êîíñòðóêòîðó ïåðåäàåòñÿ îäèí ïàðàìåòð òèïà äåëåãàòà System.Threading.ThreadStart (ïðîöåäóðà áåç ïàðàìåòðîâ). Ìåòîä, íà êîòîðûé óêàçûâàåò ýòîò äåëåãàò, íà÷èíàåò âûïîëíÿòüñÿ â îòäåëüíîì ïîòîêå ïðè âûçîâå ìåòîäà Start() îáúåêòà ïîòîêà. Êîãäà ìåòîä, çàïóùåííûé â ïîòîêå, âîçâðàùàåòñÿ, âûïîëíåíèå ïîòîêà çàâåðøàåòñÿ. Ïîâòîðíîå èñïîëüçîâàíèå òîãî æå îáúåêòà êëàññà Thread íåâîçìîæíî, åãî íóæíî ñîçäàâàòü çàíîâî. Ïðè èñïîëüçîâàíèè ìíîãîïîòî÷íîñòè ñëåäóåò ïðèíèìàòü ðÿä ìåð ïðåäîñòîðîæíîñòè äëÿ îáåñïå÷åíèÿ áåçîïàñíîãî äîñòóïà ê îáùèì äàííûì. Íàïðèìåð, ïðèñâàèâàíèå çíà÷åíèé ïåðåìåííûì, èñïîëüçóåìûì íåñêîëüêèìè ïîòîêàìè, ïî âîçìîæíîñòè ñëåäóåò ïðîèçâîäèòü ñ ïîìîùüþ ìåòîäà Interlocked.Exchange, êîòîðûé ãàðàíòèðóåò àòîìàðíîñòü îïåðàöèè, òî åñòü òî, ÷òî åå âûïîëíåíèå íå áóäåò ïðåðâàíî äî ïîëíîãî çàâåðøåíèÿ äëÿ ïåðåäà÷è óïðàâëåíèÿ äðóãîìó ïîòîêó. Òàêæå îáðàùàòüñÿ ê ìåòîäàì è ñâîéñòâàì ýëåìåíòîâ ãðàôè÷åñêîãî èíòåðôåéñà ïîëüçîâàòåëÿ  íàïðÿìóþ ìîæíî òîëüêî èç òîãî æå ïîòîêà, â êîòîðîì îíè áûëè ñîçäàíû. Åñëè íåîáõîäèìî âîçäåéñòâîâàòü íà ãðàôè÷åñêèé èíòåðôåéñ ïîëüçîâàòåëÿ èç äðóãèõ ïîòîêîâ, òî ýòî ñëåäóåò äåëàòü â ìåòîäå (ïðîöåäóðå áåç ïàðàìåòðîâ), âûçûâàåìîì ñ ïîìîùüþ äåëåãàòà System.Windows.Forms.MethodInvoker.  ÿçûêå C# èìåþòñÿ è äðóãèå ñðåäñòâà ñèíõðîíèçàöèè ðàáîòû ïîòîêîâ, êîòîðûå íå èñïîëüçóþòñÿ â äàííîì èíòåðïðåòàòîðå.


Çàêëþ÷åíèå

Ìíîþ âûïîëíåí èíòåðïðåòàòîð íåñëîæíîãî ÿçûêà ïðîãðàììèðîâàíèÿ. Èíòåðïðåòàòîð ðàáîòàåò â èíòåðàêòèâíîì ðåæèìå, âûïîëíÿÿ êîìàíäû, ââîäèìûå ñ êîíñîëè, êîòîðûå ìîãóò ñîäåðæàòü âûçîâû ïîëüçîâàòåëüñêèõ ôóíêöèé (ïîäïðîãðàìì). Ïîëüçîâàòåëüñêèå ôóíêöèè ìîãóò ñîäåðæàòü ñòðóêòóðíûå êîíñòðóêöèè – öèêëû, âåòâëåíèÿ, âûçîâû äðóãèõ ôóíêöèé (âîçìîæíà è ðåêóðñèÿ). Âîçìîæíà ðàáîòà ñ ÷èñëîâûìè è ñòðîêîâûìè äàííûìè, à òàêæå ñ îäíîìåðíûìè ìàññèâàìè. Èìååòñÿ äîñòàòî÷íî áîëüøîå ÷èñëî âñòðîåííûõ ìàòåìàòè÷åñêèõ è äðóãèõ ôóíêöèé. Ïðåäâàðèòåëüíîãî îáúÿâëåíèÿ ïåðåìåííûõ íå òðåáóåòñÿ, ñèíòàêñèñ ìàòåìàòè÷åñêèé âûðàæåíèé – òðàäèöèîííûé äëÿ ÿçûêîâ âûñîêîãî óðîâíÿ. Ýòî äåëàåò èíòåðïðåòàòîð óäîáíûì â èñïîëüçîâàíèè. Äàííûé èíòåðïðåòàòîð ìîæåò ïðèìåíÿòüñÿ êàê â ó÷åáíûõ öåëÿõ, íàïðèìåð, äëÿ îáó÷åíèÿ øêîëüíèêîâ îñíîâàì ïðîãðàììèðîâàíèÿ, òàê è êà÷åñòâå «ïðîãðàììèðóåìîãî ìèêðîêàëüêóëÿòîðà» äëÿ ïðàêòè÷åñêèõ ðàñ÷åòîâ, ñëîæíîñòü êîòîðûõ íå òðåáóåò ïðèìåíåíèÿ ñïåöèôè÷åñêîãî ïðîãðàììíîãî îáåñïå÷åíèÿ.


Ïðèëîæåíèå. Èñõîäíûé òåêñò (ñîêðàùåííî).

Ââèäó áîëüøîãî îáúåìà èñõîäíîãî êîäà, ïðèâåäåíû ëèøü íàèáîëåå âàæíûå åãî ôðàãìåíòû.

1. Êëàññ VarBase.

using System;

using System.IO;

namespace interpr.logic.vartypes {

         public abstract class VarBase : ICloneable , IComputable {

                   public bool IsArray() {

                            return (this is ArrayVar);

                   }

                   public bool IsNum() {

                            return (this is NumVar);

                   }

                   public bool IsString() {

                            return (this is StringVar);

                   }

                   public bool IsInt() {

                            return (this is IntVar);

                   }

                   public bool IsReal() {

                            return (this is RealVar);

                   }

                   public bool IsSingle() {

                            return (this is SingleVar);

                   }

                   public virtual VarBase Compute() {

                            return this.Clone() as VarBase;

                   }

                   public abstract System.Object Clone();

                   public override abstract string ToString();

                   public abstract void Serialise(BinaryWriter bw);

         }

}

2. Êëàññ ArrayVar.

using System.Collections;

using System.IO;

namespace interpr.logic.vartypes {

         public class ArrayVar : VarBase {

                   public virtual IntVar Size {

                            get { return new IntVar(m_list.Count); }

                   }

                   private ArrayList m_list;

                   public ArrayVar() {

                            m_list = new ArrayList();

                   }

                   public int GetSize() {

                            return m_list.Count;

                   }

                   public void setAt(int index, SingleVar var) {

                            if (var == null) {

                                      throw new CalcException("Îøèáêà");

                            }

                            if (index < 0)

                                      throw new CalcException("Èíäåêñ íå ìîæåò áûòü îòðèöàòåëüíûì");

                            for (int ind = index, s = m_list.Count; ind >= s; ind--)

                                      m_list.Add(null);

                            m_list[index] = var.Clone();

                   }

                   public SingleVar getAt(int index) {

                            if (index < 0)

                                      throw new CalcException("Èíäåêñ íå ìîæåò áûòü îòðèöàòåëüíûì");

                            if (index >= m_list.Count)

                                      throw new CalcException("Âûõîä çà ïðåäåëû ìàññèâà");

                            else

                                      return (SingleVar) m_list[index];

                   }

                   public SingleVar this[int index] {

                            get { return getAt(index); }

                            set { setAt(index, value); }

                   }

                   public IntVar IsElementDefined(int index) {

                            bool result = index>=0;

                            result = result&&(index<m_list.Count);

                            result = result&&(m_list[index]!=null);

                            return new IntVar(result);

                   }

                   public override System.Object Clone() {

                            ArrayVar res = new ArrayVar();

                            int li = 0;

                            SingleVar e = null;

                            while (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null)

                                               res.m_list.Add(e.Clone());

                                      else

                                               res.m_list.Add(null);

                            }

                            return res;

                   }

                   public override void Serialise(BinaryWriter bw) {

                            bw.Write('a');

                            int size = m_list.Count;

                            bw.Write(size);

                            for (int i = 0; i < size; i++) {

                                      if (m_list[i] == null)

                                               bw.Write('n');

                                      else

                                               (m_list[i] as VarBase).Serialise(bw);

                            }

                  }

                   public override System.String ToString() {

                            System.String res = "[";

                            int li = 0;

                            SingleVar e = null;

                            if (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null) {

                                               res += e.ToString();

                                      }

                                      else

                                               res += "-";

                            }

                            while (li < m_list.Count) {

                                      e = (SingleVar) m_list[li++];

                                      if (e != null) {

                                               res += ", " + e.ToString();

                                      }

                                      else

                                               res += ", -";

                            }

                            return res + "]";

                   }

         }

}

3. Êëàññ InterprEnvironment.

using System;

using System.Collections;

using System.IO;

namespace interpr.logic {

         public class InterprEnvironment {

                   private SubroutinesManager m_subsman = null;

                   private ConsoleNamespace m_console_vars;

                   private bool m_not_restored = false;

                   public bool NotRestored {

                            get { return m_not_restored; }

                   }

                   public ConsoleNamespace ConsoleNamespace {

                            get { return m_console_vars; }

                   }

                   public ConsoleNamespace.VariableReport[] GetGlobalVarsList() {

                            return m_console_vars.GetVariableList();

                   }

                   private InterprEnvironment() {

                            m_current_namespace = new ConsoleNamespace();

                            m_console_vars = m_current_namespace as ConsoleNamespace;

                            m_not_restored = false;

                            try {

                                      m_console_vars.Restore();

                            } catch {

                                      m_not_restored = true;

                                      m_console_vars = new ConsoleNamespace();

                                      m_current_namespace = m_console_vars;

                            }

                   }

                   public void LoadSubs() {

                            if (m_current_console == null)

                                      throw new OtherException("Error in Environment.LoadSubs()");

                            s_instance.m_subsman = SubroutinesManager.GetInstance();

                            s_instance.m_subsman.ReloadAll();

                   }

                   private static InterprEnvironment s_instance = null;

                   public static InterprEnvironment Instance {

                            get {

                                      if (s_instance == null)

                                               s_instance = new InterprEnvironment();

                                      return s_instance;

                            }

                   }

                   public static void Reset() {

                            s_instance = new InterprEnvironment();

                   }

                   public void SaveVars() {

                            m_console_vars.Save();

                   }

                   public bool LoadSub(string name) {

                            return m_subsman.Load(name);

                   }

                   private Namespace m_current_namespace = null;

                   public Namespace CurrentNamespace {

                            get { return m_current_namespace; }

                            set { m_current_namespace = value; }

                   }

                   private IConsole m_current_console = null;

                   public IConsole CurrentConsole {

                            get { return m_current_console; }

                            set { m_current_console = value; }

                   }

                   public Operation GetFunction(string name) {

                            if (name == "abs")

                                      return Operation.ABS;

                                    

                            ...........................

                            if (name == "size")

                                      return Operation.SIZE;

                            return new SubName(name);

                   }

                   public string[] LoadedSubs {

                            get { return m_subsman.SubroutineNames; }

                   }

                   private class SubroutinesManager {

                            private ArrayList m_subs = new ArrayList();

                            private ArrayList m_names = new ArrayList();

                            private SubroutinesManager() {

                                      DirectoryInfo di =

                                               new DirectoryInfo(Directory.GetCurrentDirectory() + @"\subroutines");

                                      if (!di.Exists) {

                                               di.Create();

                                      }

                            }

                            public bool Load(string name) {

                                      FileInfo fi = new FileInfo(Directory.GetCurrentDirectory() + @"\subroutines\" + name);

                                      if (!fi.Exists)

                                               throw new OtherException("Error in SubroutinesManager.Load()");

                                      return LoadFile(fi);

                            }

                            private bool LoadFile(FileInfo file) {

                                      try {

                                               StreamReader sr = file.OpenText();

                                               LinkedList ll = new LinkedList();

                                               try {

                                                        while (sr.Peek() != -1) {

                                                                  ll.AddFirst(sr.ReadLine());

                                                        }

                                               } finally {

                                                        sr.Close();

                                               }

                                               string[] strs = new String[ll.Count];

                                               int i = 0;

                                               while (!ll.IsEmpty()) {

                                                        strs[i] = (ll.RemoveLast() as String);

                                                        i++;

                                               }

                                               Subroutine sub;

                                               try {

                                                        sub = new Subroutine(strs, file.Name);

                                               } catch (LineSyntaxException ex) {

                                                        InterprEnvironment.Instance.CurrentConsole.PrintLn("Ñèíòàêñè÷åñêàÿ îøèáêà â " + ex.Function + "[] at line " + ex.Line + " " + ex.Message);

                                                        return false;

                                               } catch (SyntaxErrorException ex) {

                                                        InterprEnvironment.Instance.CurrentConsole.PrintLn("Ñèíòàêñè÷åñêàÿ îøèáêà â " + file.Name + " " + ex.Message);

                                                        return false;

                                               }

                                               Set(file.Name, sub);

                                      } catch {

                                               throw new OtherException("Error in Environment.Load()");

                                      }

                                      return true;

                            }

                            public Subroutine this[string name] {

                                      get {

                                               int sres = m_names.IndexOf(name);

                                               if (sres < 0)

                                                        return null;

                                               else

                                                        return m_subs[sres] as Subroutine;

                                      }

                            }

                            private void Set(string name, Subroutine sub) {

                                      int sres = m_names.IndexOf(name);

                                      if (sres >= 0) {

                                               m_names.RemoveAt(sres);

                                               m_subs.RemoveAt(sres);

                                      }

                                      m_names.Add(name);

                                      m_subs.Add(sub);

                            }

                            private static SubroutinesManager s_inst = null;

                            public static SubroutinesManager GetInstance() {

                                      if (s_inst == null)

                                               s_inst = new SubroutinesManager();

                                      return s_inst;

                            }

                            public string[] SubroutineNames {

                                      get {

                                               int count = m_names.Count;

                                               string[] res = new string[count];

                                               for (int i = 0; i < count; i++) {

                                                        res[i] = (m_names[i] as String);

                                               }

                                               for (int i = 0; i < count - 1; i++) {

                                                        int k = i;

                                                        for (int j = i + 1; j < count; j++)

                                                                  k = (string.Compare(res[j], res[k]) < 0) ? j : k;

                                                        if (i != k) {

                                                                  string temp = res[i];

                                                                  res[i] = res[k];

                                                                  res[k] = temp;

                                                        }

                                               }

                                               return res;

                                      }

                            }

                            public void ReloadAll() {

                                      m_subs = new ArrayList();

                                      m_names = new ArrayList();

                                      DirectoryInfo di =

                                               new DirectoryInfo(Directory.GetCurrentDirectory() + @"\subroutines");

                                      if (!di.Exists) {

                                               di.Create();

                                      }

                                      foreach (FileInfo file in di.GetFiles()) {

                                               if (Parser.IsID(file.Name)) {

                                                        LoadFile(file);

                                               }

                                      }

                            }

                            public void Unload(string name) {

                                      int index = m_names.IndexOf(name);

                                      if (index >= 0) {

                                               m_names.RemoveAt(index);

                                               m_subs.RemoveAt(index);

                                      }

                            }

                   }

                   public Subroutine GetSub(string name) {

                            Subroutine res = m_subsman[name];

                            if (res == null)

                                      throw new CalcException("Ôóíêöèÿ " + name + " íå ñóùåñòâóåò");

                            return res;

                   }

                   public void UnloadSub(string name) {

                            m_subsman.Unload(name);

                   }

         }

}

4. Êëàññ Namespace.

using System;

using System.Collections;

using interpr.logic.vartypes;

namespace interpr.logic {

         public class NamespaceSerializationException : Exception {

                   public NamespaceSerializationException() : base() {}

         }

         public class Namespace {

                   protected class Pair {

                            internal string m_str;

                            internal VarBase m_var;

                   }

                   protected ArrayList m_list = new ArrayList();

                   protected int m_n = 0;

                   private Namespace m_previous_namespace = null;

                   public Namespace PreviousNamespace {

                            get { return m_previous_namespace; }

                   }

                   public Namespace(Namespace previous) {

                            m_previous_namespace = previous;

                   }

                   protected Namespace() {}

                   public VarBase Get(string name) {

                            if (m_n == 0)

                                      return null;

                            int i = 0;

                            Pair p;

                            do {

                                      p = (m_list[i++] as Pair);

                                      if (p.m_str == name)

                                               return p.m_var;

                            } while (i < m_n);

                            return null;

                   }

                   public void Assign(VarBase var, string name) {

                            Pair p;

                            if (m_n != 0) {

                                      int i = 0;

                                      do {

                                               p = (m_list[i++] as Pair);

                                               if (p.m_str == name) {

                                                        p.m_var = var;

                                                        return;

                                               }

                                      } while (i < m_n);

                            }

                            p = new Pair();

                            p.m_var = var;

                            p.m_str = name;

                            m_list.Add(p);

                            m_n++;

                   }

                   public void AssignToElement(SingleVar var, string name, int index) {

                            Pair p;

                            if (m_n != 0) {

                                      int i = 0;

                                      do {

                                               p = (m_list[i++] as Pair);

                                               if (p.m_str == name) {

                                                        if (!p.m_var.IsArray())

                                                                  throw new CalcException("Ïåðåìåííàÿ íå ÿâëÿåòñÿ ìàññèâîì");

                                                        (p.m_var as ArrayVar)[index] = var;

                                                        return;

                                               }

                                      } while (i < m_n);

                            }

                            p = new Pair();

                            p.m_var = new ArrayVar();

                            (p.m_var as ArrayVar)[index] = var;

                            p.m_str = name;

                            m_list.Add(p);

                            m_n++;

                   }

                   public void Remove(String name) {

                            if (m_n == 0)

                                      return;

                            int i = 0;

                            do {

                                      Pair p = (m_list[i++] as Pair);

                                      if (p.m_str == name) {

                                               m_list.RemoveAt(i - 1);

                                               m_n--;

                                               return;

                                      }

                            } while (i < m_n);

                   }

                   public VarBase this[string name] {

                            set { Assign(value, name); }

                            get { return Get(name); }

                   }

         }

}

5. Èíòåðôåéñ IÑomputable.

namespace interpr.logic {

         public interface IComputable {

                   logic.vartypes.VarBase Compute();

         }

}

6. Êëàññ Call.

using interpr.logic.vartypes;

namespace interpr.logic {

         public class Call : IComputable {

                   private Operation m_op;

                   private ArgList m_al = null;

                   public Call(Operation op) {

                            m_op = op;

                   }

                   public void SetArgList(ArgList al) {

                            m_al = al;

                   }

                   public int ReqCount {

                            get { return m_op.ReqCount; }

                   }

                   public VarBase Compute() {

                            return m_op.Perform(m_al);

                   }

         }

}

7. Êëàññ ArgList

using interpr.logic.vartypes;

namespace interpr.logic {

         public class ArgList {

                   private bool m_read = false;

                   private LinkedList m_list = new LinkedList();

                   private LinkedList.Iterator m_i = null;

                   public void Add(VarBase var) {

                            if (m_read)

                                      throw new OtherException("Write to the argument list after reading begin");

                            m_list.Add(var);

                   }

                   public VarBase Get() {

                            if (!m_read)

                                      throw new OtherException("Try to read from argument list before reset");

                            if (!m_i.HasPrevious)

                                      throw new OtherException("Try to read from empty argument list");

                            m_read = true;

                            IComputable obj = (m_i.Previous() as IComputable);

                            if (obj == null)

                                      throw new CalcException("Ïåðåìåííàÿ íå èíèöèàëèçèðîâàííà.");

                            return obj.Compute();

                   }

                   public void Reset() {

                            m_read = true;

                            m_i = m_list.GetIterator(m_list.Count);

                   }

                   public int Count {

                            get { return m_list.Count; }

                   }

         }

}

8. Êëàññ Expression.

using System;

using interpr.logic.vartypes;

namespace interpr.logic {

         public class Expression {

                   public Expression(String str) {

                            Parser p = new Parser(str);

                            Analyse(p);

                   }

                   public Expression(Parser p) {

                            Analyse(p);

                   }

                   private class Element {

                            internal IComputable m_o;

                            internal Element m_next;

                            internal Element(IComputable obj, Element next) {

                                      m_o = obj;

                                      m_next = next;

                            }

                   }

                   private Element m_top = null;

                   private Element m_bottom = null;

                   private int m_c = 0;

                   private void AddFront(IComputable obj) {

                            m_c++;

                            if (m_c == 1)

                                      m_top = m_bottom = new Element(obj, null);

                            else {

                                      Element t = new Element(obj, null);

                                      m_bottom.m_next = t;

                                      m_bottom = t;

                            }

                   }

                   private void Analyse(Parser p) {

                            try {

                                      LinkedList l = new LinkedList();

                                      while (p.MoveNext())

                                               l.Add(p.Current);

                                      OPZ(l);

                            }

                            catch (CalcException ex) {

                                      throw ex;

                            }

                            catch {

                                      throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà â âûðàæåíèè");

                            }

                   }

                   private void OPZ(LinkedList tokens) {

                   /* ** Áèíàðíàÿ îïåðàöèÿ âûòàëêèâàåò èç ñòåêà â ðåçóëüòàò

                    * âñå îïåðàöèè ñ áîëüøèì èëè ðàâíûì ïðèîðèòåòîì, çàòåì

                    * çàïèñûâàåòñÿ â ñòåê ñàìà

                    * ** Óíàðíàÿ îïåðàöèÿ çàïèñûâàåòñÿ â ñòåê

                   * ** Îòêðûâàþùàÿ ñêîáêà çàïèñûâàåòñÿ â ñòåê

                   * ** Çàêðûâàþùàÿ ñêîáêà âûòàëêèâàåò â ðåçóëüòàò âñå îïåðàöèè

                   * èç ñòåêà äî îòêðûâàþùåé ñêîáêè, çàòåì

                    * ñêîáêè óíè÷òîæàþòñÿ è âûòàëêèâàþòñÿ óíàðíûå îïåðàöèè

                    * ** Ïåðåìåííàÿ èëè êîíñòàíòà ñðàçó ïèøóòñÿ â ðåçóëüòàò, çàòåì

                    * âûòàëêèâàþòñÿ èç ñòåêà óíàðíûå îïåðàöèè

                    * ** Ïðè âûçîâå ôóíêöèè

                    * ñíà÷àëà îòäåëüíî ðàçáèðàþòñÿ âñå îïåðàíäû, çàòåì â ðåçóëüòàò

                   * äîïèñûâàåòñÿ ñàìà ôóíêöèÿ, êàê îïåðàöèÿ

                   * ** Îáðàùåíèå ê ýëåìåíòó ìàññèâà îáðàáàòûâàåòñÿ àíàëîãè÷íî

                   * Â êîíöå âñå îñòàâøèåñÿ â ñòåêå îïåðàöèè âûòàëêèâàþòñÿ â ðåçóëüòàò

                   */

                            InterprEnvironment env = InterprEnvironment.Instance;

                            if (tokens.IsEmpty()) return;

                            LinkedList.Iterator itr = tokens.GetIterator();

                            LinkedList stk = new LinkedList();

                            while (itr.HasMore) {

                                      string si = (itr.Step() as System.String);

                                      if (si == "(") {

                                               stk.Add(O_BR);

                                      }

                                      else if (si == ")") {

                                               while (true) {

                                                        object o = stk.RemoveLast();

                                                        if (o == O_BR) break;

                                                        AddFront(new Call(o as Operation));

                                               }

                                               while ((!stk.IsEmpty()) && IsUnary(stk.Last)) {

                                                        AddFront(new Call(stk.RemoveLast() as Operation));

                                               }

                                      }

                                      else if (Parser.IsID(si)) {

                                               bool bfun = false;

                                               bool barray = false;

                                               if (itr.HasMore) {

                                                        string s = (itr.Step() as System.String);

                                                        if (s == "[")

                                                                  bfun = true;

                                                        else if (s == "{")

                                                                  barray = true;

                                                        else

                                                                  itr.Previous();

                                               }

                                               if (bfun) {

                                                        LinkedList l = null;

                                                        while (true) {

                                                                  l = new LinkedList();

                                                                  int level = 0;

                                                                  while (true) {

                                                                           if (!itr.HasMore)

                                                                                     throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà â âûðàæåíèè");

                                                                           string sj = (itr.Step() as System.String);

                                                                           if (sj == "[") {

                                                                                     level++;

                                                                                     l.Add(sj);

                                                                           }

                                                                           else if (sj == "]") {

                                                                                     if (level == 0)

                                                                                              goto label1;

                                                                                     else {

                                                                                              level--;

                                                                                              l.Add(sj);

                                                                                     }

                                                                           }

                                                                           else if (sj == ",") {

                                                                                     if (level > 0)

                                                                                              l.Add(sj);

                                                                                     else

                                                                                              break;

                                                                           }

                                                                           else

                                                                                     l.Add(sj);

                                                                  }

                                                                  OPZ(l);

                                                        }

                                                        label1:

                                                        if (l != null)

                                                                  OPZ(l);

                                                        Operation sub = env.GetFunction(si);

                                                        AddFront(new Call(sub));

                                                        while ((stk.Count > 0) && IsUnary(stk.Last)) {

                                                                  AddFront(new Call((Operation) stk.RemoveLast()));

                                                        }

                                               }

                                               else if (barray) {

                                                        LinkedList l = new LinkedList();

                                                        int level = 0;

                                                        while (true) {

                                                                  if (!itr.HasMore)

                                                                           throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà â âûðàæåíèè");

                                                                  String sj = (String) itr.Step();

                                                                  if (sj == "{") {

                                                                           level++;

                                                                           l.Add(sj);

                                                                  }

                                                                  else if (sj == "}") {

                                                                           if (level == 0)

                                                                                    break;

                                                                           else {

                                                                                     level--;

                                                                                     l.Add(sj);

                                                                           }

                                                                  }

                                                                  else

                                                                           l.Add(sj);

                                                        }

                                                        OPZ(l);

                                                        VarName v = new VarName(si);

                                                        AddFront(v);

                                                        AddFront(new Call(Operation.INDEX));

                                                        while ((stk.Count > 0) && IsUnary(stk.Last)) {

                                                                  AddFront(new Call(stk.RemoveLast() as Operation));

                                                        }

                                               }

                                               else {

                                                        VarName v = new VarName(si);

                                                        AddFront(v);

                                                        while ((stk.Count > 0) && IsUnary(stk.Last)) {

                                                                  AddFront(new Call(stk.RemoveLast() as Operation));

                                                        }

                                               }

                                      }

                                      else {

                                               Operation op = StrToOperation(si);

                                               if (op == null) {

                                                        SingleVar sv = SingleVar.FromString(si);

                                                        if (si == null)

                                                                  throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà â âûðàæåíèè");

                                                        AddFront(sv);

                                                        while ((stk.Count > 0) && IsUnary(stk.Last)) {

                                                                  AddFront(new Call(stk.RemoveLast() as Operation));

                                                        }

                                               }

                                               else {

                                                        //operation

                                                        if (op == Operation.ADD) {

                                                                  itr.Previous();

                                                                  if (!itr.HasPrevious) {

                                                                           stk.Add(Operation.UPLUS);

                                                                           itr.Step();

                                                                           continue;

                                                                  }

                                                                  String strpr = (String) itr.Previous();

                                                                  itr.Step();

                                                                  itr.Step();

                                                                  if ((StrToOperation(strpr) != null) || (strpr == "(") ||

                                                                           (strpr == "[") || (strpr == "{")) {

                                                                           stk.Add(Operation.UPLUS);

                                                                           continue;

                                                                  }

                                                        }

                                                        else if (op == Operation.SUB) {

                                                                  itr.Previous();

                                                                  if (!itr.HasPrevious) {

                                                                           stk.Add(Operation.UMINUS);

                                                                           itr.Step();

                                                                           continue;

                                                                  }

                                                                  String strpr = (String) itr.Previous();

                                                                  itr.Step();

                                                                  itr.Step();

                                                                  if ((StrToOperation(strpr) != null) || (strpr == "(") ||

                                                                           (strpr == "[") || (strpr == "{")) {

                                                                           stk.Add(Operation.UMINUS);

                                                                           continue;

                                                                  }

                                                        }

                                                        else if (op == Operation.NOT) {

                                                                  stk.Add(op);

                                                                  continue;

                                                        }

                                                        if (stk.IsEmpty() || (stk.Last == O_BR)) {

                                                                  stk.Add(op);

                                                        }

                                                        else {

                                                                  int pr = Priority(op);

                                                                  while (true) {

                                                                           if (stk.IsEmpty())

                                                                                     break;

                                                                           Object stktop = stk.Last;

                                                                           if (stktop is Operation) {

                                                                                     int pr1 = Priority(stktop as Operation);

                                                                                     if ((pr <= pr1) && (pr1 < 6)) {

                                                                                              AddFront(new Call(stktop as Operation));

                                                                                              stk.RemoveLast();

                                                                                     }

                                                                                     else

                                                                                              break;

                                                                           }

                                                                           else

                                                                                     break;

                                                                  }

                                                                  stk.Add(op);

                                                        }

                                               }

                                      }

                            }

                            while (!stk.IsEmpty()) {

                                     Object o = stk.RemoveLast();

                                      AddFront(new Call(o as Operation));

                            }

                   }

                   public VarBase Calculate() {

                            if (m_c == 0)

                                      throw new CalcException("Îøèáêà: ïóñòîå âûðàæåíèå.");

                            Element top1 = null;

                            Element cur = m_top;

                            try {

                                      for (; cur != null; cur = cur.m_next) {

                                               if (cur.m_o is Call) {

                                                        int rc = (cur.m_o as Call).ReqCount;

                                                        ArgList al = new ArgList();

                                                        for (int i = 0; i < rc; i++) {

                                                                  if (top1 == null)

                                                                           throw new CalcException("Îøèáêà ïðè âû÷èñëåíèè âûðàæåíèÿ");

                                                                  al.Add(top1.m_o.Compute());

                                                                  top1 = top1.m_next;

                                                        }

                                                        (cur.m_o as Call).SetArgList(al);

                                                        top1 = new Element((cur.m_o as Call).Compute(), top1);

                                               }

                                               else {

                                                        top1 = new Element(cur.m_o, top1);

                                               }

                                      }

                                      if ((top1 == null) || (top1.m_next != null))

                                               throw new CalcException("Îøèáêà ïðè âû÷èñëåíèè âûðàæåíèÿ");

                                      return top1.m_o.Compute();

                            }

                            catch (CalcException ex) {

                                      throw ex;

                            }

                            catch {

                                      throw new CalcException("Îøèáêà ïðè âû÷èñëåíèè âûðàæåíèÿ");

                            }

                   }

                   private static Operation StrToOperation(String str) {

                            //íå âîçâðàùàåò óíàðíûå ïëþñ è ìèíóñ

                            if (str == "+")

                                      return Operation.ADD;

                            else if (str == "-")

                                      return Operation.SUB;

                            else if (str == "*")

                                      return Operation.MUL;

                            else if (str == "/")

                                      return Operation.DIV;

                            else if (str == "~")

                                      return Operation.NOT;

                            else if (str == "|")

                                      return Operation.OR;

                            else if (str == "&")

                                      return Operation.AND;

                            else if (str == "^")

                                      return Operation.XOR;

                            else if (str == "~=")

                                      return Operation.BE;

                            else if (str == "=")

                                      return Operation.EQ;

                            else if (str == "<>")

                                      return Operation.NE;

                            else if (str == ">=")

                                      return Operation.GE;

                            else if (str == "<=")

                                      return Operation.LE;

                            else if (str == ">")

                                      return Operation.GT;

                            else if (str == "<")

                                      return Operation.LT;

                            else

                                      return null;

                   }

                   private static int Priority(Operation op) {

                            if ((op == Operation.OR) || (op == Operation.XOR) ||

                                      (op == Operation.BE))

                                      return 1;

                            else if (op == Operation.AND)

                                      return 2;

                            else if ((op == Operation.EQ) || (op == Operation.NE) ||

                                      (op == Operation.LE) || (op == Operation.LT) ||

                                      (op == Operation.GE) || (op == Operation.GT))

                                      return 3;

                            else if ((op == Operation.ADD) || (op == Operation.SUB))

                                      return 4;

                            else if ((op == Operation.MUL) || (op == Operation.DIV))

                                      return 5;

                            else

                                      return 6;

                   }

                   private static bool IsBinary(Operation op) {

                            return Priority(op) < 6;

                   }

                   private static bool IsUnary(object obj) {

                            return ((obj == Operation.NOT) || (obj == Operation.UPLUS) ||

                                      (obj == Operation.UMINUS));

                   }

                   private class BR_c {}

                   private static object O_BR = new BR_c();

         }

}

9. Êëàññ Operation (ñîêðàùåííî).

using System;

using interpr.logic.vartypes;

namespace interpr.logic {

         public abstract class Operation {

                   public abstract int ReqCount { get; }

                   public abstract VarBase Perform(ArgList al);

                   public static readonly Operation ABS = new ABS_c();

                   private class ABS_c : Operation {

                            public override int ReqCount {

                                      get { return 1; }

                            }

                            public override VarBase Perform(ArgList al) {

                                      if (al.Count != ReqCount)

                                               throw new OtherException("Invalid argument list");

                                      al.Reset();

                                      VarBase arg1 = al.Get();

                                      if (arg1 is IntVar)

                                               return ((arg1 as IntVar).Val>0) ? (arg1.Clone() as IntVar) : (new IntVar(-((IntVar) arg1).Val));

                                      else if (arg1 is RealVar)

                                               return ((arg1 as RealVar).Val>0) ? (arg1.Clone() as RealVar) : (new RealVar(-((RealVar) arg1).Val));

                                      else

                                               throw new CalcException("Íåïðàâèëüíûå àðãóìåíòû ôóíêöèè");

                            }

                   }

                   public static readonly Operation ADD = new ADD_c();

                   private class ADD_c : Operation {

                            public override int ReqCount {

                                      get { return 2; }

                            }

                            public override VarBase Perform(ArgList al) {

                                      if (al.Count != ReqCount)

                                               throw new OtherException("Invalid argument list");

                                      al.Reset();

                                      VarBase arg1 = al.Get();

                                      VarBase arg2 = al.Get();

                                      if(!(arg1.IsSingle()&&arg2.IsSingle()))

                                               throw new CalcException("Íåâåðíûå òèïû îïåðàíäîâ");

                                      return (arg1 as SingleVar).add(arg2 as SingleVar);

                            }

                   }

                   public static readonly Operation AND = new AND_c();

                   private class AND_c : Operation {

                            public override int ReqCount {

                                      get { return 2; }

                            }

                            public override VarBase Perform(ArgList al) {

                                      if (al.Count != ReqCount)

                                               throw new OtherException("Invalid argument list");

                                      al.Reset();

                                      VarBase arg1 = al.Get();

                                      VarBase arg2 = al.Get();

                                      if(!(arg1.IsSingle()&&arg2.IsSingle()))

                                               throw new CalcException("Íåâåðíûå òèïû îïåðàíäîâ");

                                      return (arg1 as SingleVar).and(arg2 as SingleVar);

                            }

                   }

                   .......................................................................................

         }

}

10. Êëàññ Parser.

using System;

using System.Collections;

namespace interpr.logic {

         public class Parser : IEnumerable, IEnumerator {

                   private char[] m_a;

                   private int m_len;

                   private int m_cur = 0;

                   private int m_new_cur = -1;

                   private bool m_at_begin;

                   private static readonly string[] s_keywords =

                            new string[] {

                                      "if",

                                      "else",

                                      "elseif",

                                      "endif",

                                      "while",

                                      "loop",

                                      "return",

                                      "call",

                                      "print",

                                      "println",

                                      "readln",

                                      "clear",

                                      "for",

                                      "next",

                                      "error"

                            };

                   private static readonly int s_keywords_length = s_keywords.Length;

                   private static bool IsLD(char c) {

                            return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '0')

                                      || ((c >= '1') && (c <= '9')) || (c == '_');

                   }

                   private static bool IsSp(char c) {

                            return (c == ' ') || (c == '\t');

                   }

                   public static bool IsID(string str) {

                            int l = str.Length;

                            if (l == 0)

                                      return false;

                            if (char.IsDigit(str[0]) || (!IsLD(str[0])))

                                      return false;

                            int i;

                            for (i = 1; i < str.Length; i++)

                                      if (!IsLD(str[i]))

                                               return false;

                            for (i = 0; i < s_keywords_length; i++)

                                      if (str == s_keywords[i])

                                               return false;

                            return true;

                   }

                   public void Reset() {

                            m_cur = 0;

                            m_new_cur = -1;

                            m_at_begin = true;

                   }

                   public string GetString() {

                            return new String(m_a, 0, m_len);

                   }

                   public bool HasMore() {

                            return m_cur < m_len;

                   }

                   public Parser(string str) {

                            char[] a = str.ToCharArray();

                            int n = a.Length;

                            int i = 0;

                            int j = 0;

                            m_a = new char[n];

                            while (i < n) {

                                      if (a[i] == '#') {

                                               break;

                                      } else if (a[i] == '\"') {

                                               m_a[j] = '\"';

                                               i++;

                                               j++;

                                               while ((i < n) && (a[i] != '\"')) {

                                                        m_a[j] = a[i];

                                                        i++;

                                                        j++;

                                               }

                                               if (i == n)

                                                        throw new SyntaxErrorException("Íå çàêðûòàÿ ñòðîêîâàÿ êîíñòàíòà");

                                               else {

                                                        m_a[j] = '\"';

                                                        i++;

                                                        j++;

                                               }

                                      } else if (IsSp(a[i])) {

                                               bool flag = false;

                                               if ((i > 0) && (IsLD(a[i - 1]))) {

                                                        m_a[j] = ' ';

                                                        j++;

                                                        flag = true;

                                               }

                                               while ((i < n) && IsSp(a[i]))

                                                        i++;

                                               if (((i == n) || (!IsLD(a[i]))) && flag)

                                                        j--;

                                      } else {

                                               m_a[j] = a[i];

                                               i++;

                                               j++;

                                      }

                            }

                            m_len = j;

                            Reset();

                   }

                   private string GetCurrent() {

                            int cur = m_cur;

                            int beg = m_cur;

                            int end = m_len;

                            string res = null;

                            bool flag = true;

                            if ((m_a[cur] == '.') && ((cur < end - 1) && (!char.IsDigit(m_a[cur + 1]))) || (cur == end - 1)) {

                                      flag = true;

                            } else if (char.IsDigit(m_a[cur]) || (m_a[cur] == '.')) {

                                      flag = false;

                                      while ((cur < end) && char.IsDigit(m_a[cur]))

                                               cur++;

                                      if (cur == end) {

                                               res = new String(m_a, beg, cur - beg);

                                      } else if ((m_a[cur] == 'e') || (m_a[cur] == 'E')) {

                                               cur++;

                                               if (cur == end) {

                                                        cur--;

                                                        res = new String(m_a, beg, cur - beg);

                                               } else if ((m_a[cur] == '+') || (m_a[cur] == '-')) {

                                                        cur++;

                                                        if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

                                                                  cur -= 2;

                                                                  res = new String(m_a, beg, cur - beg);

                                                        }

                                                        while ((cur < end) && char.IsDigit(m_a[cur]))

                                                                  cur++;

                                                        res = new String(m_a, beg, cur - beg);

                                               } else if (char.IsDigit(m_a[cur])) {

                                                        while ((cur < end) && char.IsDigit(m_a[cur]))

                                                                  cur++;

                                                        res = new String(m_a, beg, cur - beg);

                                               } else {

                                                        cur--;

                                                        res = new String(m_a, beg, cur - beg);

                                               }

                                      } else if (m_a[cur] == '.') {

                                               cur++;

                                               if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

                                                        cur--;

                                                        res = new String(m_a, beg, cur - beg);

                                               } else {

                                                        while ((cur < end) && char.IsDigit(m_a[cur]))

                                                                  cur++;

                                                        if (cur == end)

                                                                 res = new String(m_a, beg, cur - beg);

                                                        else if ((m_a[cur] == 'e') || (m_a[cur] == 'E')) {

                                                                  cur++;

                                                                  if (cur == end) {

                                                                           cur--;

                                                                           res = new String(m_a, beg, cur - beg);

                                                                  } else if ((m_a[cur] == '+') || (m_a[cur] == '-')) {

                                                                           cur++;

                                                                           if ((cur == end) || (!char.IsDigit(m_a[cur]))) {

                                                                                     cur -= 2;

                                                                                     res = new String(m_a, beg, cur - beg);

                                                                           }

                                                                           while ((cur < end) && char.IsDigit(m_a[cur]))

                                                                                     cur++;

                                                                           res = new String(m_a, beg, cur - beg);

                                                                  } else if (char.IsDigit(m_a[cur])) {

                                                                           while ((cur < end) && char.IsDigit(m_a[cur]))

                                                                                     cur++;

                                                                           res = new String(m_a, beg, cur - beg);

                                                                  } else {

                                                                           cur--;

                                                                           res = new String(m_a, beg, cur - beg);

                                                                  }

                                                        } else

                                                                  res = new String(m_a, beg, cur - beg);

                                               }

                                      } else

                                               res = new String(m_a, beg, cur - beg);

                            }

                            if (flag) {

                                      if (IsLD(m_a[cur])) {

                                               while ((cur < end) && IsLD(m_a[cur]))

                                                        cur++;

                                               res = new String(m_a, beg, cur - beg);

                                      } else if (m_a[cur] == '\"') {

                                               do {

                                                        cur++;

                                                        if (m_a[cur] == '\"') {

                                                                  if ((cur < end - 1) && (m_a[cur + 1] == '\"'))

                                                                           cur++;

                                                                  else

                                                                           break;

                                                        }

                                               } while (true);

                                               cur++;

                                               res = new String(m_a, beg, cur - beg);

                                      } else if (cur < end - 1) {

                                               switch (m_a[cur]) {

                                                        case ':':

                                                                  {

                                                                           cur++;

                                                                           if (m_a[cur] == '=') {

                                                                                     cur++;

                                                                                     res = ":=";

                                                                           } else

                                                                                     res = ":";

                                                                           break;

                                                                  }

                                                        case '~':

                                                                  {

                                                                           cur++;

                                                                           if (m_a[cur] == '=') {

                                                                                     cur++;

                                                                                     res = "~=";

                                                                           } else

                                                                                     res = "~";

                                                                           break;

                                                                  }

                                                        case '>':

                                                                  {

                                                                           cur++;

                                                                           if (m_a[cur] == '=') {

                                                                                     cur++;

                                                                                     res = ">=";

                                                                           } else

                                                                                     res = ">";

                                                                           break;

                                                                  }

                                                        case '<':

                                                                  {

                                                                           cur++;

                                                                           switch (m_a[cur]) {

                                                                                     case '=':

                                                                                              {

                                                                                                       cur++;

                                                                                                       res = "<=";

                                                                                                       break;

                                                                                              }

                                                                                     case '>':

                                                                                              {

                                                                                                       cur++;

                                                                                                       res = "<>";

                                                                                                       break;

                                                                                              }

                                                                                     default:

                                                                                              {

                                                                                                       res = "<";

                                                                                                       break;

                                                                                              }

                                                                           }

                                                                           break;

                                                                  }

                                                        default:

                                                                  {

                                                                           res = m_a[cur].ToString();

                                                                           cur++;

                                                                           break;

                                                                  }

                                               }

                                      } else {

                                               res = m_a[cur].ToString();

                                               cur++;

                                      }

                            }

                            if ((cur < end) && IsSp(m_a[cur]))

                                      cur++;

                            m_new_cur = cur;

                            return res;

                   }

                   public object Current {

                            get { return GetCurrent(); }

                   }

                   public bool MoveNext() {

                            if (m_at_begin) {

                                      m_at_begin = false;

                                      return HasMore();

                            }

                            if (m_new_cur < 0)

                                      GetCurrent();

                            m_cur = m_new_cur;

                            m_new_cur = -1;

                            return HasMore();

                   }

                   public IEnumerator GetEnumerator() {

                            return this;

                   }

                   public static bool IsUserID(string name) {

                            if (!IsID(name))

                                      return false;

                            if (name == "abs")

                                      return false;

                            if (name == "cos")

                                      return false;

                            if (name == "sin")

                                      return false;

                            if (name == "tg")

                                      return false;

                            if (name == "arccos")

                                      return false;

                            if (name == "arcsin")

                                      return false;

                            if (name == "arctg")

                                      return false;

                            if (name == "exp")

                                      return false;

                            if (name == "pow")

                                      return false;

                            if (name == "ln")

                                      return false;

                            if (name == "lg")

                                      return false;

                            if (name == "log")

                                      return false;

                            if (name == "sqrt")

                                      return false;

                            if (name == "pi")

                                      return false;

                            if (name == "idiv")

                                      return false;

                            if (name == "iff")

                                      return false;

                            if (name == "imod")

                                      return false;

                            if (name == "random")

                                      return false;

                            if (name == "substr")

                                      return false;

                            if (name == "strlen")

                                      return false;

                            if (name == "strpos")

                                     return false;

                            if (name == "toint")

                                      return false;

                            if (name == "toreal")

                                      return false;

                            if (name == "tostring")

                                      return false;

                            if (name == "isarray")

                                      return false;

                            if (name == "issingle")

                                      return false;

                            if (name == "isstring")

                                      return false;

                            if (name == "isnum")

                                      return false;

                            if (name == "isreal")

                                      return false;

                            if (name == "isint")

                                      return false;

                            if (name == "size")

                                      return false;

                            return true;

                   }

         }

}

11. Êëàññ LineCompiler.

using System;

using interpr.logic.operators;

namespace interpr.logic {

         public class LineCompiler {

                   private LineCompiler() {}

                   public static Command CompileCommand(string str) {

                            Parser p = new Parser(str);

                            if (!p.HasMore()) {

                                      return new EmptyCommand();

                            }

                            String pstr = p.GetString();

                            int posa = pstr.IndexOf(":=");

                            if (posa >= 0) {

                                      int cq = 0;

                                      for (int iq = 0; iq < posa; iq++)

                                               if (pstr[iq] == '\"')

                                                        cq++;

                                      if (cq%2 == 0) {

                                               try {

                                                        if (posa == 0)

                                                                  throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                        try {

                                                                  if (pstr[posa - 1] == '}') {

                                                                           int posob = pstr.IndexOf('{');

                                                                           if ((posob < 0) || (posob > posa))

                                                                                     throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                                           return new AssignCommand(pstr.Substring(0, posob),

                                                                                                    pstr.Substring(posob + 1, posa - posob - 2),

                                                                                                    pstr.Substring(posa + 2));

                                                                  } else {

                                                                           return new AssignCommand(pstr.Substring(0, posa),

                                                                                                    pstr.Substring(posa + 2));

                                                                  }

                                                        } catch {

                                                                  throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                        }

                                               } catch (CalcException ex) {

                                                        throw new SyntaxErrorException(ex.Message);

                                               }

                                      }

                            }

                            p.MoveNext();

                            string firsttoken = (p.Current as String);

                            try {

                                      if (firsttoken == "clear") {

                                               if (!p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               Command cc = new ClearCommand(p.Current as String);

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return cc;

                                      }

                                      if (firsttoken == "print") {

                                               Expression expr = new Expression(p);

                                               return new PrintCommand(expr);

                                      } else if (firsttoken == "println") {

                                               Expression expr = new Expression(p);

                                               return new PrintLnCommand(expr);

                                      } else if (firsttoken == "call") {

                                               Expression expr = new Expression(p);

                                               return new CallCommand(expr);

                                      } else {

                                               p.Reset();

                                               Expression expr1 = new Expression(p);

                                               return new PrintLnCommand(expr1);

                                      }

                            } catch (SyntaxErrorException ex) {

                                      throw ex;

                            } catch (Exception ex) {

                                      throw new SyntaxErrorException(ex.Message);

                            }

                   }

                   public static IOperator CompileOperator(string str) {

                            Parser p = new Parser(str);

                            if (!p.HasMore()) {

                                      return new EmptyCommand();

                            }

                            String pstr = p.GetString();

                            p.MoveNext();

                            string firsttoken = (p.Current as String);

                            if (firsttoken == "for") {

                                      try {

                                               return ParseForStatement(p.GetString());

                                      } catch (SyntaxErrorException ex) {

                                               throw ex;

                                      } catch (Exception ex) {

                                               throw new SyntaxErrorException(ex.Message);

                                      }

                            }

                            int posa = pstr.IndexOf(":=");

                            if (posa >= 0) {

                                      int cq = 0;

                                      for (int iq = 0; iq < posa; iq++)

                                               if (pstr[iq] == '\"')

                                                        cq++;

                                      if (cq%2 == 0) {

                                               try {

                                                        if (posa == 0)

                                                                  throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                        try {

                                                                  if (pstr[posa - 1] == '}') {

                                                                           int posob = pstr.IndexOf('{');

                                                                           if ((posob < 0) || (posob > posa))

                                                                                     throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                                           return new AssignCommand(pstr.Substring(0, posob),

                                                                                                    pstr.Substring(posob + 1, posa - posob - 2),

                                                                                                    pstr.Substring(posa + 2));

                                                                  } else {

                                                                           return new AssignCommand(pstr.Substring(0, posa),

                                                                                                    pstr.Substring(posa + 2));

                                                                  }

                                                        } catch {

                                                                  throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                                        }

                                               } catch (CalcException ex) {

                                                        throw new SyntaxErrorException(ex.Message);

                                               }

                                      }

                            }

                            try {

                                      if (firsttoken == "clear") {

                                               if (!p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               Command cc = new ClearCommand(p.Current as String);

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return cc;

                                      } else if (firsttoken == "next") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new NextOperator();

                                      } else if (firsttoken == "else") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new ElseOperator();

                                      } else if (firsttoken == "endif") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new EndifOperator();

                                      } else if (firsttoken == "loop") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new LoopOperator();

                                      } else if (firsttoken == "return") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new ReturnOperator();

                                      } else if (firsttoken == "error") {

                                               if (p.MoveNext())

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               return new ErrorOperator();

                                      }

                                      Expression expr = new Expression(p);

                                      if (firsttoken == "print")

                                               return new PrintCommand(expr);

                                      else if (firsttoken == "println")

                                               return new PrintLnCommand(expr);

                                      else if (firsttoken == "call")

                                               return new CallCommand(expr);

                                      else if (firsttoken == "while")

                                               return new WhileOperator(expr);

                                      else if (firsttoken == "if")

                                               return new IfOperator(expr);

                                      else if (firsttoken == "elseif")

                                               return new ElseifOperator(expr);

                                      else

                                               throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                            } catch (SyntaxErrorException ex) {

                                      throw ex;

                            } catch (Exception ex) {

                                      throw new SyntaxErrorException(ex.Message);

                            }

                   }

                   private static IOperator ParseForStatement(string str) {

                            str = str.Substring(3);

                            int assignpos = str.IndexOf(":=");

                            if (assignpos < 0)

                                      throw new SyntaxErrorException("Íåïðàâèëüíûé ñèíòàêñèñ îïåðàòîðà for");

                            string countername = str.Substring(0, assignpos).Trim();

                            if (!Parser.IsID(countername))

                                      throw new SyntaxErrorException("Íåïðàâèëüíûé ñèíòàêñèñ îïåðàòîðà for");

                            str = str.Substring(assignpos + 2);

                            int colonpos = str.IndexOf(":");

                            if (colonpos < 0)

                                      throw new SyntaxErrorException("Íåïðàâèëüíûé ñèíòàêñèñ îïåðàòîðà for");

                            string expr1str = str.Substring(0, colonpos);

                            string expr2str = str.Substring(colonpos + 1);

                            Expression expr1 = new Expression(expr1str);

                            Expression expr2 = new Expression(expr2str);

                            return new ForOperator(countername, expr1, expr2);

                   }

         }

}

12. Èíòåðôåéñ IOperator.

namespace interpr.logic.operators {

         public enum OperatorKind {

                   Plain,

                   If,

                   Elseif,

                   Else,

                   Endif,

                   While,

                   Loop,

                   For,

                   Next,

                   Return

         }

         public interface IOperator {

                   void Execute(Subroutine.Moment pos);

                   OperatorKind GetKind();

         }

}

13. Êëàññ Command.

namespace interpr.logic.operators {

         public abstract class Command : IOperator {

                   public abstract void Execute();

                   public void Execute(Subroutine.Moment pos) {

                            Execute();

                            pos.Next();

                   }

                   public OperatorKind GetKind() {

                            return OperatorKind.Plain;

                   }

         }

}

14. Êëàññ ForOperator.

using interpr.logic.vartypes;

namespace interpr.logic.operators {

         public class ForOperator : IOperator {

                   private int m_next_pos = -1;

                   private string m_counter_var = null;

                   private Expression m_begin = null;

                   private Expression m_end = null;

                   private IntVar m_end_res = null;

                   public ForOperator(string counter, Expression beg, Expression end) {

                            m_counter_var = counter;

                            m_begin = beg;

                            m_end = end;

                   }

                   public int NextPos {

                            get {

                                      if (m_next_pos < 0)

                                               throw new OtherException("Error in LoopOperator.NextPos");

                                      return m_next_pos;

                            }

                            set { m_next_pos = value; }

                   }

                   public void Step(Subroutine.Moment pos, int forpos) {

                            Namespace cn = InterprEnvironment.Instance.CurrentNamespace;

                            VarBase res = cn[m_counter_var];

                            if (!res.IsInt())

                                      throw new CalcException("Òèï ïåðåìåííîé - ñ÷åò÷èêà öèêëà áûë èçìåíåí");

                            int resval = (res as IntVar).Val;

                            resval++;

                            res = new IntVar(resval);

                            cn[m_counter_var] = res;

                            if (resval > m_end_res.Val)

                                      pos.GoTo(m_next_pos + 1);

                            else

                                      pos.GoTo(forpos + 1);

                   }

                   public void Execute(Subroutine.Moment pos) {

                            VarBase resb, rese;

                            resb = m_begin.Calculate();

                            if (!resb.IsInt())

                                      throw new CalcException("Ãðàíèöû èçìåíåíèÿ ñ÷åò÷èêà äîëæíû áûòü öåëûìè");

                            IntVar resbi = resb as IntVar;

                            Namespace cn = InterprEnvironment.Instance.CurrentNamespace;

                            cn[m_counter_var] = resb;

                            rese = m_end.Calculate();

                            if (!rese.IsInt())

                                      throw new CalcException("Ãðàíèöû èçìåíåíèÿ ñ÷åò÷èêà äîëæíû áûòü öåëûìè");

                            m_end_res = rese as IntVar;

                            if (resbi.Val > m_end_res.Val)

                                      pos.GoTo(m_next_pos + 1);

                            else

                                      pos.Next();

                   }

                   public OperatorKind GetKind() {

                            return OperatorKind.For;

                   }

         }

}

15. Êëàññ NextOperator

namespace interpr.logic.operators {

         public class NextOperator : IOperator {

                   private int m_for_pos = -1;

                   private ForOperator m_for_op = null;

                   public NextOperator() {}

                   public int ForPos {

                            get {

                                      if (m_for_pos < 0)

                                               throw new OtherException("Error in NextOperator.ForPos");

                                      return m_for_pos;

                            }

                            set { m_for_pos = value; }

                   }

                   public ForOperator ForOp {

                            get { return m_for_op; }

                            set { m_for_op = value; }

                   }

                   public void Execute(interpr.logic.Subroutine.Moment pos) {

                            m_for_op.Step(pos, m_for_pos);

                   }

                   public interpr.logic.operators.OperatorKind GetKind() {

                            return OperatorKind.Next;

                   }

         }

}

16. Êëàññ Subroutine.

using System;

using System.Collections;

using System.Threading;

using interpr.logic.vartypes;

using interpr.logic.operators;

namespace interpr.logic {

         public sealed class Subroutine  {

                   private void AnalyseHeader(string str) {

                            Parser header_p = new Parser(str);

                            if (!header_p.MoveNext())

                                      throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                            if ((header_p.Current as System.String) != m_name)

                                      throw new SyntaxErrorException("Èìÿ ôóíêöèè íå ñîâïàäàåò ñ èìåíåì ôàéëà");

                            if ((!header_p.MoveNext()) || ((header_p.Current as String) != "["))

                                      throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                            if ((!header_p.MoveNext()))

                                      throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                            if ((header_p.Current as System.String != "]")) {

                                      string readstr;

                                      while (true) {

                                               readstr = (header_p.Current as System.String);

                                               if (!Parser.IsID(readstr))

                                                        throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                                               m_args.Add(readstr);

                                               if (!header_p.MoveNext())

                                                        throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                                               readstr = (header_p.Current as System.String);

                                               if (readstr == ",") {

                                                        if (!header_p.MoveNext())

                                                                  throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                                               }

                                               else if (readstr == "]")

                                                        break;

                                               else

                                                        throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                                      }

                            }

                            if (header_p.MoveNext())

                                      throw new SyntaxErrorException("Îøèáêà â çàãîëîâêå ôóíêöèè");

                            if (m_args.IndexOf("result") >= 0)

                                      throw new SyntaxErrorException("Ïàðàìåòð ôóíêöèè íå ìîæåò èìåòü èìÿ \"result\"");

                   }

                   public Subroutine(string[] code, string name) {

                            m_name = name;

                            if (code.Length == 0)

                                      throw new SyntaxErrorException("Ôàéë ôóíêöèè ïóñò");

                            AnalyseHeader(code[0]);

                            int clen = code.Length;

                            int i = 0;

                            try {

                                      Stack stk = new Stack();

                                      m_operators.Add(new EmptyCommand()); //÷òîáû èíäåêñàöèÿ íà÷èíàëàñü ñ åäèíèöû

                                      for (i = 1; i < clen; i++) {

                                               IOperator op = LineCompiler.CompileOperator(code[i]);

                                               if (op == null)

                                                        throw new SyntaxErrorException("Ñèíòàêñè÷åñêàÿ îøèáêà");

                                               m_operators.Add(op);

                                               switch (op.GetKind()) {

                                                        case OperatorKind.If:

                                                        case OperatorKind.While:

                                                         case OperatorKind.For:

                                                                  {

                                                                           stk.Push(i);

                                                                           break;

                                                                  }

                                                        case OperatorKind.Elseif:

                                                                  {

                                                                           if (stk.Count == 0)

                                                                                     throw new SyntaxErrorException("Ëèøíåå elseif");

                                                                           int j = (int) stk.Pop();

                                                                           switch ((m_operators[j] as IOperator).GetKind()) {

                                                                                     case OperatorKind.If:

                                                                                              {

                                                                                                       (m_operators[j] as IfOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     case OperatorKind.Elseif:

                                                                                              {

                                                                                                       (m_operators[j] as ElseifOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     default:

                                                                                              throw new SyntaxErrorException("Ëèøíåå elseif");

                                                                           }

                                                                           stk.Push(i);

                                                                           break;

                                                                  }

                                                        case OperatorKind.Else:

                                                                  {

                                                                           if (stk.Count == 0)

                                                                                     throw new SyntaxErrorException("Ëèøíåå else");

                                                                           int j = (int) stk.Pop();

                                                                           stk.Push(i);

                                                                           switch ((m_operators[j] as IOperator).GetKind()) {

                                                                                     case OperatorKind.If:

                                                                                              {

                                                                                                       (m_operators[j] as IfOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     case OperatorKind.Elseif:

                                                                                              {

                                                                                                       (m_operators[j] as ElseifOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     default:

                                                                                              throw new SyntaxErrorException("Ëèøíåå else");

                                                                           }

                                                                           break;

                                                                  }

                                                        case OperatorKind.Endif:

                                                                  {

                                                                           if (stk.Count == 0)

                                                                                     throw new SyntaxErrorException("Ëèøíåå endif");

                                                                           int j = (int) stk.Pop();

                                                                           switch ((m_operators[j] as IOperator).GetKind()) {

                                                                                     case OperatorKind.If:

                                                                                              {

                                                                                                       (m_operators[j] as IfOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     case OperatorKind.Elseif:

                                                                                              {

                                                                                                       (m_operators[j] as ElseifOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     case OperatorKind.Else:

                                                                                              {

                                                                                                       (m_operators[j] as ElseOperator).NextPos = i;

                                                                                                       break;

                                                                                              }

                                                                                     default:

                                                                                              throw new SyntaxErrorException("Ëèøíåå endif");

                                                                           }

                                                                           break;

                                                                  }

                                                        case OperatorKind.Loop:

                                                                  {

                                                                           if (stk.Count == 0)

                                                                                     throw new SyntaxErrorException("Ëèøíåå loop");

                                                                           int j = (int) stk.Pop();

                                                                           if ((m_operators[j] as IOperator).GetKind() != OperatorKind.While)

                                                                                     throw new SyntaxErrorException("Ëèøíåå loop");

                                                                           (m_operators[i] as LoopOperator).WhilePos = j;

                                                                           (m_operators[j] as WhileOperator).LoopPos = i;

                                                                           break;

                                                                  }

                                                        case OperatorKind.Next:

                                                                  {

                                                                           if (stk.Count == 0)

                                                                                     throw new SyntaxErrorException("Ëèøíåå next");

                                                                           int j = (int) stk.Pop();

                                                                           if ((m_operators[j] as IOperator).GetKind() != OperatorKind.For)

                                                                                     throw new SyntaxErrorException("Ëèøíåå next");

                                                                           (m_operators[i] as NextOperator).ForPos = j;

                                                                           (m_operators[i] as NextOperator).ForOp = (m_operators[j] as ForOperator);

                                                                           (m_operators[j] as ForOperator).NextPos = i;

                                                                           break;

                                                                  }

                                               }

                                      }

                                      if (stk.Count != 0)

                                               throw new SyntaxErrorException("Íå çàêðûòûé áëîê");

                            }

                            catch (SyntaxErrorException ex) {

                                      throw new LineSyntaxException(ex.Message, m_name, i + 1);

                            }

                            m_count = m_operators.Count;

                   }

                   private string m_name;

                   private ArrayList m_args = new ArrayList();

                   private ArrayList m_operators = new ArrayList();

                   private int m_count;

                   public int ReqCount {

                            get { return m_args.Count; }

                   }

                   public VarBase Perform(ArgList al) {

                            Namespace ns = new Namespace(InterprEnvironment.Instance.CurrentNamespace);

                            ns["result"] = new IntVar(0);

                            int argc = m_args.Count;

                            if (al.Count != argc)

                                      throw new CalcException("Íåâåðíîå ÷èñëî ïàðàìåòðîâ");

                            al.Reset();

                            for (int i = 0; i < argc; i++) {

                                      ns[m_args[i] as System.String] = al.Get();

                            }

                            InterprEnvironment.Instance.CurrentNamespace = ns;

                            Moment moment = new Moment(this);

                            if (m_count > 1) {

                                      try {

                                               moment.Run();

                                      }

                                      catch (SyntaxErrorException ex) {

                                               throw ex;

                                      }

                                      catch (CalcException ex) {

                                               throw new CalcException("Îøèáêà â ôóíêöèè " + m_name + "[] â ñòðîêå " + (moment.Pos + 1) + " : " + ex.Message);

                                      }

                            }

                            VarBase res = ns["result"];

                            InterprEnvironment.Instance.CurrentNamespace = ns.PreviousNamespace;

                            if (res == null)

                                      throw new CalcException("Îøèáêà â ôóíêöèè " + m_name + "[] : ïåðåìåííàÿ result íå îïðåäåëåíà íà ìîìåíò âûõîäà");

                            return res;

                   }

                   public class Moment {

                            private Subroutine m_sub;

                            private int m_pos;

                            private static int s_break = 0;

                            public static void Break() {

                                      Interlocked.Exchange(ref s_break, 1);

                            }

                            public int Pos {

                                      get { return m_pos; }

                            }

                            public Moment(Subroutine sub) {

                                      m_sub = sub;

                                      m_pos = 1;

                                      s_break = 0;

                            }

                            public void GoTo(int to) {

                                      m_pos = to;

                            }

                            public void Next() {

                                      m_pos++;

                            }

                            public void Run() {

                                      while (m_pos < m_sub.m_count) {

                                               if (s_break == 1)

                                                        throw new CalcException("Ïðåðâàíî ïîëüçîâàòåëåì");

                                               (m_sub.m_operators[m_pos] as IOperator).Execute(this);

                                      }

                            }

                            public void Return() {

                                      m_pos = m_sub.m_count;

                            }

                            public IOperator Current {

                                      get { return m_sub.m_operators[m_pos] as IOperator; }

                            }

                   }

         }

}

17. Êëàññ Facade.

using System.Threading;

using interpr.logic;

using interpr.logic.operators;

namespace interpr {

         public class Facade {

                   private static Facade s_instance = null;

                   public static void Create(IConsole console) {

                            if (s_instance == null)

                                      s_instance = new Facade(console);

                   }

                   public static Facade Instance {

                            get { return s_instance; }

                   }

                   private IConsole m_console;

                   private InterprEnvironment m_env;

                   private string m_cmd;

                   private bool m_doing = false;

                   private Facade(IConsole console) {

                            m_console = console;

                            m_env = InterprEnvironment.Instance;

                            m_env.CurrentConsole = m_console;

                   }

                   public delegate void CommandDoneHandler();

                   public event CommandDoneHandler Done;

                   private void ThrStart() {

                            m_doing = true;

                            Command cmd;

                            do {

                                      try {

                                               cmd = LineCompiler.CompileCommand(m_cmd);

                                      }

                                      catch (SyntaxErrorException ex) {

                                               m_env.CurrentConsole.PrintLn("Îøèáêà : " + ex.Message);

                                               break;

                                      }

                                      try {

                                               cmd.Execute();

                                      }

                                      catch (CalcException ex) {

                                               m_env.CurrentConsole.PrintLn("Îøèáêà : " + ex.Message);

                                               m_env.CurrentNamespace = m_env.ConsoleNamespace;

                                               break;

                                      }

                            } while (false);

                            Done();

                            m_doing = false;

                   }

                   public void ExecuteCommand(string cmd) {

                            if (m_doing)

                                      throw new OtherException("Error in Bridge.ExecuteCommand()");

                            m_cmd = cmd;

                            new Thread(new ThreadStart(ThrStart)).Start();

                   }

                   private void DoRestart() {

                            if (m_doing)

                                      Subroutine.Moment.Break();

                            while (m_doing) {}

                            InterprEnvironment.Reset();

                            m_env = InterprEnvironment.Instance;

                            m_env.CurrentConsole = m_console;

                            m_env.LoadSubs();

                   }

                   public void Restart() {

                            new Thread(new ThreadStart(DoRestart)).Start();

                   }

                   public bool Busy {

                            get { return m_doing; }

                   }

                   public void SaveVariables() {

                            m_env.SaveVars();

                   }

                   public void LoadSubs() {

                            m_env.LoadSubs();

                   }

                   public ConsoleNamespace.VariableReport[] GetVariables() {

                            return m_env.GetGlobalVarsList();

                   }

                   public string[] GetSubs() {

                            return m_env.LoadedSubs;

                   }

                   public void DeleteVariable(string name) {

                            m_env.ConsoleNamespace.Remove(name);

                   }

                   public bool LoadSub(string name) {

                            return m_env.LoadSub(name);

                  }

                   public void UnloadSub(string name) {

                            m_env.UnloadSub(name);

                   }

                   public bool NotRestored {

                            get {

                                      return m_env.NotRestored;

                            }

                   }

         }

}

18. Êëàññ SourceBox.

using System;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

namespace interpr {

         public class SourceBox : UserControl {

                   private RichTextBox m_tb;

                   private TextBox m_tb_2;

                  

                   ....................................................................

                   private int m_curline = 0;//òåêóùàÿ ñòðîêà

                   private int m_lincount = 0;//îáùåå ÷èñëî ñòðîê

                   private HighlightParser m_hp = new HighlightParser();

                   private static Font s_nfont =

                            new Font("Lucida Console", 10, FontStyle.Regular);

                   private static Font s_cfont =

                            new Font("Lucida Console", 12, FontStyle.Bold);

                   private int GetCurrentLine() {

                            return m_tb.GetLineFromCharIndex(m_tb.SelectionStart);

                   }

                   private int GetLinesCount() {

                            return m_tb.Lines.Length;

                   }

                   private String GetLine(int index) {

                            return m_tb.Lines[index];

                   }

                   private void m_tb_KeyPress(object sender, KeyPressEventArgs e) {

                            if (e.KeyChar == '\r') {

                                      string txt = m_tb.Text;

                                      int i = m_tb.SelectionStart - 2;

                                      int j;

                                      while (i >= 0) {

                                               if (txt[i] == '\n')

                                                        return;

                                               else if (txt[i] == '\t') {

                                                        j = 0;

                                                        while ((i >= 0) && (txt[i] == '\t')) {

                                                                  j++;

                                                                  i--;

                                                        }

                                                        if ((i < 0) || (txt[i] == '\n')) {

                                                                  m_tb.SelectedText = new String('\t', j);

                                                                  return;

                                                        }

                                               }

                                               i--;

                                      }

                            }

                   }

                   private bool GetLinePos(int index, out int beg, out int len) {

                            if ((index < 0) || (index >= GetLinesCount())) {

                                      beg = len = 0;

                                      return false;

                            }

                            int i;

                            string[] ls = m_tb.Lines;

                            beg = 0;

                            for (i = 0; i < index; i++)

                                      beg += ls[i].Length + 1;

                            len = ls[index].Length;

                            return true;

                   }

                   private void SelectLine(int index) {

                            int beg, len;

                            if (!GetLinePos(index, out beg, out len))

                                      throw new IndexOutOfRangeException();

                            m_tb.SelectionStart = beg;

                            m_tb.SelectionLength = len;

                   }

                   private void HighlightLine(int index) {

                            int beg, len;

                            int curbeg = m_tb.SelectionStart;

                            int curlen = m_tb.SelectionLength;

                            GetLinePos(index, out beg, out len);

                            string str = m_tb.Lines[index];

                            m_hp.Reset(str);

                            while (m_hp.HasMore()) {

                                      int tbeg, tlen;

                                      HighlightParser.TokenType type;

                                      m_hp.GetNext(out tbeg, out tlen, out type);

                                      m_tb.SelectionStart = beg + tbeg;

                                      m_tb.SelectionLength = tlen;

                                     switch (type) {

                                               case HighlightParser.TokenType.Comment:

                                                        {

                                                                  m_tb.SelectionColor = Color.DarkGreen;

                                                                  break;

                                                        }

                                               case HighlightParser.TokenType.Identifier:

                                                        {

                                                                  m_tb.SelectionColor = Color.Purple;

                                                                  break;

                                                        }

                                               case HighlightParser.TokenType.Keyword:

                                                        {

                                                                  m_tb.SelectionColor = Color.Blue;

                                                                  break;

                                                        }

                                               case HighlightParser.TokenType.Number:

                                                        {

                                                                  m_tb.SelectionColor = Color.Red;

                                                                  break;

                                                        }

                                               case HighlightParser.TokenType.String:

                                                        {

                                                                  m_tb.SelectionColor = Color.Brown;

                                                                  break;

                                                        }

                                               case HighlightParser.TokenType.Other:

                                                        {

                                                                  m_tb.SelectionColor = Color.Black;

                                                                  break;

                                                        }

                                      }

                            }

                            m_tb.SelectionStart = curbeg;

                            m_tb.SelectionLength = curlen;

                   }

                   public enum LineState {

                            ErrorLine,

                            CurrentLine,

                            NormalLine

                   }

                   private void ColorLine(int index, LineState state) {

                            int curbeg = m_tb.SelectionStart;

                            int curlen = m_tb.SelectionLength;

                            SelectLine(index);

                            switch (state) {

                                      case LineState.ErrorLine:

                                               {

                                                        m_tb.SelectionColor = Color.Red;

                                                        break;

                                               }

                                      case LineState.CurrentLine:

                                               {

                                                        m_tb.SelectionFont = s_cfont;

                                                        break;

                                               }

                                      case LineState.NormalLine:

                                               {

                                                        m_tb.SelectionFont = s_nfont;

                                                        HighlightLine(index);

                                                        break;

                                               }

                            }

                            m_tb.SelectionStart = curbeg;

                            m_tb.SelectionLength = curlen;

                   }

                   private void HighlightText(bool anyway) {

                            int l = GetCurrentLine();

                            int lc = GetLinesCount();

                            if ((l != m_curline) || (lc != m_lincount) || anyway) {

                                      m_tb_2.Focus();

                                      m_curline = l;

                                      m_lincount = lc;

                                      int bi = m_tb.GetCharIndexFromPosition(new Point(0, 0));

                                      int ei = m_tb.GetCharIndexFromPosition(new Point(m_tb.Size));

                                      int bl = m_tb.GetLineFromCharIndex(bi);

                                      int el = m_tb.GetLineFromCharIndex(ei);

                                      if (bl > 0) bl--;

                                      if (el < lc) el++;

                                      for (int i = bl; i < el; i++)

                                               HighlightLine(i);

                                      m_tb.Focus();

                            }

                   }

                   private void m_tb_KeyUp(object sender, KeyEventArgs e) {

                            HighlightText(false);

                   }

                   private void m_tb_MouseUp(object sender, MouseEventArgs e) {

                            if (e.Button == MouseButtons.Left)

                                      HighlightText(true);

                   }

                   public string[] Lines {

                            get { return (string[]) m_tb.Lines.Clone(); }

                   }

                   public bool LoadFile(string filename) {

                            try {

                                      m_tb.LoadFile(filename, RichTextBoxStreamType.PlainText);

                                      HighlightText(true);

                                      return true;

                            }

                            catch {

                                      return false;

                            }

                   }

                   public bool SaveFile(string filename) {

                            try {

                                      m_tb.SaveFile(filename, RichTextBoxStreamType.PlainText);

                                      return true;

                            }

                            catch {

                                      return false;

                            }

                   }

                   public int CurrentLine {

                            get { return m_tb.GetLineFromCharIndex(m_tb.SelectionStart); }

                   }

                   private class HighlightParser {

                            private char[] m_a;

                            private int m_len;

                            private int m_cur;

                            public enum TokenType {

                                      String,

                                      Number,

                                      Keyword,

                                      Comment,

                                      Identifier,

                                      Other

                            }

                            public void Reset(string str) {

                                      m_a = str.ToCharArray();

                                      m_len = str.Length;

                                      m_cur = 0;

                                      while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))

                                               m_cur++;

                            }

                            public bool HasMore() {

                                      return m_cur < m_len;

                            }

                            private bool IsKeyword(string str) {

                                      return

                                               (str == "if") ||

                                                        (str == "else") ||

                                                        (str == "elseif") ||

                                                        (str == "endif") ||

                                                        (str == "while") ||

                                                        (str == "loop") ||

                                                        (str == "return") ||

                                                        (str == "result") ||

                                                        (str == "call") ||

                                                        (str == "print") ||

                                                        (str == "println") ||

                                                        (str == "readln") ||

                                                        (str == "clear") ||

                                                        (str == "for") ||

                                                        (str == "next") ||

                                                        (str == "error");

                            }

                            public void GetNext(out int beg, out int len, out TokenType type) {

                                      if (m_cur >= m_len)

                                               throw new IndexOutOfRangeException();

                                      beg = m_cur;

                                      if (m_a[m_cur] == '\"') {

                                               m_cur++;

                                               while ((m_cur < m_len) && (m_a[m_cur] != '\"'))

                                                        m_cur++;

                                               if (m_cur < m_len)

                                                        m_cur++;

                                               len = m_cur - beg;

                                               type = TokenType.String;

                                      }

                                      else if (isL(m_a[m_cur])) {

                                               m_cur++;

                                               while ((m_cur < m_len) && isLD(m_a[m_cur]))

                                                        m_cur++;

                                               len = m_cur - beg;

                                               if (IsKeyword(new string(m_a, beg, len)))

                                                        type = TokenType.Keyword;

                                               else

                                                        type = TokenType.Identifier;

                                      }

                                      else if (m_a[m_cur] == '#') {

                                               len = m_len - m_cur;

                                               m_cur = m_len;

                                               type = TokenType.Comment;

                                      }

                                      else if (m_a[m_cur] == '.') {

                                               if (GetNumber()) {

                                                        len = m_cur - beg;

                                                        type = TokenType.Number;

                                               }

                                               else {

                                                        m_cur = beg + 1;

                                                        len = 1;

                                                        type = TokenType.Other;

                                               }

                                      }

                                      else if (char.IsDigit(m_a[m_cur])) {

                                               GetNumber();

                                               len = m_cur - beg;

                                               type = TokenType.Number;

                                     }

                                      else {

                                               m_cur++;

                                               len = 1;

                                               type = TokenType.Other;

                                      }

                                      while ((m_cur < m_len) && Char.IsWhiteSpace(m_a[m_cur]))

                                               m_cur++;

                            }

                            private bool GetNumber() {

                                      if (!((m_a[m_cur] == '.') || char.IsDigit(m_a[m_cur])))

                                               return false;

                                      while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                               m_cur++;

                                      if (m_cur == m_len)

                                               return true;

                                      else if (m_a[m_cur] == '.') {

                                               m_cur++;

                                               while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                                        m_cur++;

                                               if (m_cur == m_len)

                                                        return true;

                                               else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {

                                                        int p1 = m_cur;

                                                        m_cur++;

                                                        if (m_cur == m_len) {

                                                                  m_cur = p1;

                                                                  return true;

                                                        }

                                                        else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {

                                                                  m_cur++;

                                                                  if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {

                                                                           m_cur = p1;

                                                                           return true;

                                                                  }

                                                                  while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                                                           m_cur++;

                                                                  return true;

                                                        }

                                                        else if (char.IsDigit(m_a[m_cur])) {

                                                                  while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                                                           m_cur++;

                                                                  return true;

                                                        }

                                                        else {

                                                                  m_cur = p1;

                                                                  return true;

                                                        }

                                               }

                                               else

                                                        return true;

                                      }

                                      else if ((m_a[m_cur] == 'e') || (m_a[m_cur] == 'E')) {

                                               int p1 = m_cur;

                                               m_cur++;

                                               if (m_cur == m_len) {

                                                        m_cur = p1;

                                                        return true;

                                               }

                                               else if ((m_a[m_cur] == '-') || (m_a[m_cur] == '+')) {

                                                        m_cur++;

                                                        if ((m_cur == m_len) || !char.IsDigit(m_a[m_cur])) {

                                                                  m_cur = p1;

                                                                  return true;

                                                        }

                                                        while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                                                  m_cur++;

                                                        return true;

                                               }

                                               else if (char.IsDigit(m_a[m_cur])) {

                                                         while ((m_cur < m_len) && char.IsDigit(m_a[m_cur]))

                                                                  m_cur++;

                                                        return true;

                                               }

                                               else {

                                                        m_cur = p1;

                                                        return true;

                                               }

                                      }

                                      else

                                               return true;

                            }

                            private static bool isLD(char c) {

                                      return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '0')

                                               || ((c >= '1') && (c <= '9')) || (c == '_');

                            }

                            private static bool isL(char c) {

                                      return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || (c == '_');

                            }

                   }

         }

}

19. Êëàññ Form1.

using System;

using System.ComponentModel;

using System.Windows.Forms;

namespace interpr {

         public class Form1 : Form {

                   private Panel panel1;

                   private Button button1;

                  private Button button2;

                   private Button button3;

                   private Button button4;

                   private Button button5;

                   private ConsoleBox consoleBox1;

                   private Facade m_fasade;

                   private void Form1_Load(object sender, EventArgs e) {

                            Facade.Create(consoleBox1);

                            m_fasade = Facade.Instance;

                            if (m_fasade.NotRestored) {

                                      MessageBox.Show("Îøèáêà! Ïåðåìåííûå íå áûëè óñïåøíî âîññòàíîâëåíû.");

                            }

                            m_fasade.Done += new Facade.CommandDoneHandler(EndExec);

                            m_fasade.LoadSubs();

                            consoleBox1.Prompt();

                   }

                   private void EndExec() {

                            consoleBox1.Prompt();

                   }

                   private void button1_Click(object sender, EventArgs e) {

                            if (m_fasade.Busy) {

                                      MessageBox.Show("Íå ìîãó îòêðûòü îêíî ôóíêöèé âî âðåìÿ âûïîëíåíèÿ êîììàíäû!");

                                      return;

                            }

                            FunctionsForm ff = new FunctionsForm(m_fasade);

                            ff.ShowDialog();

                            EditorForm ef = ff.LastOpenedEditorForm;

                            if (ef != null) {

                                      ef.Activate();

                                      ff.SetLastEditorFormNull();

                            }

                            else

                                      consoleBox1.Focus();

                   }

                   private void button2_Click(object sender, EventArgs e) {

                            if (m_fasade.Busy) {

                                      MessageBox.Show("Íå ìîãó îòêðûòü îêíî ïåðåìåííûõ âî âðåìÿ âûïîëíåíèÿ êîììàíäû!");

                                      return;

                            }

                            VariablesForm vf = new VariablesForm(m_fasade);

                            vf.ShowDialog();

                            consoleBox1.Focus();

                   }

                   private void consoleBox1_GetCommand(object sender, ConsoleBoxGetCommandEventArgs e) {

                            if (e.Command.Length > 0)

                                      m_fasade.ExecuteCommand(e.Command);

                            else

                                      consoleBox1.Prompt();

                   }

                   private void button3_Click(object sender, EventArgs e) {

                            m_fasade.Restart();

                            if (m_fasade.NotRestored) {

                                      MessageBox.Show("Îøèáêà! Ïåðåìåííûå íå áûëè óñïåøíî âîññòàíîâëåíû.");

                            }

                            consoleBox1.Focus();

                   }

                   private void button5_Click(object sender, EventArgs e) {

                            if (m_fasade.Busy) {

                                      MessageBox.Show("Íå ìîãó ñîõðàíèòü ïåðåìåííûå âî âðåìÿ âûïîëíåíèÿ ïðîãðàììû");

                                      return;

                            }

                            m_fasade.SaveVariables();

                            consoleBox1.Focus();

                   }

                   private void Form1_Closing(object sender, CancelEventArgs e) {

                            if (EditorForm.ThereAreOpened()) {

                                      MessageBox.Show("Ñíà÷àëà çàêðîéòå âñå îêíà ðåäàêòîðà êîäà.");

                                      e.Cancel = true;

                                      return;

                            }

                            m_fasade.SaveVariables();

                   }

                   private void button4_Click(object sender, EventArgs e) {

                            this.Close();

                   }

         }

}


Èñïîëüçîâàííàÿ ëèòåðàòóðà è äîêóìåíòàöèÿ.

1.         À. Àõî, Äæ. Õîïêðîôò, Ä. Óëüìàí. Ñòðóêòóðû äàííûõ è àëãîðèòìû – Ì. «Âèëüÿìñ», 2003.

2.         Ý. Ãàììà, Ð. Õåëì, Ð. Äæîíñîí, Äæ. Âëèññèäåñ. Ïðèåìû îáúåêòíî-îðèåíòèðîâàííîãî ïðîåêòèðîâàíèÿ: ïàòòåðíû ïðîåêòèðîâàíèÿ – ÑÏá., «Ïèòåð», 2001.

3.         Ä. Ãðèñ. Êîíñòðóèðîâàíèå êîìïèëÿòîðîâ äëÿ öèôðîâûõ âû÷èñëèòåëüíûõ ìàøèí – Ì. «Ìèð», 1975.

4.         Ã. Êîðíåëë, Äæ. Ìîððèñîí. Ïðîãðàììèðîâàíèå íà VB.NET. Ó÷åáíûé êóðñ – ÑÏá., «Ïèòåð», 2002.

5.         Ý. Òðîåëñåí. C# è ïëàòôîðìà .NET – ÑÏá., «Ïèòåð», 2004.

6.         MSDN Library – April 2003.

ÌÈÍÈÑÒÅÐÑÒÂÎ ÎÁÐÀÇÎÂÀÍÈß ÐÅÑÏÓÁËÈÊÈ ÁÅËÀÐÓÑÜ Ó×ÐÅÆÄÅÍÈÅ ÎÁÐÀÇÎÂÀÍÈß «ÁÅËÎÐÓÑÑÊÈÉ ÃÎÑÓÄÀÐÑÒÂÅÍÍÛÉ ÓÍÈÂÅÐÑÈÒÅÒ ÈÍÔÎÐÌÀÒÈÊÈ È ÐÀÄÈÎÝËÅÊÒÐÎÍÈÊÈ» Êàôåäðà èíôîðìàòèêè ÊÓÐÑÎÂÎÉ ÏÐÎÅÊÒ

 

 

 

Âíèìàíèå! Ïðåäñòàâëåííàÿ Êóðñîâàÿ ðàáîòà íàõîäèòñÿ â îòêðûòîì äîñòóïå â ñåòè Èíòåðíåò, è óæå íåîäíîêðàòíî ñäàâàëàñü, âîçìîæíî, äàæå â òâîåì ó÷åáíîì çàâåäåíèè.
Ñîâåòóåì íå ðèñêîâàòü. Óçíàé, ñêîëüêî ñòîèò àáñîëþòíî óíèêàëüíàÿ Êóðñîâàÿ ðàáîòà ïî òâîåé òåìå:

Íîâîñòè îáðàçîâàíèÿ è íàóêè

Çàêàçàòü óíèêàëüíóþ ðàáîòó

Ïîõîæèå ðàáîòû:

Èíòåðíåò - ãëîáàëüíàÿ êîìïüþòåðíàÿ ñåòü
Èíòåðíåò êàê ñðåäñòâî ìàññîâîé êîììóíèêàöèè è åãî ôóíêöèè
Èíòåðíåò-ðåêëàìà, êàê èíñòðóìåíò ïðîäâèæåíèÿ òóðèñòñêîãî ïðîäóêòà
Èíòåðíåò-òåõíîëîãèè
Èíòåðïîëÿöèÿ ôóíêöèè îäíîé ïåðåìåííîé ìåòîäîì Íüþòîíà
Èíòåðïðåòàòîð êîìàíä MS DOS
Èíòåðôåéñ Serial ATA
Èíôîëîãè÷åñêàÿ ìîäåëü áàçû äàííûõ &quot;Âèäåïðîêàò&quot;
Èíôîëîãè÷åñêàÿ ìîäåëü áàçû äàííûõ &quot;Çàùèòà äîñòóïà&quot;
Èíôîëîãè÷åñêàÿ ìîäåëü áàçû äàííûõ &quot;Ïàñïîðòíûé ó÷åò&quot;

Ñâîè ñäàííûå ñòóäåí÷åñêèå ðàáîòû

ïðèñûëàéòå íàì íà e-mail

Client@Stud-Baza.ru