?login_element?

Subversion Repositories NedoOS

Rev

Rev 777 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /// imported
  2. #include "../_sdk/typecode.h"
  3. #include "../_sdk/str.h"
  4. #include "../_sdk/io.h"
  5. #include "../_sdk/emit.h"
  6.  
  7. CONST BYTE _typesz[32];
  8.  
  9. #ifdef TARGET_THUMB
  10. #include "sizesarm.h"
  11. #else
  12. #ifdef TARGET_SCRIPT
  13. #include "sizesspt.h"
  14. #else
  15. #ifdef TARGET_386
  16. #include "sizes386.h"
  17. #else
  18. #include "sizesz80.h"
  19. #endif
  20. #endif
  21. #endif
  22.  
  23. CONST BOOL _isalphanum[256];
  24.  
  25. EXTERN BOOL _doskip; //яЁюяєёърЄ№ ёЄЁюъш, ъЁюьх эрўшэр■∙шїё  ё #
  26.  
  27. EXTERN PCHAR _tword; //Єхъє∙хх ёыютю
  28. EXTERN UINT  _lentword;
  29. VAR PCHAR _prefix; //яЁхЇшъё Єхъє∙хую ёыютр (юёЄрЄюъ - т _tword)
  30. VAR UINT  _lenprefix;
  31. VAR PCHAR _title; //эрчтрэшх Єхъє∙хщ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
  32. VAR UINT  _lentitle;
  33. EXTERN PCHAR _callee; //эрчтрэшх т√ч√трхьющ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
  34. EXTERN UINT  _lencallee;
  35. EXTERN PCHAR _name; //ьхЄър схч яЁхЇшъёр (фы  ЄрсышЎ√ ьхЄюъ)
  36. EXTERN UINT  _lenname;
  37. EXTERN PCHAR _joined; //ртЄюьхЄър
  38. EXTERN UINT  _lenjoined;
  39. VAR PCHAR _ncells; //т addlbl эхы№ч  юс·хфшэшЄ№ ncells ё callee //Єрь цх тЁхьхээю яЁю°ыр  ьхЄър фы  enum
  40. VAR UINT  _lenncells;
  41. VAR CHAR  _s1[_STRLEN]; //яЁхЇшъё Єхъє∙хую ёыютр (юёЄрЄюъ - т _tword)
  42. VAR CHAR  _s2[_STRLEN]; //эрчтрэшх Єхъє∙хщ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
  43. VAR CHAR  _s3[_STRLEN]; //эрчтрэшх т√ч√трхьющ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
  44. VAR CHAR  _s4[_STRLEN]; //ьхЄър схч яЁхЇшъёр (фы  ЄрсышЎ√ ьхЄюъ)
  45. VAR CHAR  _s5[_STRLEN]; //ртЄюьхЄър
  46. VAR CHAR  _s6[_STRLEN]; //ўшёыю ¤ыхьхэЄют
  47.  
  48. EXTERN CHAR _cnext;
  49. EXTERN UINT _spcsize; //ўшёыю яЁюсхыют яюёых яЁюўшЄрээющ ъюьрэф√
  50.  
  51. EXTERN UINT _curline; //Єхъє∙шщ эюьхЁ ёЄЁюъш
  52.  
  53. EXTERN UINT _waseols; //ёъюы№ъю с√ыю EOL ё яЁю°ыюую Ёрчр
  54.  
  55. EXTERN UINT _typeaddr;
  56.  
  57. PROC rdch FORWARD();
  58. PROC rdchcmt FORWARD();
  59. PROC rdquotes FORWARD(CHAR eol);
  60. PROC rdaddword FORWARD();
  61. PROC rdword FORWARD();
  62. PROC initrd FORWARD();
  63.  
  64. PROC strpush FORWARD(PCHAR s, UINT len); //joined шыш callee
  65. FUNC UINT strpop FORWARD(PCHAR s);
  66. EXTERN UINT _lenstrstk;
  67.  
  68. PROC initlblbuf FORWARD();
  69.  
  70. //math (схч ьр°шээюую ъюфр)
  71. PROC cmdneg FORWARD();
  72. PROC cmdinv FORWARD();
  73. PROC cmdpoke FORWARD();
  74. PROC cmdpeek FORWARD();
  75. PROC cmdpushvar FORWARD();
  76. PROC cmdpopvar FORWARD();
  77. PROC cmdpushnum FORWARD();
  78. PROC cmdmul FORWARD();
  79. PROC cmddiv FORWARD();
  80. PROC cmdshl FORWARD();
  81. PROC cmdshr FORWARD();
  82. PROC cmdadd FORWARD();
  83. PROC cmdsub FORWARD();
  84. PROC cmdaddpoi FORWARD(); //ёфтшурхЄ ёююЄтхЄёЄтхээю Єшяє ш яЁшсрты хЄ
  85. PROC cmdand FORWARD();
  86. PROC cmdor FORWARD();
  87. PROC cmdxor FORWARD();
  88. PROC cmdinc FORWARD();
  89. PROC cmddec FORWARD();
  90. PROC cmdincbyaddr FORWARD();
  91. PROC cmddecbyaddr FORWARD();
  92.  
  93. //ёЁртэхэш  (схч ьр°шээюую ъюфр)
  94. PROC cmdless FORWARD();
  95. PROC cmdmore FORWARD();
  96. PROC cmdlesseq FORWARD();
  97. PROC cmdmoreeq FORWARD();
  98. PROC cmdeq FORWARD();
  99. PROC cmdnoteq FORWARD();
  100.  
  101. //ухэхЁрЎш  т√чютют ш яхЁхїюфют (схч ьр°шээюую ъюфр)
  102. PROC cmdjpval FORWARD();
  103. PROC cmdcallval FORWARD();
  104. PROC cmdjp FORWARD();
  105. PROC cmdjpiffalse FORWARD();
  106. PROC cmdcall FORWARD();
  107. PROC cmdfunc FORWARD();
  108. PROC cmdpushpar FORWARD(); //фы  ЁхъєЁёштэ√ї яЁюЎхфєЁ (ёюїЁрэхэшх ярЁрьхЄЁют тэєЄЁш шыш ёэрЁєцш)
  109. PROC cmdstorergs FORWARD(); //яюёых ёюїЁрэхэш  ыюъры№эющ яхЁхьхээющ ЁхъєЁёштэющ яЁюЎхфєЁ√
  110. PROC cmdpoppar FORWARD(); //фы  ЁхъєЁёштэ√ї яЁюЎхфєЁ (тюёёЄрэютыхэшх ярЁрьхЄЁют тэєЄЁш шыш ёэрЁєцш)
  111. PROC cmdresult FORWARD();
  112. PROC cmdret FORWARD(BOOL isfunc); //тюёёЄрэютыхэшх Ёхчєы№ЄрЄр яюёых ёэ Єш  ыюърыют ёю ёЄхър ш т√їюф
  113.  
  114. PROC cmdcastto FORWARD(TYPE t2);
  115. PROC cmdlabel FORWARD();
  116. PROC var_alignwsz_label FORWARD(TYPE t);
  117. PROC var_def FORWARD(TYPE t, PCHAR s);
  118.  
  119. PROC initcmd FORWARD();
  120.  
  121. PROC initcode FORWARD();
  122. PROC endcode FORWARD();
  123. PROC emitasmlabel FORWARD(PCHAR s);
  124. PROC emitfunclabel FORWARD(PCHAR s);
  125. PROC emitvarlabel FORWARD(PCHAR s);
  126. PROC emitexport FORWARD(PCHAR s);
  127. PROC emitvarpreequ FORWARD(PCHAR s);
  128. PROC emitvarpostequ FORWARD();
  129. PROC varequ FORWARD(PCHAR s);
  130. PROC asm_db FORWARD(); //ъюёЄ√ы№ фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ TODO
  131. PROC var_db FORWARD();
  132. PROC var_dw FORWARD();
  133. PROC var_ds FORWARD();
  134. FUNC UINT varshift FORWARD(UINT shift, UINT sz);
  135.  
  136. FUNC UINT gettypename FORWARD(PCHAR s); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т s (ёЁрчє яюёых lbltype)
  137. PROC setvarsz FORWARD(UINT addr, UINT shift);
  138. FUNC TYPE lbltype FORWARD(); //тхЁэєЄ№ Єшя ьхЄъш _name
  139. PROC dellbl FORWARD(); //єфрышЄ№ ьхЄъє _name
  140. PROC addlbl FORWARD(TYPE t, BOOL isloc, UINT varsz/**, PCHAR size, UINT lensize*/); //(_name)
  141. PROC keepvars FORWARD(); //яхЁхф эрўрыюь ыюъры№э√ї ьхЄюъ
  142. PROC undovars FORWARD(); //яюёых ыюъры№э√ї ьхЄюъ (чрс√Є№ шї)
  143. EXTERN UINT _varszaddr;
  144. EXTERN UINT _varsz;
  145.  
  146. EXTERN BYTE _exprlvl; //уыєсшэр т√Ёрцхэш  (тхЁїэшщ єЁютхэ№ == 1)
  147. EXTERN TYPE _t; //Єхъє∙шщ Єшя
  148. EXTERN BOOL _isloc; //ыюъры№эр  ыш яЁюўшЄрээр  яхЁхьхээр 
  149.  
  150. ////
  151. CONST UINT _MAXPARS = 16; /**ьръёшьры№эюх ўшёыю ярЁрьхЄЁют т т√чютх ЇєэъЎшш*/
  152. //todo юуЁрэшўшЄ№ уыєсшэє ЁхъєЁёшш f(g(h(...()...)
  153.  
  154. //ёюёЄю эшх ъюьяшы ЄюЁр (яы■ё х∙╕ ёюёЄю эш  commands ш codetg):
  155. VAR UINT _curlbl; //эюьхЁ ртЄюьхЄъш
  156. VAR UINT _tmpendlbl; //эюьхЁ ртЄюьхЄъш фы  т√їюфр шч Ўшъыр while/repeat
  157.  
  158. VAR BYTE _namespclvl; //уыєсшэр тыюцхээюёЄш яЁюёЄЁрэёЄтр шь╕э (ўшёыю Єюўхъ т яЁхЇшъёх)
  159.  
  160. VAR BOOL _isrecursive; //Єхъє∙р  юс· ты хьр  яЁюЎхфєЁр ЁхъєЁёштэр 
  161. VAR BOOL _wasreturn; //с√ыр ъюьрэфр return (яюёых эх╕ эхы№ч  ъюьрэф√ т ЁхъєЁёштэющ ЇєэъЎшш) //ёюїЁрэ ■Єё  т func
  162. VAR TYPE _curfunct; //Єшя ЇєэъЎшш (фы  return) //ёюїЁрэ ■Єё  т func
  163. VAR BOOL _isexp; //Єхъє∙р  юс· ты хьр  яхЁхьхээр , ъюэёЄрэЄэ√щ ьрёёшт/ёЄЁєъЄєЁр, яЁюЎхфєЁр/ЇєэъЎш  ¤ъёяюЁЄшЁєхЄё  (эю эх ъюэёЄрэЄр, Є.ъ. ¤Єю эх рфЁхё ш эх эєцэю)
  164.  
  165. VAR CHAR _c0;
  166. VAR CHAR _c2;
  167.  
  168. VAR UINT _parnum;
  169.  
  170. VAR UINT _doskipcond;
  171. //_doskipcond т сшЄютюь тшфх яюьэшЄ, ёъюы№ъю єЁютэхщ ръЄштэ√ї ifdef ш ёъюы№ъю єЁютэхщ эхръЄштэ√ї (ъЁюьх Єхъє∙хую)
  172. //(тэєЄЁш эхръЄштэюую ьюуєЄ с√Є№ Єюы№ъю эхръЄштэ√х)
  173. //хёыш (_doskipcond&1) == 0 (Є.х. ь√ т эхръЄштэющ тхЄъх), Єю Єхъє∙шщ ifdef шуэюЁшЁєхЄё  ёю тёхьш тїюф ∙шьш (Є.х. else эх ЁрсюЄрхЄ)
  174. //эхръЄштэюёЄ№ Єхъє∙хщ тхЄъш ifdef ыхцшЄ т _doskip
  175. //эр тхЁїэхь єЁютэх _doskipcond = 1, _doskip = +FALSE
  176.  
  177. VAR BOOL _morecmd; //Їыру "сыюъ эх юъюэўхэ" т eatcmd
  178.  
  179. VAR CHAR _opsym;
  180.  
  181. VAR BOOL _addrexpr; //т√Ёрцхэшх ё & фы  &(<structname>-><field>) (TODO тыюцхээю?)
  182.  
  183. #define _MAXHINCLUDES 0x08
  184. VAR PBYTE _hinclfile[_MAXHINCLUDES];
  185. VAR UINT _hnline[_MAXHINCLUDES];
  186. VAR BYTE _nhinclfiles; //ўшёыю юЄъЁ√Є√ї Їрщыют
  187. //
  188.  
  189. #ifdef USE_HINTS
  190. ;;PROC hint_tword() {
  191. ;;  hintstr("//_tword=\""); hintstr(_tword); hintstr("\", cnext=\""); hint(_cnext); hint('\"'); endhint();
  192. ;;}
  193. #endif
  194.  
  195. PROC err_tword(PCHAR s)
  196. {
  197.   errstr(s); errstr(" expected, but we have \'"); errstr(_tword); err('\''); enderr();
  198. }
  199.  
  200. PROC doexp() //тёхуфр _joined
  201. {
  202.   IF (_isexp) emitexport(_joined);
  203. }
  204.  
  205. PROC eat(CHAR c)
  206. {
  207.   IF (*(PCHAR)_tword!=c) {
  208.     err(c); errstr(" expected, but we have \'"); errstr(_tword); err('\''); enderr();
  209.   };
  210.   rdword();
  211. }
  212.  
  213. PROC jdot()
  214. {
  215.   _lenjoined = stradd(_joined, _lenjoined,'.');
  216.   _joined[_lenjoined] = '\0';
  217. }
  218.  
  219. VAR UINT _genn;
  220.  
  221. PROC gendig(UINT d)
  222. {
  223. VAR BYTE dig;
  224.   dig = (BYTE)'A';
  225.   WHILE (_genn >= d) {
  226.     _genn = _genn - d;
  227.     INC dig;
  228.     _wasdig = +TRUE;
  229.   };
  230.   IF (_wasdig) {
  231.     _lenjoined = stradd(_joined, _lenjoined, (CHAR)dig);
  232.   };
  233. }
  234.  
  235. PROC jautonum(UINT n)
  236. {
  237.   _genn = n;
  238.   _wasdig = +TRUE;
  239.   IF (n != 0) {
  240.     _wasdig = +FALSE;
  241.     gendig(676);
  242.     gendig(26);
  243.   };
  244.   gendig(1);
  245.   jdot();
  246. }
  247.  
  248. PROC genjplbl(UINT n)
  249. {
  250.   _lenjoined = strcopy(_title, _lentitle, _joined);
  251.   jautonum(n);
  252. }
  253.  
  254. PROC jtitletword()
  255. {
  256.   _lenjoined = strcopy(_title, _lentitle, _joined);
  257.   _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword);
  258.   _joined[_lenjoined] = '\0';
  259. }
  260.  
  261. PROC do_type()
  262. {
  263. loop:
  264.   _lenname = strcopy(_tword, _lentword, _name);
  265.   _t = lbltype();
  266.   IF ((_t&_T_TYPE)!=(TYPE)0x00) { //хёыш ¤Єю эх яхЁхьхээр , р Єшя
  267.     IF (_t == (_T_TYPE+_T_STRUCTWORD)) {
  268.       rdword(); //use STRUCT
  269.       goto loop;
  270.     };
  271.     IF (_cnext == '*') {
  272.       _t = _t|_T_POI;
  273.       _varsz = (UINT)_SZ_REG;
  274.       rdword(); //use *
  275.     };
  276.   };
  277. }
  278.  
  279. PROC eattype()
  280. {
  281.   do_type();
  282.   _t = _t&~_T_TYPE;
  283.   rdword();
  284. }
  285.  
  286. PROC doprefix(BYTE nb) //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
  287. {
  288.   _lenprefix = 0;
  289.   WHILE (nb > 0x00) { //яхЁхсшЁрхь ёыютр
  290.     _lenprefix = strjoineol(/**to=*/_prefix, _lenprefix, &_title[_lenprefix], '.');
  291.     _lenprefix = stradd(_prefix, _lenprefix, '.');
  292.     DEC nb;
  293.   };
  294.   _prefix[_lenprefix] = '\0';
  295.   _lenjoined = strcopy(_prefix, _lenprefix, _joined);
  296.   _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword/**, _lentword*/);
  297.   _joined[_lenjoined] = '\0';
  298. }
  299.  
  300. PROC adddots()
  301. {
  302. /**  WHILE (_cnext == '.') {
  303.     rdaddword(); //яЁшъыхшЄ№ Єюўъє
  304.     rdaddword(); //яЁшъыхшЄ№ ёыхфє■∙хх ёыютю
  305.   };*/
  306. }
  307.  
  308. PROC twordtojoined()
  309. {
  310.   _lenjoined = strcopy(_tword, _lentword, _joined);
  311. }
  312.  
  313. PROC joinvarname(BOOL iscall) //тючтЁр∙рхЄ _t = Єшя(_name)???
  314. { //шфхэЄшЇшърЄюЁ єцх яЁюўшЄрэ
  315. VAR BYTE lvl;
  316.   do_type();
  317.   IF (!_isloc) {
  318.     twordtojoined();
  319.   }ELSE {
  320.     lvl = _namespclvl;
  321.     IF (iscall && (lvl != 0x00)) {
  322.       DEC lvl; //proc()
  323.     };
  324.     doprefix(lvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
  325.     //todo яЁютхЁшЄ№ ш ¤ЄюЄ Єшя (фы  ьюфєы№эюёЄш)?
  326.     //шыш todo яЁхтЁрЄшЄ№ stru1->f1.f2 т tstru1.f1+tstru2.f2
  327.   };
  328. }
  329.  
  330. PROC eatvarname() //фы  ёючфрэш  ьхЄюъ
  331. {
  332.   eattype(); //t = _t; //Єшя с√ы єцх яЁюўшЄрэ
  333.   adddots();
  334.   _lenname = strcopy(_tword, _lentword, _name);
  335.   doprefix(_namespclvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
  336.   rdword(); //'['
  337.   IF (*(PCHAR)_tword == '[') {
  338.     _t = _t|_T_ARRAY;
  339.   };
  340. }
  341.  
  342. PROC getstructfield() //тючтЁр∙рхЄ _t = Єшя яюы 
  343. { //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr (т lbltype шыш addlbl), Єшя _t = эхъшщ єърчрЄхы№???
  344.   _lenjoined = gettypename(_joined); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined
  345.   eat('>'); //use '>'
  346.   jdot();
  347.   _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword); //structname.structfield
  348.   _joined[_lenjoined] = '\0';
  349.   cmdpushnum(); //structname.structfield
  350.   cmdadd();
  351.   _lenname = strcopy(/**from=*/_joined, _lenjoined, _name); //structname.structfield
  352.   _t = lbltype(); //(_name)
  353. }
  354.  
  355. //////////////////////////////////////////
  356. // compiler
  357.  
  358. //call т√ч√трхЄ _tword ш expr
  359. PROC eatexpr RECURSIVE FORWARD();  //т√ч√трхЄ call
  360. FUNC BOOL eatcmd RECURSIVE FORWARD();  //т√ч√трхЄ call
  361. FUNC TYPE do_call RECURSIVE FORWARD(BOOL isfunc); //тючтЁр∙рхЄ Єшя ЇєэъЎшш
  362. PROC compfile RECURSIVE FORWARD(PCHAR fn);
  363.  
  364. PROC varstrz() //фы  ёЄЁюъют√ї ъюэёЄрэЄ т т√Ёрцхэш ї
  365. {
  366.   emitvarlabel(_joined);
  367.   WHILE (+TRUE) {
  368.     rdquotes('\"');
  369.     rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
  370.     _tword[_lentword] = '\0';
  371.     var_db(); varstr(_tword); endvar();
  372.     IF (_cnext != '\"') BREAK;
  373.     rdword(); //юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
  374.   };
  375.   var_db(); varc('0'); endvar();
  376. }
  377.  
  378. PROC asmstrz() //тёх CONST ёЄЁюъш ЄхяхЁ№ т ъюфх (Ёрэ№°х с√ыю Єюы№ъю фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ)
  379. {
  380.   emitasmlabel(_joined);
  381.   WHILE (+TRUE) {
  382.     rdquotes('\"');
  383.     rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
  384.     _tword[_lentword] = '\0';
  385.     asm_db(); asmstr(_tword); endasm();
  386.     IF (_cnext != '\"') BREAK;
  387.     rdword(); //юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
  388.   };
  389.   asm_db(); asmc('0'); endasm();
  390. }
  391.  
  392. PROC eatidx() //фы  idxarray ш switch
  393. {
  394.   INC _exprlvl; //no jump optimization
  395.   eatexpr(); //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
  396.   DEC _exprlvl;
  397.   IF (_t==_T_BYTE) cmdcastto(_T_UINT);
  398.   IF (_t!=_T_UINT) {errstr("idx bad type "); erruint((UINT)_t); enderr(); };
  399. }
  400.  
  401. FUNC TYPE idxarray RECURSIVE(TYPE t)
  402. {
  403.   rdword(); //яхЁтюх ёыютю expr
  404.   IF ((t&_T_ARRAY) != (TYPE)0x00) { //ьрёёшт
  405.     t = t&_TYPEMASK; //&(~(_T_ARRAY|_T_CONST)); //ьюцхЄ с√Є№ _T_POI (хёыш ьрёёшт ёЄЁюъ)
  406.     _t = _T_POI|_T_BYTE; cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
  407.   }ELSE IF ((t&_T_POI) != (TYPE)0x00) { //єърчрЄхы№
  408.     _t = t; cmdpushvar(); //шёяюы№чютрэшх єърчрЄхы  т ърўхёЄтх ьрёёштр - ўшЄрхь хую чэрўхэшх
  409.     t = t&(~_T_POI);
  410.   }ELSE {errstr("[] not in array "); erruint((UINT)t); enderr(); };
  411.   eatidx();
  412.   _t = t; //Єшя ¤ыхьхэЄр ьрёёштр
  413.   cmdaddpoi();
  414. RETURN t; //Єшя ¤ыхьхэЄр ьрёёштр
  415. }
  416.  
  417. PROC numtype()
  418. {
  419.   IF (_cnext == '.') { //фЁюсэюх ўшёыю (эхы№ч  эрўшэрЄ№ ё Єюўъш шыш чрърэўштрЄ№ Єюўъющ)
  420.     rdaddword(); //яЁшъыхшЄ№ Єюўъє
  421.     rdaddword(); //яЁшъыхшЄ№ фЁюсэє■ ўрёЄ№
  422.     IF ( (_tword[_lentword-1]=='e') && (_cnext=='-') ) {
  423.       rdaddword(); //яЁшъыхшЄ№ '-' юЄЁшЎрЄхы№эющ ¤ъёяюэхэЄ√
  424.       rdaddword(); //яЁшъыхшЄ№ юЄЁшЎрЄхы№эє■ ¤ъёяюэхэЄє
  425.     };
  426.     _t = _T_FLOAT;
  427.   }ELSE IF (*(PCHAR)_tword == '-') { //т val єцх хёЄ№, эрфю фы  define
  428.     _t = _T_INT;
  429.   }ELSE IF (_tword[_lentword-1]=='L') {
  430.     _t = _T_LONG;
  431.   }ELSE IF ((BYTE)_tword[1] > (BYTE)'9') { //єёъюЁхэшх яЁютхЁъш ўшёыютюую ЇюЁьрЄр
  432.     IF ((_lentword<=4)&&(_tword[1]=='x')) {
  433.       _t = _T_BYTE;
  434.     }ELSE IF ((_lentword<=10)&&(_tword[1]=='b')) {
  435.       _t = _T_BYTE;
  436.     }ELSE {
  437.       _t = _T_UINT;
  438.     };
  439.   }ELSE {
  440.     _t = _T_UINT;
  441.   };
  442. }
  443.  
  444. PROC val RECURSIVE()
  445. {
  446. VAR TYPE t; //фы  cast,peek
  447. VAR UINT typeaddr; //фы  cast
  448. {
  449. //<val>::=
  450. //(<expr>) //т√Ёрцхэшх (т√ўшёы хЄё )
  451. //|<num> //фхё Єшўэюх ўшёыю (яхЁхфр╕Єё  Ўхышъюь) INT/UINT/LONG
  452. //|<num>.<num>[e-<num>] //float ўшёыю (яхЁхфр╕Єё  Ўхышъюь)
  453. //|<var> //яхЁхьхээр 
  454. //|'CHAR' //ёшьтюы№эр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
  455. //|"str" //ёЄЁюъютр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
  456. //|(<type>)<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ яхЁхтюф т <type>
  457. //|+<boolconst>
  458. //|+_<enumconst> BYTE
  459. //|+(constexpr) //Єшя яю ыхтюьє ъюэЄхъёЄє
  460. //|<lbl>([<val>,...]) //call
  461. //|-<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ NEG
  462. //|~<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV
  463. //|!<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV(BOOL)
  464. //|*(<ptype>)<val> //яЁюўшЄрЄ№ ярь Є№ яю рфЁхёє (т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ PEEK)
  465. //|&<var> //рфЁхё яхЁхьхээющ
  466.  //ъюьрэфр єцх яЁюўшЄрэр
  467. #ifdef USE_HINTS
  468. ;;  hintstr("//val: word=\""); hintstr(_tword); hintstr("\", cnext=\""); hint(_cnext); hint('\"'); endhint();
  469. #endif
  470.   _opsym = *(PCHAR)_tword;
  471.   IF (_opsym == '~') {
  472.     rdword(); //яхЁтюх ёыютю val
  473.     IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
  474.     cmdinv();
  475.   }ELSE IF ((BYTE)_opsym >= 0x41) { //<var>
  476.     adddots();
  477.    //хёыш т√чют ЇєэъЎшш, Єю do_variable эрфю фхырЄ№ ё namespclvl-1!!!
  478.     IF (_cnext == '(') { //call
  479.       _t = do_call(+TRUE); //isfunc
  480.     }ELSE {
  481.       joinvarname(+FALSE); //iscall
  482.       IF (_cnext == '[') { //<varname>[<idx>]
  483.         rdword();
  484.         _t = idxarray(_t);
  485.         cmdpeek();
  486.       }ELSE { //<varname>
  487.         IF ((_t&_T_TYPE)==(TYPE)0x00) {
  488.           /**IF (_t==_T_STRUCT) {
  489.             _t = _T_POI|_T_BYTE;
  490.             cmdpushnum(); //схЁ╕ь рфЁхё ёЄЁєъЄєЁ√ (фы  .)
  491.           }ELSE*/ IF ((_t&_T_ARRAY)!=(TYPE)0x00) { //array without [] as a pointer
  492.             _t = _t&(~(_T_ARRAY|_T_CONST))|_T_POI;
  493.             cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
  494.           }ELSE IF ((_t&_T_CONST)==(TYPE)0x00) {
  495.             cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
  496.           }ELSE { //ъюэёЄрэЄр (equ)
  497.             _t = _t&_TYPEMASK; //&(~_T_CONST);
  498.             cmdpushnum();
  499.           };
  500.         };
  501.       };
  502.     };
  503.   }ELSE IF (_opsym == '\'') {
  504.     rdquotes('\'');
  505.     rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
  506.     _tword[_lentword] = '\0';
  507.     twordtojoined();
  508.     _t = _T_CHAR; cmdpushnum();
  509.   }ELSE IF (_opsym == '\"') {
  510.     _lenjoined = strcopy(_title, _lentitle, _joined);
  511.     jautonum(_curlbl);
  512.     INC _curlbl;
  513.     _t = _T_POI|_T_CHAR; cmdpushnum();
  514.     varstrz(); //ё ьхЄъющ joined
  515.   }ELSE IF (_opsym == '+') {
  516.     rdword(); //'(' of type or +TRUE/+FALSE (BOOL) or +_CONSTANT or +__CONSTANT (BYTE)
  517.     _opsym = *(PCHAR)_tword;
  518.     IF (_opsym=='_') { //+_CONSTANT
  519.       //эрўры№эр  ўрёЄ№ шьхэш ъюэёЄрэЄ√ єцх яЁюўшЄрэр
  520.       adddots();
  521.       joinvarname(/**iscall*/+FALSE);
  522.       _lenjoined = strcopy(_name, _lenname, _joined); //уыюсры№эр 
  523.       _t = _T_BYTE; cmdpushnum();
  524.     }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //+num //extra BYTE for C bug
  525.       IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
  526.       IF (_t == _T_UINT) cmdcastto(_T_INT); //фы  чэръют√ї ъюэёЄрэЄ Єшяр +15
  527.     }ELSE IF (_opsym!='(') { //+TRUE/+FALSE (BOOL) //+sizeof
  528.       IF (_opsym=='s') { //+sizeof //TODO uppercase?
  529.         rdword(); //шёяюы№чютрыш sizeof
  530.         eat('('/**, "\'(\'"*/);
  531.         eattype();
  532. //        IF ((_t&_T_TYPE)!=0x00) {
  533.           emitn(_varsz); //gettypesz();
  534.           _lenjoined = strcopy(_nbuf, _lennbuf, _joined); //уыюсры№эр 
  535. //        }ELSE { //эх Єшя
  536.           //- шч яхЁхьхээющ срчютюую Єшяр - сєфхЄ ю°шсър, Є.ъ. яє° чэрўхэш  яхЁхьхээющ TODO (ёфхырЄ№ ёюёЄю эшх _issizeof)
  537.           //- шч яхЁхьхээющ ьрёёштр - сєфхЄ ю°шсър, Є.ъ. яє° рфЁхёр ьрёёштр TODO
  538.           //- шч яхЁхьхээющ ёЄЁєъЄєЁ√ - сєфхЄ ю°шсър, Є.ъ. яє° рфЁхёр ёЄЁєъЄєЁ√ TODO
  539.           //- шч т√Ёрцхэш  - сєфхЄ ю°шсър, Є.ъ. ёухэхЁшЁє■Єё  юяхЁрЎшш TODO
  540. //        };
  541.         _t = _T_UINT; cmdpushnum(); //(_joined)
  542.       }ELSE { //+TRUE/+FALSE (BOOL)
  543.         twordtojoined();
  544.         _t = _T_BOOL; cmdpushnum(); //(_joined)
  545.       };
  546.     }ELSE { //'(': с√ы typecast
  547. #ifdef USE_COMMENTS
  548. ;;  cmtstr(";+(val)"); endcmt();
  549. #endif
  550.       rdword(); //(
  551.       rdquotes(')');
  552.       twordtojoined();
  553.       rdword(); //)
  554.       cmdpushnum(); //(_joined) //type from left context!!!
  555.     };
  556.   }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //num //extra BYTE for C bug
  557.     numtype(); //_t
  558.     twordtojoined();
  559.     cmdpushnum();
  560.   }ELSE IF (_opsym == '(') {
  561.     rdword(); //яхЁтюх ёыютю expr
  562.     eatexpr(); //эр т√їюфх шч expr єцх яЁюўшЄрэр ')'???, эю ёыхфє■∙шщ ёшьтюы шыш ъюьрэфр эх яЁюўшЄрэ√
  563.     typeaddr = _typeaddr;
  564.     IF ((_t&_T_TYPE)!=(TYPE)0x00) { //(type)val typecast//эхы№ч  т sizeof(expr)
  565.       t = _t&~_T_TYPE;
  566.       _t = t;
  567.       rdword();
  568.       val();
  569.       _typeaddr = typeaddr;
  570.       cmdcastto(t);
  571.     };
  572.   }ELSE IF (_opsym == '-') {
  573.     IF ((BYTE)((BYTE)_cnext - (BYTE)'0') < 0x0a) { //-<const>
  574.       rdaddword();
  575.       //todo float
  576.       _t = _T_INT;
  577.       twordtojoined();
  578.       cmdpushnum();
  579.     }ELSE { //-<var>
  580.       rdword(); //яхЁтюх ёыютю val
  581.       IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
  582.       cmdneg();
  583.     };
  584.   }ELSE IF (_opsym == '!') {
  585.     rdword(); //яхЁтюх ёыютю val
  586.     IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
  587.     cmdinv(); //TODO invBOOL
  588.   }ELSE IF (_opsym == '*') {
  589.     rdword(); //'(' of type
  590.     IF (!_waseof) val(); //чфхё№ Єшя єърчрЄхы  эх трцхэ //ЁхъєЁёштэ√щ т√чют val
  591.     _t = _t&~_T_POI; //&~_T_CONST;
  592.     cmdpeek();
  593.   }ELSE IF (_opsym == '&') {
  594.     IF (_cnext == '(') { //&(<structname>-><field>)
  595.       _addrexpr = +TRUE;
  596.       rdword(); //'('
  597.       val();
  598.       _t = _t|_T_POI;
  599.     }ELSE {
  600.       rdword();
  601.       adddots();
  602.       joinvarname(/**iscall*/+FALSE);
  603.       IF (_cnext == '[') { //&<varname>[<idx>]
  604.         rdword(); //'['
  605.         _t = idxarray(_t)/**Єшя ¤ыхьхэЄр ьрёёштр*/|_T_POI;
  606.       }ELSE { //&<varname>
  607.         //IF ((_t&_T_ARRAY)!=0x00) { //&<arrayname> - error
  608.         //}ELSE IF ((_t&_T_CONST)!=0x00) { //&<constname> - error
  609.         //}ELSE { //&<varname>
  610.           _t = _t&_TYPEMASK|_T_POI;
  611.           cmdpushnum();
  612.         //};
  613.       };
  614.     };
  615.   }ELSE {
  616.     errstr("WRONG PREFIX "); err(_opsym); enderr();
  617.     _t = _T_UNKNOWN; //debug (шэрўх ьюцхЄ т√ыхЄхЄ№ чр ЄрсышЎє typesz яЁш юсЁ√тх Їрщыр)
  618.   };
  619. #ifdef USE_HINTS
  620. ;;  hinttype("end val",_t);
  621. #endif
  622. }
  623. }
  624.  
  625. PROC eatmulval RECURSIVE()
  626. {
  627. VAR CHAR opsym;
  628. VAR TYPE t1;
  629. {
  630. //<val>[<*|/><val>...] => push[push<*|/>...]
  631. //чрърэўштрхЄё  яю ёшьтюыє ы■сющ эхюяшёрээющ юяхЁрЎшш (эряЁшьхЁ, ')' шыш ';')
  632.  //ъюьрэфр єцх яЁюўшЄрэр
  633. #ifdef USE_HINTS
  634. ;;  hintstr("//mulval"); endhint();
  635. #endif
  636.   val();
  637.   rdword();
  638. #ifdef USE_HINTS
  639. ;;  hintstr("//mulval after val"); hint_tword();
  640. #endif
  641.   REPEAT {
  642.     opsym = *(PCHAR)_tword;
  643.     IF (opsym!='*')
  644.       IF (opsym!='/')
  645.         IF (opsym!='&')
  646.           BREAK;
  647.     t1 = _t;
  648.     rdword();
  649.     IF (opsym=='&')
  650.       IF (*(PCHAR)_tword==opsym)
  651.         rdword(); //use '&' //C compatibility
  652.     val();
  653.     _t = _t&_TYPEMASK; //&(~_T_CONST);
  654.     rdword();
  655. #ifdef USE_HINTS
  656. ;;    hintstr("//mulval after val2"); hint_tword();
  657. #endif
  658.     IF (t1 != _t) {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
  659.     IF       (opsym=='&') {cmdand();
  660.     }ELSE IF (opsym=='*') {cmdmul();
  661.     }ELSE /**IF (opsym=='/')*/ {cmddiv();
  662.     };
  663.   }UNTIL (_waseof);
  664. #ifdef USE_HINTS
  665. ;;  hinttype("end mulval",_t);
  666. #endif
  667. }
  668. }
  669.  
  670. PROC eatsumval RECURSIVE()
  671. {
  672. VAR CHAR opsym;
  673. VAR TYPE t1;
  674. {
  675. //<mulval>[<+|-><mulval>...] => push[push<+|->...]
  676.  //ъюьрэфр єцх яЁюўшЄрэр
  677. #ifdef USE_HINTS
  678. ;;  hintstr("//sumval"); endhint();
  679. #endif
  680.   eatmulval();
  681.   REPEAT {
  682.     opsym = *(PCHAR)_tword;
  683.     IF (opsym!='+')
  684.       IF (opsym!='-')
  685.         IF (opsym!='|')
  686.           IF (opsym!='^')
  687.             BREAK;
  688.     t1 = _t;
  689.     rdword();
  690.     IF (*(PCHAR)_tword=='>') { //structinstancepointer->structfield
  691.       //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr, Єшя _t = эхъшщ єърчрЄхы№
  692.       IF (_t == _T_UNKNOWN) {errstr("nolbl:"); errstr(_name); enderr(); };
  693.       getstructfield(); //_t = Єшя яюы 
  694.       IF (!_addrexpr) cmdpeek(); //peek
  695.       rdword(); //шёяюы№чютрыш structfield
  696.     }ELSE {
  697.       IF (opsym=='|') //||(opsym=='^')
  698.         IF (*(PCHAR)_tword==opsym)
  699.           rdword(); //use '|' or '^' //C compatibility
  700.       eatmulval();
  701.       _t = _t&_TYPEMASK; //&(~_T_CONST);
  702.       IF (t1 != _t) /**&& ((t&_T_POI)!=0x00)*/ {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
  703.       //todo addpointer
  704.       IF       (opsym == '+') {cmdadd();
  705.       }ELSE IF (opsym == '-') {cmdsub(); //шч ёЄрЁюую т√ўхёЄ№ эютюх!
  706.       }ELSE IF (opsym == '|') {cmdor();
  707.       }ELSE /**IF (opsym == '^')*/ {cmdxor();
  708.       };
  709.     };
  710.   }UNTIL (_waseof);
  711. #ifdef USE_HINTS
  712. ;;  hinttype("end sumval",_t);
  713. #endif
  714. }
  715. }
  716.  
  717. PROC eatexpr RECURSIVE()
  718. {
  719. VAR CHAR opsym;
  720. VAR TYPE t1;
  721. VAR BOOL modified;
  722. VAR BOOL dbl;
  723. {
  724. //<sumval>[<=><sumval>...]
  725.  //ъюьрэфр єцх яЁюўшЄрэр (эєцэю фы  do_call_par)
  726. #ifdef USE_HINTS
  727. ;;  hintstr("//expr"); endhint();
  728. #endif
  729.   INC _exprlvl;
  730.   eatsumval();
  731.   REPEAT {
  732.     opsym = *(PCHAR)_tword;
  733.     IF (opsym!='<')
  734.       IF (opsym!='>')
  735.         IF (opsym!='=')
  736.           IF (opsym!='!')
  737.             BREAK;
  738.     t1 = _t;
  739.     rdword();
  740.     modified = (*(PCHAR)_tword=='=');
  741.     dbl = (*(PCHAR)_tword==opsym);
  742.     IF ( modified||dbl ) rdword(); //use '=' or '>' or '<'
  743.     eatsumval();
  744.     _t = _t&_TYPEMASK; //&(~_T_CONST);
  745.     IF (t1 != _t) {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
  746.     IF (opsym == '=') {
  747.       IF (!dbl) {errstr( "assign in expr" ); enderr(); };
  748.       cmdeq(); //фхырхЄ _t = _T_BOOL
  749.     }ELSE IF (opsym == '!') {
  750.       cmdnoteq(); //фхырхЄ _t = _T_BOOL
  751.     }ELSE IF (opsym == '<') {
  752.       IF (dbl) {
  753.         cmdshl(); //ёЄрЁюх ёфтшэєЄ№ ёЄюы№ъю Ёрч, ёъюы№ъю уырёшЄ эютюх!
  754.       }ELSE IF (modified) {
  755.         cmdlesseq(); //фхырхЄ _t = _T_BOOL
  756.       }ELSE cmdless(); //фхырхЄ _t = _T_BOOL
  757.     }ELSE /**IF (opsym == '>')*/ {
  758.       IF (dbl) {
  759.         cmdshr(); //ёЄрЁюх ёфтшэєЄ№ ёЄюы№ъю Ёрч, ёъюы№ъю уырёшЄ эютюх!
  760.       }ELSE IF (modified) {
  761.         cmdmoreeq(); //фхырхЄ _t = _T_BOOL
  762.       }ELSE cmdmore(); //фхырхЄ _t = _T_BOOL
  763.     };
  764.   }UNTIL (_waseof);
  765.   //т _tword юцшфрхЄё  ')' шыш фЁєующ эхёююЄтхЄёЄтє■∙шщ ёшьтюы
  766.   DEC _exprlvl;
  767.   _addrexpr = +FALSE; //эх т√Ёрцхэшх ё &
  768. #ifdef USE_HINTS
  769. ;;  hinttype("end expr",_t);
  770. ;;  hint_tword();
  771. #endif
  772. }
  773. }
  774.  
  775. PROC eatpoke()
  776. //poke*(<ptype>)(<pointerexpr>)=<expr>
  777. {
  778. VAR TYPE t;
  779. #ifdef USE_HINTS
  780. ;;  hintstr("//poke"); endhint();
  781. #endif
  782.   _exprlvl = 0x01; //no jump optimization
  783.   eat('*');
  784.   val(); t = _t&~_T_POI;
  785.   rdword();
  786.   eat('=');
  787.   eatexpr();
  788.   IF (t != _t) {errstr("poke variable type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
  789.   cmdpoke();
  790. #ifdef USE_HINTS
  791. ;;  hintstr("//end poke"); endhint();
  792. #endif
  793. }
  794.  
  795. PROC eatlet()
  796. //<var>[<[><expr><]>]=<expr>
  797. //<var>-><field>=<expr>
  798. {
  799. VAR TYPE t;
  800. VAR BOOL ispoke;
  801. #ifdef USE_HINTS
  802. ;;  hintstr("//let"); endhint();
  803. #endif
  804.   _exprlvl = 0x01; //no jp optimization
  805.   joinvarname(/**iscall*/+FALSE); t = _t; //t!!!
  806.   rdword(); //'['
  807.   ispoke = +FALSE;
  808.   IF (*(PCHAR)_tword == '[') {
  809.     t = idxarray(t); //t = t&(~(_T_ARRAY|_T_POI));
  810.     eat(']');
  811.     ispoke = +TRUE;
  812.   }ELSE {
  813.     WHILE (*(PCHAR)_tword == '-') {
  814.       _t = t;
  815.       IF (ispoke) { //эх яхЁт√щ ->
  816.         cmdpeek();
  817.       }ELSE { //яхЁт√щ ->
  818.         cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
  819.       };
  820.       eat('-');
  821.       //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr, Єшя _t = эхъшщ єърчрЄхы№
  822.       IF (_t == _T_UNKNOWN) {errstr("nolbl:"); errstr(_name); enderr(); };
  823.       getstructfield(); //_t = Єшя яюы 
  824.       t = _t; //todo
  825.       rdword(); //шёяюы№чютрыш structfield
  826.       ispoke = +TRUE;
  827.     };
  828.   };
  829.   eat('=');
  830.  strpush(_joined,_lenjoined);
  831.   eatexpr(); //яюыєўрхЄ Єшя _t
  832.  _lenjoined = strpop(_joined);
  833.   IF (t!=_t) {
  834.     errstr("let variable type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr();
  835.   };
  836.   IF (ispoke) {
  837.     cmdpoke();
  838.   }ELSE {
  839.     cmdpopvar();
  840.   };
  841. #ifdef USE_HINTS
  842. ;;  hintstr("//end let"); hint_tword();
  843. #endif
  844. }
  845.  
  846. PROC eatwhile RECURSIVE()
  847. //while<expr><cmd>
  848. {
  849. VAR UINT beglbl;
  850. VAR UINT wasendlbl;
  851. {
  852. #ifdef USE_HINTS
  853. ;;  hintstr("//while"); endhint();
  854. #endif
  855.   _exprlvl = 0x00; //jp optimization possible
  856.   wasendlbl = _tmpendlbl;
  857.   beglbl = _curlbl; INC _curlbl;
  858.   _tmpendlbl = _curlbl; INC _curlbl;
  859.   genjplbl(beglbl); cmdlabel();
  860.   eat('(');
  861.   eatexpr(); //parentheses not included
  862.   genjplbl(_tmpendlbl); cmdjpiffalse();
  863.   eat(')');
  864.   eatcmd(); //Єхыю while
  865.   genjplbl(beglbl); cmdjp();
  866.   genjplbl(_tmpendlbl); cmdlabel();
  867.   _tmpendlbl = wasendlbl;
  868. #ifdef USE_HINTS
  869. ;;  hintstr("//end while"); endhint();
  870. #endif
  871. }
  872. }
  873.  
  874. PROC eatrepeat RECURSIVE()
  875. //repeat<cmd>until<expr>
  876. {
  877. VAR UINT beglbl;
  878. VAR UINT wasendlbl;
  879. {
  880. #ifdef USE_HINTS
  881. ;;  hintstr("//repeat"); endhint();
  882. #endif
  883.   wasendlbl = _tmpendlbl;
  884.   beglbl = _curlbl; INC _curlbl;
  885.   _tmpendlbl = _curlbl; INC _curlbl;
  886.   genjplbl(beglbl); cmdlabel();
  887.   eatcmd(); //Єхыю repeat
  888.   IF ( (CHAR)((BYTE)(*(PCHAR)_tword)|0x20)!='u'/**"until"*/ ) err_tword("UNTIL");
  889.   rdword();
  890.   eat('(');
  891.   _exprlvl = 0x00; //jp optimization possible
  892.   eatexpr(); //parentheses not included
  893.   eat(')');
  894.   genjplbl(beglbl); cmdjpiffalse();
  895.   genjplbl(_tmpendlbl); cmdlabel();
  896.   _tmpendlbl = wasendlbl;
  897. #ifdef USE_HINTS
  898. ;;  hintstr("//end repeat"); endhint();
  899. #endif
  900. }
  901. }
  902.  
  903. PROC eatbreak() //todo inline
  904. //break
  905. {
  906.   genjplbl(_tmpendlbl);
  907.   cmdjp();
  908. }
  909.  
  910. PROC eatif RECURSIVE()
  911. //if <expr> <cmd>[else<cmd>];
  912. //(; яЁюЄшт ю°шсъш "IF (expr);cmd" ш ю°шсъш тыюцхээюую if)
  913. {
  914. VAR UINT elselbl;
  915. VAR UINT endiflbl;
  916. {
  917. #ifdef USE_HINTS
  918. ;;  hintstr("//if"); endhint();
  919. #endif
  920.   _exprlvl = 0x00; //jp optimization possible
  921.   elselbl = _curlbl; INC _curlbl;
  922.   endiflbl = _curlbl; INC _curlbl;
  923.   eat('(');
  924.   eatexpr(); //parentheses not included
  925.   genjplbl(elselbl); cmdjpiffalse();
  926.   eat(')');
  927.   eatcmd(); //Єхыю then
  928.   IF (*(PCHAR)_tword != ';'/**"endif"*/) {
  929.     IF ( (CHAR)((BYTE)(*(PCHAR)_tword)|0x20)!='e'/**"else"*/ ) err_tword("ELSE or \';\'");
  930.     genjplbl(endiflbl); cmdjp();
  931.     genjplbl(elselbl); cmdlabel();
  932.     rdword();
  933.     eatcmd(); //Єхыю else
  934.     genjplbl(endiflbl); cmdlabel();
  935.     IF (*(PCHAR)_tword != ';'/**"endif"*/) { errstr( "\';\' expected, but we have \'"); err(*(PCHAR)_tword); err('\''); enderr(); };
  936.     //эхы№ч  ё·хфрЄ№ ';', юэ эєцхэ фы  тыюцхээ√ї if
  937.   }ELSE { //юцшфрхь 'endif' (хёыш IF схч ELSE)
  938.     genjplbl(elselbl); cmdlabel();
  939.   };
  940. #ifdef USE_HINTS
  941. ;;  hintstr("//end if"); endhint();
  942. #endif
  943. }
  944. }
  945. /**
  946. PROC eatmodule RECURSIVE()
  947. //module<lbl><cmd>
  948. {
  949.   _lentitle = strjoin(_title, _lentitle, _tword);
  950.   _lentitle = stradd(_title, _lentitle, '.');
  951.   INC _namespclvl; //фюсрты хь ёыютю ъ title
  952.  
  953.   rdword();
  954.   eatcmd();
  955.  
  956.   DEC _namespclvl;
  957.   doprefix(_namespclvl); //to prefix
  958.   _lentitle = strcopy(_prefix, _lenprefix, _title); //title = prefix //юЄЁхчрхь фюсртыхээюх ёыютю
  959. }
  960. */
  961. PROC eatreturn() //todo inline
  962. {
  963. //todo яЁютхЁшЄ№ isfunc (ўЄю ь√ т ЇєэъЎшш) фы  т√тюфр ю°шсъш
  964. #ifdef USE_HINTS
  965. ;;  hintstr("//return"); endhint();
  966. #endif
  967.   _exprlvl = 0x01; //no jp optimization
  968.   eatexpr(); //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
  969.   IF ( _t != (_curfunct&(~_T_RECURSIVE)) ) {errstr("return type="); erruint((UINT)_curfunct); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
  970.   cmdresult();
  971. #ifdef USE_HINTS
  972. ;;  hintstr("//end return"); endhint();
  973. #endif
  974.   _wasreturn = +TRUE; //єёЄрэютшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
  975. }
  976.  
  977. PROC eatinc()
  978. {
  979. #ifdef USE_HINTS
  980. ;;  hintstr("//inc"); endhint();
  981. #endif
  982.   IF (*(PCHAR)_tword == '*') {
  983.     rdword(); //'('
  984.     eatexpr();
  985.     _t = _t&~_T_POI;
  986.     cmdincbyaddr();
  987.   }ELSE {
  988.     //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  989.     adddots(); //фюўшЄрЄ№ шь 
  990.     joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
  991.     cmdinc();
  992.     rdword();
  993.   };
  994. }
  995.  
  996. PROC eatdec()
  997. {
  998. #ifdef USE_HINTS
  999. ;;  hintstr("//dec"); endhint();
  1000. #endif
  1001.   IF (*(PCHAR)_tword == '*') {
  1002.     rdword(); //'('
  1003.     eatexpr();
  1004.     _t = _t&~_T_POI;
  1005.     cmddecbyaddr();
  1006.   }ELSE {
  1007.     //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  1008.     adddots(); //фюўшЄрЄ№ шь 
  1009.     joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
  1010.     cmddec();
  1011.     rdword();
  1012.   };
  1013. }
  1014.  
  1015. PROC var_num(TYPE t, PCHAR s)
  1016. {
  1017. VAR TYPE tmasked = t&(~_T_ARRAY);
  1018. /**  IF ( (t&_T_POI)!=(TYPE)0x00 ) { //шёяюы№чєхЄё  фы  ёЄЁюъ (эхы№ч  equ)
  1019.     varstr_tword(); //DB "str"
  1020.   }ELSE*/ IF ( (t&_T_CONST)!=(TYPE)0x00 ) {
  1021.     varequ(_title); /**varstr(_title); varc( '=' );*/ varstr(s); endvar();
  1022.   }ELSE {
  1023.     IF (t==tmasked/**(t&_T_ARRAY)==(TYPE)0x00*/) {
  1024.       var_alignwsz_label(t);
  1025.       //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
  1026.     };
  1027.     var_def(tmasked, s);
  1028.   };
  1029. }
  1030.  
  1031. //TODO т√Ёрцхэш (юЄфрЄ№ рёьє?) + ЄрсышЎє ъюэёЄрэЄ т ъюьяшы ЄюЁх?
  1032. PROC do_const_num(TYPE t)
  1033. {
  1034.   IF ((*(PCHAR)_tword == '-') || (*(PCHAR)_tword == '+')) {
  1035.     rdaddword(); //яЁшъыхшЄ№ ўшёыю
  1036.     var_num(t, _tword);
  1037.   }ELSE IF (*(PCHAR)_tword == '\'') {
  1038.     rdquotes('\'');
  1039.     rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
  1040.     _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
  1041.     var_num(t, _tword);
  1042.   }ELSE IF (*(PCHAR)_tword == '&') { //&<var>, &<func>, &<structinstance>
  1043.     rdword(); //шёяюы№чютрЄ№ &, яЁюўшЄрЄ№ эрўрыю шьхэш
  1044.     adddots(); //фюўшЄрЄ№ шь 
  1045.     var_num(_T_ARRAY|_T_UINT, _tword); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
  1046.   }ELSE IF (*(PCHAR)_tword == '\"') {
  1047.     _lenjoined = strcopy(_title, _lentitle, _joined);
  1048.     IF ((t&_T_ARRAY)!=(TYPE)0x00) { //ёЄЁюър тэєЄЁш ьрёёштр
  1049.       jdot();
  1050.       jautonum(_curlbl);
  1051.       INC _curlbl;
  1052.       //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  1053.       var_num(_T_ARRAY|_T_UINT, _joined); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
  1054.       asmstrz(); //ё ьхЄъющ _joined //ъюёЄ√ы№ тьхёЄю varstrz //todo Ўхышъюь чряюыэшЄ№ єърчрЄхыш, яюЄюь ухэхЁшЁютрЄ№ ёЄЁюъш? (эхы№ч  сєфхЄ &str т const pchar arr[]?)
  1055.     }ELSE {
  1056.       asmstrz(); //varstrz(); //ё ьхЄъющ joined
  1057.     };
  1058.   }ELSE var_num(t, _tword);
  1059. }
  1060.  
  1061. PROC eatextern()
  1062. //extern<type><variable>[<[><expr><]>]
  1063. {
  1064. VAR TYPE t;
  1065. #ifdef USE_HINTS
  1066. ;;  hintstr("//extern"); endhint();
  1067. #endif
  1068.   _exprlvl = 0x01; //no jump optimization
  1069.   eatvarname(); t = _t; //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _name)
  1070.   IF (*(PCHAR)_tword == '[') {
  1071.     //t = t|_T_ARRAY; //єцх т eatvarname
  1072.     //rdbrackets(); //_tword='[' //TODO evaluate expr (т э╕ь эхы№ч  яхЁхьхээ√х ш т√чют√, Є.х. эх чрярЁ√трхЄё  joined?)
  1073.     _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
  1074.     rdquotes(']');
  1075.     rdch(); //яЁюяєёЄшЄ№ ']'
  1076.     //_lenncells = strcopy(_tword, _lentword, _ncells); //n = _tword;
  1077.   //}ELSE {
  1078.     //n ="1";
  1079.     //_lenncells = stradd(_ncells, strclear(_ncells), '1'); //n = n + '1';
  1080.     //strclose(_ncells, _lenncells);
  1081.     rdword();
  1082.   };
  1083.   addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр (ёЄЁєъЄєЁ√ эх с√тр■Є extern?)!
  1084. #ifdef USE_HINTS
  1085. ;;  hintstr("//end extern"); endhint();
  1086. #endif
  1087. }
  1088.  
  1089. PROC eatvar RECURSIVE(BOOL ispar, BOOL body) //хёыш var, Єю body==+TRUE, шэрўх body==!forward
  1090. //var<type><variable>[<[><expr><]>][=<expr>]
  1091. //шыш т ярЁрьхЄЁрї яЁш юс· тыхэшш ЇєэъЎшш <type><variable>
  1092. {
  1093. VAR TYPE t;
  1094. {
  1095. #ifdef USE_HINTS
  1096. ;;  hintstr("//var"); endhint();
  1097. #endif
  1098.   _exprlvl = 0x01; //no jump optimization
  1099.   eatvarname(); t = _t; //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _name)
  1100.   IF (*(PCHAR)_tword == '[') {
  1101.     //t = t|_T_ARRAY; //єцх т eatvarname
  1102.    //strpush(_joined,_lenjoined);
  1103.     //TODO evaluate expr (т э╕ь эхы№ч  яхЁхьхээ√х ш т√чют√, Є.х. эх чрярЁ√трхЄё  joined?)
  1104.     _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
  1105.     rdquotes(']');
  1106.    //_lenjoined = strpop(_joined);
  1107.     _lenncells = strcopy(_tword, _lentword, _ncells); //n = _tword;
  1108.     rdch(); //яЁюяєёЄшЄ№ ']'
  1109.     rdword();
  1110.   }ELSE { //n = "1"
  1111.     _lenncells = stradd(_ncells, 0/**strclear(_ncells)*/, '1'); //n = n + '1';
  1112.     _ncells[_lenncells] = '\0'; //strclose(_ncells, _lenncells);
  1113.   };
  1114.   IF (body) addlbl(t, /**isloc*/(_namespclvl!=0x00), (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  1115.   IF (ispar) { //parameter of func/proc
  1116.     IF (body) {
  1117.       var_alignwsz_label(t);
  1118.       //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
  1119.     };
  1120.     _lenjoined = strcopy(_prefix, _lenprefix, _joined); //_lenjoined = strjoin(/**to=*/_joined, 0/**strclear(_joined)*/, _prefix/**, _lenprefix*/); //prefix юёЄрыё  юЄ doprefix/eatvarname т√°х
  1121.     jautonum(_parnum);
  1122.     INC _parnum; //!!! todo эряшёрЄ№ яюўхьє
  1123.     INC _curlbl; //!!! todo эряшёрЄ№ яюўхьє
  1124.     //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  1125.     _lenname = strcopy(_joined, _lenjoined, _name);
  1126.     addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№ //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  1127.   };
  1128.   //printf("%s \n",_joined);
  1129.   IF (body) {
  1130.     IF ((t&_T_ARRAY)!=(TYPE)0x00) {
  1131.       var_alignwsz_label(t);
  1132.       //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
  1133.       var_ds(); /**varstr( "\tDS " );*/ varuint((UINT)_typesz[t&_TYPEMASK]); varc('*'); varstr(_ncells); endvar(); //todo ЁрёёўшЄрЄ№ ЁрчьхЁ єцх т addlbl, Єюуфр ьюцэю сєфхЄ фхырЄ№ +sizeof(<array>)
  1134.       //printf("%s ds \n",_joined);
  1135.     }ELSE {
  1136.       var_num(t, "0");
  1137.     };
  1138.     doexp(); //_joined
  1139.   };
  1140.   IF (*(PCHAR)_tword == '=') { //TODO яЁютхЁшЄ№, ўЄю ь√ тэєЄЁш ЇєэъЎшш (эхЁхъєЁёштэющ!)
  1141.     rdword(); //'='
  1142.    strpush(_joined,_lenjoined);
  1143.     eatexpr();
  1144.    _lenjoined = strpop(_joined);
  1145.     //IF ( (t!=_t) && !( ((t&_T_POI)!=(TYPE)0x00) && (/**(texpr==_T_UINT)||*/((_t&_T_POI)!=(TYPE)0x00)) ) ) {errstr("let variable="); errstr(_joined); errstr(" type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
  1146.     IF (t!=_t) {errstr("let variable="); errstr(_joined); errstr(" type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
  1147.     cmdpopvar();
  1148.   };
  1149.   IF (_isrecursive && !ispar) { //local variable of recursive func/proc
  1150.     _t = t;
  1151.     cmdpushpar(); //todo ўЄю фхырЄ№ ё ьрёёштрьш?
  1152.    strpush(_joined,_lenjoined);
  1153.     WHILE (*(PCHAR)_tword==';') {
  1154.       rdword();
  1155.     }; //C compatibility
  1156.     eatcmd(); //recursive function body must be in {} after vars!
  1157.    _lenjoined = strpop(_joined);
  1158.     _t = t;
  1159.     cmdpoppar(); //todo ўЄю фхырЄ№ ё ьрёёштрьш?
  1160.   };
  1161. #ifdef USE_HINTS
  1162. ;;  hintstr("//end var"); endhint();
  1163. #endif
  1164. }
  1165. }
  1166.  
  1167. //TODO т√Ёрцхэш (юЄфрЄ№ рёьє?) + ЄрсышЎє ъюэёЄрэЄ?
  1168. PROC eatconst()
  1169. //<constnum>::=[-]<num>|'<char>'|"<str>"["<str>"...]
  1170. //const<type><variable>[=<constnum>]
  1171. //|const<type><variable><[><expr><]>[<[><expr><]>...][={<constnum>[,<constnum>...]}] - тыюцхээ√х {} чряЁх∙хэ√ (todo ёфхырЄ№ шыш шуэюЁшЁютрЄ№ ё ртЄюяхЁхёў╕Єюь ьэюуюьхЁэ√ї ьрёёштют т юфэюьхЁэ√х)
  1172. //|const pchar<variable><[><expr><]><[><expr><]>={"<str>"[,"<str>"...]}
  1173. {
  1174. VAR TYPE t;
  1175. VAR UINT i = 0;
  1176. #ifdef USE_HINTS
  1177. ;;  hintstr("//const"); endhint();
  1178. #endif
  1179.   _exprlvl = 0x01; //no jump optimization
  1180.   eattype(); t = _t|_T_CONST; //Єшя с√ы єцх яЁюўшЄрэ
  1181.   adddots();
  1182.   doprefix(_namespclvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
  1183.   rdword(); //'['
  1184.   IF (*(PCHAR)_tword == '[') {
  1185.     t = t|_T_ARRAY;
  1186.   };
  1187.   //_joined ёюфхЁцшЄ шь  ъюэёЄрэЄ√
  1188.   //_name ёюфхЁцшЄ Єшя
  1189.   _lentitle = strcopy(_joined, _lenjoined, _title); //фы  єэшъры№эюёЄш шь╕э ёЄЁюъют√ї ъюэёЄрэЄ
  1190.   INC _namespclvl; //фюсрты хь ёыютю ъ title
  1191.  
  1192.   //эрь эєцэю яюыєўшЄ№ шь  Єшяр
  1193.   lbltype();
  1194.   _lenname = strcopy(_joined, _lenjoined, _name); //шь  ъюэёЄрэЄ√
  1195.   _lencallee = gettypename(_callee); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т callee (ёЁрчє яюёых lbltype)
  1196.  
  1197.   //title ёюфхЁцшЄ шь  ъюэёЄрэЄ√ (эєцэю фы  єэшъры№эюёЄш шь╕э ёЄЁюъют√ї ъюэёЄрэЄ т ьрёёштх т do_const_num)
  1198.   //_joined Єюцх ёюфхЁцшЄ шь  ъюэёЄрэЄ√
  1199.   addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  1200.   WHILE (*(PCHAR)_tword == '[') { //[size]
  1201.     _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
  1202.     rdquotes(']');
  1203.     rdch(); //яЁюяєёЄшЄ№ ']'
  1204.     rdword();
  1205.   };
  1206.   IF (*(PCHAR)_tword == '=') {
  1207.     rdword(); //num or '{'
  1208.     IF (*(PCHAR)_tword == '{') { //array or struct
  1209.       var_alignwsz_label(t);
  1210.       doexp(); //_joined //эрфю ыш ¤ъёяюЁЄшЁютрЄ№ ъюэёЄрэЄ√? Єюы№ъю ъюэёЄрэЄэ√х ьрёёшт√/ёЄЁєъЄєЁ√
  1211.       REPEAT{ //¤ЄюЄ Ўшъы чряюЁЄшЄ _joined, эю шёяюы№чєхЄ _title
  1212.         rdword(); //num
  1213.  
  1214.         IF (t == (_T_STRUCT|_T_CONST)) { //ёЄЁєъЄєЁр (є эх╕ эхЄ рЄюьрЁэюую Єшяр)
  1215.           _lenjoined = strcopy(_callee, _lencallee, _joined); //callee ёюфхЁцшЄ шь  Єшяр ъюэёЄрэЄ√
  1216.           _lenjoined = stradd(_joined, _lenjoined, '.');
  1217.           jautonum(i);
  1218.           _lenname = strcopy(_joined, _lenjoined, _name);
  1219.           _t = lbltype();
  1220.           do_const_num(lbltype()&(~_T_TYPE)|_T_ARRAY); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє //TODO _t
  1221.           INC i;
  1222.         }ELSE { //эх ёЄЁєъЄєЁр
  1223.           do_const_num(t&(~_T_CONST)); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
  1224.         };
  1225.  
  1226.         rdword(); //',' or '}'
  1227.       }UNTIL (*(PCHAR)_tword == '}');
  1228.     }ELSE { //not array
  1229.       do_const_num(t);
  1230.     };
  1231.     rdword();
  1232.   };
  1233.  
  1234.   DEC _namespclvl; doprefix(_namespclvl); _lentitle=strcopy(_prefix,_lenprefix,_title);/**title =prefix;*/ //юЄЁхчрхь фюсртыхээюх ёыютю
  1235.  
  1236.   //_isexp = +FALSE; //эрфю ыш ¤ъёяюЁЄшЁютрЄ№ ъюэёЄрэЄ√? Єюы№ъю ъюэёЄрэЄэ√х ьрёёшт√/ёЄЁєъЄєЁ√
  1237.  
  1238. #ifdef USE_HINTS
  1239. ;;  hintstr("//end const"); endhint();
  1240. #endif
  1241. }
  1242.  
  1243. PROC eatfunc(BOOL isfunc, TYPE oldfunct, BOOL oldwasreturn)
  1244. //proc<procname>[recursive][forward](<type><par>,...])[<cmd>]
  1245. //|func<type><funcname>[recursive][forward]([<type><par>,...])[<cmd>]
  1246. {
  1247. VAR BOOL isforward;
  1248.   _curlbl = 0; //ёсЁрё√трхь эєьхЁрЎш■ ртЄюьхЄюъ, Є.ъ. є эшї яЁхЇшъё ЇєэъЎшш
  1249.   IF ( isfunc ) {
  1250.     eattype(); _curfunct = _t;
  1251.   }ELSE _curfunct = _T_PROC;
  1252. #ifdef USE_HINTS
  1253. ;;    hintstr("//func "); hinttype(_title,_curfunct);
  1254. #endif
  1255.   _lenname = strcopy(_tword, _lentword, _name);
  1256.   jtitletword();
  1257.   rdword(); //'(' or "recursive" or "forward"
  1258.   IF ((CHAR)((BYTE)(*(PCHAR)_tword)|0x20) == 'r') {
  1259.     _curfunct = _curfunct|_T_RECURSIVE;
  1260.     _isrecursive = +TRUE;
  1261.     rdword(); //'('
  1262.   }ELSE _isrecursive = +FALSE;
  1263.   IF ((CHAR)((BYTE)(*(PCHAR)_tword)|0x20) == 'f') {
  1264.     isforward = +TRUE;
  1265.     rdword(); //'('
  1266.   }ELSE isforward = +FALSE;
  1267.   addlbl(_curfunct, /**isloc*/+FALSE, 0/**, _ncells"0", 1*/); //(_name) //эхы№ч  if (!isforward), яюЄюьє ўЄю эрфю чряюьэшЄ№ Єшя ЇєэъЎшш т forward
  1268.   IF (!isforward) {
  1269.     cmdlabel(); //_joined
  1270.     cmdfunc(); //фхырхЄ initrgs
  1271.     doexp(); //_joined
  1272.   };
  1273.   jdot();
  1274.   _lentitle = strcopy(_joined, _lenjoined, _title);
  1275.   INC _namespclvl; //фюсрты хь ёыютю ъ title
  1276.  
  1277.   eat('(');
  1278.   _parnum = 0;
  1279.   WHILE (!_waseof) {
  1280.     IF (*(PCHAR)_tword == ')') BREAK;
  1281.     eatvar(/**ispar*/+TRUE, /**body*/!isforward); //ьхЄър ярЁрьхЄЁр ёючфр╕Єё  схч яЁхЇшъёр ш ё Їыруюь isloc, х∙╕ ёючфр╕Єё  f.A.
  1282.     IF (*(PCHAR)_tword == ')') BREAK; //шэрўх ','
  1283.     rdword(); //type or ')'
  1284.   };
  1285.   rdword();
  1286.  
  1287.   keepvars(); //эхы№ч  яхЁхф ярЁрьхЄЁрьш, Є.ъ. f.A. эрфю яюьэшЄ№ яюёых Єхыр ЇєэъЎшш
  1288.  
  1289.   IF (!isforward) {
  1290.     eatcmd(); //Єхыю ЇєэъЎшш
  1291.     _t = _curfunct&(~_T_RECURSIVE);
  1292.     cmdret(isfunc);
  1293.     IF (isfunc && !_wasreturn) {errstr("return expected"); enderr(); };
  1294. #ifdef USE_HINTS
  1295. ;;    hintstr("/////end func"); endhint();
  1296. #endif
  1297.   };
  1298.  
  1299.   undovars(); //TODO єэшўЄюцшЄ№ ъюЁюЄъшх ьхЄъш ярЁрьхЄЁют, шэрўх юэш чрЄЁєЄ уыюсры√ эртхўэю. ═рфю їЁрэшЄ№ рфЁхёр Єръшї ьхЄюъ т ЄрсышЎх
  1300.  
  1301.   DEC _namespclvl; doprefix(_namespclvl); _lentitle=strcopy(_prefix,_lenprefix,_title);/**title =prefix;*/ //юЄЁхчрхь фюсртыхээюх ёыютю
  1302.   _curfunct = oldfunct; //тючтЁрЄшЄ№ тэх°эшщ Єшя ЇєэъЎшш
  1303.   _wasreturn = oldwasreturn; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
  1304.   _isexp = +FALSE;
  1305. }
  1306.  
  1307. PROC do_callpar RECURSIVE(TYPE funct, UINT parnum)
  1308. {
  1309. VAR TYPE t;
  1310. {
  1311. #ifdef USE_HINTS
  1312. ;;  hintstr("//call_par"); endhint();
  1313. #endif
  1314.   IF ( (*(PCHAR)_tword!=')') && !_waseof ) {
  1315.     _lenjoined = strcopy(_callee, _lencallee, _joined);
  1316.     jdot();
  1317.     jautonum(parnum);
  1318.     //INC _curlbl; //эх эєцэю, Є.ъ. ¤Єю т√чют (Є.х. фЁєующ яЁхЇшъё)
  1319.     //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  1320. ;;    cmtstr(";accesspar="); cmtstr(_joined); endcmt();
  1321.     _lenname = strcopy(_joined, _lenjoined, _name);
  1322.     t = lbltype(); //(_name)
  1323.     IF ((funct&_T_RECURSIVE)!=(TYPE)0x00/**isstacked*/) {
  1324.       _t = t;
  1325.       cmdpushpar(); //(_joined)
  1326.     };
  1327.     strpush(_joined,_lenjoined);
  1328.     INC _exprlvl; //no jump optimization
  1329.     eatexpr(); //ьюцхЄ ЁхъєЁёштэю т√чтрЄ№ do_call ш чрЄхЁхЄ№ callee (хёыш юэ уыюсры№э√щ)! //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
  1330.     DEC _exprlvl;
  1331.     IF (t != _t) {errstr("callpar type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
  1332.     _lenjoined = strpop(_joined);
  1333.     cmdpopvar(); //(_joined)
  1334.     IF (*(PCHAR)_tword == ',') rdword(); //parameter or ')'
  1335.     IF (parnum < _MAXPARS) {
  1336.       strpush(_joined,_lenjoined);
  1337.       do_callpar(/**isfunc,*/ funct, /**isstacked,*/ parnum+1); //ЁхъєЁёштэю
  1338.       _lenjoined = strpop(_joined);
  1339.     }/**ELSE {errstr("too many parameters"); enderr(); }*/;
  1340.     IF ((funct&_T_RECURSIVE)!=(TYPE)0x00/**isstacked*/) {
  1341.       _t = t;
  1342.       cmdpoppar(); //(_joined)
  1343.     };
  1344.   }ELSE {
  1345.     _t = funct&(~_T_RECURSIVE);
  1346.     cmdcall();
  1347.   };
  1348. #ifdef USE_HINTS
  1349. ;;  hintstr("//end call_par"); endhint();
  1350. #endif
  1351. }
  1352. }
  1353.  
  1354. FUNC TYPE do_call RECURSIVE(BOOL isfunc)
  1355. //<lbl>([recursive][(<type>)<val>,...])
  1356. {
  1357. VAR TYPE t;
  1358. {
  1359.   INC _exprlvl; //no jump optimization
  1360.   joinvarname(/**iscall*/+TRUE); t = _t; //t!!!
  1361.   IF (t == _T_UNKNOWN) {errstr("unknown function "); errstr(_joined); enderr(); };
  1362. #ifdef USE_HINTS
  1363. ;;    hinttype("call",t);
  1364. #endif
  1365.   IF (!isfunc) t = (t&_T_RECURSIVE)|_T_PROC; //ўЄюс√ ьюцэю с√ыю т√ч√трЄ№ ЇєэъЎшш ъръ яЁюЎхфєЁ√
  1366.   strpush(_callee,_lencallee); //эр ёыєўрщ тыюцхээ√ї т√чютют
  1367.   _lencallee = strcopy(_joined, _lenjoined, _callee); //схч Єюўъш
  1368.   jdot();
  1369.   rdword(); //'('
  1370.   eat('(');
  1371.   do_callpar(t, /**parnum*/0); //ёюїЁрэхэшх [call]title, [ёюїЁрэхэшх яхЁхьхээющ], яЁшётрштрэшх, ЁхъєЁёш , [тюёёЄрэютыхэшх яхЁхьхээющ], тюёёЄрэютыхэшх [call]title
  1372.   _lencallee = strpop(_callee); //эр ёыєўрщ тыюцхээ√ї т√чютют
  1373.   DEC _exprlvl; //no jump optimization
  1374. RETURN t&(~_T_RECURSIVE);
  1375. }
  1376. }
  1377.  
  1378. PROC eatcallpoi()
  1379. //call(<poi>)
  1380. {
  1381.  //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  1382.   adddots(); //фюўшЄрЄ№ шь 
  1383.   joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
  1384.   eat('(');
  1385.   eatexpr();
  1386.   //todo яЁютхЁшЄ№ pointer
  1387.   eat(')');
  1388.   cmdcallval();
  1389.   rdword();
  1390. }
  1391.  
  1392. PROC eatlbl() //todo inline
  1393. //_lbl<lblname><:>
  1394. {
  1395.   jtitletword();
  1396.   cmdlabel();
  1397.   rdword(); //skip ':' for C compatibility
  1398.   rdword(); //эєцэю!
  1399. }
  1400.  
  1401. PROC eatgoto() //яхЁхїюф Єюы№ъю тэєЄЁш Єхъє∙хщ яЁюЎхфєЁ√ //todo inline
  1402. //goto<lblname>
  1403. {
  1404.   //rdword(); //lbl
  1405.   jtitletword();
  1406.   cmdjp();
  1407.   rdword();
  1408. }
  1409.  
  1410. PROC eatasm()
  1411. //asm("asmtext")
  1412. {
  1413.   //rdword(); //'('
  1414.   rdword(); //'\"'
  1415.   WHILE (!_waseof) {
  1416.     _lentword = 0/**strclear(_tword)*/; //ўшЄрхь ё яєёЄющ ёЄЁюъш
  1417.     rdquotes('\"'/**, +FALSE*/);
  1418.     asmstr(_tword); endasm();
  1419.     rdch(); //яЁюяєёЄшЄ№ чръЁ√тр■∙є■ ърт√ўъє
  1420.     IF (_cnext != '\"') BREAK;
  1421.     rdword(); //'\"' юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
  1422.   };
  1423.   rdword(); //')'
  1424.   rdword();
  1425. }
  1426.  
  1427. PROC eatenum()
  1428. //enum{<constname0>[=<num>],<constname1>...[,]}
  1429. {
  1430.   //rdword(); //'{'
  1431. _lenncells = strcopy("-1", 2, _ncells);
  1432.   WHILE (!_waseof) {
  1433.     rdword(); //ьхЄър
  1434.     IF (*(PCHAR)_tword=='}') BREAK; //BREAK ЁрсюЄрхЄ, р goto qqq эх ЁрсюЄрхЄ ('}' эх ё·хфхэр)
  1435.     varequ(_tword); /**varstr(_tword); varc('=');*/
  1436.  
  1437. //ъюёЄ√ы№ фы  script: ёючфр╕ь яхЁхьхээє■ UINT ё рфЁхёюь, ъръ Єхъє∙хх ўшёыю т enum:
  1438. //    _lenname = strcopy(_tword, _lentword, _name);
  1439. //    addlbl(_T_UINT, /**isloc*/+FALSE, /**varsz*/0/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№
  1440. //    rdword(); //',' шыш '}'
  1441. //    IF (*(PCHAR)_tword=='=') {
  1442.     IF (_cnext=='=') {
  1443.       rdword(); //ё·хыш =
  1444.       rdword(); //яхЁтюх ёыютю expr
  1445.       //eatexpr(); //parentheses not included
  1446.       //rdword(); //',' шыш '}'
  1447.       varstr(_tword);
  1448.     }ELSE {
  1449.       varstr(_ncells); varc('+'); varc('1'); /**varuint(i);*/
  1450.     };
  1451. _lenncells = strcopy(_tword, _lentword, _ncells);
  1452.     endvar();
  1453.     rdword(); //',' шыш '}'
  1454.     IF (*(PCHAR)_tword!=',') BREAK; //}
  1455.   };
  1456.   rdword(); //ёыютю яюёых }
  1457. }
  1458.  
  1459. PROC eatevar()
  1460. //evar{<type><varname0>[=<addr>],<type><varname1>...[,]}
  1461. {
  1462.   //rdword(); //'{'
  1463. _lenncells = strcopy("-1", 2, _ncells);
  1464.   WHILE (!_waseof) {
  1465.     rdword(); //type
  1466.     IF (*(PCHAR)_tword=='}') BREAK; //BREAK ЁрсюЄрхЄ, р goto qqq эх ЁрсюЄрхЄ ('}' эх ё·хфхэр)
  1467.     eattype(); //_t //фхырхЄ rdword(); //ьхЄър
  1468.     varequ(_tword); /**varstr(_tword); varc('=');*/
  1469. //ёючфр╕ь яхЁхьхээє■ Єшяр _t ё рфЁхёюь, ъръ Єхъє∙хх ўшёыю т evar:
  1470.     _lenname = strcopy(_tword, _lentword, _name);
  1471.     addlbl(_t/**_T_UINT*/, /**isloc*/+FALSE, /**varsz*/0/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№
  1472. //    rdword(); //',' шыш '}'
  1473. //    IF (*(PCHAR)_tword=='=') {
  1474.     IF (_cnext=='=') {
  1475.       rdword(); //ё·хыш =
  1476.       rdword(); //яхЁтюх ёыютю expr
  1477.       //eatexpr(); //parentheses not included
  1478.       //rdword(); //',' шыш '}'
  1479.       varstr(_tword);
  1480.     }ELSE {
  1481.       varstr(_ncells); varc('+'); varc('1'); /**varuint(i);*/
  1482.     };
  1483. _lenncells = strcopy(_tword, _lentword, _ncells);
  1484.     endvar();
  1485.     rdword(); //',' шыш '}'
  1486.     IF (*(PCHAR)_tword!=',') BREAK; //}
  1487.   };
  1488.   rdword(); //ёыютю яюёых }
  1489. }
  1490.  
  1491. PROC eatstruct()
  1492. //struct<name>{<type1><field1>[;]<type2><field2>[;]...}
  1493. {
  1494. VAR UINT shift = 0;
  1495. VAR UINT varszaddr;
  1496. VAR UINT i = 0;
  1497. VAR UINT sz;
  1498.   _lentitle = strjoin(/**to=*/_title, _lentitle, _tword/**, _lentword*/);
  1499.   _title[_lentitle] = '\0'; //strclose(_title, _lentitle);
  1500.   //strpush(_title,_lentitle); //схч Єюўъш
  1501.   _lenname = strcopy(_title, _lentitle, _name); //схч Єюўъш
  1502.   addlbl(_T_STRUCT|_T_TYPE, /**isloc*/+FALSE, 0/**, "0", _lenncells*/); //(_name) //яЁхфтрЁшЄхы№эю ёючфрыш, ўЄюс√ ёё√ырЄ№ё 
  1503.   varszaddr = _varszaddr;
  1504.  
  1505.   _lentitle = stradd(_title, _lentitle, '.');
  1506.   _title[_lentitle] = '\0'; //strclose(_title, _lentitle);
  1507.   INC _namespclvl; //фюсрты хь ёыютю ъ title
  1508.   rdword(); //шёяюы№чютрыш шь 
  1509.   eat('{');
  1510.  
  1511.   WHILE (!_waseof) {
  1512.     eattype(); //шёяюы№чютрыш Єшя
  1513.     sz = (UINT)_typesz[_t&_TYPEMASK];
  1514.     //rdword(); //ьхЄър
  1515.     jtitletword();
  1516.     shift = varshift(shift, sz);
  1517.  
  1518.     _lenname = strcopy(_joined, _lenjoined, _name);
  1519.     addlbl(_t, /**isloc*/+FALSE, sz/**, "0", _lenncells*/); //(_name)
  1520.  
  1521.     genjplbl(i);
  1522.     _lenname = strcopy(_joined, _lenjoined, _name);
  1523.     addlbl(_t, /**isloc*/+FALSE, sz/**, "0", _lenncells*/); //ртЄюэєьхЁютрээр  (_name)
  1524.     INC i;
  1525.  
  1526.     shift = shift + sz;
  1527.     rdword(); //Єшя шыш ';' шыш '}' //шёяюы№чютрыш ьхЄъє
  1528.     IF (*(PCHAR)_tword==';') rdword(); //Єшя
  1529.     IF (*(PCHAR)_tword=='}') BREAK;
  1530.   };
  1531.  
  1532.   //_lenname = strpop(_name);
  1533.   //addlbl(_T_STRUCT|_T_TYPE, /**isloc*/+FALSE/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№ //(_name)
  1534.   //Єрь цх ёюїЁрэшЄ№ sizeof_structname (=shift)
  1535.   //яЁш ¤Єюь тё╕ х∙╕ ЁрчЁх°шЄ№ ёё√ырЄ№ё  эр ¤Єє цх ёЄЁєъЄєЁє (Є.х. юяЁхфхышЄ№ х╕ Ёрэ№°х, р чряюыэшЄ№ фрээ√х яюЄюь; ёючфрЄ№ чрэютю эхы№ч  - фЁєующ рфЁхё)
  1536.   setvarsz(varszaddr, shift);
  1537.  
  1538.   DEC _namespclvl;
  1539.   doprefix(_namespclvl); //to prefix
  1540.   _lentitle = strcopy(_prefix, _lenprefix, _title); //title = prefix //юЄЁхчрхь фюсртыхээюх ёыютю
  1541.   rdword();
  1542. }
  1543.  
  1544. PROC eatswitch() //яЁюЎхфєЁр ЄхюЁхЄшўхёъш ЁхъєЁёштэр , эю яЁръЄшўхёъш тыюцхээюёЄ№ switch чряЁх∙хэр
  1545. //'J' т эєьхЁютрээ√ї ьхЄърї ьюцэю єсЁрЄ№, Є.ъ. ртЄюьхЄъш ЄхяхЁ№ схч ЎшЇЁ ш эх яхЁхёхъєЄё  (ьюцэю ёъыхштрЄ№ '.' ё ўшёыюь)
  1546. //switch (<byteexpr>){...};
  1547. //case <byteconst>: //ухэхЁшЁєхЄё  ртЄюьхЄър ё ўшёыюь (эх яхЁхёхў╕Єё  эш ё ўхь)
  1548. //default: //ухэхЁшЁєхЄё  ртЄюьхЄър ё Єюўъющ (эх яхЁхёхў╕Єё  эш ё ўхь)
  1549. {
  1550. VAR BYTE ib;
  1551. VAR UINT wastmpendlbl;
  1552.   //rdword(); //'('
  1553.   wastmpendlbl = _tmpendlbl;
  1554.   _tmpendlbl = _curlbl; INC _curlbl;
  1555.  
  1556.   //pushvar <title>.J
  1557.   _lenjoined = strcopy(_title, _lentitle, _joined);
  1558.   _lenjoined = stradd(_joined, _lenjoined, 'J');
  1559.   _joined[_lenjoined] = '\0'; //strclose(_joined , _lenjoined);
  1560.   _t = _T_UINT|_T_POI;
  1561.   cmdpushnum(); //шёяюы№чютрэшх єърчрЄхы  т ърўхёЄтх ьрёёштр - ўшЄрхь хую чэрўхэшх
  1562.  
  1563.   eatidx();
  1564.   _t = _T_UINT; //Єшя ¤ыхьхэЄр ьрёёштр
  1565.   cmdaddpoi();
  1566.   cmdpeek();
  1567.  
  1568.   cmdjpval();
  1569.  
  1570.   //ухэхЁшЁютрЄ№ ёяшёюъ эрўры№э√ї чэрўхэшщ эєьхЁютрээ√ї ьхЄюъ яхЁхїюфр
  1571.   //procname.aab.<num> = procname.aab.default (яюър схч aab TODO)
  1572.   //ухэхЁшЁютрЄ№ ЄрсышЎє яхЁхїюфют, чряюыэхээє■ эєьхЁютрээ√ьш ьхЄърьш яхЁхїюфр
  1573.   //DW procname.aab.1 (яюър схч aab TODO)
  1574.   varstr(_title); varc('J'); endvar();
  1575.   ib = 0x00;
  1576.   REPEAT {
  1577.     asmstr(_title); asmuint((UINT)ib); asmc('='); asmstr(_title); asmstr("default"); endasm(); //фю ъюфр! яю¤Єюьє asm
  1578.     var_dw(); varstr(_title); varuint((UINT)ib); endvar(); //TODO "DP", Є.х. эр °шЁшэє POINTER?
  1579.     INC ib;
  1580.   }UNTIL (ib == 0x00);
  1581.  
  1582.   eatcmd(); //{...}
  1583.  
  1584.   genjplbl(_tmpendlbl); cmdlabel();
  1585.   _tmpendlbl = wastmpendlbl;
  1586. }
  1587.  
  1588. PROC eatcase()
  1589. //case <byteconst>:
  1590. {
  1591.   //rdword(); //byteconst
  1592.  
  1593.   //чряюыэшЄ№ эєьхЁютрээє■ ьхЄъє яхЁхїюфр
  1594.   //procname.aab.#<_tword> = $ (яюър схч aab TODO)
  1595.   asmstr(_title); asmc('#'); asmstr(_tword); asmc('='); asmc('$'); endasm();
  1596.  
  1597.   rdword(); //skip ':' for C compatibility
  1598.   rdword(); //эєцэю!
  1599. }
  1600.  
  1601. FUNC BOOL eatcmd RECURSIVE() //тючтЁр∙рхЄ +FALSE, хёыш ъюэхЎ сыюър
  1602. {
  1603. {
  1604.  //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  1605.   adddots(); //фюўшЄрЄ№ шь 
  1606. //ўЄюс√ ЁхрышчютрЄ№ юс· тыхэш  схч VAR ш FUNC, эрфю єцх ёхщўрё яЁютхЁшЄ№ Єшя ьхЄъш TODO FAST!!!
  1607.   _c0 = *(PCHAR)_tword;
  1608.   IF ((_c0=='}') || _waseof) {
  1609.     rdword();
  1610.     _morecmd = +FALSE;
  1611.   }ELSE {
  1612. //    IF (_wasreturn) {
  1613. //      IF (_c0!=';') {errstr("cmd after return!"); enderr(); };
  1614. //    };
  1615.     IF (_cnext=='=') { //let
  1616.       eatlet();
  1617.     }ELSE IF ( (((BYTE)_cnext-0x28/**'('*/) | ((BYTE)_spcsize/**==0x00*/)) == 0x00) { //call
  1618.       do_call(/**isfunc*/+FALSE); rdword();
  1619.     }ELSE IF (_cnext=='[') { //let []
  1620.       eatlet();
  1621.     }ELSE IF ( _cnext==':' ) { //lbl
  1622.       eatlbl();
  1623.     }ELSE IF (_cnext=='-') { //let ->
  1624.       eatlet();
  1625.     }ELSE {
  1626.       IF (_c0==';') {
  1627.         rdword(); //C compatibility
  1628.       }ELSE IF (_c0=='{') {
  1629.         rdword(); WHILE (eatcmd()) {};
  1630.       }ELSE {
  1631.         _c0 = (CHAR)((BYTE)_c0|0x20);
  1632.         IF       (_c0=='v') { //var
  1633.           rdword(); eatvar(/**ispar*/+FALSE, /**body*/+TRUE);
  1634.           _isexp = +FALSE; //эхы№ч  тэєЄЁ№, шэрўх эх ¤ъёяюЁЄшЁє■Єё  ярЁрьхЄЁ√ яЁюЎхфєЁ√
  1635.         }ELSE IF (_c0=='f') { //func
  1636.           rdword(); eatfunc(+TRUE, _curfunct, _wasreturn);
  1637.         }ELSE IF ( _c0=='w' ) { //while
  1638.           rdword(); eatwhile();
  1639.         }ELSE IF ( _c0=='b' ) { //break
  1640.           rdword(); eatbreak(); //no parameters (rds nothing)
  1641.         }ELSE {
  1642.         _c2 = (CHAR)((BYTE)_tword[2]|0x20);
  1643.         IF (_c0=='c') { //const //case //call
  1644.           IF (_c2=='n') { //const
  1645.             rdword(); eatconst();
  1646.           }ELSE IF (_c2=='l') { //call
  1647.             rdword(); eatcallpoi();
  1648.           }ELSE { //case
  1649.             rdword(); eatcase();
  1650.           };
  1651.         }ELSE IF (_c0=='p') { //proc //poke
  1652.           IF (_c2=='o') { //proc
  1653.             rdword(); eatfunc(+FALSE, _curfunct, _wasreturn);
  1654.           }ELSE { //poke
  1655.             rdword(); eatpoke();
  1656.           };
  1657.         }ELSE IF (_c0=='r') { //return //repeat
  1658.           IF (_c2=='t') { //return
  1659.             rdword(); eatreturn();
  1660.           }ELSE { //repeat
  1661.             rdword(); eatrepeat();
  1662.           };
  1663.         }ELSE IF ( _c0=='d' ) { //dec
  1664.           rdword(); eatdec();
  1665.         }ELSE IF ( _c0=='i' ) { //inc //if
  1666.           IF ( _c2=='c' ) { //inc
  1667.             rdword(); eatinc();
  1668.           }ELSE { //if
  1669.             rdword(); eatif();
  1670.           };
  1671.         }ELSE IF (_c0=='e') { //enum //extern //export //evar
  1672.           IF (_c2=='t') { //extern
  1673.             rdword(); eatextern();
  1674.           }ELSE IF (_c2=='p') { //export
  1675.             rdword(); _isexp = +TRUE;
  1676.           }ELSE IF (_c2=='a') { //evar
  1677.             rdword(); eatevar();
  1678.           }ELSE { //enum
  1679.             rdword(); eatenum();
  1680.           };
  1681.         }ELSE IF ( _c0=='g' ) { //goto
  1682.           rdword(); eatgoto();
  1683.         }ELSE IF ( _c0=='a' ) { //asm
  1684.           rdword(); eatasm();
  1685.         }ELSE IF ( _c0=='s' ) { //struct //switch
  1686.           IF (_c2=='r') { //struct
  1687.             rdword(); eatstruct();
  1688.           }ELSE { //switch
  1689.             rdword(); eatswitch();
  1690.           };
  1691. //        }ELSE IF ( _c0=='m' ) { //module
  1692. //          rdword(); eatmodule();
  1693.         }ELSE IF ( _c0=='t' ) { //typedef <type> <name>
  1694.           rdword();
  1695.           eattype();
  1696.           _lenname = strcopy(_tword, _lentword, _name);
  1697.           addlbl(_T_TYPE + _t, /**isloc*/+FALSE, (UINT)_typesz[_t]);
  1698.           rdword(); //шёяюы№чютрыш шь 
  1699.         }ELSE IF ( _c0=='#' ) { //define, include... (ё■фр яюярфрхь фрцх т эхръЄштэ√ї тхЄърї єёыютэющ ъюьяшы Ўшш)
  1700.           rdword(); //define, undef, include, if, else, [elif], ifdef, ifndef, endif, [import], [line], [error], [pragma]
  1701. //тыюцхээр  єёыютэр  ъюьяшы Ўш :
  1702. //_doskipcond т сшЄютюь тшфх яюьэшЄ, ёъюы№ъю єЁютэхщ ръЄштэ√ї ifdef ш ёъюы№ъю єЁютэхщ эхръЄштэ√ї (ъЁюьх Єхъє∙хую)
  1703. //(тэєЄЁш эхръЄштэюую ьюуєЄ с√Є№ Єюы№ъю эхръЄштэ√х)
  1704. //хёыш (_doskipcond&1) == 0 (Є.х. ь√ т эхръЄштэющ тхЄъх), Єю Єхъє∙шщ ifdef шуэюЁшЁєхЄё  ёю тёхьш тїюф ∙шьш (Є.х. else эх ЁрсюЄрхЄ)
  1705. //эхръЄштэюёЄ№ Єхъє∙хщ тхЄъш ifdef ыхцшЄ т _doskip
  1706. //эр тхЁїэхь єЁютэх _doskipcond = 1, _doskip = +FALSE
  1707. //хёыш ifdef, Єю:
  1708.   //_doskipcond = _doskipcond+_doskipcond
  1709.   //хёыш !_doskip, Єю:
  1710.     //INC _doskipcond;
  1711.     //хёыш ifdef эх уюфхэ, Єю _doskip = +TRUE
  1712. //хёыш else ш ((_doskipcond&1) != 0), Єю _doskip = !_doskip
  1713. //хёыш endif, Єю _doskip = ((_doskipcond&1) == 0); _doskipcond = _doskipcond>>1
  1714.           _c2 = _tword[2];
  1715.           IF ((_c2 == 'c')&&(!_doskip)) { //include
  1716.             rdword(); //"
  1717.             _lentword = 0;
  1718.             rdquotes('\"'/**, +FALSE*/); //IF (_c0 == '\"') { rdquotes('>'); }ELSE rdquotes('\"');
  1719.             _hinclfile[_nhinclfiles] = _fin;
  1720.             _hnline[_nhinclfiles] = _curline;
  1721.             INC _nhinclfiles; compfile(_tword); DEC _nhinclfiles;
  1722.             _fin = _hinclfile[_nhinclfiles];
  1723.             _curline = _hnline[_nhinclfiles];
  1724.             _waseof = +FALSE;
  1725.             rdch(); //яЁюяєёЄшЄ№ чръЁ√тр■∙є■ ърт√ўъє
  1726.           }ELSE IF (_c2 == 'd') { //ifdef/endif/undef
  1727.             IF (*(PCHAR)_tword == 'e') { //endif
  1728.               //_doskip = +FALSE; //todo тыюцхээюёЄ№ (яюфёў╕Є ўшёыр шЇют)
  1729.               _doskip = ((_doskipcond&1) == 0);
  1730.               _doskipcond = _doskipcond>>1;
  1731. //erruint(_doskipcond); errstr("#endif "); erruint((UINT)_doskip); enderr();
  1732.             }ELSE IF (*(PCHAR)_tword == 'i') { //ifdef
  1733.               _doskipcond = _doskipcond+_doskipcond;
  1734.               rdword(); //шь 
  1735.               _lenname = strcopy(_tword, _lentword, _name);
  1736.               //_t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
  1737.               IF (!_doskip) {
  1738.                 INC _doskipcond; //эх шуэюЁшЁєхь ¤ЄюЄ ifdef
  1739.                 //эхЄ ьхЄъш - яЁюяєёЄшЄ№ Єхыю
  1740.                 _doskip = (lbltype() == _T_UNKNOWN); //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
  1741.               };
  1742. //erruint(_doskipcond); errstr("#ifdef "); erruint((UINT)_doskip); enderr();
  1743.             }ELSE { //undef
  1744.               rdword(); //шь 
  1745.               _lenname = strcopy(_tword, _lentword, _name);
  1746.               dellbl();
  1747.             };
  1748.           }ELSE IF (_c2 == 'n') { //ifndef
  1749.               _doskipcond = _doskipcond+_doskipcond;
  1750.               rdword(); //шь 
  1751.               _lenname = strcopy(_tword, _lentword, _name);
  1752.               //_t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
  1753.               IF (!_doskip) {
  1754.                 INC _doskipcond; //эх шуэюЁшЁєхь ¤ЄюЄ ifndef
  1755.                 //хёЄ№ ьхЄър - яЁюяєёЄшЄ№ Єхыю
  1756.                 _doskip = (lbltype() != _T_UNKNOWN); //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
  1757.               };
  1758.           }ELSE IF (_c2 == 's') { //else
  1759.             //_doskip = !_doskip;
  1760.             IF ((_doskipcond&1) != 0) _doskip = !_doskip; //эх шуэюЁшЁєхь ¤ЄюЄ ifdef
  1761. //erruint(_doskipcond); errstr("#else "); erruint((UINT)_doskip); enderr();
  1762.           }ELSE IF ((_c2 == 'f')&&(!_doskip)) { //define
  1763.             rdword(); //шь 
  1764.             twordtojoined(); //_lenjoined = strcopy(_tword, _lentword, _joined);
  1765.             rdword(); //чэрўхэшх шыш (
  1766.             IF (*(PCHAR)_tword == '(') { //TODO ¤Єє ъюэёЄЁєъЎш■ яЁшьхэшЄ№ ш т const
  1767.               rdword(); //eat('(');
  1768.               eattype();
  1769.               eat(')');
  1770.               rdquotes(')');
  1771.               rdch(); //фюсрты хь чръЁ√тр■∙є■ ёъюсъє
  1772.               _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
  1773.             }ELSE {
  1774.               numtype(); //_t
  1775.             };
  1776.             _lenname = strcopy(_joined, _lenjoined, _name);
  1777.             addlbl(_t|_T_CONST, /**isloc*/+FALSE, (UINT)_typesz[_t/**&_TYPEMASK*/]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  1778.             emitvarpreequ(_name);
  1779.             varequ(_name); /**varstr(_name); varc( '=' );*/ varstr(_tword); endvar();
  1780.             emitvarpostequ();
  1781.           };
  1782.  
  1783.           //rdchcmt(); //rdaddword(); //шёяюы№чєхь яхЁт√щ ёшьтюы чэрър ъюььхэЄрЁш , ўшЄрхь ёыхфє■∙шщ ёшьтюы
  1784.           WHILE (_waseols==0/** && !_waseof*/ ) {
  1785.             rdchcmt(); //яЁюяєёърхЄ тёх хэЄхЁ√
  1786.           };
  1787.           _tword[_lentword] = '\0'; //strclose(_tword, _lentword); //todo эрЁє°хэр ярЁэюёЄ№ clear..close
  1788.           IF ((BYTE)_cnext < (BYTE)'!') {
  1789.             rdch(); //шёяюы№чєхь яюёыхфэшщ ёшьтюы ъюььхэЄрЁш , ўшЄрхь ёыхфє■∙шщ ёшьтюы (TODO єэшЇшЎшЁютрЄ№ ъръ /* */)
  1790.           };
  1791.           rdword();
  1792.         }ELSE {
  1793.           errstr("WRONG COMMAND "); errstr(_tword); enderr();
  1794.           rdword();
  1795.         };
  1796.         };
  1797.       };
  1798.     }; //not a headless cmd
  1799.     _morecmd = +TRUE;
  1800.   }; //not '{'
  1801.   RETURN _morecmd;
  1802. }
  1803. }
  1804.  
  1805. PROC compfile RECURSIVE(PCHAR fn)
  1806. {
  1807.   _fin = nfopen(fn, "rb");
  1808.   IF (_fin != (PBYTE)0) {
  1809.     strpush(_fn,_lenfn);
  1810.     _lenfn = strjoineol(_fn, 0/**_lenfn*/, fn, '\0');
  1811.     _fn[_lenfn] = '\0';
  1812.     _waseof = +FALSE;
  1813.  
  1814.     _curline = 1;
  1815.     initrd();
  1816.     rdword();
  1817.  
  1818.     WHILE (eatcmd()) {};
  1819.  
  1820.     fclose(_fin);
  1821.     _lenfn = strpop(_fn);
  1822.   }ELSE {
  1823.     errstr("no file "); errstr(fn); enderr();
  1824.   };
  1825. }
  1826.  
  1827. FUNC UINT strjoineollast(PCHAR to, UINT tolen, PCHAR s2/**, UINT s2len*/, CHAR eol) //фышэр схч ЄхЁьшэрЄюЁр!
  1828. { //to = to + s2;
  1829. VAR UINT len;
  1830. VAR UINT last;
  1831. VAR CHAR c;
  1832.   to = &to[tolen];
  1833.   len = tolen; //фышэр схч ЄхЁьшэрЄюЁр!
  1834.   last = 0; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
  1835.   loop:
  1836.     c = *(PCHAR)s2;
  1837.     IF ((c == '\0') || (len>=_STRMAX)) goto endloop; //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
  1838.     POKE *(PCHAR)(to) = c;
  1839.     INC s2;
  1840.     IF (c == eol) last = len;
  1841.     INC to;
  1842.     INC len;
  1843.   goto loop; //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
  1844.   endloop:
  1845. RETURN last; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
  1846. }
  1847.  
  1848. PROC compile(PCHAR fn)
  1849. {
  1850.   _doskipcond = 1;
  1851.  
  1852.   _prefix = (PCHAR)_s1; //чряюыэ хЄё  т doprefix: module/func/const/var/extern - ыюъры№эю, joinvarname
  1853.   _title  = (PCHAR)_s2;
  1854.   _callee = (PCHAR)_s3;
  1855.   _name   = (PCHAR)_s4;
  1856.   _joined = (PCHAR)_s5;
  1857.   _ncells = (PCHAR)_s6;
  1858.  
  1859.   _fn = (PCHAR)_m_fn;
  1860.   _lenfn = 0;
  1861.  
  1862.   _tmpendlbl = 0; //ўЄюс√ эшъюуфр эх ёютярыю (break тэх ЇєэъЎшш т√фрёЄ ю°шсъє т рёьх)
  1863.   _lenstrstk = 0;
  1864.   _curlbl = 0; //ёсЁрё√трхь эєьхЁрЎш■ ртЄюьхЄюъ (фы  ьрёёштют ёЄЁюъ)
  1865.  
  1866.   initlblbuf();
  1867.  
  1868.   _lenname = strcopy("INT", 3, _name);
  1869.   addlbl(_T_TYPE + _T_INT, +FALSE, (UINT)_typesz[_T_INT]);
  1870.   _lenname = strcopy("UINT", 4, _name);
  1871.   addlbl(_T_TYPE + _T_UINT, +FALSE, (UINT)_typesz[_T_UINT]);
  1872.   _lenname = strcopy("BYTE", 4, _name);
  1873.   addlbl(_T_TYPE + _T_BYTE, +FALSE, (UINT)_typesz[_T_BYTE]);
  1874.   _lenname = strcopy("BOOL", 4, _name);
  1875.   addlbl(_T_TYPE + _T_BOOL, +FALSE, (UINT)_typesz[_T_BOOL]);
  1876.   _lenname = strcopy("LONG", 4, _name);
  1877.   addlbl(_T_TYPE + _T_LONG, +FALSE, (UINT)_typesz[_T_LONG]);
  1878.   _lenname = strcopy("CHAR", 4, _name);
  1879.   addlbl(_T_TYPE + _T_CHAR, +FALSE, (UINT)_typesz[_T_CHAR]);
  1880.   _lenname = strcopy("FLOAT", 5, _name);
  1881.   addlbl(_T_TYPE + _T_FLOAT, +FALSE, (UINT)_typesz[_T_FLOAT]);
  1882.   _lenname = strcopy("STRUCT", 6, _name);
  1883.   addlbl(_T_TYPE + _T_STRUCTWORD, +FALSE, (UINT)_typesz[_T_STRUCT]);
  1884.   _lenname = strcopy("PINT", 4, _name);
  1885.   addlbl(_T_TYPE + _T_POI + _T_INT, +FALSE, (UINT)_typesz[_T_POI]);
  1886.   _lenname = strcopy("PUINT", 5, _name);
  1887.   addlbl(_T_TYPE + _T_POI + _T_UINT, +FALSE, (UINT)_typesz[_T_POI]);
  1888.   _lenname = strcopy("PBYTE", 5, _name);
  1889.   addlbl(_T_TYPE + _T_POI + _T_BYTE, +FALSE, (UINT)_typesz[_T_POI]);
  1890.   _lenname = strcopy("PBOOL", 5, _name);
  1891.   addlbl(_T_TYPE + _T_POI + _T_BOOL, +FALSE, (UINT)_typesz[_T_POI]);
  1892.   _lenname = strcopy("PLONG", 5, _name);
  1893.   addlbl(_T_TYPE + _T_POI + _T_LONG, +FALSE, (UINT)_typesz[_T_POI]);
  1894.   _lenname = strcopy("PCHAR", 5, _name);
  1895.   addlbl(_T_TYPE + _T_POI + _T_CHAR, +FALSE, (UINT)_typesz[_T_POI]);
  1896.   _lenname = strcopy("PFLOAT", 6, _name);
  1897.   addlbl(_T_TYPE + _T_POI + _T_FLOAT, +FALSE, (UINT)_typesz[_T_POI]);
  1898.   //_lenname = strcopy("PPROC", 5, _name);
  1899.   //addlbl(_T_TYPE + _T_POI + _T_PROC, +FALSE, (UINT)_typesz[_T_POI]);
  1900.  
  1901.   _lentitle = 0/**strclear(_title)*/;
  1902.   POKE *(PCHAR)(_title) = '\0'; //strclose(_title, _lentitle);
  1903.   _namespclvl = 0x00;
  1904.   //_exprlvl = 0x00; //ёхщўрё тхчфх ЁрёёЄртыхэю 0 (ьюцэю юяЄшьшчшЁютрЄ№ ёЁртэхэш ) шыш 1 (эхы№ч ) шыш inc-dec (фы  тыюцхээ√ї т√ўшёыхэшщ Єюцх эхы№ч )
  1905.  
  1906.  _addrexpr = +FALSE;
  1907.   _isexp = +FALSE;
  1908.   _curfunct = _T_UNKNOWN; //эр тё ъшщ ёыєўрщ
  1909.   _wasreturn = +FALSE; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
  1910.  
  1911.    _lenjoined = strjoineollast(_joined, 0, fn, '.');
  1912.    _lenjoined = strjoin(_joined, _lenjoined, ".ast");
  1913.    _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  1914.   _fout = openwrite(_joined);
  1915.  
  1916.    _lenjoined = strjoineollast(_joined, 0, fn, '.');
  1917.    _lenjoined = strjoin(_joined, _lenjoined, ".var");
  1918.    _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  1919.   _fvar = openwrite(_joined);
  1920.  
  1921.   _nhinclfiles = 0x00;
  1922.  
  1923.   initcmd();
  1924.   initcode(); //т√ч√трхЄ emitregs
  1925.   compfile(fn);
  1926.   endcode();
  1927.  
  1928.   fclose(_fvar);
  1929.   fclose(_fout);
  1930. }
  1931.