/// imported
 
#include "../_sdk/typecode.h"
 
#include "../_sdk/str.h"
 
#include "../_sdk/io.h"
 
#include "../_sdk/emit.h"
 
 
 
CONST BYTE _typesz[32];
 
 
 
#ifdef TARGET_THUMB
 
#include "sizesarm.h"
 
#else
 
#ifdef TARGET_SCRIPT
 
#include "sizesspt.h"
 
#else
 
#ifdef TARGET_386
 
#include "sizes386.h"
 
#else
 
#include "sizesz80.h"
 
#endif
 
#endif
 
#endif
 
 
 
CONST BOOL _isalphanum[256];
 
 
 
EXTERN BOOL _doskip; //яЁюяєёърЄ№ ёЄЁюъш, ъЁюьх эрўшэр■∙шїё  ё #
 
 
 
EXTERN PCHAR _tword; //Єхъє∙хх ёыютю
 
EXTERN UINT  _lentword;
 
VAR PCHAR _prefix; //яЁхЇшъё Єхъє∙хую ёыютр (юёЄрЄюъ - т _tword)
 
VAR UINT  _lenprefix;
 
VAR PCHAR _title; //эрчтрэшх Єхъє∙хщ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
 
VAR UINT  _lentitle;
 
EXTERN PCHAR _callee; //эрчтрэшх т√ч√трхьющ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
 
EXTERN UINT  _lencallee;
 
EXTERN PCHAR _name; //ьхЄър схч яЁхЇшъёр (фы  ЄрсышЎ√ ьхЄюъ)
 
EXTERN UINT  _lenname;
 
EXTERN PCHAR _joined; //ртЄюьхЄър
 
EXTERN UINT  _lenjoined;
 
VAR PCHAR _ncells; //т addlbl эхы№ч  юс·хфшэшЄ№ ncells ё callee //Єрь цх тЁхьхээю яЁю°ыр  ьхЄър фы  enum
 
VAR UINT  _lenncells;
 
VAR CHAR  _s1[_STRLEN]; //яЁхЇшъё Єхъє∙хую ёыютр (юёЄрЄюъ - т _tword)
 
VAR CHAR  _s2[_STRLEN]; //эрчтрэшх Єхъє∙хщ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
 
VAR CHAR  _s3[_STRLEN]; //эрчтрэшх т√ч√трхьющ яЁюЎхфєЁ√ (ё єў╕Єюь ьюфєы )
 
VAR CHAR  _s4[_STRLEN]; //ьхЄър схч яЁхЇшъёр (фы  ЄрсышЎ√ ьхЄюъ)
 
VAR CHAR  _s5[_STRLEN]; //ртЄюьхЄър
 
VAR CHAR  _s6[_STRLEN]; //ўшёыю ¤ыхьхэЄют
 
 
 
EXTERN CHAR _cnext;
 
EXTERN UINT _spcsize; //ўшёыю яЁюсхыют яюёых яЁюўшЄрээющ ъюьрэф√
 
 
 
EXTERN UINT _curline; //Єхъє∙шщ эюьхЁ ёЄЁюъш
 
 
 
EXTERN UINT _waseols; //ёъюы№ъю с√ыю EOL ё яЁю°ыюую Ёрчр
 
 
 
EXTERN UINT _typeaddr;
 
 
 
PROC rdch FORWARD();
 
PROC rdchcmt FORWARD();
 
PROC rdquotes FORWARD(CHAR eol);
 
PROC rdaddword FORWARD();
 
PROC rdword FORWARD();
 
PROC initrd FORWARD();
 
 
 
PROC strpush FORWARD(PCHAR s, UINT len); //joined шыш callee
 
FUNC UINT strpop FORWARD(PCHAR s);
 
EXTERN UINT _lenstrstk;
 
 
 
PROC initlblbuf FORWARD();
 
 
 
//math (схч ьр°шээюую ъюфр)
 
PROC cmdneg FORWARD();
 
PROC cmdinv FORWARD();
 
PROC cmdpoke FORWARD();
 
PROC cmdpeek FORWARD();
 
PROC cmdpushvar FORWARD();
 
PROC cmdpopvar FORWARD();
 
PROC cmdpushnum FORWARD();
 
PROC cmdmul FORWARD();
 
PROC cmddiv FORWARD();
 
PROC cmdshl FORWARD();
 
PROC cmdshr FORWARD();
 
PROC cmdadd FORWARD();
 
PROC cmdsub FORWARD();
 
PROC cmdaddpoi FORWARD(); //ёфтшурхЄ ёююЄтхЄёЄтхээю Єшяє ш яЁшсрты хЄ
 
PROC cmdand FORWARD();
 
PROC cmdor FORWARD();
 
PROC cmdxor FORWARD();
 
PROC cmdinc FORWARD();
 
PROC cmddec FORWARD();
 
PROC cmdincbyaddr FORWARD();
 
PROC cmddecbyaddr FORWARD();
 
 
 
//ёЁртэхэш  (схч ьр°шээюую ъюфр)
 
PROC cmdless FORWARD();
 
PROC cmdmore FORWARD();
 
PROC cmdlesseq FORWARD();
 
PROC cmdmoreeq FORWARD();
 
PROC cmdeq FORWARD();
 
PROC cmdnoteq FORWARD();
 
 
 
//ухэхЁрЎш  т√чютют ш яхЁхїюфют (схч ьр°шээюую ъюфр)
 
PROC cmdjpval FORWARD();
 
PROC cmdcallval FORWARD();
 
PROC cmdjp FORWARD();
 
PROC cmdjpiffalse FORWARD();
 
PROC cmdcall FORWARD();
 
PROC cmdfunc FORWARD();
 
PROC cmdpushpar FORWARD(); //фы  ЁхъєЁёштэ√ї яЁюЎхфєЁ (ёюїЁрэхэшх ярЁрьхЄЁют тэєЄЁш шыш ёэрЁєцш)
 
PROC cmdstorergs FORWARD(); //яюёых ёюїЁрэхэш  ыюъры№эющ яхЁхьхээющ ЁхъєЁёштэющ яЁюЎхфєЁ√
 
PROC cmdpoppar FORWARD(); //фы  ЁхъєЁёштэ√ї яЁюЎхфєЁ (тюёёЄрэютыхэшх ярЁрьхЄЁют тэєЄЁш шыш ёэрЁєцш)
 
PROC cmdresult FORWARD();
 
PROC cmdret FORWARD(BOOL isfunc); //тюёёЄрэютыхэшх Ёхчєы№ЄрЄр яюёых ёэ Єш  ыюърыют ёю ёЄхър ш т√їюф
 
 
 
PROC cmdcastto FORWARD(TYPE t2);
 
PROC cmdlabel FORWARD();
 
PROC var_alignwsz_label FORWARD(TYPE t);
 
PROC var_def FORWARD(TYPE t, PCHAR s);
 
 
 
PROC initcmd FORWARD();
 
 
 
PROC initcode FORWARD();
 
PROC endcode FORWARD();
 
PROC emitasmlabel FORWARD(PCHAR s);
 
PROC emitfunclabel FORWARD(PCHAR s);
 
PROC emitvarlabel FORWARD(PCHAR s);
 
PROC emitexport FORWARD(PCHAR s);
 
PROC emitvarpreequ FORWARD(PCHAR s);
 
PROC emitvarpostequ FORWARD();
 
PROC varequ FORWARD(PCHAR s);
 
PROC asm_db FORWARD(); //ъюёЄ√ы№ фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ TODO
 
PROC var_db FORWARD();
 
PROC var_dw FORWARD();
 
PROC var_ds FORWARD();
 
FUNC UINT varshift FORWARD(UINT shift, UINT sz);
 
 
 
FUNC UINT gettypename FORWARD(PCHAR s); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т s (ёЁрчє яюёых lbltype)
 
PROC setvarsz FORWARD(UINT addr, UINT shift);
 
FUNC TYPE lbltype FORWARD(); //тхЁэєЄ№ Єшя ьхЄъш _name
 
PROC dellbl FORWARD(); //єфрышЄ№ ьхЄъє _name
 
PROC addlbl FORWARD(TYPE t, BOOL isloc, UINT varsz/**, PCHAR size, UINT lensize*/); //(_name)
 
PROC keepvars FORWARD(); //яхЁхф эрўрыюь ыюъры№э√ї ьхЄюъ
 
PROC undovars FORWARD(); //яюёых ыюъры№э√ї ьхЄюъ (чрс√Є№ шї)
 
EXTERN UINT _varszaddr;
 
EXTERN UINT _varsz;
 
 
 
EXTERN BYTE _exprlvl; //уыєсшэр т√Ёрцхэш  (тхЁїэшщ єЁютхэ№ == 1)
 
EXTERN TYPE _t; //Єхъє∙шщ Єшя
 
EXTERN BOOL _isloc; //ыюъры№эр  ыш яЁюўшЄрээр  яхЁхьхээр 
 
 
 
////
 
CONST UINT _MAXPARS = 16; /**ьръёшьры№эюх ўшёыю ярЁрьхЄЁют т т√чютх ЇєэъЎшш*/
 
//todo юуЁрэшўшЄ№ уыєсшэє ЁхъєЁёшш f(g(h(...()...)
 
 
 
//ёюёЄю эшх ъюьяшы ЄюЁр (яы■ё х∙╕ ёюёЄю эш  commands ш codetg):
 
VAR UINT _curlbl; //эюьхЁ ртЄюьхЄъш
 
VAR UINT _tmpendlbl; //эюьхЁ ртЄюьхЄъш фы  т√їюфр шч Ўшъыр while/repeat
 
 
 
VAR BYTE _namespclvl; //уыєсшэр тыюцхээюёЄш яЁюёЄЁрэёЄтр шь╕э (ўшёыю Єюўхъ т яЁхЇшъёх)
 
 
 
VAR BOOL _isrecursive; //Єхъє∙р  юс· ты хьр  яЁюЎхфєЁр ЁхъєЁёштэр 
 
VAR BOOL _wasreturn; //с√ыр ъюьрэфр return (яюёых эх╕ эхы№ч  ъюьрэф√ т ЁхъєЁёштэющ ЇєэъЎшш) //ёюїЁрэ ■Єё  т func
 
VAR TYPE _curfunct; //Єшя ЇєэъЎшш (фы  return) //ёюїЁрэ ■Єё  т func
 
VAR BOOL _isexp; //Єхъє∙р  юс· ты хьр  яхЁхьхээр , ъюэёЄрэЄэ√щ ьрёёшт/ёЄЁєъЄєЁр, яЁюЎхфєЁр/ЇєэъЎш  ¤ъёяюЁЄшЁєхЄё  (эю эх ъюэёЄрэЄр, Є.ъ. ¤Єю эх рфЁхё ш эх эєцэю)
 
 
 
VAR CHAR _c0;
 
VAR CHAR _c2;
 
 
 
VAR UINT _parnum;
 
 
 
VAR UINT _doskipcond;
 
//_doskipcond т сшЄютюь тшфх яюьэшЄ, ёъюы№ъю єЁютэхщ ръЄштэ√ї ifdef ш ёъюы№ъю єЁютэхщ эхръЄштэ√ї (ъЁюьх Єхъє∙хую)
 
//(тэєЄЁш эхръЄштэюую ьюуєЄ с√Є№ Єюы№ъю эхръЄштэ√х)
 
//хёыш (_doskipcond&1) == 0 (Є.х. ь√ т эхръЄштэющ тхЄъх), Єю Єхъє∙шщ ifdef шуэюЁшЁєхЄё  ёю тёхьш тїюф ∙шьш (Є.х. else эх ЁрсюЄрхЄ)
 
//эхръЄштэюёЄ№ Єхъє∙хщ тхЄъш ifdef ыхцшЄ т _doskip
 
//эр тхЁїэхь єЁютэх _doskipcond = 1, _doskip = +FALSE
 
 
 
VAR BOOL _morecmd; //Їыру "сыюъ эх юъюэўхэ" т eatcmd
 
 
 
VAR CHAR _opsym;
 
 
 
VAR BOOL _addrexpr; //т√Ёрцхэшх ё & фы  &(<structname>-><field>) (TODO тыюцхээю?)
 
 
 
#define _MAXHINCLUDES 0x08
 
VAR PBYTE _hinclfile[_MAXHINCLUDES];
 
VAR UINT _hnline[_MAXHINCLUDES];
 
VAR BYTE _nhinclfiles; //ўшёыю юЄъЁ√Є√ї Їрщыют
 
//
 
 
 
#ifdef USE_HINTS
 
;;PROC hint_tword() {
 
;;  hintstr("//_tword=\""); hintstr(_tword); hintstr("\", cnext=\""); hint(_cnext); hint('\"'); endhint();
 
;;}
 
#endif
 
 
 
PROC err_tword(PCHAR s)
 
{
 
  errstr(s); errstr(" expected, but we have \'"); errstr(_tword); err('\''); enderr();
 
}
 
 
 
PROC doexp() //тёхуфр _joined
 
{
 
  IF (_isexp) emitexport(_joined);
 
}
 
 
 
PROC eat(CHAR c)
 
{
 
  IF (*(PCHAR)_tword!=c) {
 
    err(c); errstr(" expected, but we have \'"); errstr(_tword); err('\''); enderr();
 
  };
 
  rdword();
 
}
 
 
 
PROC jdot()
 
{
 
  _lenjoined = stradd(_joined, _lenjoined,'.');
 
  _joined[_lenjoined] = '\0';
 
}
 
 
 
VAR UINT _genn;
 
 
 
PROC gendig(UINT d)
 
{
 
VAR BYTE dig;
 
  dig = (BYTE)'A';
 
  WHILE (_genn >= d) {
 
    _genn = _genn - d;
 
    INC dig;
 
    _wasdig = +TRUE;
 
  };
 
  IF (_wasdig) {
 
    _lenjoined = stradd(_joined, _lenjoined, (CHAR)dig);
 
  };
 
}
 
 
 
PROC jautonum(UINT n)
 
{
 
  _genn = n;
 
  _wasdig = +TRUE;
 
  IF (n != 0) {
 
    _wasdig = +FALSE;
 
    gendig(676);
 
    gendig(26);
 
  };
 
  gendig(1);
 
  jdot();
 
}
 
 
 
PROC genjplbl(UINT n)
 
{
 
  _lenjoined = strcopy(_title, _lentitle, _joined);
 
  jautonum(n);
 
}
 
 
 
PROC jtitletword()
 
{
 
  _lenjoined = strcopy(_title, _lentitle, _joined);
 
  _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword);
 
  _joined[_lenjoined] = '\0';
 
}
 
 
 
PROC do_type()
 
{
 
loop:
 
  _lenname = strcopy(_tword, _lentword, _name);
 
  _t = lbltype();
 
  IF ((_t&_T_TYPE)!=(TYPE)0x00) { //хёыш ¤Єю эх яхЁхьхээр , р Єшя
 
    IF (_t == (_T_TYPE+_T_STRUCTWORD)) {
 
      rdword(); //use STRUCT
 
      goto loop;
 
    };
 
    IF (_cnext == '*') {
 
      _t = _t|_T_POI;
 
      _varsz = (UINT)_SZ_REG;
 
      rdword(); //use *
 
    };
 
  };
 
}
 
 
 
PROC eattype()
 
{
 
  do_type();
 
  _t = _t&~_T_TYPE;
 
  rdword();
 
}
 
 
 
PROC doprefix(BYTE nb) //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
 
{
 
  _lenprefix = 0;
 
  WHILE (nb > 0x00) { //яхЁхсшЁрхь ёыютр
 
    _lenprefix = strjoineol(/**to=*/_prefix, _lenprefix, &_title[_lenprefix], '.');
 
    _lenprefix = stradd(_prefix, _lenprefix, '.');
 
    DEC nb;
 
  };
 
  _prefix[_lenprefix] = '\0';
 
  _lenjoined = strcopy(_prefix, _lenprefix, _joined);
 
  _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword/**, _lentword*/);
 
  _joined[_lenjoined] = '\0';
 
}
 
 
 
PROC adddots()
 
{
 
/**  WHILE (_cnext == '.') {
 
    rdaddword(); //яЁшъыхшЄ№ Єюўъє
 
    rdaddword(); //яЁшъыхшЄ№ ёыхфє■∙хх ёыютю
 
  };*/
 
}
 
 
 
PROC twordtojoined()
 
{
 
  _lenjoined = strcopy(_tword, _lentword, _joined);
 
}
 
 
 
PROC joinvarname(BOOL iscall) //тючтЁр∙рхЄ _t = Єшя(_name)???
 
{ //шфхэЄшЇшърЄюЁ єцх яЁюўшЄрэ
 
VAR BYTE lvl;
 
  do_type();
 
  IF (!_isloc) {
 
    twordtojoined();
 
  }ELSE {
 
    lvl = _namespclvl;
 
    IF (iscall && (lvl != 0x00)) {
 
      DEC lvl; //proc()
 
    };
 
    doprefix(lvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
 
    //todo яЁютхЁшЄ№ ш ¤ЄюЄ Єшя (фы  ьюфєы№эюёЄш)?
 
    //шыш todo яЁхтЁрЄшЄ№ stru1->f1.f2 т tstru1.f1+tstru2.f2
 
  };
 
}
 
 
 
PROC eatvarname() //фы  ёючфрэш  ьхЄюъ
 
{
 
  eattype(); //t = _t; //Єшя с√ы єцх яЁюўшЄрэ
 
  adddots();
 
  _lenname = strcopy(_tword, _lentword, _name);
 
  doprefix(_namespclvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
 
  rdword(); //'['
 
  IF (*(PCHAR)_tword == '[') {
 
    _t = _t|_T_ARRAY;
 
  };
 
}
 
 
 
PROC getstructfield() //тючтЁр∙рхЄ _t = Єшя яюы 
 
{ //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr (т lbltype шыш addlbl), Єшя _t = эхъшщ єърчрЄхы№???
 
  _lenjoined = gettypename(_joined); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined
 
  eat('>'); //use '>'
 
  jdot();
 
  _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword); //structname.structfield
 
  _joined[_lenjoined] = '\0';
 
  cmdpushnum(); //structname.structfield
 
  cmdadd();
 
  _lenname = strcopy(/**from=*/_joined, _lenjoined, _name); //structname.structfield
 
  _t = lbltype(); //(_name)
 
}
 
 
 
//////////////////////////////////////////
 
// compiler
 
 
 
//call т√ч√трхЄ _tword ш expr
 
PROC eatexpr RECURSIVE FORWARD();  //т√ч√трхЄ call
 
FUNC BOOL eatcmd RECURSIVE FORWARD();  //т√ч√трхЄ call
 
FUNC TYPE do_call RECURSIVE FORWARD(BOOL isfunc); //тючтЁр∙рхЄ Єшя ЇєэъЎшш
 
PROC compfile RECURSIVE FORWARD(PCHAR fn);
 
 
 
PROC varstrz() //фы  ёЄЁюъют√ї ъюэёЄрэЄ т т√Ёрцхэш ї
 
{
 
  emitvarlabel(_joined);
 
  WHILE (+TRUE) {
 
    rdquotes('\"');
 
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
 
    _tword[_lentword] = '\0';
 
    var_db(); varstr(_tword); endvar();
 
    IF (_cnext != '\"') BREAK;
 
    rdword(); //юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
 
  };
 
  var_db(); varc('0'); endvar();
 
}
 
 
 
PROC asmstrz() //тёх CONST ёЄЁюъш ЄхяхЁ№ т ъюфх (Ёрэ№°х с√ыю Єюы№ъю фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ)
 
{
 
  emitasmlabel(_joined);
 
  WHILE (+TRUE) {
 
    rdquotes('\"');
 
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
 
    _tword[_lentword] = '\0';
 
    asm_db(); asmstr(_tword); endasm();
 
    IF (_cnext != '\"') BREAK;
 
    rdword(); //юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
 
  };
 
  asm_db(); asmc('0'); endasm();
 
}
 
 
 
PROC eatidx() //фы  idxarray ш switch
 
{
 
  INC _exprlvl; //no jump optimization
 
  eatexpr(); //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
 
  DEC _exprlvl;
 
  IF (_t==_T_BYTE) cmdcastto(_T_UINT);
 
  IF (_t!=_T_UINT) {errstr("idx bad type "); erruint((UINT)_t); enderr(); };
 
}
 
 
 
FUNC TYPE idxarray RECURSIVE(TYPE t)
 
{
 
  rdword(); //яхЁтюх ёыютю expr
 
  IF ((t&_T_ARRAY) != (TYPE)0x00) { //ьрёёшт
 
    t = t&_TYPEMASK; //&(~(_T_ARRAY|_T_CONST)); //ьюцхЄ с√Є№ _T_POI (хёыш ьрёёшт ёЄЁюъ)
 
    _t = _T_POI|_T_BYTE; cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
 
  }ELSE IF ((t&_T_POI) != (TYPE)0x00) { //єърчрЄхы№
 
    _t = t; cmdpushvar(); //шёяюы№чютрэшх єърчрЄхы  т ърўхёЄтх ьрёёштр - ўшЄрхь хую чэрўхэшх
 
    t = t&(~_T_POI);
 
  }ELSE {errstr("[] not in array "); erruint((UINT)t); enderr(); };
 
  eatidx();
 
  _t = t; //Єшя ¤ыхьхэЄр ьрёёштр
 
  cmdaddpoi();
 
RETURN t; //Єшя ¤ыхьхэЄр ьрёёштр
 
}
 
 
 
PROC numtype()
 
{
 
  IF (_cnext == '.') { //фЁюсэюх ўшёыю (эхы№ч  эрўшэрЄ№ ё Єюўъш шыш чрърэўштрЄ№ Єюўъющ)
 
    rdaddword(); //яЁшъыхшЄ№ Єюўъє
 
    rdaddword(); //яЁшъыхшЄ№ фЁюсэє■ ўрёЄ№
 
    IF ( (_tword[_lentword-1]=='e') && (_cnext=='-') ) {
 
      rdaddword(); //яЁшъыхшЄ№ '-' юЄЁшЎрЄхы№эющ ¤ъёяюэхэЄ√
 
      rdaddword(); //яЁшъыхшЄ№ юЄЁшЎрЄхы№эє■ ¤ъёяюэхэЄє
 
    };
 
    _t = _T_FLOAT;
 
  }ELSE IF (*(PCHAR)_tword == '-') { //т val єцх хёЄ№, эрфю фы  define
 
    _t = _T_INT;
 
  }ELSE IF (_tword[_lentword-1]=='L') {
 
    _t = _T_LONG;
 
  }ELSE IF ((BYTE)_tword[1] > (BYTE)'9') { //єёъюЁхэшх яЁютхЁъш ўшёыютюую ЇюЁьрЄр
 
    IF ((_lentword<=4)&&(_tword[1]=='x')) {
 
      _t = _T_BYTE;
 
    }ELSE IF ((_lentword<=10)&&(_tword[1]=='b')) {
 
      _t = _T_BYTE;
 
    }ELSE {
 
      _t = _T_UINT;
 
    };
 
  }ELSE {
 
    _t = _T_UINT;
 
  };
 
}
 
 
 
PROC val RECURSIVE()
 
{
 
VAR TYPE t; //фы  cast,peek
 
VAR UINT typeaddr; //фы  cast
 
{
 
//<val>::=
 
//(<expr>) //т√Ёрцхэшх (т√ўшёы хЄё )
 
//|<num> //фхё Єшўэюх ўшёыю (яхЁхфр╕Єё  Ўхышъюь) INT/UINT/LONG
 
//|<num>.<num>[e-<num>] //float ўшёыю (яхЁхфр╕Єё  Ўхышъюь)
 
//|<var> //яхЁхьхээр 
 
//|'CHAR' //ёшьтюы№эр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
 
//|"str" //ёЄЁюъютр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
 
//|(<type>)<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ яхЁхтюф т <type>
 
//|+<boolconst>
 
//|+_<enumconst> BYTE
 
//|+(constexpr) //Єшя яю ыхтюьє ъюэЄхъёЄє
 
//|<lbl>([<val>,...]) //call
 
//|-<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ NEG
 
//|~<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV
 
//|!<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV(BOOL)
 
//|*(<ptype>)<val> //яЁюўшЄрЄ№ ярь Є№ яю рфЁхёє (т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ PEEK)
 
//|&<var> //рфЁхё яхЁхьхээющ
 
 //ъюьрэфр єцх яЁюўшЄрэр
 
#ifdef USE_HINTS
 
;;  hintstr("//val: word=\""); hintstr(_tword); hintstr("\", cnext=\""); hint(_cnext); hint('\"'); endhint();
 
#endif
 
  _opsym = *(PCHAR)_tword;
 
  IF (_opsym == '~') {
 
    rdword(); //яхЁтюх ёыютю val
 
    IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
 
    cmdinv();
 
  }ELSE IF ((BYTE)_opsym >= 0x41) { //<var>
 
    adddots();
 
   //хёыш т√чют ЇєэъЎшш, Єю do_variable эрфю фхырЄ№ ё namespclvl-1!!!
 
    IF (_cnext == '(') { //call
 
      _t = do_call(+TRUE); //isfunc
 
    }ELSE {
 
      joinvarname(+FALSE); //iscall
 
      IF (_cnext == '[') { //<varname>[<idx>]
 
        rdword();
 
        _t = idxarray(_t);
 
        cmdpeek();
 
      }ELSE { //<varname>
 
        IF ((_t&_T_TYPE)==(TYPE)0x00) {
 
          /**IF (_t==_T_STRUCT) {
 
            _t = _T_POI|_T_BYTE;
 
            cmdpushnum(); //схЁ╕ь рфЁхё ёЄЁєъЄєЁ√ (фы  .)
 
          }ELSE*/ IF ((_t&_T_ARRAY)!=(TYPE)0x00) { //array without [] as a pointer
 
            _t = _t&(~(_T_ARRAY|_T_CONST))|_T_POI;
 
            cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
 
          }ELSE IF ((_t&_T_CONST)==(TYPE)0x00) {
 
            cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
 
          }ELSE { //ъюэёЄрэЄр (equ)
 
            _t = _t&_TYPEMASK; //&(~_T_CONST);
 
            cmdpushnum();
 
          };
 
        };
 
      };
 
    };
 
  }ELSE IF (_opsym == '\'') {
 
    rdquotes('\'');
 
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
 
    _tword[_lentword] = '\0';
 
    twordtojoined();
 
    _t = _T_CHAR; cmdpushnum();
 
  }ELSE IF (_opsym == '\"') {
 
    _lenjoined = strcopy(_title, _lentitle, _joined);
 
    jautonum(_curlbl);
 
    INC _curlbl;
 
    _t = _T_POI|_T_CHAR; cmdpushnum();
 
    varstrz(); //ё ьхЄъющ joined
 
  }ELSE IF (_opsym == '+') {
 
    rdword(); //'(' of type or +TRUE/+FALSE (BOOL) or +_CONSTANT or +__CONSTANT (BYTE)
 
    _opsym = *(PCHAR)_tword;
 
    IF (_opsym=='_') { //+_CONSTANT
 
      //эрўры№эр  ўрёЄ№ шьхэш ъюэёЄрэЄ√ єцх яЁюўшЄрэр
 
      adddots();
 
      joinvarname(/**iscall*/+FALSE);
 
      _lenjoined = strcopy(_name, _lenname, _joined); //уыюсры№эр 
 
      _t = _T_BYTE; cmdpushnum();
 
    }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //+num //extra BYTE for C bug
 
      IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
 
      IF (_t == _T_UINT) cmdcastto(_T_INT); //фы  чэръют√ї ъюэёЄрэЄ Єшяр +15
 
    }ELSE IF (_opsym!='(') { //+TRUE/+FALSE (BOOL) //+sizeof
 
      IF (_opsym=='s') { //+sizeof //TODO uppercase?
 
        rdword(); //шёяюы№чютрыш sizeof
 
        eat('('/**, "\'(\'"*/);
 
        eattype();
 
//        IF ((_t&_T_TYPE)!=0x00) {
 
          emitn(_varsz); //gettypesz();
 
          _lenjoined = strcopy(_nbuf, _lennbuf, _joined); //уыюсры№эр 
 
//        }ELSE { //эх Єшя
 
          //- шч яхЁхьхээющ срчютюую Єшяр - сєфхЄ ю°шсър, Є.ъ. яє° чэрўхэш  яхЁхьхээющ TODO (ёфхырЄ№ ёюёЄю эшх _issizeof)
 
          //- шч яхЁхьхээющ ьрёёштр - сєфхЄ ю°шсър, Є.ъ. яє° рфЁхёр ьрёёштр TODO
 
          //- шч яхЁхьхээющ ёЄЁєъЄєЁ√ - сєфхЄ ю°шсър, Є.ъ. яє° рфЁхёр ёЄЁєъЄєЁ√ TODO
 
          //- шч т√Ёрцхэш  - сєфхЄ ю°шсър, Є.ъ. ёухэхЁшЁє■Єё  юяхЁрЎшш TODO
 
//        };
 
        _t = _T_UINT; cmdpushnum(); //(_joined)
 
      }ELSE { //+TRUE/+FALSE (BOOL)
 
        twordtojoined();
 
        _t = _T_BOOL; cmdpushnum(); //(_joined)
 
      };
 
    }ELSE { //'(': с√ы typecast
 
#ifdef USE_COMMENTS
 
;;  cmtstr(";+(val)"); endcmt();
 
#endif
 
      rdword(); //(
 
      rdquotes(')');
 
      twordtojoined();
 
      rdword(); //)
 
      cmdpushnum(); //(_joined) //type from left context!!!
 
    };
 
  }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //num //extra BYTE for C bug
 
    numtype(); //_t
 
    twordtojoined();
 
    cmdpushnum();
 
  }ELSE IF (_opsym == '(') {
 
    rdword(); //яхЁтюх ёыютю expr
 
    eatexpr(); //эр т√їюфх шч expr єцх яЁюўшЄрэр ')'???, эю ёыхфє■∙шщ ёшьтюы шыш ъюьрэфр эх яЁюўшЄрэ√
 
    typeaddr = _typeaddr;
 
    IF ((_t&_T_TYPE)!=(TYPE)0x00) { //(type)val typecast//эхы№ч  т sizeof(expr)
 
      t = _t&~_T_TYPE;
 
      _t = t;
 
      rdword();
 
      val();
 
      _typeaddr = typeaddr;
 
      cmdcastto(t);
 
    };
 
  }ELSE IF (_opsym == '-') {
 
    IF ((BYTE)((BYTE)_cnext - (BYTE)'0') < 0x0a) { //-<const>
 
      rdaddword();
 
      //todo float
 
      _t = _T_INT;
 
      twordtojoined();
 
      cmdpushnum();
 
    }ELSE { //-<var>
 
      rdword(); //яхЁтюх ёыютю val
 
      IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
 
      cmdneg();
 
    };
 
  }ELSE IF (_opsym == '!') {
 
    rdword(); //яхЁтюх ёыютю val
 
    IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
 
    cmdinv(); //TODO invBOOL
 
  }ELSE IF (_opsym == '*') {
 
    rdword(); //'(' of type
 
    IF (!_waseof) val(); //чфхё№ Єшя єърчрЄхы  эх трцхэ //ЁхъєЁёштэ√щ т√чют val
 
    _t = _t&~_T_POI; //&~_T_CONST;
 
    cmdpeek();
 
  }ELSE IF (_opsym == '&') {
 
    IF (_cnext == '(') { //&(<structname>-><field>)
 
      _addrexpr = +TRUE;
 
      rdword(); //'('
 
      val();
 
      _t = _t|_T_POI;
 
    }ELSE {
 
      rdword();
 
      adddots();
 
      joinvarname(/**iscall*/+FALSE);
 
      IF (_cnext == '[') { //&<varname>[<idx>]
 
        rdword(); //'['
 
        _t = idxarray(_t)/**Єшя ¤ыхьхэЄр ьрёёштр*/|_T_POI;
 
      }ELSE { //&<varname>
 
        //IF ((_t&_T_ARRAY)!=0x00) { //&<arrayname> - error
 
        //}ELSE IF ((_t&_T_CONST)!=0x00) { //&<constname> - error
 
        //}ELSE { //&<varname>
 
          _t = _t&_TYPEMASK|_T_POI;
 
          cmdpushnum();
 
        //};
 
      };
 
    };
 
  }ELSE {
 
    errstr("WRONG PREFIX "); err(_opsym); enderr();
 
    _t = _T_UNKNOWN; //debug (шэрўх ьюцхЄ т√ыхЄхЄ№ чр ЄрсышЎє typesz яЁш юсЁ√тх Їрщыр)
 
  };
 
#ifdef USE_HINTS
 
;;  hinttype("end val",_t);
 
#endif
 
}
 
}
 
 
 
PROC eatmulval RECURSIVE()
 
{
 
VAR CHAR opsym;
 
VAR TYPE t1;
 
{
 
//<val>[<*|/><val>...] => push[push<*|/>...]
 
//чрърэўштрхЄё  яю ёшьтюыє ы■сющ эхюяшёрээющ юяхЁрЎшш (эряЁшьхЁ, ')' шыш ';')
 
 //ъюьрэфр єцх яЁюўшЄрэр
 
#ifdef USE_HINTS
 
;;  hintstr("//mulval"); endhint();
 
#endif
 
  val();
 
  rdword();
 
#ifdef USE_HINTS
 
;;  hintstr("//mulval after val"); hint_tword();
 
#endif
 
  REPEAT {
 
    opsym = *(PCHAR)_tword;
 
    IF (opsym!='*')
 
      IF (opsym!='/')
 
        IF (opsym!='&')
 
          BREAK;
 
    t1 = _t;
 
    rdword();
 
    IF (opsym=='&')
 
      IF (*(PCHAR)_tword==opsym)
 
        rdword(); //use '&' //C compatibility
 
    val();
 
    _t = _t&_TYPEMASK; //&(~_T_CONST);
 
    rdword();
 
#ifdef USE_HINTS
 
;;    hintstr("//mulval after val2"); hint_tword();
 
#endif
 
    IF (t1 != _t) {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
 
    IF       (opsym=='&') {cmdand();
 
    }ELSE IF (opsym=='*') {cmdmul();
 
    }ELSE /**IF (opsym=='/')*/ {cmddiv();
 
    };
 
  }UNTIL (_waseof);
 
#ifdef USE_HINTS
 
;;  hinttype("end mulval",_t);
 
#endif
 
}
 
}
 
 
 
PROC eatsumval RECURSIVE()
 
{
 
VAR CHAR opsym;
 
VAR TYPE t1;
 
{
 
//<mulval>[<+|-><mulval>...] => push[push<+|->...]
 
 //ъюьрэфр єцх яЁюўшЄрэр
 
#ifdef USE_HINTS
 
;;  hintstr("//sumval"); endhint();
 
#endif
 
  eatmulval();
 
  REPEAT {
 
    opsym = *(PCHAR)_tword;
 
    IF (opsym!='+')
 
      IF (opsym!='-')
 
        IF (opsym!='|')
 
          IF (opsym!='^')
 
            BREAK;
 
    t1 = _t;
 
    rdword();
 
    IF (*(PCHAR)_tword=='>') { //structinstancepointer->structfield
 
      //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr, Єшя _t = эхъшщ єърчрЄхы№
 
      IF (_t == _T_UNKNOWN) {errstr("nolbl:"); errstr(_name); enderr(); };
 
      getstructfield(); //_t = Єшя яюы 
 
      IF (!_addrexpr) cmdpeek(); //peek
 
      rdword(); //шёяюы№чютрыш structfield
 
    }ELSE {
 
      IF (opsym=='|') //||(opsym=='^')
 
        IF (*(PCHAR)_tword==opsym)
 
          rdword(); //use '|' or '^' //C compatibility
 
      eatmulval();
 
      _t = _t&_TYPEMASK; //&(~_T_CONST);
 
      IF (t1 != _t) /**&& ((t&_T_POI)!=0x00)*/ {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
 
      //todo addpointer
 
      IF       (opsym == '+') {cmdadd();
 
      }ELSE IF (opsym == '-') {cmdsub(); //шч ёЄрЁюую т√ўхёЄ№ эютюх!
 
      }ELSE IF (opsym == '|') {cmdor();
 
      }ELSE /**IF (opsym == '^')*/ {cmdxor();
 
      };
 
    };
 
  }UNTIL (_waseof);
 
#ifdef USE_HINTS
 
;;  hinttype("end sumval",_t);
 
#endif
 
}
 
}
 
 
 
PROC eatexpr RECURSIVE()
 
{
 
VAR CHAR opsym;
 
VAR TYPE t1;
 
VAR BOOL modified;
 
VAR BOOL dbl;
 
{
 
//<sumval>[<=><sumval>...]
 
 //ъюьрэфр єцх яЁюўшЄрэр (эєцэю фы  do_call_par)
 
#ifdef USE_HINTS
 
;;  hintstr("//expr"); endhint();
 
#endif
 
  INC _exprlvl;
 
  eatsumval();
 
  REPEAT {
 
    opsym = *(PCHAR)_tword;
 
    IF (opsym!='<')
 
      IF (opsym!='>')
 
        IF (opsym!='=')
 
          IF (opsym!='!')
 
            BREAK;
 
    t1 = _t;
 
    rdword();
 
    modified = (*(PCHAR)_tword=='=');
 
    dbl = (*(PCHAR)_tword==opsym);
 
    IF ( modified||dbl ) rdword(); //use '=' or '>' or '<'
 
    eatsumval();
 
    _t = _t&_TYPEMASK; //&(~_T_CONST);
 
    IF (t1 != _t) {errstr("opsym "); err(opsym); errstr(" type "); erruint((UINT)t1); errstr("!="); erruint((UINT)_t); enderr(); };
 
    IF (opsym == '=') {
 
      IF (!dbl) {errstr( "assign in expr" ); enderr(); };
 
      cmdeq(); //фхырхЄ _t = _T_BOOL
 
    }ELSE IF (opsym == '!') {
 
      cmdnoteq(); //фхырхЄ _t = _T_BOOL
 
    }ELSE IF (opsym == '<') {
 
      IF (dbl) {
 
        cmdshl(); //ёЄрЁюх ёфтшэєЄ№ ёЄюы№ъю Ёрч, ёъюы№ъю уырёшЄ эютюх!
 
      }ELSE IF (modified) {
 
        cmdlesseq(); //фхырхЄ _t = _T_BOOL
 
      }ELSE cmdless(); //фхырхЄ _t = _T_BOOL
 
    }ELSE /**IF (opsym == '>')*/ {
 
      IF (dbl) {
 
        cmdshr(); //ёЄрЁюх ёфтшэєЄ№ ёЄюы№ъю Ёрч, ёъюы№ъю уырёшЄ эютюх!
 
      }ELSE IF (modified) {
 
        cmdmoreeq(); //фхырхЄ _t = _T_BOOL
 
      }ELSE cmdmore(); //фхырхЄ _t = _T_BOOL
 
    };
 
  }UNTIL (_waseof);
 
  //т _tword юцшфрхЄё  ')' шыш фЁєующ эхёююЄтхЄёЄтє■∙шщ ёшьтюы
 
  DEC _exprlvl;
 
  _addrexpr = +FALSE; //эх т√Ёрцхэшх ё &
 
#ifdef USE_HINTS
 
;;  hinttype("end expr",_t);
 
;;  hint_tword();
 
#endif
 
}
 
}
 
 
 
PROC eatpoke()
 
//poke*(<ptype>)(<pointerexpr>)=<expr>
 
{
 
VAR TYPE t;
 
#ifdef USE_HINTS
 
;;  hintstr("//poke"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jump optimization
 
  eat('*');
 
  val(); t = _t&~_T_POI;
 
  rdword();
 
  eat('=');
 
  eatexpr();
 
  IF (t != _t) {errstr("poke variable type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
 
  cmdpoke();
 
#ifdef USE_HINTS
 
;;  hintstr("//end poke"); endhint();
 
#endif
 
}
 
 
 
PROC eatlet()
 
//<var>[<[><expr><]>]=<expr>
 
//<var>-><field>=<expr>
 
{
 
VAR TYPE t;
 
VAR BOOL ispoke;
 
#ifdef USE_HINTS
 
;;  hintstr("//let"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jp optimization
 
  joinvarname(/**iscall*/+FALSE); t = _t; //t!!!
 
  rdword(); //'['
 
  ispoke = +FALSE;
 
  IF (*(PCHAR)_tword == '[') {
 
    t = idxarray(t); //t = t&(~(_T_ARRAY|_T_POI));
 
    eat(']');
 
    ispoke = +TRUE;
 
  }ELSE {
 
    WHILE (*(PCHAR)_tword == '-') {
 
      _t = t;
 
      IF (ispoke) { //эх яхЁт√щ ->
 
        cmdpeek();
 
      }ELSE { //яхЁт√щ ->
 
        cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
 
      };
 
      eat('-');
 
      //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр _typeaddr, Єшя _t = эхъшщ єърчрЄхы№
 
      IF (_t == _T_UNKNOWN) {errstr("nolbl:"); errstr(_name); enderr(); };
 
      getstructfield(); //_t = Єшя яюы 
 
      t = _t; //todo
 
      rdword(); //шёяюы№чютрыш structfield
 
      ispoke = +TRUE;
 
    };
 
  };
 
  eat('=');
 
 strpush(_joined,_lenjoined);
 
  eatexpr(); //яюыєўрхЄ Єшя _t
 
 _lenjoined = strpop(_joined);
 
  IF (t!=_t) {
 
    errstr("let variable type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr();
 
  };
 
  IF (ispoke) {
 
    cmdpoke();
 
  }ELSE {
 
    cmdpopvar();
 
  };
 
#ifdef USE_HINTS
 
;;  hintstr("//end let"); hint_tword();
 
#endif
 
}
 
 
 
PROC eatwhile RECURSIVE()
 
//while<expr><cmd>
 
{
 
VAR UINT beglbl;
 
VAR UINT wasendlbl;
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//while"); endhint();
 
#endif
 
  _exprlvl = 0x00; //jp optimization possible
 
  wasendlbl = _tmpendlbl;
 
  beglbl = _curlbl; INC _curlbl;
 
  _tmpendlbl = _curlbl; INC _curlbl;
 
  genjplbl(beglbl); cmdlabel();
 
  eat('(');
 
  eatexpr(); //parentheses not included
 
  genjplbl(_tmpendlbl); cmdjpiffalse();
 
  eat(')');
 
  eatcmd(); //Єхыю while
 
  genjplbl(beglbl); cmdjp();
 
  genjplbl(_tmpendlbl); cmdlabel();
 
  _tmpendlbl = wasendlbl;
 
#ifdef USE_HINTS
 
;;  hintstr("//end while"); endhint();
 
#endif
 
}
 
}
 
 
 
PROC eatrepeat RECURSIVE()
 
//repeat<cmd>until<expr>
 
{
 
VAR UINT beglbl;
 
VAR UINT wasendlbl;
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//repeat"); endhint();
 
#endif
 
  wasendlbl = _tmpendlbl;
 
  beglbl = _curlbl; INC _curlbl;
 
  _tmpendlbl = _curlbl; INC _curlbl;
 
  genjplbl(beglbl); cmdlabel();
 
  eatcmd(); //Єхыю repeat
 
  IF ( (CHAR)((BYTE)(*(PCHAR)_tword)|0x20)!='u'/**"until"*/ ) err_tword("UNTIL");
 
  rdword();
 
  eat('(');
 
  _exprlvl = 0x00; //jp optimization possible
 
  eatexpr(); //parentheses not included
 
  eat(')');
 
  genjplbl(beglbl); cmdjpiffalse();
 
  genjplbl(_tmpendlbl); cmdlabel();
 
  _tmpendlbl = wasendlbl;
 
#ifdef USE_HINTS
 
;;  hintstr("//end repeat"); endhint();
 
#endif
 
}
 
}
 
 
 
PROC eatbreak() //todo inline
 
//break
 
{
 
  genjplbl(_tmpendlbl);
 
  cmdjp();
 
}
 
 
 
PROC eatif RECURSIVE()
 
//if <expr> <cmd>[else<cmd>];
 
//(; яЁюЄшт ю°шсъш "IF (expr);cmd" ш ю°шсъш тыюцхээюую if)
 
{
 
VAR UINT elselbl;
 
VAR UINT endiflbl;
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//if"); endhint();
 
#endif
 
  _exprlvl = 0x00; //jp optimization possible
 
  elselbl = _curlbl; INC _curlbl;
 
  endiflbl = _curlbl; INC _curlbl;
 
  eat('(');
 
  eatexpr(); //parentheses not included
 
  genjplbl(elselbl); cmdjpiffalse();
 
  eat(')');
 
  eatcmd(); //Єхыю then
 
  IF (*(PCHAR)_tword != ';'/**"endif"*/) {
 
    IF ( (CHAR)((BYTE)(*(PCHAR)_tword)|0x20)!='e'/**"else"*/ ) err_tword("ELSE or \';\'");
 
    genjplbl(endiflbl); cmdjp();
 
    genjplbl(elselbl); cmdlabel();
 
    rdword();
 
    eatcmd(); //Єхыю else
 
    genjplbl(endiflbl); cmdlabel();
 
    IF (*(PCHAR)_tword != ';'/**"endif"*/) { errstr( "\';\' expected, but we have \'"); err(*(PCHAR)_tword); err('\''); enderr(); };
 
    //эхы№ч  ё·хфрЄ№ ';', юэ эєцхэ фы  тыюцхээ√ї if
 
  }ELSE { //юцшфрхь 'endif' (хёыш IF схч ELSE)
 
    genjplbl(elselbl); cmdlabel();
 
  };
 
#ifdef USE_HINTS
 
;;  hintstr("//end if"); endhint();
 
#endif
 
}
 
}
 
/**
 
PROC eatmodule RECURSIVE()
 
//module<lbl><cmd>
 
{
 
  _lentitle = strjoin(_title, _lentitle, _tword);
 
  _lentitle = stradd(_title, _lentitle, '.');
 
  INC _namespclvl; //фюсрты хь ёыютю ъ title
 
 
 
  rdword();
 
  eatcmd();
 
 
 
  DEC _namespclvl;
 
  doprefix(_namespclvl); //to prefix
 
  _lentitle = strcopy(_prefix, _lenprefix, _title); //title = prefix //юЄЁхчрхь фюсртыхээюх ёыютю
 
}
 
*/
 
PROC eatreturn() //todo inline
 
{
 
//todo яЁютхЁшЄ№ isfunc (ўЄю ь√ т ЇєэъЎшш) фы  т√тюфр ю°шсъш
 
#ifdef USE_HINTS
 
;;  hintstr("//return"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jp optimization
 
  eatexpr(); //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
 
  IF ( _t != (_curfunct&(~_T_RECURSIVE)) ) {errstr("return type="); erruint((UINT)_curfunct); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
 
  cmdresult();
 
#ifdef USE_HINTS
 
;;  hintstr("//end return"); endhint();
 
#endif
 
  _wasreturn = +TRUE; //єёЄрэютшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
 
}
 
 
 
PROC eatinc()
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//inc"); endhint();
 
#endif
 
  IF (*(PCHAR)_tword == '*') {
 
    rdword(); //'('
 
    eatexpr();
 
    _t = _t&~_T_POI;
 
    cmdincbyaddr();
 
  }ELSE {
 
    //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
 
    adddots(); //фюўшЄрЄ№ шь 
 
    joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
 
    cmdinc();
 
    rdword();
 
  };
 
}
 
 
 
PROC eatdec()
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//dec"); endhint();
 
#endif
 
  IF (*(PCHAR)_tword == '*') {
 
    rdword(); //'('
 
    eatexpr();
 
    _t = _t&~_T_POI;
 
    cmddecbyaddr();
 
  }ELSE {
 
    //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
 
    adddots(); //фюўшЄрЄ№ шь 
 
    joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
 
    cmddec();
 
    rdword();
 
  };
 
}
 
 
 
PROC var_num(TYPE t, PCHAR s)
 
{
 
VAR TYPE tmasked = t&(~_T_ARRAY);
 
/**  IF ( (t&_T_POI)!=(TYPE)0x00 ) { //шёяюы№чєхЄё  фы  ёЄЁюъ (эхы№ч  equ)
 
    varstr_tword(); //DB "str"
 
  }ELSE*/ IF ( (t&_T_CONST)!=(TYPE)0x00 ) {
 
    varequ(_title); /**varstr(_title); varc( '=' );*/ varstr(s); endvar();
 
  }ELSE {
 
    IF (t==tmasked/**(t&_T_ARRAY)==(TYPE)0x00*/) {
 
      var_alignwsz_label(t);
 
      //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
 
    };
 
    var_def(tmasked, s);
 
  };
 
}
 
 
 
//TODO т√Ёрцхэш (юЄфрЄ№ рёьє?) + ЄрсышЎє ъюэёЄрэЄ т ъюьяшы ЄюЁх?
 
PROC do_const_num(TYPE t)
 
{
 
  IF ((*(PCHAR)_tword == '-') || (*(PCHAR)_tword == '+')) {
 
    rdaddword(); //яЁшъыхшЄ№ ўшёыю
 
    var_num(t, _tword);
 
  }ELSE IF (*(PCHAR)_tword == '\'') {
 
    rdquotes('\'');
 
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
 
    _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
 
    var_num(t, _tword);
 
  }ELSE IF (*(PCHAR)_tword == '&') { //&<var>, &<func>, &<structinstance>
 
    rdword(); //шёяюы№чютрЄ№ &, яЁюўшЄрЄ№ эрўрыю шьхэш
 
    adddots(); //фюўшЄрЄ№ шь 
 
    var_num(_T_ARRAY|_T_UINT, _tword); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
 
  }ELSE IF (*(PCHAR)_tword == '\"') {
 
    _lenjoined = strcopy(_title, _lentitle, _joined);
 
    IF ((t&_T_ARRAY)!=(TYPE)0x00) { //ёЄЁюър тэєЄЁш ьрёёштр
 
      jdot();
 
      jautonum(_curlbl);
 
      INC _curlbl;
 
      //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
 
      var_num(_T_ARRAY|_T_UINT, _joined); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
 
      asmstrz(); //ё ьхЄъющ _joined //ъюёЄ√ы№ тьхёЄю varstrz //todo Ўхышъюь чряюыэшЄ№ єърчрЄхыш, яюЄюь ухэхЁшЁютрЄ№ ёЄЁюъш? (эхы№ч  сєфхЄ &str т const pchar arr[]?)
 
    }ELSE {
 
      asmstrz(); //varstrz(); //ё ьхЄъющ joined
 
    };
 
  }ELSE var_num(t, _tword);
 
}
 
 
 
PROC eatextern()
 
//extern<type><variable>[<[><expr><]>]
 
{
 
VAR TYPE t;
 
#ifdef USE_HINTS
 
;;  hintstr("//extern"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jump optimization
 
  eatvarname(); t = _t; //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _name)
 
  IF (*(PCHAR)_tword == '[') {
 
    //t = t|_T_ARRAY; //єцх т eatvarname
 
    //rdbrackets(); //_tword='[' //TODO evaluate expr (т э╕ь эхы№ч  яхЁхьхээ√х ш т√чют√, Є.х. эх чрярЁ√трхЄё  joined?)
 
    _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
 
    rdquotes(']');
 
    rdch(); //яЁюяєёЄшЄ№ ']'
 
    //_lenncells = strcopy(_tword, _lentword, _ncells); //n = _tword;
 
  //}ELSE {
 
    //n ="1";
 
    //_lenncells = stradd(_ncells, strclear(_ncells), '1'); //n = n + '1';
 
    //strclose(_ncells, _lenncells);
 
    rdword();
 
  };
 
  addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр (ёЄЁєъЄєЁ√ эх с√тр■Є extern?)!
 
#ifdef USE_HINTS
 
;;  hintstr("//end extern"); endhint();
 
#endif
 
}
 
 
 
PROC eatvar RECURSIVE(BOOL ispar, BOOL body) //хёыш var, Єю body==+TRUE, шэрўх body==!forward
 
//var<type><variable>[<[><expr><]>][=<expr>]
 
//шыш т ярЁрьхЄЁрї яЁш юс· тыхэшш ЇєэъЎшш <type><variable>
 
{
 
VAR TYPE t;
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//var"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jump optimization
 
  eatvarname(); t = _t; //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _name)
 
  IF (*(PCHAR)_tword == '[') {
 
    //t = t|_T_ARRAY; //єцх т eatvarname
 
   //strpush(_joined,_lenjoined);
 
    //TODO evaluate expr (т э╕ь эхы№ч  яхЁхьхээ√х ш т√чют√, Є.х. эх чрярЁ√трхЄё  joined?)
 
    _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
 
    rdquotes(']');
 
   //_lenjoined = strpop(_joined);
 
    _lenncells = strcopy(_tword, _lentword, _ncells); //n = _tword;
 
    rdch(); //яЁюяєёЄшЄ№ ']'
 
    rdword();
 
  }ELSE { //n = "1"
 
    _lenncells = stradd(_ncells, 0/**strclear(_ncells)*/, '1'); //n = n + '1';
 
    _ncells[_lenncells] = '\0'; //strclose(_ncells, _lenncells);
 
  };
 
  IF (body) addlbl(t, /**isloc*/(_namespclvl!=0x00), (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
 
  IF (ispar) { //parameter of func/proc
 
    IF (body) {
 
      var_alignwsz_label(t);
 
      //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
 
    };
 
    _lenjoined = strcopy(_prefix, _lenprefix, _joined); //_lenjoined = strjoin(/**to=*/_joined, 0/**strclear(_joined)*/, _prefix/**, _lenprefix*/); //prefix юёЄрыё  юЄ doprefix/eatvarname т√°х
 
    jautonum(_parnum);
 
    INC _parnum; //!!! todo эряшёрЄ№ яюўхьє
 
    INC _curlbl; //!!! todo эряшёрЄ№ яюўхьє
 
    //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
 
    _lenname = strcopy(_joined, _lenjoined, _name);
 
    addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№ //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
 
  };
 
  //printf("%s \n",_joined);
 
  IF (body) {
 
    IF ((t&_T_ARRAY)!=(TYPE)0x00) {
 
      var_alignwsz_label(t);
 
      //emitvarlabel(_joined); //varstr(_joined); /**varc( ':' );*/ endvar();
 
      var_ds(); /**varstr( "\tDS " );*/ varuint((UINT)_typesz[t&_TYPEMASK]); varc('*'); varstr(_ncells); endvar(); //todo ЁрёёўшЄрЄ№ ЁрчьхЁ єцх т addlbl, Єюуфр ьюцэю сєфхЄ фхырЄ№ +sizeof(<array>)
 
      //printf("%s ds \n",_joined);
 
    }ELSE {
 
      var_num(t, "0");
 
    };
 
    doexp(); //_joined
 
  };
 
  IF (*(PCHAR)_tword == '=') { //TODO яЁютхЁшЄ№, ўЄю ь√ тэєЄЁш ЇєэъЎшш (эхЁхъєЁёштэющ!)
 
    rdword(); //'='
 
   strpush(_joined,_lenjoined);
 
    eatexpr();
 
   _lenjoined = strpop(_joined);
 
    //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(); };
 
    IF (t!=_t) {errstr("let variable="); errstr(_joined); errstr(" type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
 
    cmdpopvar();
 
  };
 
  IF (_isrecursive && !ispar) { //local variable of recursive func/proc
 
    _t = t;
 
    cmdpushpar(); //todo ўЄю фхырЄ№ ё ьрёёштрьш?
 
   strpush(_joined,_lenjoined);
 
    WHILE (*(PCHAR)_tword==';') {
 
      rdword();
 
    }; //C compatibility
 
    eatcmd(); //recursive function body must be in {} after vars!
 
   _lenjoined = strpop(_joined);
 
    _t = t;
 
    cmdpoppar(); //todo ўЄю фхырЄ№ ё ьрёёштрьш?
 
  };
 
#ifdef USE_HINTS
 
;;  hintstr("//end var"); endhint();
 
#endif
 
}
 
}
 
 
 
//TODO т√Ёрцхэш (юЄфрЄ№ рёьє?) + ЄрсышЎє ъюэёЄрэЄ?
 
PROC eatconst()
 
//<constnum>::=[-]<num>|'<char>'|"<str>"["<str>"...]
 
//const<type><variable>[=<constnum>]
 
//|const<type><variable><[><expr><]>[<[><expr><]>...][={<constnum>[,<constnum>...]}] - тыюцхээ√х {} чряЁх∙хэ√ (todo ёфхырЄ№ шыш шуэюЁшЁютрЄ№ ё ртЄюяхЁхёў╕Єюь ьэюуюьхЁэ√ї ьрёёштют т юфэюьхЁэ√х)
 
//|const pchar<variable><[><expr><]><[><expr><]>={"<str>"[,"<str>"...]}
 
{
 
VAR TYPE t;
 
VAR UINT i = 0;
 
#ifdef USE_HINTS
 
;;  hintstr("//const"); endhint();
 
#endif
 
  _exprlvl = 0x01; //no jump optimization
 
  eattype(); t = _t|_T_CONST; //Єшя с√ы єцх яЁюўшЄрэ
 
  adddots();
 
  doprefix(_namespclvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
 
  rdword(); //'['
 
  IF (*(PCHAR)_tword == '[') {
 
    t = t|_T_ARRAY;
 
  };
 
  //_joined ёюфхЁцшЄ шь  ъюэёЄрэЄ√
 
  //_name ёюфхЁцшЄ Єшя
 
  _lentitle = strcopy(_joined, _lenjoined, _title); //фы  єэшъры№эюёЄш шь╕э ёЄЁюъют√ї ъюэёЄрэЄ
 
  INC _namespclvl; //фюсрты хь ёыютю ъ title
 
 
 
  //эрь эєцэю яюыєўшЄ№ шь  Єшяр
 
  lbltype();
 
  _lenname = strcopy(_joined, _lenjoined, _name); //шь  ъюэёЄрэЄ√
 
  _lencallee = gettypename(_callee); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т callee (ёЁрчє яюёых lbltype)
 
 
 
  //title ёюфхЁцшЄ шь  ъюэёЄрэЄ√ (эєцэю фы  єэшъры№эюёЄш шь╕э ёЄЁюъют√ї ъюэёЄрэЄ т ьрёёштх т do_const_num)
 
  //_joined Єюцх ёюфхЁцшЄ шь  ъюэёЄрэЄ√
 
  addlbl(t, /**isloc*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
 
  WHILE (*(PCHAR)_tword == '[') { //[size]
 
    _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
 
    rdquotes(']');
 
    rdch(); //яЁюяєёЄшЄ№ ']'
 
    rdword();
 
  };
 
  IF (*(PCHAR)_tword == '=') {
 
    rdword(); //num or '{'
 
    IF (*(PCHAR)_tword == '{') { //array or struct
 
      var_alignwsz_label(t);
 
      doexp(); //_joined //эрфю ыш ¤ъёяюЁЄшЁютрЄ№ ъюэёЄрэЄ√? Єюы№ъю ъюэёЄрэЄэ√х ьрёёшт√/ёЄЁєъЄєЁ√
 
      REPEAT{ //¤ЄюЄ Ўшъы чряюЁЄшЄ _joined, эю шёяюы№чєхЄ _title
 
        rdword(); //num
 
 
 
        IF (t == (_T_STRUCT|_T_CONST)) { //ёЄЁєъЄєЁр (є эх╕ эхЄ рЄюьрЁэюую Єшяр)
 
          _lenjoined = strcopy(_callee, _lencallee, _joined); //callee ёюфхЁцшЄ шь  Єшяр ъюэёЄрэЄ√
 
          _lenjoined = stradd(_joined, _lenjoined, '.');
 
          jautonum(i);
 
          _lenname = strcopy(_joined, _lenjoined, _name);
 
          _t = lbltype();
 
          do_const_num(lbltype()&(~_T_TYPE)|_T_ARRAY); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє //TODO _t
 
          INC i;
 
        }ELSE { //эх ёЄЁєъЄєЁр
 
          do_const_num(t&(~_T_CONST)); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
 
        };
 
 
 
        rdword(); //',' or '}'
 
      }UNTIL (*(PCHAR)_tword == '}');
 
    }ELSE { //not array
 
      do_const_num(t);
 
    };
 
    rdword();
 
  };
 
 
 
  DEC _namespclvl; doprefix(_namespclvl); _lentitle=strcopy(_prefix,_lenprefix,_title);/**title =prefix;*/ //юЄЁхчрхь фюсртыхээюх ёыютю
 
 
 
  //_isexp = +FALSE; //эрфю ыш ¤ъёяюЁЄшЁютрЄ№ ъюэёЄрэЄ√? Єюы№ъю ъюэёЄрэЄэ√х ьрёёшт√/ёЄЁєъЄєЁ√
 
 
 
#ifdef USE_HINTS
 
;;  hintstr("//end const"); endhint();
 
#endif
 
}
 
 
 
PROC eatfunc(BOOL isfunc, TYPE oldfunct, BOOL oldwasreturn)
 
//proc<procname>[recursive][forward](<type><par>,...])[<cmd>]
 
//|func<type><funcname>[recursive][forward]([<type><par>,...])[<cmd>]
 
{
 
VAR BOOL isforward;
 
  _curlbl = 0; //ёсЁрё√трхь эєьхЁрЎш■ ртЄюьхЄюъ, Є.ъ. є эшї яЁхЇшъё ЇєэъЎшш
 
  IF ( isfunc ) {
 
    eattype(); _curfunct = _t;
 
  }ELSE _curfunct = _T_PROC;
 
#ifdef USE_HINTS
 
;;    hintstr("//func "); hinttype(_title,_curfunct);
 
#endif
 
  _lenname = strcopy(_tword, _lentword, _name);
 
  jtitletword();
 
  rdword(); //'(' or "recursive" or "forward"
 
  IF ((CHAR)((BYTE)(*(PCHAR)_tword)|0x20) == 'r') {
 
    _curfunct = _curfunct|_T_RECURSIVE;
 
    _isrecursive = +TRUE;
 
    rdword(); //'('
 
  }ELSE _isrecursive = +FALSE;
 
  IF ((CHAR)((BYTE)(*(PCHAR)_tword)|0x20) == 'f') {
 
    isforward = +TRUE;
 
    rdword(); //'('
 
  }ELSE isforward = +FALSE;
 
  addlbl(_curfunct, /**isloc*/+FALSE, 0/**, _ncells"0", 1*/); //(_name) //эхы№ч  if (!isforward), яюЄюьє ўЄю эрфю чряюьэшЄ№ Єшя ЇєэъЎшш т forward
 
  IF (!isforward) {
 
    cmdlabel(); //_joined
 
    cmdfunc(); //фхырхЄ initrgs
 
    doexp(); //_joined
 
  };
 
  jdot();
 
  _lentitle = strcopy(_joined, _lenjoined, _title);
 
  INC _namespclvl; //фюсрты хь ёыютю ъ title
 
 
 
  eat('(');
 
  _parnum = 0;
 
  WHILE (!_waseof) {
 
    IF (*(PCHAR)_tword == ')') BREAK;
 
    eatvar(/**ispar*/+TRUE, /**body*/!isforward); //ьхЄър ярЁрьхЄЁр ёючфр╕Єё  схч яЁхЇшъёр ш ё Їыруюь isloc, х∙╕ ёючфр╕Єё  f.A.
 
    IF (*(PCHAR)_tword == ')') BREAK; //шэрўх ','
 
    rdword(); //type or ')'
 
  };
 
  rdword();
 
 
 
  keepvars(); //эхы№ч  яхЁхф ярЁрьхЄЁрьш, Є.ъ. f.A. эрфю яюьэшЄ№ яюёых Єхыр ЇєэъЎшш
 
 
 
  IF (!isforward) {
 
    eatcmd(); //Єхыю ЇєэъЎшш
 
    _t = _curfunct&(~_T_RECURSIVE);
 
    cmdret(isfunc);
 
    IF (isfunc && !_wasreturn) {errstr("return expected"); enderr(); };
 
#ifdef USE_HINTS
 
;;    hintstr("/////end func"); endhint();
 
#endif
 
  };
 
 
 
  undovars(); //TODO єэшўЄюцшЄ№ ъюЁюЄъшх ьхЄъш ярЁрьхЄЁют, шэрўх юэш чрЄЁєЄ уыюсры√ эртхўэю. ═рфю їЁрэшЄ№ рфЁхёр Єръшї ьхЄюъ т ЄрсышЎх
 
 
 
  DEC _namespclvl; doprefix(_namespclvl); _lentitle=strcopy(_prefix,_lenprefix,_title);/**title =prefix;*/ //юЄЁхчрхь фюсртыхээюх ёыютю
 
  _curfunct = oldfunct; //тючтЁрЄшЄ№ тэх°эшщ Єшя ЇєэъЎшш
 
  _wasreturn = oldwasreturn; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
 
  _isexp = +FALSE;
 
}
 
 
 
PROC do_callpar RECURSIVE(TYPE funct, UINT parnum)
 
{
 
VAR TYPE t;
 
{
 
#ifdef USE_HINTS
 
;;  hintstr("//call_par"); endhint();
 
#endif
 
  IF ( (*(PCHAR)_tword!=')') && !_waseof ) {
 
    _lenjoined = strcopy(_callee, _lencallee, _joined);
 
    jdot();
 
    jautonum(parnum);
 
    //INC _curlbl; //эх эєцэю, Є.ъ. ¤Єю т√чют (Є.х. фЁєующ яЁхЇшъё)
 
    //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
 
;;    cmtstr(";accesspar="); cmtstr(_joined); endcmt();
 
    _lenname = strcopy(_joined, _lenjoined, _name);
 
    t = lbltype(); //(_name)
 
    IF ((funct&_T_RECURSIVE)!=(TYPE)0x00/**isstacked*/) {
 
      _t = t;
 
      cmdpushpar(); //(_joined)
 
    };
 
    strpush(_joined,_lenjoined);
 
    INC _exprlvl; //no jump optimization
 
    eatexpr(); //ьюцхЄ ЁхъєЁёштэю т√чтрЄ№ do_call ш чрЄхЁхЄ№ callee (хёыш юэ уыюсры№э√щ)! //ёЁртэхэш  эхы№ч  схч ёъюсюъ!!!
 
    DEC _exprlvl;
 
    IF (t != _t) {errstr("callpar type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
 
    _lenjoined = strpop(_joined);
 
    cmdpopvar(); //(_joined)
 
    IF (*(PCHAR)_tword == ',') rdword(); //parameter or ')'
 
    IF (parnum < _MAXPARS) {
 
      strpush(_joined,_lenjoined);
 
      do_callpar(/**isfunc,*/ funct, /**isstacked,*/ parnum+1); //ЁхъєЁёштэю
 
      _lenjoined = strpop(_joined);
 
    }/**ELSE {errstr("too many parameters"); enderr(); }*/;
 
    IF ((funct&_T_RECURSIVE)!=(TYPE)0x00/**isstacked*/) {
 
      _t = t;
 
      cmdpoppar(); //(_joined)
 
    };
 
  }ELSE {
 
    _t = funct&(~_T_RECURSIVE);
 
    cmdcall();
 
  };
 
#ifdef USE_HINTS
 
;;  hintstr("//end call_par"); endhint();
 
#endif
 
}
 
}
 
 
 
FUNC TYPE do_call RECURSIVE(BOOL isfunc)
 
//<lbl>([recursive][(<type>)<val>,...])
 
{
 
VAR TYPE t;
 
{
 
  INC _exprlvl; //no jump optimization
 
  joinvarname(/**iscall*/+TRUE); t = _t; //t!!!
 
  IF (t == _T_UNKNOWN) {errstr("unknown function "); errstr(_joined); enderr(); };
 
#ifdef USE_HINTS
 
;;    hinttype("call",t);
 
#endif
 
  IF (!isfunc) t = (t&_T_RECURSIVE)|_T_PROC; //ўЄюс√ ьюцэю с√ыю т√ч√трЄ№ ЇєэъЎшш ъръ яЁюЎхфєЁ√
 
  strpush(_callee,_lencallee); //эр ёыєўрщ тыюцхээ√ї т√чютют
 
  _lencallee = strcopy(_joined, _lenjoined, _callee); //схч Єюўъш
 
  jdot();
 
  rdword(); //'('
 
  eat('(');
 
  do_callpar(t, /**parnum*/0); //ёюїЁрэхэшх [call]title, [ёюїЁрэхэшх яхЁхьхээющ], яЁшётрштрэшх, ЁхъєЁёш , [тюёёЄрэютыхэшх яхЁхьхээющ], тюёёЄрэютыхэшх [call]title
 
  _lencallee = strpop(_callee); //эр ёыєўрщ тыюцхээ√ї т√чютют
 
  DEC _exprlvl; //no jump optimization
 
RETURN t&(~_T_RECURSIVE);
 
}
 
}
 
 
 
PROC eatcallpoi()
 
//call(<poi>)
 
{
 
 //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
 
  adddots(); //фюўшЄрЄ№ шь 
 
  joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
 
  eat('(');
 
  eatexpr();
 
  //todo яЁютхЁшЄ№ pointer
 
  eat(')');
 
  cmdcallval();
 
  rdword();
 
}
 
 
 
PROC eatlbl() //todo inline
 
//_lbl<lblname><:>
 
{
 
  jtitletword();
 
  cmdlabel();
 
  rdword(); //skip ':' for C compatibility
 
  rdword(); //эєцэю!
 
}
 
 
 
PROC eatgoto() //яхЁхїюф Єюы№ъю тэєЄЁш Єхъє∙хщ яЁюЎхфєЁ√ //todo inline
 
//goto<lblname>
 
{
 
  //rdword(); //lbl
 
  jtitletword();
 
  cmdjp();
 
  rdword();
 
}
 
 
 
PROC eatasm()
 
//asm("asmtext")
 
{
 
  //rdword(); //'('
 
  rdword(); //'\"'
 
  WHILE (!_waseof) {
 
    _lentword = 0/**strclear(_tword)*/; //ўшЄрхь ё яєёЄющ ёЄЁюъш
 
    rdquotes('\"'/**, +FALSE*/);
 
    asmstr(_tword); endasm();
 
    rdch(); //яЁюяєёЄшЄ№ чръЁ√тр■∙є■ ърт√ўъє
 
    IF (_cnext != '\"') BREAK;
 
    rdword(); //'\"' юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
 
  };
 
  rdword(); //')'
 
  rdword();
 
}
 
 
 
PROC eatenum()
 
//enum{<constname0>[=<num>],<constname1>...[,]}
 
{
 
  //rdword(); //'{'
 
_lenncells = strcopy("-1", 2, _ncells);
 
  WHILE (!_waseof) {
 
    rdword(); //ьхЄър
 
    IF (*(PCHAR)_tword=='}') BREAK; //BREAK ЁрсюЄрхЄ, р goto qqq эх ЁрсюЄрхЄ ('}' эх ё·хфхэр)
 
    varequ(_tword); /**varstr(_tword); varc('=');*/
 
 
 
//ъюёЄ√ы№ фы  script: ёючфр╕ь яхЁхьхээє■ UINT ё рфЁхёюь, ъръ Єхъє∙хх ўшёыю т enum:
 
//    _lenname = strcopy(_tword, _lentword, _name);
 
//    addlbl(_T_UINT, /**isloc*/+FALSE, /**varsz*/0/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№
 
//    rdword(); //',' шыш '}'
 
//    IF (*(PCHAR)_tword=='=') {
 
    IF (_cnext=='=') {
 
      rdword(); //ё·хыш =
 
      rdword(); //яхЁтюх ёыютю expr
 
      //eatexpr(); //parentheses not included
 
      //rdword(); //',' шыш '}'
 
      varstr(_tword);
 
    }ELSE {
 
      varstr(_ncells); varc('+'); varc('1'); /**varuint(i);*/
 
    };
 
_lenncells = strcopy(_tword, _lentword, _ncells);
 
    endvar();
 
    rdword(); //',' шыш '}'
 
    IF (*(PCHAR)_tword!=',') BREAK; //}
 
  };
 
  rdword(); //ёыютю яюёых }
 
}
 
 
 
PROC eatevar()
 
//evar{<type><varname0>[=<addr>],<type><varname1>...[,]}
 
{
 
  //rdword(); //'{'
 
_lenncells = strcopy("-1", 2, _ncells);
 
  WHILE (!_waseof) {
 
    rdword(); //type
 
    IF (*(PCHAR)_tword=='}') BREAK; //BREAK ЁрсюЄрхЄ, р goto qqq эх ЁрсюЄрхЄ ('}' эх ё·хфхэр)
 
    eattype(); //_t //фхырхЄ rdword(); //ьхЄър
 
    varequ(_tword); /**varstr(_tword); varc('=');*/
 
//ёючфр╕ь яхЁхьхээє■ Єшяр _t ё рфЁхёюь, ъръ Єхъє∙хх ўшёыю т evar:
 
    _lenname = strcopy(_tword, _lentword, _name);
 
    addlbl(_t/**_T_UINT*/, /**isloc*/+FALSE, /**varsz*/0/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№
 
//    rdword(); //',' шыш '}'
 
//    IF (*(PCHAR)_tword=='=') {
 
    IF (_cnext=='=') {
 
      rdword(); //ё·хыш =
 
      rdword(); //яхЁтюх ёыютю expr
 
      //eatexpr(); //parentheses not included
 
      //rdword(); //',' шыш '}'
 
      varstr(_tword);
 
    }ELSE {
 
      varstr(_ncells); varc('+'); varc('1'); /**varuint(i);*/
 
    };
 
_lenncells = strcopy(_tword, _lentword, _ncells);
 
    endvar();
 
    rdword(); //',' шыш '}'
 
    IF (*(PCHAR)_tword!=',') BREAK; //}
 
  };
 
  rdword(); //ёыютю яюёых }
 
}
 
 
 
PROC eatstruct()
 
//struct<name>{<type1><field1>[;]<type2><field2>[;]...}
 
{
 
VAR UINT shift = 0;
 
VAR UINT varszaddr;
 
VAR UINT i = 0;
 
VAR UINT sz;
 
  _lentitle = strjoin(/**to=*/_title, _lentitle, _tword/**, _lentword*/);
 
  _title[_lentitle] = '\0'; //strclose(_title, _lentitle);
 
  //strpush(_title,_lentitle); //схч Єюўъш
 
  _lenname = strcopy(_title, _lentitle, _name); //схч Єюўъш
 
  addlbl(_T_STRUCT|_T_TYPE, /**isloc*/+FALSE, 0/**, "0", _lenncells*/); //(_name) //яЁхфтрЁшЄхы№эю ёючфрыш, ўЄюс√ ёё√ырЄ№ё 
 
  varszaddr = _varszaddr;
 
 
 
  _lentitle = stradd(_title, _lentitle, '.');
 
  _title[_lentitle] = '\0'; //strclose(_title, _lentitle);
 
  INC _namespclvl; //фюсрты хь ёыютю ъ title
 
  rdword(); //шёяюы№чютрыш шь 
 
  eat('{');
 
 
 
  WHILE (!_waseof) {
 
    eattype(); //шёяюы№чютрыш Єшя
 
    sz = (UINT)_typesz[_t&_TYPEMASK];
 
    //rdword(); //ьхЄър
 
    jtitletword();
 
    shift = varshift(shift, sz);
 
 
 
    _lenname = strcopy(_joined, _lenjoined, _name);
 
    addlbl(_t, /**isloc*/+FALSE, sz/**, "0", _lenncells*/); //(_name)
 
 
 
    genjplbl(i);
 
    _lenname = strcopy(_joined, _lenjoined, _name);
 
    addlbl(_t, /**isloc*/+FALSE, sz/**, "0", _lenncells*/); //ртЄюэєьхЁютрээр  (_name)
 
    INC i;
 
 
 
    shift = shift + sz;
 
    rdword(); //Єшя шыш ';' шыш '}' //шёяюы№чютрыш ьхЄъє
 
    IF (*(PCHAR)_tword==';') rdword(); //Єшя
 
    IF (*(PCHAR)_tword=='}') BREAK;
 
  };
 
 
 
  //_lenname = strpop(_name);
 
  //addlbl(_T_STRUCT|_T_TYPE, /**isloc*/+FALSE/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№ //(_name)
 
  //Єрь цх ёюїЁрэшЄ№ sizeof_structname (=shift)
 
  //яЁш ¤Єюь тё╕ х∙╕ ЁрчЁх°шЄ№ ёё√ырЄ№ё  эр ¤Єє цх ёЄЁєъЄєЁє (Є.х. юяЁхфхышЄ№ х╕ Ёрэ№°х, р чряюыэшЄ№ фрээ√х яюЄюь; ёючфрЄ№ чрэютю эхы№ч  - фЁєующ рфЁхё)
 
  setvarsz(varszaddr, shift);
 
 
 
  DEC _namespclvl;
 
  doprefix(_namespclvl); //to prefix
 
  _lentitle = strcopy(_prefix, _lenprefix, _title); //title = prefix //юЄЁхчрхь фюсртыхээюх ёыютю
 
  rdword();
 
}
 
 
 
PROC eatswitch() //яЁюЎхфєЁр ЄхюЁхЄшўхёъш ЁхъєЁёштэр , эю яЁръЄшўхёъш тыюцхээюёЄ№ switch чряЁх∙хэр
 
//'J' т эєьхЁютрээ√ї ьхЄърї ьюцэю єсЁрЄ№, Є.ъ. ртЄюьхЄъш ЄхяхЁ№ схч ЎшЇЁ ш эх яхЁхёхъєЄё  (ьюцэю ёъыхштрЄ№ '.' ё ўшёыюь)
 
//switch (<byteexpr>){...};
 
//case <byteconst>: //ухэхЁшЁєхЄё  ртЄюьхЄър ё ўшёыюь (эх яхЁхёхў╕Єё  эш ё ўхь)
 
//default: //ухэхЁшЁєхЄё  ртЄюьхЄър ё Єюўъющ (эх яхЁхёхў╕Єё  эш ё ўхь)
 
{
 
VAR BYTE ib;
 
VAR UINT wastmpendlbl;
 
  //rdword(); //'('
 
  wastmpendlbl = _tmpendlbl;
 
  _tmpendlbl = _curlbl; INC _curlbl;
 
 
 
  //pushvar <title>.J
 
  _lenjoined = strcopy(_title, _lentitle, _joined);
 
  _lenjoined = stradd(_joined, _lenjoined, 'J');
 
  _joined[_lenjoined] = '\0'; //strclose(_joined , _lenjoined);
 
  _t = _T_UINT|_T_POI;
 
  cmdpushnum(); //шёяюы№чютрэшх єърчрЄхы  т ърўхёЄтх ьрёёштр - ўшЄрхь хую чэрўхэшх
 
 
 
  eatidx();
 
  _t = _T_UINT; //Єшя ¤ыхьхэЄр ьрёёштр
 
  cmdaddpoi();
 
  cmdpeek();
 
 
 
  cmdjpval();
 
 
 
  //ухэхЁшЁютрЄ№ ёяшёюъ эрўры№э√ї чэрўхэшщ эєьхЁютрээ√ї ьхЄюъ яхЁхїюфр
 
  //procname.aab.<num> = procname.aab.default (яюър схч aab TODO)
 
  //ухэхЁшЁютрЄ№ ЄрсышЎє яхЁхїюфют, чряюыэхээє■ эєьхЁютрээ√ьш ьхЄърьш яхЁхїюфр
 
  //DW procname.aab.1 (яюър схч aab TODO)
 
  varstr(_title); varc('J'); endvar();
 
  ib = 0x00;
 
  REPEAT {
 
    asmstr(_title); asmuint((UINT)ib); asmc('='); asmstr(_title); asmstr("default"); endasm(); //фю ъюфр! яю¤Єюьє asm
 
    var_dw(); varstr(_title); varuint((UINT)ib); endvar(); //TODO "DP", Є.х. эр °шЁшэє POINTER?
 
    INC ib;
 
  }UNTIL (ib == 0x00);
 
 
 
  eatcmd(); //{...}
 
 
 
  genjplbl(_tmpendlbl); cmdlabel();
 
  _tmpendlbl = wastmpendlbl;
 
}
 
 
 
PROC eatcase()
 
//case <byteconst>:
 
{
 
  //rdword(); //byteconst
 
 
 
  //чряюыэшЄ№ эєьхЁютрээє■ ьхЄъє яхЁхїюфр
 
  //procname.aab.#<_tword> = $ (яюър схч aab TODO)
 
  asmstr(_title); asmc('#'); asmstr(_tword); asmc('='); asmc('$'); endasm();
 
 
 
  rdword(); //skip ':' for C compatibility
 
  rdword(); //эєцэю!
 
}
 
 
 
FUNC BOOL eatcmd RECURSIVE() //тючтЁр∙рхЄ +FALSE, хёыш ъюэхЎ сыюър
 
{
 
{
 
 //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
 
  adddots(); //фюўшЄрЄ№ шь 
 
//ўЄюс√ ЁхрышчютрЄ№ юс· тыхэш  схч VAR ш FUNC, эрфю єцх ёхщўрё яЁютхЁшЄ№ Єшя ьхЄъш TODO FAST!!!
 
  _c0 = *(PCHAR)_tword;
 
  IF ((_c0=='}') || _waseof) {
 
    rdword();
 
    _morecmd = +FALSE;
 
  }ELSE {
 
//    IF (_wasreturn) {
 
//      IF (_c0!=';') {errstr("cmd after return!"); enderr(); };
 
//    };
 
    IF (_cnext=='=') { //let
 
      eatlet();
 
    }ELSE IF ( (((BYTE)_cnext-0x28/**'('*/) | ((BYTE)_spcsize/**==0x00*/)) == 0x00) { //call
 
      do_call(/**isfunc*/+FALSE); rdword();
 
    }ELSE IF (_cnext=='[') { //let []
 
      eatlet();
 
    }ELSE IF ( _cnext==':' ) { //lbl
 
      eatlbl();
 
    }ELSE IF (_cnext=='-') { //let ->
 
      eatlet();
 
    }ELSE {
 
      IF (_c0==';') {
 
        rdword(); //C compatibility
 
      }ELSE IF (_c0=='{') {
 
        rdword(); WHILE (eatcmd()) {};
 
      }ELSE {
 
        _c0 = (CHAR)((BYTE)_c0|0x20);
 
        IF       (_c0=='v') { //var
 
          rdword(); eatvar(/**ispar*/+FALSE, /**body*/+TRUE);
 
          _isexp = +FALSE; //эхы№ч  тэєЄЁ№, шэрўх эх ¤ъёяюЁЄшЁє■Єё  ярЁрьхЄЁ√ яЁюЎхфєЁ√
 
        }ELSE IF (_c0=='f') { //func
 
          rdword(); eatfunc(+TRUE, _curfunct, _wasreturn);
 
        }ELSE IF ( _c0=='w' ) { //while
 
          rdword(); eatwhile();
 
        }ELSE IF ( _c0=='b' ) { //break
 
          rdword(); eatbreak(); //no parameters (rds nothing)
 
        }ELSE {
 
        _c2 = (CHAR)((BYTE)_tword[2]|0x20);
 
        IF (_c0=='c') { //const //case //call
 
          IF (_c2=='n') { //const
 
            rdword(); eatconst();
 
          }ELSE IF (_c2=='l') { //call
 
            rdword(); eatcallpoi();
 
          }ELSE { //case
 
            rdword(); eatcase();
 
          };
 
        }ELSE IF (_c0=='p') { //proc //poke
 
          IF (_c2=='o') { //proc
 
            rdword(); eatfunc(+FALSE, _curfunct, _wasreturn);
 
          }ELSE { //poke
 
            rdword(); eatpoke();
 
          };
 
        }ELSE IF (_c0=='r') { //return //repeat
 
          IF (_c2=='t') { //return
 
            rdword(); eatreturn();
 
          }ELSE { //repeat
 
            rdword(); eatrepeat();
 
          };
 
        }ELSE IF ( _c0=='d' ) { //dec
 
          rdword(); eatdec();
 
        }ELSE IF ( _c0=='i' ) { //inc //if
 
          IF ( _c2=='c' ) { //inc
 
            rdword(); eatinc();
 
          }ELSE { //if
 
            rdword(); eatif();
 
          };
 
        }ELSE IF (_c0=='e') { //enum //extern //export //evar
 
          IF (_c2=='t') { //extern
 
            rdword(); eatextern();
 
          }ELSE IF (_c2=='p') { //export
 
            rdword(); _isexp = +TRUE;
 
          }ELSE IF (_c2=='a') { //evar
 
            rdword(); eatevar();
 
          }ELSE { //enum
 
            rdword(); eatenum();
 
          };
 
        }ELSE IF ( _c0=='g' ) { //goto
 
          rdword(); eatgoto();
 
        }ELSE IF ( _c0=='a' ) { //asm
 
          rdword(); eatasm();
 
        }ELSE IF ( _c0=='s' ) { //struct //switch
 
          IF (_c2=='r') { //struct
 
            rdword(); eatstruct();
 
          }ELSE { //switch
 
            rdword(); eatswitch();
 
          };
 
//        }ELSE IF ( _c0=='m' ) { //module
 
//          rdword(); eatmodule();
 
        }ELSE IF ( _c0=='t' ) { //typedef <type> <name>
 
          rdword();
 
          eattype();
 
          _lenname = strcopy(_tword, _lentword, _name);
 
          addlbl(_T_TYPE + _t, /**isloc*/+FALSE, (UINT)_typesz[_t]);
 
          rdword(); //шёяюы№чютрыш шь 
 
        }ELSE IF ( _c0=='#' ) { //define, include... (ё■фр яюярфрхь фрцх т эхръЄштэ√ї тхЄърї єёыютэющ ъюьяшы Ўшш)
 
          rdword(); //define, undef, include, if, else, [elif], ifdef, ifndef, endif, [import], [line], [error], [pragma]
 
//тыюцхээр  єёыютэр  ъюьяшы Ўш :
 
//_doskipcond т сшЄютюь тшфх яюьэшЄ, ёъюы№ъю єЁютэхщ ръЄштэ√ї ifdef ш ёъюы№ъю єЁютэхщ эхръЄштэ√ї (ъЁюьх Єхъє∙хую)
 
//(тэєЄЁш эхръЄштэюую ьюуєЄ с√Є№ Єюы№ъю эхръЄштэ√х)
 
//хёыш (_doskipcond&1) == 0 (Є.х. ь√ т эхръЄштэющ тхЄъх), Єю Єхъє∙шщ ifdef шуэюЁшЁєхЄё  ёю тёхьш тїюф ∙шьш (Є.х. else эх ЁрсюЄрхЄ)
 
//эхръЄштэюёЄ№ Єхъє∙хщ тхЄъш ifdef ыхцшЄ т _doskip
 
//эр тхЁїэхь єЁютэх _doskipcond = 1, _doskip = +FALSE
 
//хёыш ifdef, Єю:
 
  //_doskipcond = _doskipcond+_doskipcond
 
  //хёыш !_doskip, Єю:
 
    //INC _doskipcond;
 
    //хёыш ifdef эх уюфхэ, Єю _doskip = +TRUE
 
//хёыш else ш ((_doskipcond&1) != 0), Єю _doskip = !_doskip
 
//хёыш endif, Єю _doskip = ((_doskipcond&1) == 0); _doskipcond = _doskipcond>>1
 
          _c2 = _tword[2];
 
          IF ((_c2 == 'c')&&(!_doskip)) { //include
 
            rdword(); //"
 
            _lentword = 0;
 
            rdquotes('\"'/**, +FALSE*/); //IF (_c0 == '\"') { rdquotes('>'); }ELSE rdquotes('\"');
 
            _hinclfile[_nhinclfiles] = _fin;
 
            _hnline[_nhinclfiles] = _curline;
 
            INC _nhinclfiles; compfile(_tword); DEC _nhinclfiles;
 
            _fin = _hinclfile[_nhinclfiles];
 
            _curline = _hnline[_nhinclfiles];
 
            _waseof = +FALSE;
 
            rdch(); //яЁюяєёЄшЄ№ чръЁ√тр■∙є■ ърт√ўъє
 
          }ELSE IF (_c2 == 'd') { //ifdef/endif/undef
 
            IF (*(PCHAR)_tword == 'e') { //endif
 
              //_doskip = +FALSE; //todo тыюцхээюёЄ№ (яюфёў╕Є ўшёыр шЇют)
 
              _doskip = ((_doskipcond&1) == 0);
 
              _doskipcond = _doskipcond>>1;
 
//erruint(_doskipcond); errstr("#endif "); erruint((UINT)_doskip); enderr();
 
            }ELSE IF (*(PCHAR)_tword == 'i') { //ifdef
 
              _doskipcond = _doskipcond+_doskipcond;
 
              rdword(); //шь 
 
              _lenname = strcopy(_tword, _lentword, _name);
 
              //_t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
 
              IF (!_doskip) {
 
                INC _doskipcond; //эх шуэюЁшЁєхь ¤ЄюЄ ifdef
 
                //эхЄ ьхЄъш - яЁюяєёЄшЄ№ Єхыю
 
                _doskip = (lbltype() == _T_UNKNOWN); //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
 
              };
 
//erruint(_doskipcond); errstr("#ifdef "); erruint((UINT)_doskip); enderr();
 
            }ELSE { //undef
 
              rdword(); //шь 
 
              _lenname = strcopy(_tword, _lentword, _name);
 
              dellbl();
 
            };
 
          }ELSE IF (_c2 == 'n') { //ifndef
 
              _doskipcond = _doskipcond+_doskipcond;
 
              rdword(); //шь 
 
              _lenname = strcopy(_tword, _lentword, _name);
 
              //_t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
 
              IF (!_doskip) {
 
                INC _doskipcond; //эх шуэюЁшЁєхь ¤ЄюЄ ifndef
 
                //хёЄ№ ьхЄър - яЁюяєёЄшЄ№ Єхыю
 
                _doskip = (lbltype() != _T_UNKNOWN); //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
 
              };
 
          }ELSE IF (_c2 == 's') { //else
 
            //_doskip = !_doskip;
 
            IF ((_doskipcond&1) != 0) _doskip = !_doskip; //эх шуэюЁшЁєхь ¤ЄюЄ ifdef
 
//erruint(_doskipcond); errstr("#else "); erruint((UINT)_doskip); enderr();
 
          }ELSE IF ((_c2 == 'f')&&(!_doskip)) { //define
 
            rdword(); //шь 
 
            twordtojoined(); //_lenjoined = strcopy(_tword, _lentword, _joined);
 
            rdword(); //чэрўхэшх шыш (
 
            IF (*(PCHAR)_tword == '(') { //TODO ¤Єє ъюэёЄЁєъЎш■ яЁшьхэшЄ№ ш т const
 
              rdword(); //eat('(');
 
              eattype();
 
              eat(')');
 
              rdquotes(')');
 
              rdch(); //фюсрты хь чръЁ√тр■∙є■ ёъюсъє
 
              _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
 
            }ELSE {
 
              numtype(); //_t
 
            };
 
            _lenname = strcopy(_joined, _lenjoined, _name);
 
            addlbl(_t|_T_CONST, /**isloc*/+FALSE, (UINT)_typesz[_t/**&_TYPEMASK*/]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
 
            emitvarpreequ(_name);
 
            varequ(_name); /**varstr(_name); varc( '=' );*/ varstr(_tword); endvar();
 
            emitvarpostequ();
 
          };
 
 
 
          //rdchcmt(); //rdaddword(); //шёяюы№чєхь яхЁт√щ ёшьтюы чэрър ъюььхэЄрЁш , ўшЄрхь ёыхфє■∙шщ ёшьтюы
 
          WHILE (_waseols==0/** && !_waseof*/ ) {
 
            rdchcmt(); //яЁюяєёърхЄ тёх хэЄхЁ√
 
          };
 
          _tword[_lentword] = '\0'; //strclose(_tword, _lentword); //todo эрЁє°хэр ярЁэюёЄ№ clear..close
 
          IF ((BYTE)_cnext < (BYTE)'!') {
 
            rdch(); //шёяюы№чєхь яюёыхфэшщ ёшьтюы ъюььхэЄрЁш , ўшЄрхь ёыхфє■∙шщ ёшьтюы (TODO єэшЇшЎшЁютрЄ№ ъръ /* */)
 
          };
 
          rdword();
 
        }ELSE {
 
          errstr("WRONG COMMAND "); errstr(_tword); enderr();
 
          rdword();
 
        };
 
        };
 
      };
 
    }; //not a headless cmd
 
    _morecmd = +TRUE;
 
  }; //not '{'
 
  RETURN _morecmd;
 
}
 
}
 
 
 
PROC compfile RECURSIVE(PCHAR fn)
 
{
 
  _fin = nfopen(fn, "rb");
 
  IF (_fin != (PBYTE)0) {
 
    strpush(_fn,_lenfn);
 
    _lenfn = strjoineol(_fn, 0/**_lenfn*/, fn, '\0');
 
    _fn[_lenfn] = '\0';
 
    _waseof = +FALSE;
 
 
 
    _curline = 1;
 
    initrd();
 
    rdword();
 
 
 
    WHILE (eatcmd()) {};
 
 
 
    _lenfn = strpop(_fn);
 
  }ELSE {
 
    errstr("no file "); errstr(fn); enderr();
 
  };
 
}
 
 
 
FUNC UINT strjoineollast(PCHAR to, UINT tolen, PCHAR s2/**, UINT s2len*/, CHAR eol) //фышэр схч ЄхЁьшэрЄюЁр!
 
{ //to = to + s2;
 
VAR UINT len;
 
VAR UINT last;
 
VAR CHAR c;
 
  to = &to[tolen];
 
  len = tolen; //фышэр схч ЄхЁьшэрЄюЁр!
 
  last = 0; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
 
  loop:
 
    c = *(PCHAR)s2;
 
    IF ((c == '\0') || (len>=_STRMAX)) goto endloop; //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
 
    POKE *(PCHAR)(to) = c;
 
    INC s2;
 
    IF (c == eol) last = len;
 
    INC to;
 
    INC len;
 
  goto loop; //ЄхЁьшэрЄюЁ эх ъюяшЁєхЄё 
 
  endloop:
 
RETURN last; //яюёых яюёыхфэхую ЄхЁьшэрЄюЁр
 
}
 
 
 
PROC compile(PCHAR fn)
 
{
 
  _doskipcond = 1;
 
 
 
  _prefix = (PCHAR)_s1; //чряюыэ хЄё  т doprefix: module/func/const/var/extern - ыюъры№эю, joinvarname
 
  _title  = (PCHAR)_s2;
 
  _callee = (PCHAR)_s3;
 
  _name   = (PCHAR)_s4;
 
  _joined = (PCHAR)_s5;
 
  _ncells = (PCHAR)_s6;
 
 
 
  _fn = (PCHAR)_m_fn;
 
  _lenfn = 0;
 
 
 
  _tmpendlbl = 0; //ўЄюс√ эшъюуфр эх ёютярыю (break тэх ЇєэъЎшш т√фрёЄ ю°шсъє т рёьх)
 
  _lenstrstk = 0;
 
  _curlbl = 0; //ёсЁрё√трхь эєьхЁрЎш■ ртЄюьхЄюъ (фы  ьрёёштют ёЄЁюъ)
 
 
 
  initlblbuf();
 
 
 
  _lenname = strcopy("INT", 3, _name);
 
  addlbl(_T_TYPE + _T_INT, +FALSE, (UINT)_typesz[_T_INT]);
 
  _lenname = strcopy("UINT", 4, _name);
 
  addlbl(_T_TYPE + _T_UINT, +FALSE, (UINT)_typesz[_T_UINT]);
 
  _lenname = strcopy("BYTE", 4, _name);
 
  addlbl(_T_TYPE + _T_BYTE, +FALSE, (UINT)_typesz[_T_BYTE]);
 
  _lenname = strcopy("BOOL", 4, _name);
 
  addlbl(_T_TYPE + _T_BOOL, +FALSE, (UINT)_typesz[_T_BOOL]);
 
  _lenname = strcopy("LONG", 4, _name);
 
  addlbl(_T_TYPE + _T_LONG, +FALSE, (UINT)_typesz[_T_LONG]);
 
  _lenname = strcopy("CHAR", 4, _name);
 
  addlbl(_T_TYPE + _T_CHAR, +FALSE, (UINT)_typesz[_T_CHAR]);
 
  _lenname = strcopy("FLOAT", 5, _name);
 
  addlbl(_T_TYPE + _T_FLOAT, +FALSE, (UINT)_typesz[_T_FLOAT]);
 
  _lenname = strcopy("STRUCT", 6, _name);
 
  addlbl(_T_TYPE + _T_STRUCTWORD, +FALSE, (UINT)_typesz[_T_STRUCT]);
 
  _lenname = strcopy("PINT", 4, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_INT, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PUINT", 5, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_UINT, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PBYTE", 5, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_BYTE, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PBOOL", 5, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_BOOL, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PLONG", 5, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_LONG, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PCHAR", 5, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_CHAR, +FALSE, (UINT)_typesz[_T_POI]);
 
  _lenname = strcopy("PFLOAT", 6, _name);
 
  addlbl(_T_TYPE + _T_POI + _T_FLOAT, +FALSE, (UINT)_typesz[_T_POI]);
 
  //_lenname = strcopy("PPROC", 5, _name);
 
  //addlbl(_T_TYPE + _T_POI + _T_PROC, +FALSE, (UINT)_typesz[_T_POI]);
 
 
 
  _lentitle = 0/**strclear(_title)*/;
 
  POKE *(PCHAR)(_title) = '\0'; //strclose(_title, _lentitle);
 
  _namespclvl = 0x00;
 
  //_exprlvl = 0x00; //ёхщўрё тхчфх ЁрёёЄртыхэю 0 (ьюцэю юяЄшьшчшЁютрЄ№ ёЁртэхэш ) шыш 1 (эхы№ч ) шыш inc-dec (фы  тыюцхээ√ї т√ўшёыхэшщ Єюцх эхы№ч )
 
 
 
 _addrexpr = +FALSE;
 
  _isexp = +FALSE;
 
  _curfunct = _T_UNKNOWN; //эр тё ъшщ ёыєўрщ
 
  _wasreturn = +FALSE; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
 
 
 
   _lenjoined = strjoineollast(_joined, 0, fn, '.');
 
   _lenjoined = strjoin(_joined, _lenjoined, ".ast");
 
   _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
 
  _fout = openwrite(_joined);
 
 
 
   _lenjoined = strjoineollast(_joined, 0, fn, '.');
 
   _lenjoined = strjoin(_joined, _lenjoined, ".var");
 
   _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
 
  _fvar = openwrite(_joined);
 
 
 
  _nhinclfiles = 0x00;
 
 
 
  initcmd();
 
  initcode(); //т√ч√трхЄ emitregs
 
  compfile(fn);
 
  endcode();
 
 
 
}