Subversion Repositories NedoOS

Rev

Rev 20 | Rev 477 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

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