Login

Subversion Repositories NedoOS

Rev

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

//VAR INT a=+5;
//VAR UINT bb=4;

evar {
 INT var0 = 0,
 UINT var1,
 FLOAT var2,
}

CONST UINT ma[10] = {
1,1,2,3,4,5,6,7,8,9
}

VAR BYTE ab = (BYTE)2++(0x2+0x3+0x4)+0x6;
VAR BYTE ab1 = ab+0x3;
VAR BYTE ab2 = 0x2+ab;

VAR FLOAT ffa;
ffa = var2;
VAR INT fia = (INT)ab;
VAR INT fib = +4;
ab = +(0x4+0x5);
//ffa = 3.1415926536e-4+(FLOAT)fia;
//fia = (INT)ffa;

/**
FUNC INT f(UINT p) {
  RETURN (INT)(((FLOAT)(INT)p+1.0+(FLOAT)(+1)));
}
*/

/**
FUNC INT f(UINT p) {
  RETURN (INT)((BYTE)(INT)p+0x02+(BYTE)(1));
}
*/

CONST PCHAR str = "123""456";
enum {
        CMD_NOP,
        CMD_ADD,
        CMD_SUB, //CONST A CONST B SUB = A-B
        CMD_MUL,
        CMD_DIV, //CONST A CONST B DIV = A/B
        CMD_DIVSIGNED,
        CMD_IF0GOTO, //IF0GOTO ADDR
        CMD_GOTO, //GOTO ADDR
        CMD_DUP,
        CMD_DROP,
        CMD_SWAP, //CONST A CONST B SWAP SUB = B-A
        CMD_READVAR, //CONST A READVAR = VAR(A)
        CMD_WRITEVAR, //CONST A CONST B WRITEVAR: VAR(A) = B
        CMD_CONST, //CONST A
        CMD_RET,
        CMD_CALL, //CALL ADDR
        CMD_AND,
        CMD_OR,
        CMD_XOR,
        CMD_EQ,
        CMD_MOREEQ,
        CMD_MOREEQSIGNED,
        CMD_INV,
        CMD_RST, //RST <systemprocnum>
        CMD_SHR, //CONST A CONST B SHR = A>>B
        CMD_SHRSIGNED,
        CMD_SHL,
        CMD_MOD, //CONST A CONST B MOD = A % B
        CMD_DONE, //end
};


VAR INT iia[5];
VAR LONG la[5];

enum {
_a=5, //123
_b=10, //asb cd
_c, //23423
_d, //1231243
_e, //dsfdfg
}
VAR INT asa = +(_a);

#define X 1

VAR INT a;
INC a;
CONST PCHAR bla = "blabla";


struct zzz{
  BYTE ba;
  LONG lb;
  STRUCT zzz* pcc;
}

VAR zzz arrzzz[2]; //BUG! фхырхЄ 0*2

CONST STRUCT zzz zuzu={
  0x03,
  5L,
  &zuzu
}
TYPEDEF STRUCT zzz* tpzzz

VAR STRUCT zzz* pzz1
VAR tpzzz pzzz

CONST UINT zzz_nnn = 0;
VAR LONG ly = (LONG)2;
VAR LONG lx = (STRUCT zzz*)(zzz_nnn)->lb;
VAR LONG l0 = &zuzu->lb;
VAR LONG l1 = (STRUCT zzz*)(zzz_nnn+(UINT)&zuzu)->lb;
VAR LONG l2 = (STRUCT zzz*)((UINT)&zuzu+zzz_nnn)->lb;
VAR LONG l3 = (STRUCT zzz*)((UINT)&zuzu+0)->lb;

#ifdef DOUBLES

INC *(PBYTE)(&pp);

#else

#ifndef X
//VAR STRUCT zzz* pzz1 = &zuzu;
#else
//VAR PBYTE pp = &(pzz1->ba); //ёъюсъш юс чрЄхы№э√!
#endif
DEC *(&(pzz1->ba));

#endif

CONST PCHAR strings[3] = {
  "str1",
  "str2",
  &bla //"str3"
};

VAR BYTE b
VAR UINT ui
ui = +sizeof(b)
ui = (UINT)+sizeof(STRUCT zzz)

VAR PBYTE pb
VAR PCHAR pcc
//pb = (PBYTE)pcc

VAR LONG lb
struct sss{
 INT a
 LONG lb
 STRUCT zzz* pzzz
 STRUCT sss* psss
}
VAR sss* psss
VAR INT ia;
lb = psss->lb;
ia = (INT)(psss->pzzz->ba);
psss->a = (INT)+sizeof(zzz);
pb = (PBYTE)pcc
psss->pzzz->ba = 0x00;
psss->psss->a = +5;

proc recpr recursuve(BYTE b)
{
}

proc prosto()
{
  recpr(0x10);
}

/// imported
#include "../_sdk/typecode.h"
#include "../_sdk/str.h"
#include "../_sdk/io.h"
#include "../_sdk/emit.h"

//EXTERN UINT _curlnbeg; //эюьхЁ ёЄЁюъш эр ьюьхэЄ эрўрыр Єюъхэр //фы  read, emit
//EXTERN BOOL _cmts; //фы  read, emit

//#ifdef DOUBLES
CONST BYTE _typesz[32];

#include "../comp/sizesz80.h"
//CONST BYTE _SZ_REG;

CONST BOOL _isalphanum[256];
//#endif

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
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 ё яЁю°ыюую Ёрчр

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();

//EXTERN BYTE _sz;

//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 cmdshl1 FORWARD();
//PROC cmdshr1 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 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 cmdendfunc FORWARD(BOOL isfunc); //тюёёЄрэютыхэшх Ёхчєы№ЄрЄр яюёых ёэ Єш  ыюърыют ёю ёЄхър ш т√їюф

PROC cmdcastto FORWARD(BYTE t2);
PROC cmdlabel FORWARD();

PROC initcmd FORWARD();

PROC initcode FORWARD();
PROC asm_db FORWARD(); //ъюёЄ√ы№ фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ TODO
PROC var_db FORWARD();
PROC var_dw FORWARD();
//PROC var_dl FORWARD();
PROC var_def FORWARD(BYTE t, PCHAR s);

PROC gettypename FORWARD(); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined (ёЁрчє яюёых lbltype)
PROC setvarsz FORWARD(UINT addr, UINT shift);
FUNC BYTE lbltype FORWARD(); //тхЁэєЄ№ Єшя ьхЄъш _name
PROC dellbl FORWARD(); //єфрышЄ№ ьхЄъє _name
PROC addlbl FORWARD(BYTE t, BOOL islocal, UINT varsz/**, PCHAR size, UINT lensize*/); //(_name)
PROC keepvars FORWARD(); //яхЁхф эрўрыюь ыюъры№э√ї ьхЄюъ
PROC undovars FORWARD(); //яюёых ыюъры№э√ї ьхЄюъ (чрс√Є№ шї)
EXTERN UINT _varszaddr;
EXTERN UINT _varsz;

////
CONST UINT _MAXPARS = 16; /**ьръёшьры№эюх ўшёыю ярЁрьхЄЁют т т√чютх ЇєэъЎшш*/

//ёюёЄю эшх ъюьяшы ЄюЁр (яы■ё х∙╕ ёюёЄю эш  commands ш codetg):
VAR UINT _curlbl; //эюьхЁ ртЄюьхЄъш
VAR UINT _tmpendlbl; //эюьхЁ ртЄюьхЄъш фы  т√їюфр шч Ўшъыр while/repeat

VAR BYTE _namespclvl; //уыєсшэр тыюцхээюёЄш яЁюёЄЁрэёЄтр шь╕э (ўшёыю Єюўхъ т яЁхЇшъёх)
EXTERN BYTE _exprlvl; //уыєсшэр т√Ёрцхэш  (тхЁїэшщ єЁютхэ№ == 1)

VAR BOOL _isrecursive; //Єхъє∙р  юс· ты хьр  яЁюЎхфєЁр ЁхъєЁёштэр 
VAR BOOL _wasreturn; //с√ыр ъюьрэфр return (яюёых эх╕ эхы№ч  ъюьрэф√ т ЁхъєЁёштэющ ЇєэъЎшш) //ёюїЁрэ ■Єё  т func
VAR BYTE _curfunct; //Єшя ЇєэъЎшш (фы  return) //ёюїЁрэ ■Єё  т func
EXTERN BYTE _t; //Єхъє∙шщ Єшя
EXTERN BOOL _islocal; //ыюъры№эр  ыш яЁюўшЄрээр  яхЁхьхээр 
VAR BOOL _isexp; //Єхъє∙р  юс· ты хьр  яхЁхьхээр , ъюэёЄрэЄэ√щ ьрёёшт/ёЄЁєъЄєЁр, яЁюЎхфєЁр/ЇєэъЎш  ¤ъёяюЁЄшЁєхЄё  (эю эх ъюэёЄрэЄр, Є.ъ. ¤Єю эх рфЁхё ш эх эєцэю)

VAR CHAR _c0;
VAR CHAR _c2;

VAR UINT _parnum;

VAR BOOL _morecmd; //Їыру "сыюъ эх юъюэўхэ" т eatcmd

VAR CHAR _opsym;

#define _MAXHINCLUDES 0x03
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(PCHAR s)
{
  IF (_isexp) {
    asmstr("\tEXPORT "); asmstr(s); endasm();
  };
}

PROC eat(CHAR c)
{
  IF (*(PCHAR)_tword!=c) {
    err(c); errstr(" expected, but we have \'"); errstr(_tword); err('\''); enderr();
    //err_tword(s);
  };
  rdword();
}

PROC jdot()
{
  _lenjoined = stradd(_joined, _lenjoined,'.');
  _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
}

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, 0/**strclear(_joined)*/, _title);
  _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword);
  _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
}

FUNC BYTE eattype()
{
VAR BYTE t; //todo _t?
  _lenname = strcopy(_tword, _lentword, _name);
  t = lbltype()&~_T_TYPE;
  IF (_cnext == '*') {
    t = t|_T_POI;
    _varsz = (UINT)_SZ_REG;
    rdword(); //use *
  };
  rdword();
  RETURN t;
}

PROC doprefix(BYTE nb) //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
{
  _lenprefix = 0; //strclear(_prefix)
  WHILE (nb > 0x00) { //яхЁхсшЁрхь ёыютр
    _lenprefix = strjoineol(/**to=*/_prefix, _lenprefix, &_title[_lenprefix], '.');
    _lenprefix = stradd(_prefix, _lenprefix, '.');
    DEC nb;
  };
  _prefix[_lenprefix] = '\0'; //strclose(_prefix, _lenprefix);
  _lenjoined = strcopy(_prefix, _lenprefix, _joined);
  _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword/**, _lentword*/);
  _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
}

PROC adddots()
{
  WHILE (_cnext == '.') {
    rdaddword(); //яЁшъыхшЄ№ Єюўъє
    rdaddword(); //яЁшъыхшЄ№ ёыхфє■∙хх ёыютю
  };
}

FUNC BYTE joinvarname(BOOL iscall)
{
VAR BYTE lvl;
VAR BYTE t;
 //шфхэЄшЇшърЄюЁ єцх яЁюўшЄрэ
  _lenname = strcopy(_tword, _lentword, _name);
  t = lbltype();
  IF ((_cnext == '*')&&((t&_T_TYPE)!=0x00)) { //todo т√фхышЄ№ т яюфяЁюуЁрььє
    t = t|_T_POI;
    _varsz = (UINT)_SZ_REG;
    rdword(); //use *
  };
  //lvl = *(PBYTE)_tword; //todo єсЁрЄ№
  IF (!_islocal) {
    _lenjoined = strcopy(_tword, _lentword, _joined);
  }ELSE {
    lvl = _namespclvl;
    IF (iscall && (lvl != 0x00)) {
      DEC lvl; //proc()
    };
    doprefix(lvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
    //todo яЁютхЁшЄ№ ш ¤ЄюЄ Єшя (фы  ьюфєы№эюёЄш)?
  };
  RETURN t; //(_name) //todo _t?
}

FUNC BYTE eatvarname() //фы  ёючфрэш  ьхЄюъ
{
VAR BYTE t;
  t = eattype(); //Єшя с√ы єцх яЁюўшЄрэ
  adddots();
  _lenname = strcopy(_tword, _lentword, _name);
  doprefix(_namespclvl); //ёъыхшЄ№ n ёыют Єшяр 'word.' шч title т prefix (name схч яЁхЇшъёр)
  rdword(); //'['
  IF (*(PCHAR)_tword == '[') {
    t = t|_T_ARRAY;
  };
  RETURN t;
}

//////////////////////////////////////////
// compiler

//call т√ч√трхЄ _tword ш expr
PROC eatexpr RECURSIVE FORWARD();  //т√ч√трхЄ call
FUNC BOOL eatcmd RECURSIVE FORWARD();  //т√ч√трхЄ call
FUNC BYTE do_call RECURSIVE FORWARD(BOOL isfunc); //тючтЁр∙рхЄ Єшя ЇєэъЎшш
PROC compfile RECURSIVE FORWARD(PCHAR fn);

PROC varstrz()
{
  varstr(_joined); /**varc( ':' );*/ endvar();
  WHILE (+TRUE) {
    rdquotes('\"');
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
    _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
    var_db(); varstr(_tword); endvar();
    IF (_cnext != '\"') BREAK;
    rdword(); //юЄъЁ√тр■∙р  ърт√ўър яЁшъыххээющ ёЄЁюъш
  };
  var_db(); varc('0'); endvar();
}

PROC asmstrz() //ъюёЄ√ы№ фы  ъюэёЄрэЄэ√ї ьрёёштют ёЄЁюъ
{
  asmstr(_title/**_joined*/); /**varc( ':' );*/ endasm();
  WHILE (+TRUE) {
    rdquotes('\"');
    rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
    _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
    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 BYTE idxarray RECURSIVE(BYTE t)
{
  rdword(); //яхЁтюх ёыютю expr
  IF ((t&_T_ARRAY) != 0x00) { //ьрёёшт
    t = t&_TYPEMASK; //&(~(_T_ARRAY|_T_CONST)); //ьюцхЄ с√Є№ _T_POI (хёыш ьрёёшт ёЄЁюъ)
    _t = _T_POI|_T_BYTE; cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
  }ELSE IF ((t&_T_POI) != 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 BYTE t; //cast,peek
{
//<val>::=
//(<expr>) //т√Ёрцхэшх (т√ўшёы хЄё )
//|<num> //фхё Єшўэюх ўшёыю (яхЁхфр╕Єё  Ўхышъюь) INT/UINT/LONG
//|<num>.<num>[e-<num>] //float ўшёыю (яхЁхфр╕Єё  Ўхышъюь)
//|<var> //яхЁхьхээр 
//|'CHAR' //ёшьтюы№эр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
//|"str" //ёЄЁюъютр  ъюэёЄрэЄр (яхЁхфр╕Єё  Ўхышъюь)
//|+(<type>)<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ яхЁхтюф т <type>
//|+<boolconst>
//|+_<enumconst> BYTE
//|<lbl>([<val>,...]) //call
//|-<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ NEG
//|~<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV
//|!<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ INV(BOOL)
////|<<val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ SHL1
////|><val> //т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ SHR1
//|*(<ptype>)<val> //яЁюўшЄрЄ№ ярь Є№ яю рфЁхёє (т√ўшёышЄ№ val, яюЄюь ёфхырЄ№ PEEK)
//|&<var> //рфЁхё яхЁхьхээющ
 //ъюьрэфр єцх яЁюўшЄрэр
#ifdef USE_HINTS
;;  hintstr("//val: word=\""); hintstr(_tword); hintstr("\", cnext=\""); hint(_cnext); hint('\"'); endhint();
#endif
  //_t = _T_UNKNOWN; //debug (шэрўх ьюцхЄ т√ыхЄхЄ№ чр ЄрсышЎє typesz яЁш юсЁ√тх Їрщыр)
  //IF ( !_waseof )
  { //чр∙шЄр юЄ чрЎшъыштрэш  т ъюэЎх ю°шсюўэюую Їрщыр (ЄхяхЁ№ т ЁхъєЁёштэ√ї т√чютрї)
    _opsym = *(PCHAR)_tword;
    IF (_opsym == '\'') {
      rdquotes('\'');
      rdch(); //фюсрты хь чръЁ√тр■∙є■ ърт√ўъє
      _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
      _lenjoined = strcopy(_tword, _lentword, _joined);
      _t = _T_CHAR; cmdpushnum();
    }ELSE IF (_opsym == '\"') {
      _lenjoined = strcopy(_title, _lentitle, _joined);
      jautonum(_curlbl);
      INC _curlbl;
      //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
      _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;//|+(CHAR)0x20;
      IF (_opsym=='_') { //+_CONSTANT or +__CONSTANT (BYTE)
        //эрўры№эр  ўрёЄ№ шьхэш ъюэёЄрэЄ√ єцх яЁюўшЄрэр
        adddots();
        /**t=*/joinvarname(/**iscall*/+FALSE);
        _lenjoined = strcopy(_name, _lenname, _joined); //уыюсры№эр 
        _t = _T_BYTE; cmdpushnum();
      }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //+num
        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('('/**, "\'(\'"*/);
          _t = eattype();
          //eatexpr(); //эр т√їюфх шч expr єцх яЁюўшЄрэр ')', эю ёыхфє■∙шщ ёшьтюы шыш ъюьрэфр эх яЁюўшЄрэ√
          //eat(')', "\')\'");
//          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)
          _lenjoined = strcopy(_tword, _lentword, _joined); //_lenjoined = strjoin(/**to=*/_joined, 0/**strclear(_joined)*/, _tword/**, _lentword*/);
          //strclose(_joined, _lenjoined);
          _t = _T_BOOL; cmdpushnum(); //(_joined)
        };
      }ELSE { //'(': с√ы typecast
/**        rdword(); //type
        t = eattype();
        eat(')', "\')\'");
        IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
        cmdcastto(t);*/

        //rdword(); //яхЁтюх ёыютю expr
        //eatexpr(); //эр т√їюфх шч expr єцх яЁюўшЄрэр ')', эю ёыхфє■∙шщ ёшьтюы шыш ъюьрэфр эх яЁюўшЄрэ√
        IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
        //IF (_t == _T_UINT) cmdcastto(_T_INT); //фы  чэръют√ї ъюэёЄрэЄ Єшяр +15 (ьх°рхЄ фхырЄ№ +(type)val)
      };
    }ELSE IF ((BYTE)((BYTE)_opsym - (BYTE)'0') < 0x0a) { //num
      numtype(); //_t
      _lenjoined = strcopy(_tword, _lentword, _joined);
      cmdpushnum();
    }ELSE IF (_isalphanum[(BYTE)_opsym] /**|| (_opsym=='.')*/) { //<var> //с√ыю isalpha
      adddots();
     //хёыш т√чют ЇєэъЎшш, Єю do_variable эрфю фхырЄ№ ё namespclvl-1!!!
      IF (_cnext == '(') { //call
        _t = do_call(+TRUE); //isfunc
      }ELSE {
        _t = joinvarname(+FALSE); //iscall
        IF (_cnext == '[') { //<varname>[<idx>]
          rdword(); //'['
          _t = idxarray(_t);
          cmdpeek();
        }ELSE { //<varname>
          IF ((_t&_T_TYPE)==0x00) {
            /**IF (_t==_T_STRUCT) {
              _t = _T_POI|_T_BYTE;
              cmdpushnum(); //схЁ╕ь рфЁхё ёЄЁєъЄєЁ√ (фы  .)
            }ELSE*/
IF ((_t&_T_ARRAY)!=0x00) { //array without [] as a pointer
              _t = _t&(~(_T_ARRAY|_T_CONST))|_T_POI;
              cmdpushnum(); //шёяюы№чютрэшх юс√ўэюую ьрёёштр - схЁ╕ь хую рфЁхё
            }ELSE IF ((_t&_T_CONST)==0x00) {
              cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
            }ELSE { //ъюэёЄрэЄр (equ)
              _t = _t&_TYPEMASK; //&(~_T_CONST);
              cmdpushnum();
            };
          };
        };
      };
    }ELSE IF (_opsym == '(') {
      rdword(); //яхЁтюх ёыютю expr
      eatexpr(); //эр т√їюфх шч expr єцх яЁюўшЄрэр ')', эю ёыхфє■∙шщ ёшьтюы шыш ъюьрэфр эх яЁюўшЄрэ√
      IF ((_t&_T_TYPE)!=0x00) { //(type)val //эхы№ч  т sizeof(expr)
        t = _t&~_T_TYPE;
        _t = t;
        rdword();
        val();
        cmdcastto(t);
      };
    }ELSE IF (_opsym == '-') {
      IF (/**isnum(_cnext)*/(BYTE)((BYTE)_cnext - (BYTE)'0') < 0x0a) { //-<const>
        rdaddword();
        //todo float
        _t = _T_INT;
        _lenjoined = strcopy(_tword, _lentword, _joined);
        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(); //яхЁтюх ёыютю val
      IF (!_waseof) val(); //ЁхъєЁёштэ√щ т√чют val
      cmdinv();
    }ELSE IF (_opsym == '*') {
      rdword(); //'(' of type
      eat('('/**, "\'(\'"*/); //IF (*(PCHAR)_tword != '(') err_tword("\'(\'");
      t = eattype()/**|_T_POI*/; //tpoi //todo PPOINTER
      eat(')'/**, "\')\'"*/); //IF (*(PCHAR)_tword != ')') err_tword("\')\'");
      IF (!_waseof) val(); //чфхё№ Єшя єърчрЄхы  эх трцхэ //ЁхъєЁёштэ√щ т√чют val
      _t = t&~_T_POI; //&~_T_CONST;
      cmdpeek();
    }ELSE IF (_opsym == '&') {
      rdword();
      adddots();
      _t = 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 BYTE 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==')') BREAK; //fast exit
    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 BYTE t1;
{
//<mulval>[<+|-><mulval>...] => push[push<+|->...]
 //ъюьрэфр єцх яЁюўшЄрэр
#ifdef USE_HINTS
;;  hintstr("//sumval"); endhint();
#endif
  eatmulval();
  REPEAT {
    opsym = *(PCHAR)_tword;
    //IF (opsym==')') BREAK; //fast exit
    IF (opsym!='+')
      IF (opsym!='-')
        IF (opsym!='|')
          IF (opsym!='^')
            BREAK;
    t1 = _t;
    rdword();
    IF (*(PCHAR)_tword=='>') { //structinstancepointer->structfield
      //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр, Єшя _t = эхъшщ єърчрЄхы№
      gettypename(); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined
      rdword(); //use '>'
      jdot();
      _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword); //structname.structfield
      _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
      //_t = _T_POI|_T_BYTE; //Єшя єцх - эхъшщ єърчрЄхы№
      cmdpushnum(); //structname.structfield
      cmdadd();
      _lenname = strcopy(_joined, _lenjoined, _name); //structname.structfield
      _t = lbltype(); //(_name)
      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 BYTE 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==')') BREAK; //fast exit
    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;
#ifdef USE_HINTS
;;  hinttype("end expr",_t);
;;  hint_tword();
#endif
}
}

PROC eatpoke()
//poke*(<ptype>)(<pointerexpr>)=<expr>
{
VAR BYTE t;
#ifdef USE_HINTS
;;  hintstr("//poke"); endhint();
#endif
  _exprlvl = 0x01; //no jump optimization
  eat('*');
  eat('(');
  t = eattype()&(~_T_POI);
  eat(')');
  eat('('); //'=' ьюцхЄ с√Є№ т т√Ёрцхэшш
  eatexpr();
  //todo яЁютхЁшЄ№ pointer
  eat(')'); //'=' ьюцхЄ с√Є№ т т√Ёрцхэшш
  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 BYTE t;
VAR BOOL ispoke;
#ifdef USE_HINTS
;;  hintstr("//let"); endhint();
#endif
  _exprlvl = 0x01; //no jump optimization
  t = joinvarname(/**iscall*/+FALSE); //t!!!
  rdword(); //'['
  ispoke = +FALSE;
  IF (*(PCHAR)_tword/**_cnext*/ == '[') {
    t = idxarray(t); //t = t&(~(_T_ARRAY|_T_POI));
    eat(']');
    ispoke = +TRUE;
  }ELSE {
    WHILE (*(PCHAR)_tword/**_cnext*/ == '-') {
      _t = t;
      IF (ispoke) { //эх яхЁт√щ ->
        cmdpeek();
      }ELSE { //яхЁт√щ ->
        cmdpushvar(); //єърчрЄхы№ (т Єюь ўшёых эр ёЄЁєъЄєЁє) шыш юс√ўэр  яхЁхьхээр 
      };
      eat('-');
      //ёЄЁєъЄєЁр єцх яЁюўшЄрэр ш рфЁхёютрэр, Єшя _t = эхъшщ єърчрЄхы№
      gettypename(); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined
      eat('>'); //rdword(); //use '>'
      jdot();
      _lenjoined = strjoin(/**to=*/_joined, _lenjoined, _tword); //structname.structfield
      _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
      //_t = _T_POI|_T_BYTE; //Єшя єцх - эхъшщ єърчрЄхы№
      cmdpushnum(); //structname.structfield
      cmdadd();
      _lenname = strcopy(_joined, _lenjoined, _name); //structname.structfield
      t = lbltype(); //(_name)
      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>[;]
//; яЁюЄшт ю°шсъш "WHILE (expr);cmd"
/**
LOCAL ;ухэхЁшЁєхЄ єэшъры№э√щ_шфхэЄшЇшърЄюЁ
TEMPWHILE: ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPWHILE
 <єёыютшх>
 jp cc,TEMPEND ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPEND
 <Єхыю>
 jp TEMPWHILE ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPWHILE
TEMPEND: ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPEND ;х∙╕ фы  break
ENDL
*/

{
VAR UINT beglbl;
VAR UINT wasendlbl;
{
#ifdef USE_HINTS
;;  hintstr("//while"); endhint();
#endif
  _exprlvl = 0x00; //jump 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;
  //IF (*(PCHAR)_tword/**_cnext*/ != ';') {errstr("\';\' expected, but we have \'"); err(*(PCHAR)_tword/**_cnext*/); err('\''); enderr();};
#ifdef USE_HINTS
;;  hintstr("//end while"); endhint();
#endif
}
}

PROC eatrepeat RECURSIVE()
//repeat<cmd>until<expr>
/**
LOCAL ;ухэхЁшЁєхЄ єэшъры№э√щ_шфхэЄшЇшърЄюЁ
TEMPREPEAT: ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPREPEAT
 <Єхыю>
 <єёыютшх>
 jp cc,TEMPREPEAT ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPREPEAT
TEMPEND: ;фы  break
ENDL
*/

{
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; //jump 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)
/**
<єёыютшх>
LOCAL ;ухэхЁшЁєхЄ єэшъры№э√щ_шфхэЄшЇшърЄюЁ
 jp cc,TEMPELSE;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPELSE
 <Єхыю then>
[ jp TEMPENDIF ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPENDIF]
TEMPELSE: ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPELSE
 <Єхыю else>
TEMPENDIF: ;¤ътштрыхэЄэю єэшъры№э√щ_шфхэЄшЇшърЄюЁ.TEMPENDIF
ENDL
*/

{
VAR UINT elselbl;
VAR UINT endiflbl;
{
#ifdef USE_HINTS
;;  hintstr("//if"); endhint();
#endif
  _exprlvl = 0x00; //jump optimization possible
  elselbl = _curlbl; INC _curlbl;
  endiflbl = _curlbl; INC _curlbl;
  eat('(');
  eatexpr(); //parentheses not included
  genjplbl(elselbl); cmdjpiffalse();
  eat(')'); //rdword();
  eatcmd(); //Єхыю then
  IF (*(PCHAR)_tword/**_cnext*/ != ';'/**"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/**_cnext*/ != ';'/**"endif"*/) { errstr( "\';\' expected, but we have \'"); err(*(PCHAR)_tword/**_cnext*/); 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 jump 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
 //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  adddots(); //фюўшЄрЄ№ шь 
  _t = joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
  cmdinc();
  rdword();
}

PROC eatdec()
{
#ifdef USE_HINTS
;;  hintstr("//dec"); endhint();
#endif
 //эрўры№эр  ўрёЄ№ шьхэш яхЁхьхээющ єцх яЁюўшЄрэр
  adddots(); //фюўшЄрЄ№ шь 
  _t = joinvarname(/**iscall*/+FALSE); //doprefix(_namespclvl); //prefix:=title[FIRST to...];
  cmddec();
  rdword();
}

PROC var_num(BYTE t, PCHAR s)
{
VAR BYTE tmasked = t&(~_T_ARRAY);
/**  IF ( (t&_T_POI)!=0x00 ) { //шёяюы№чєхЄё  фы  ёЄЁюъ (эхы№ч  equ)
    varstr_tword(); //DB "str"
  }ELSE*/
IF ( (t&_T_CONST)!=0x00 ) {
    varstr(_title/**_joined*/); varc( '=' ); varstr(s); endvar();
  }ELSE {
    IF (t==tmasked/**(t&_T_ARRAY)==0x00*/) {
      varstr(_joined); /**varc( ':' );*/ endvar();
    };
    var_def(tmasked, s);
  };
}

//TODO т√Ёрцхэш (юЄфрЄ№ рёьє?) + ЄрсышЎє ъюэёЄрэЄ т ъюьяшы ЄюЁх?
//эрфю ъръ ьшэшьєь &funcname, &structinstancename, (c1+c2 ЁрсюЄрхЄ ўхЁхч рёь)
PROC do_const_num(BYTE 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>
    rdword(); //шёяюы№чютрЄ№ &, яЁюўшЄрЄ№ эрўрыю шьхэш
    adddots(); //фюўшЄрЄ№ шь 
    var_num(_T_ARRAY|_T_UINT, _tword); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
  }ELSE IF (*(PCHAR)_tword == '\"') {
    IF ((t&_T_ARRAY)!=0x00) { //ёЄЁюър тэєЄЁш ьрёёштр
      _lenjoined = strcopy(_title, _lentitle, _joined);
      jdot();
      jautonum(_curlbl);
      INC _curlbl;
      //_joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
      var_num(_T_ARRAY|_T_UINT, _joined); //_T_ARRAY эх фр╕Є ёючфрЄ№ ьхЄъє
    };
    asmstrz(); //ё ьхЄъющ title //ъюёЄ√ы№ тьхёЄю varstrz
  }ELSE var_num(t, _tword);
}

PROC eatextern()
//extern<type><variable>[<[><expr><]>]
{
VAR BYTE t;
#ifdef USE_HINTS
;;  hintstr("//extern"); endhint();
#endif
  _exprlvl = 0x01; //no jump optimization
  t = eatvarname(); //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _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, /**islocal*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр (ёЄЁєъЄєЁ√ эх с√тр■Є extern?)!
#ifdef USE_HINTS
;;  hintstr("//end extern"); endhint();
#endif
}

PROC eatvar(BOOL ispar, BOOL body) //хёыш var, Єю body==+TRUE, шэрўх body==!forward
//var<type><variable>[<[><expr><]>][=<expr>]
//шыш т ярЁрьхЄЁрї яЁш юс· тыхэшш ЇєэъЎшш <type><variable>
{
VAR BYTE t;
#ifdef USE_HINTS
;;  hintstr("//var"); endhint();
#endif
  _exprlvl = 0x01; //no jump optimization
  t = eatvarname(); //схч ёЁєсрэш  тыюцхээюёЄхщ яю _ (ёючфр╕Є _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, /**islocal*/(_namespclvl!=0x00), (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  IF (ispar) { //parameter of func/proc
    IF (body) {
      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, /**islocal*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, "0", _lenncells*/); //юЄьхЄшыш т ЄрсышЎх, ўЄю эх т√фхы Є№ ярь Є№ //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  };
  IF (body) {
    IF ((t&_T_ARRAY)!=0x00) {
      varstr(_joined); /**varc( ':' );*/ endvar();
      varstr( "\tDS " ); varuint((UINT)_typesz[t&_TYPEMASK]); varc('*'); varstr(_ncells); endvar();
    }ELSE {
      var_num(t, "0");
    };
    doexp(_joined);
  };
  IF (*(PCHAR)_tword == '=') {
    rdword(); //'='
    //TODO яЁютхЁшЄ№, ўЄю ь√ тэєЄЁш ЇєэъЎшш (эхЁхъєЁёштэющ!)
   strpush(_joined,_lenjoined);
    eatexpr();
   _lenjoined = strpop(_joined);
    IF ( (t!=_t) && !( ((t&_T_POI)!=0x00) && (/**(texpr==_T_UINT)||*/((_t&_T_POI)!=0x00)) ) ) {errstr("let variable="); errstr(_joined); errstr(" type="); erruint((UINT)t); errstr(", but expr type="); erruint((UINT)_t); enderr(); };
    //_t = t; //todo яЁютхЁшЄ№
    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 BYTE t;
VAR UINT i = 0;
#ifdef USE_HINTS
;;  hintstr("//const"); endhint();
#endif
  _exprlvl = 0x01; //no jump optimization
  t = eattype()|_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); //шь  ъюэёЄрэЄ√
  gettypename(); //тч Є№ эрчтрэшх Єшяр ёЄЁєъЄєЁ√ т joined (ёЁрчє яюёых lbltype)
  _lencallee = strcopy(_joined, _lenjoined, _callee);

  //n ="1";
  //_lenncells=strclear(_ncells); //n ="";
  //_lenncells=stradd(_ncells, _lenncells, '1'); //n = n + '1';
  //strclose(_ncells, _lenncells);
  //IF (_cnext == '[') { //[size]
  //  t = t|_T_ARRAY;
  //};

  //title ёюфхЁцшЄ шь  ъюэёЄрэЄ√
  addlbl(t, /**islocal*/+FALSE, (UINT)_typesz[t&_TYPEMASK]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
  WHILE (*(PCHAR)_tword == '[') { //[size]
    //rdbrackets(); //_tword='['
    _lentword = 0; //strclear(_tword); //ўшЄрхь ё яєёЄющ ёЄЁюъш
    rdquotes(']');
    rdch(); //яЁюяєёЄшЄ№ ']'
    rdword();
  };
  IF (*(PCHAR)_tword == '=') {
    rdword(); //num or '{'
    IF (*(PCHAR)_tword == '{') { //array or struct
      varstr(_title/**_joined*/); /**varc( ':' );*/ endvar();
      doexp(_title); //эрфю ыш ¤ъёяюЁЄшЁютрЄ№ ъюэёЄрэЄ√? Єюы№ъю ъюэёЄрэЄэ√х ьрёёшт√/ёЄЁєъЄєЁ√
      REPEAT{
        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 эх фр╕Є ёючфрЄ№ ьхЄъє
          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, BYTE 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 ) {
    _curfunct = eattype();
  }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, /**islocal*/+FALSE, 0/**, _ncells"0", 1*/); //(_name) //todo т√ ёэшЄ№, яюўхьє эхы№ч  if (!isforward)
  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);
    IF (*(PCHAR)_tword == ')') BREAK; //шэрўх ','
    rdword(); //type or ')'
  };
  rdword();

  keepvars();

  IF (!isforward) {
    eatcmd(); //Єхыю ЇєэъЎшш
    _t = _curfunct&(~_T_RECURSIVE);
    cmdendfunc(isfunc);
    IF (isfunc && !_wasreturn) {errstr("return expected"); enderr(); };
#ifdef USE_HINTS
;;    hintstr(";/////end func"); endhint();
#endif
  };

  undovars();

  DEC _namespclvl; doprefix(_namespclvl); _lentitle=strcopy(_prefix,_lenprefix,_title);/**title =prefix;*/ //юЄЁхчрхь фюсртыхээюх ёыютю
  _curfunct = oldfunct; //тючтЁрЄшЄ№ тэх°эшщ Єшя ЇєэъЎшш
  _wasreturn = oldwasreturn; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"
  _isexp = +FALSE;
}

PROC do_callpar RECURSIVE(BYTE funct, UINT parnum)
{
VAR BYTE 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)!=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)!=0x00/**isstacked*/) {
      _t = t;
      cmdpoppar(); //(_joined)
    };
  }ELSE {
    _t = funct&(~_T_RECURSIVE);
    cmdcall();
  };
#ifdef USE_HINTS
;;  hintstr("//end call_par"); endhint();
#endif
}
}

FUNC BYTE do_call RECURSIVE(BOOL isfunc)
//<lbl>([recursive][(<type>)<val>,...])
{
VAR BYTE t;
{
  INC _exprlvl; //no jump optimization
  t = joinvarname(/**iscall*/+TRUE);
  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(); //фюўшЄрЄ№ шь 
  _t = 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>,<constname1>...}
{
VAR UINT i = 0;
  //rdword(); //'{'
  WHILE (!_waseof) {
    rdword(); //ьхЄър
    varstr(_tword); /**varc('.');*/ varc('='); varuint(i); endvar();
    rdword(); //',' шыш '}'
    IF (*(PCHAR)_tword!=',') BREAK;
    INC i;
  };
  rdword();
}

PROC eatstruct()
//struct<name>{<type1><field1>[;]<type2><field2>[;]...}
{
VAR UINT shift = 0;
VAR UINT varszaddr;
VAR UINT i = 0;
  _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, /**islocal*/+FALSE, 0/**, "0", _lenncells*/); //(_name) //яЁхфтрЁшЄхы№эю ёючфрыш, ўЄюс√ ёё√ырЄ№ё 
  varszaddr = _varszaddr;

  _lentitle = stradd(_title, _lentitle, '.');
  _title[_lentitle] = '\0'; //strclose(_title, _lentitle);
  INC _namespclvl; //фюсрты хь ёыютю ъ title
  rdword(); //шёяюы№чютрыш шь 
  eat('{');

  WHILE (!_waseof) {
    //rdword(); //Єшя
    _t = eattype(); //шёяюы№чютрыш Єшя

    //rdword(); //ьхЄър
    jtitletword();
    //asmstr(_joined); asmc('='); asmuint(shift); endasm();
    varstr(_joined); varc('='); varuint(shift); endvar();
    _lenname = strcopy(_joined, _lenjoined, _name);
    addlbl(_t, /**islocal*/+FALSE, (UINT)_typesz[_t&_TYPEMASK]/**, "0", _lenncells*/); //(_name)

    genjplbl(i);
    _lenname = strcopy(_joined, _lenjoined, _name);
    addlbl(_t, /**islocal*/+FALSE, (UINT)_typesz[_t&_TYPEMASK]/**, "0", _lenncells*/); //ртЄюэєьхЁютрээр  (_name)
    INC i;

    shift = shift + (UINT)_typesz[_t&_TYPEMASK];

    rdword(); //Єшя шыш ';' шыш '}' //шёяюы№чютрыш ьхЄъє
    IF (*(PCHAR)_tword==';') rdword(); //Єшя
    IF (*(PCHAR)_tword=='}') BREAK;
  };

  //_lenname = strpop(_name);
  //addlbl(_T_STRUCT|_T_TYPE, /**islocal*/+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(); //фюўшЄрЄ№ шь 
  _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 (_cnext=='[') { //let []
      eatlet();
    }ELSE IF (_cnext=='-') { //let ->
      eatlet();
    }ELSE IF ( (_cnext=='(') && (_spcsize==0) ) { //call
      do_call(/**isfunc*/+FALSE); rdword();
    }ELSE IF ( _cnext==':' ) { //lbl
      eatlbl();
    }ELSE {
      IF (_c0==';') {
        rdword(); //C compatibility
      }ELSE IF (_c0=='{') {
        rdword(); WHILE (eatcmd()) {};
      }ELSE {
        _c0 = (CHAR)((BYTE)_c0|0x20);
        _c2 = (CHAR)((BYTE)_tword[2]|0x20);
        IF       (_c0=='v') { //var
          rdword(); eatvar(/**ispar*/+FALSE, /**body*/+TRUE);
          _isexp = +FALSE; //эхы№ч  тэєЄЁ№, шэрўх эх ¤ъёяюЁЄшЁє■Єё  ярЁрьхЄЁ√ яЁюЎхфєЁ√
        }ELSE IF (_c0=='e') { //enum //extern //export
          IF (_c2=='t') { //extern
            rdword(); eatextern();
          }ELSE IF (_c2=='p') { //export
            rdword(); _isexp = +TRUE;
          }ELSE { //enum
            rdword(); eatenum();
          };
        }ELSE 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=='f') { //func
          rdword(); eatfunc(+TRUE, _curfunct, _wasreturn);
        }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=='w' ) { //while
          rdword(); eatwhile();
        }ELSE IF ( _c0=='b' ) { //break
          rdword(); eatbreak(); //no parameters (rds nothing)
        }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=='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();
          _t = eattype();
          _lenname = strcopy(_tword, _lentword, _name);
          addlbl(_T_TYPE + _t, /**islocal*/+FALSE, (UINT)_typesz[_t]);
          rdword(); //шёяюы№чютрыш шь 
        }ELSE IF ( _c0=='#' ) { //define, include... (ё■фр яюярфрхь фрцх т эхръЄштэ√ї тхЄърї єёыютэющ ъюьяшы Ўшш)
          rdword(); //define, undef, include, if, else, [elif], ifdef, ifndef, endif, [import], [line], [error], [pragma]
//todo ъръ ьюцэю ёфхырЄ№ тыюцхээє■ єёыютэє■ ъюьяшы Ўш■:
//_doskipcond т сшЄютюь тшфх яюьэшЄ, ёъюы№ъю єЁютэхщ ръЄштэ√ї ifdef ш ёъюы№ъю єЁютэхщ эхръЄштэ√ї (ъЁюьх Єхъє∙хую)
//(тэєЄЁш эхръЄштэюую ьюуєЄ с√Є№ Єюы№ъю эхръЄштэ√х)
//хёыш (_doskipcond&1) == 0 (Є.х. ь√ т эхръЄштэющ тхЄъх), Єю Єхъє∙шщ ifdef шуэюЁшЁєхЄё  ёю тёхьш тїюф ∙шьш (Є.х. else эх ЁрсюЄрхЄ)
//эхръЄштэюёЄ№ Єхъє∙хщ тхЄъш ifdef ыхцшЄ т _doskip
//эр тхЁїэхь єЁютэх _doskipcond = 1, _doskip = +FALSE
//хёыш ifdef, Єю:
  //_doskipcond = _doskipcond+_doskipcond
  //хёыш !_doskip, Єю:
    //хёыш ifdef уюфхэ, Єю INC _doskipcond
    //шэрўх _doskip = +TRUE
//хёыш else ш ((_doskipcond&1) == 0), Єю _doskip = !_doskip
//хёыш endif, Єю _doskip = ((_doskipcond&1) == 0); _doskipcond = _doskipcond>>1
          IF ((_tword[2] == '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 (_tword[2] == 'd') { //ifdef/endif/undef
            IF (*(PCHAR)_tword == 'e') { //endif
              _doskip = +FALSE; //todo тыюцхээюёЄ№ (яюфёў╕Є ўшёыр шЇют)
            }ELSE IF (*(PCHAR)_tword == 'i') { //ifdef
              rdword(); //шь 
              _lenname = strcopy(_tword, _lentword, _name);
              _t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
              IF (_t == _T_UNKNOWN) { //эхЄ ьхЄъш - яЁюяєёЄшЄ№ Єхыю
                _doskip = +TRUE; //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
              };
            }ELSE { //undef
              rdword(); //шь 
              _lenname = strcopy(_tword, _lentword, _name);
              dellbl();
            };
          }ELSE IF (_tword[2] == 'n') { //ifndef
              rdword(); //шь 
              _lenname = strcopy(_tword, _lentword, _name);
              _t = lbltype(); //хёыш эхЄє, Єю _T_UNKNOWN
              IF (_t != _T_UNKNOWN) { //хёЄ№ ьхЄър - яЁюяєёЄшЄ№ Єхыю
                _doskip = +TRUE; //тъы■ўшЄ№ яЁюяєёъ ёЄЁюъ, ъЁюьх эрўшэр■∙шїё  ё #, р чфхё№ юсЁрсрЄ√трЄ№ Єюы№ъю шї
              };
          }ELSE IF (_tword[2] == 's') { //else
            _doskip = !_doskip;
          }ELSE IF ((_tword[2] == 'f')&&(!_doskip)) { //define
            rdword(); //шь 
            _lenjoined = strcopy(_tword, _lentword, _joined);
            rdword();
            IF (*(PCHAR)_tword == '(') { //TODO ¤Єє ъюэёЄЁєъЎш■ яЁшьхэшЄ№ ш т const
              rdword(); //eat('(');
              eattype(); //_t
              eat(')');
              //eat('(');
              rdquotes(')');
              rdch(); //фюсрты хь чръЁ√тр■∙є■ ёъюсъє
              _tword[_lentword] = '\0'; //strclose(_tword, _lentword);
            }ELSE {
              //rdword(); //чэрўхэшх
              numtype(); //_t
            };
            _lenname = strcopy(_joined, _lenjoined, _name);
            addlbl(_t|_T_CONST, /**islocal*/+FALSE, (UINT)_typesz[_t/**&_TYPEMASK*/]/**, _ncells, _lenncells*/); //(_name) //TODO ЁрчьхЁ ьрёёштр шыш ёЄЁєъЄєЁ√!
            varstr(_name/**_joined*/); varc( '=' ); varstr(_tword); endvar();
          };

          //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");
  _waseof = +FALSE;

  _curline = 1;
  initrd();
  rdword();

  WHILE (eatcmd()) {};

  fclose(_fin);
}

PROC zxc(CHAR cd)
{
}

PROC compile(PCHAR fn)
{
VAR BYTE cd;
  _prefix = _s1; //чряюыэ хЄё  т doprefix: module/func/const/var/extern - ыюъры№эю, joinvarname
  _title  = (PCHAR)_s2;
  _callee = (PCHAR)_s3;
  _name   = (PCHAR)_s4;
  _joined = (PCHAR)_s5;
  _ncells = (PCHAR)_s6;

  _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("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", 5, _name);
  //addlbl(_T_TYPE + _T_POI + _T_FLOAT, +FALSE, (UINT)_typesz[_T_POI]);
//  _lenname = strcopy("POINTER", 7, _name);
//  addlbl(_T_TYPE + _T_POI, +FALSE);
  //_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 (фы  тыюцхээ√ї т√ўшёыхэшщ Єюцх эхы№ч )

  initcmd();
  initcode(); //т√ч√трхЄ emitregs

  _isexp = +FALSE;
  _curfunct = _T_UNKNOWN; //эр тё ъшщ ёыєўрщ
  _wasreturn = +FALSE; //ёсЁюёшЄ№ яЁютхЁъє "юяхЁрЄюЁ яюёых return"

   _lenjoined = strjoineol(_joined, 0, fn, '.');
   _lenjoined = strjoin(_joined, _lenjoined, ".asm");
   _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  _fout = openwrite(_joined);

   _lenjoined = strjoineol(_joined, 0, fn, '.');
   _lenjoined = strjoin(_joined, _lenjoined, ".var");
   _joined[_lenjoined] = '\0'; //strclose(_joined, _lenjoined);
  _fvar = openwrite(_joined);

  _nhinclfiles = 0x00;

  compfile(fn);

  fclose(_fvar);
  fclose(_fout);
}