U0 ParseVarInit(CCompCtrl *cc, U8 **_dst, CHashClass *tmpc, CArrayDim *tmpad,
                U8 *data_addr_rip, U8 **_base, Bool data_heap, I64 pass)
{
    U8                  *dst = *_dst, *machine_code;
    I64                  i, j, r, old_flags, type, size;
    CMemberList         *tmpm;
    CIntermediateCode   *tmpi;
    CAOTCtrl            *aotc = cc->aotc;
    CAOTAbsAddr         *tmpa;
    CAOTImportExport    *tmpie;
    Bool                 is_str;

    tmpc = OptClassFwd(tmpc);
    if (tmpm = tmpc->member_list_and_root)
    {
        if (cc->token != '{')
            LexExcept(cc, "Expecting '{' at ");
        LexPopNoRestore(cc);
        LexPush(cc);
        Lex(cc);
        while (tmpm)
        {
            ParseVarInit2(cc, &dst, tmpm->member_class, &tmpm->dim, data_addr_rip, _base, data_heap, pass);
            if (cc->token == ',')
                Lex(cc);
            tmpm = tmpm->next;
        }
        LexPopNoRestore(cc);
        if (cc->token != '}')
            LexExcept(cc, "Missing '}' at ");
        Lex(cc);
    }
    else
    {
        if (tmpc->ptr_stars_count == 1 && ((tmpc - 1)->raw_type == RT_I8 || (tmpc - 1)->raw_type == RT_U8) && !tmpad &&
                cc->token == TK_STR)
            is_str = TRUE;
        else
            is_str = FALSE;
        if (cc->flags & CCF_AOT_COMPILE && is_str)
        {
            LexPopNoRestore(cc);
            machine_code = LexExtStr(cc, &i);
            if (pass == 2)
            {
                tmpa = CAlloc(sizeof(CAOTAbsAddr));
                tmpa->next = aotc->abss;
                tmpa->type = AAT_ADD_U64;
                aotc->abss = tmpa;
                tmpa->rip = data_addr_rip + dst - *_base;
                *dst(I64 *) = aotc->rip;
                for (j = 0; j < i; j++)
                    AOTStoreCodeU8(cc, machine_code[j]);
            }
            Free(machine_code);
        }
        else
        {
            old_flags = cc->flags;
            cc->flags = CCF_NO_ABSS | cc->flags & ~(CCF_AOT_COMPILE | CCF_HAS_MISC_DATA | CCF_NOT_CONST);
            machine_code = LexExpression2Bin(cc, &type);
            if (old_flags & CCF_AOT_COMPILE && cc->flags & CCF_NOT_CONST && !Bt(&cc->opts, OPTf_GLOBALS_ON_DATA_HEAP))
            {
                cc->flags = cc->flags & ~CCF_NO_ABSS | CCF_AOT_COMPILE;
                Free(machine_code);
                if (pass == 2)
                {
                    MemSet(dst, 0, tmpc->size);
                    LexPopRestore(cc);
                    Lex(cc);
                    COCPush(cc);
                    COCInit(cc);
                    ICAdd(cc, IC_ABS_ADDR, data_addr_rip, tmpc + 1);
                    ICAdd(cc, IC_IMM_I64, dst - *_base, tmpc + 1);
                    ICAdd(cc, IC_ADD, 0, tmpc + 1);
                    if (!ParseExpression(cc, NULL, TRUE))
                        throw('Compiler');
                    tmpi = cc->coc.coc_head.last;
                    if (tmpi->ic_code == IC_END_EXP) {
                        tmpi->ic_code = IC_NOP1;
                        tmpi->ic_flags = 0;
                    }
                    ICAdd(cc, IC_ASSIGN, 0, tmpc);
                    ICAdd(cc, IC_END_EXP, 0, tmpc, ICF_RES_NOT_USED);
                    ICAdd(cc, IC_RET, 0, 0);
                    if (machine_code = COCCompile(cc, &size, NULL, NULL))
                    {
                        tmpie = CAlloc(sizeof(CAOTImportExport));
                        tmpie->type = IET_MAIN;
                        tmpie->rip = cc->aotc->rip;
                        QueueInsert(tmpie, cc->aot->last_ie);
                        for (i = 0; i < size; i++)
                            AOTStoreCodeU8(cc, machine_code[i]);
                        Free(machine_code);
                    }
                    COCPop(cc);
                }
                else
                    LexPopNoRestore(cc);
            }
            else
            {
                LexPopNoRestore(cc);
                if (!machine_code)
                    throw('Compiler');
                r = Call(machine_code);
                if (!(cc->flags & CCF_HAS_MISC_DATA) || pass == 1)
                    Free(machine_code);

                if (type == RT_F64 && tmpc->raw_type != RT_F64)
                    r = r(F64);
                else if (type != RT_F64 && tmpc->raw_type == RT_F64)
                    r(F64) = r;
                MemCopy(dst, &r, tmpc->size);
            }
        }
        dst += tmpc->size;
        cc->flags = cc->flags & ~CCF_NO_ABSS | old_flags & (CCF_HAS_MISC_DATA | CCF_AOT_COMPILE);
    }
    *_dst = dst;
}

class CVI2
{
    CVI2 *next, *last;
    U0    base;
};

U0 ParseVarInit2(CCompCtrl *cc, U8 **_dst, CHashClass *tmpc, CArrayDim *tmpad,
                 U8 *data_addr_rip, U8 **_base, Bool data_heap, I64 pass)
{
    I64          i, j, count;
    U8          *st, *_b;
    CVI2         head, *tmpvi, *tmpvi1;
    CArrayDim   *tmpad1;

    tmpc = OptClassFwd(tmpc);
    if (tmpad1 = tmpad->next)
    {
        if (!tmpc->ptr_stars_count && (tmpc->raw_type == RT_I8 || tmpc->raw_type == RT_U8) && cc->token == TK_STR)
        {
            LexPopNoRestore(cc);
            st = LexExtStr(cc,&i);
            if (tmpad1->count < 0)
            {//[]
                tmpad1->count = i;
                tmpad->total_count = i * tmpad1->total_count;
                Free(*_base);
                if (data_heap)
                    *_base = MAlloc(i);
                else
                    *_base = MAlloc(i, Fs->code_heap);
                MemCopy(*_base, st, i);
                *_dst = *_base + i;
            }
            else
            {
                MemCopy(*_dst, st, tmpad1->count);
                *_dst += tmpad1->count;
            }
            Free(st);
            LexPush(cc);
        }
        else
        {
            if (cc->token == '{')
            {
                LexPopNoRestore(cc);
                LexPush(cc);
                Lex(cc);
            }
            if (tmpad1->count < 0)
            {//[]
                QueueInit(&head);
                count = 0;
                while (cc->token != '}')
                {
                    tmpvi = MAlloc(offset(CVI2.base) + tmpad1->total_count * tmpc->size);
                    _b = &tmpvi->base;
                    ParseVarInit2(cc, &_b, tmpc, tmpad1, data_addr_rip, _base, data_heap, pass);
                    QueueInsert(tmpvi, head.last);
                    if (cc->token == ',')
                        Lex(cc);
                    count++;
                }
                Lex(cc); //skip '}'
                tmpad1->count = count;
                tmpad->total_count = count * tmpad1->total_count;
                j = tmpad1->total_count * tmpc->size;
                i = count * j;
                Free(*_base);
                if (data_heap)
                    *_base = _b = MAlloc(i);
                else
                    *_base = _b = MAlloc(i, Fs->code_heap);
                tmpvi = head.next;
                while (tmpvi != &head)
                {
                    tmpvi1 = tmpvi->next;
                    MemCopy(_b, &tmpvi->base, j);
                    _b += j;
                    Free(tmpvi);
                    tmpvi = tmpvi1;
                }
                *_dst = _b;
            }
            else
            {
                for (i = 0; i < tmpad1->count; i++)
                {
                    ParseVarInit2(cc, _dst, tmpc, tmpad1, data_addr_rip, _base, data_heap, pass);
                    if (tmpad1->count > 1 && cc->token == ',')
                        Lex(cc);
                }
                if (cc->token == '}')
                    Lex(cc);
            }
        }
    }
    else
    {
        ParseVarInit(cc, _dst, tmpc, tmpad1, data_addr_rip, _base, data_heap, pass);
        LexPush(cc);
    }
}

U0 ParseGlobalInit(CCompCtrl *cc, CHashGlobalVar *tmpg, I64 pass)
{
    U8 *dst = tmpg->data_addr;

    ParseVarInit2(cc, &dst, tmpg->var_class, &tmpg->dim, tmpg->data_addr_rip, &tmpg->data_addr,
                  Bt(&cc->opts, OPTf_GLOBALS_ON_DATA_HEAP) || Bt(&cc->flags, CCf_AOT_COMPILE), pass);
}

U0 ParseStaticInit(CCompCtrl *cc, CMemberList *tmpm, I64 pass)
{
    U8                  *machine_code, *dst = tmpm->static_data;
    CHashClass          *tmpc = tmpm->member_class;
    I64                  i, size;
    CAOTImportExport    *tmpie;

    if (cc->flags & CCF_AOT_COMPILE && pass == 2)
    {
        COCPush(cc);
        COCInit(cc);
    }
    ParseVarInit2(cc, &dst, tmpc, &tmpm->dim, tmpm->static_data_rip, &tmpm->static_data,
                  Bt(&cc->flags, CCf_AOT_COMPILE), pass);
    if (cc->flags & CCF_AOT_COMPILE && pass == 2)
    {
        if (cc->coc.coc_head.next != &cc->coc.coc_head)
        {
            ICAdd(cc, IC_RET, 0, 0);
            if (machine_code = COCCompile(cc, &size, NULL, NULL))
            {
                if (pass == 2)
                {
                    tmpie = CAlloc(sizeof(CAOTImportExport));
                    tmpie->type = IET_MAIN;
                    tmpie->rip = cc->aotc->rip;
                    QueueInsert(tmpie, cc->aot->last_ie);
                    for (i = 0; i < size; i++)
                        AOTStoreCodeU8(cc, machine_code[i]);
                }
                Free(machine_code);
            }
        } //TODO: else del misc?
        COCPop(cc);
    }
}

U0 ParseArrayDims(CCompCtrl *cc, I64 mode, CArrayDim *dim)
{//dim->next!=0 for array
    CArrayDim   *tmpad, *tmpad1;
    I64          j;

    dim->next = NULL;
    dim->count = 0;
    dim->total_count = 1;
    tmpad1 = &dim->next;
    if (cc->token == '[')
    {
        if (mode.u8[1] == PRS1B_FUN_ARG)
            LexExcept(cc, "No arrays in function args at ");
        do
        {
            if (Lex(cc) == ']' && !dim->next)
                j = 0;
            else
            {
                if ((j = LexExpressionI64(cc)) < 0)
                    LexExcept(cc, "Invalid array size at ");
            }
            tmpad = MAlloc(sizeof(CArrayDim));
            tmpad->next = NULL;
            tmpad1 = &dim;
            do
            {
                tmpad1->total_count *= j;
                if (!tmpad1->next)
                {
                    tmpad1->next = tmpad;
                    break;
                }
                tmpad1 = tmpad1->next;
            }
            while (tmpad1);

            tmpad1 = tmpad;
            tmpad->count = j;
            tmpad->total_count = 1;
            if (cc->token != ']')
                LexExcept(cc, "Missing ']' at ");
        }
        while (Lex(cc) == '[');
    }
}

CHashClass *ParseType(CCompCtrl *cc, CHashClass **_tmpc1, I64 *_mode, CMemberList *tmpm, U8 **_ident, CHashFun **_fun_ptr,
                      CHashExport **_tmpex, CArrayDim *tmpad, I64 fsp_flags)
{
    I64          k, ptr_stars_count, mode = *_mode;
    CHashClass  *tmpc1 = *_tmpc1, *tmpc2;
    CHashFun    *fun_ptr = NULL;
    CHashExport *tmpex = NULL;

    pt_start:
    if (!tmpc1 || !(tmpc1->type & (HTT_CLASS | HTT_INTERNAL_TYPE)))
        LexExcept(cc, "Invalid class at ");

    ptr_stars_count = 0;
    while (cc->token == '*')
    {
        if (mode.u8[1])
        {
            LexPopNoRestore(cc);
            LexPush(cc);
        }
        Lex(cc);
        tmpc1++;
        if (++ptr_stars_count > PTR_STARS_NUM)
            LexExcept(cc, "Too many *'s at ");
    }

    k = ParseKeyWord(cc);
    if (k == KW_UNION || k == KW_CLASS)
    {
        Lex(cc);
        tmpc2 = ParseClass(cc, k, fsp_flags, mode & 255 == PRS0_EXTERN);
        tmpc2->fwd_class = tmpc1;
        tmpc1 = tmpc2;
        if (_tmpc1)
            *_tmpc1 = tmpc1;
        mode = PRS0_NULL|PRS1_NULL;
        goto pt_start;
    }

    if (cc->token == '(')
    {
        if (Lex(cc) != '*')
            LexExcept(cc, "Expecting '*' at ");
        ptr_stars_count = 1; //fun_ptr
        while (Lex(cc) == '*')
            ptr_stars_count++; //fun_ptr
        if (ptr_stars_count > PTR_STARS_NUM)
            LexExcept(cc, "Too many *'s at ");
    }
    else
        ptr_stars_count = -1; //fun_ptr

    if (_ident)
    {
        if (cc->token == TK_IDENT)
        {
            tmpex = cc->hash_entry;
            *_ident = cc->cur_str;
            cc->cur_str = NULL;
            Lex(cc);
        }
        else
        {
            if (!mode.u8[1])
                *_ident = NULL;
            else if (cc->token == ',' || cc->token == ';' || cc->token == ')')
            {
                tmpex = NULL;
                *_ident = StrNew("_anon_");
                tmpm->flags |= MLF_NO_UNUSED_WARN;
            }
            else
                LexExcept(cc, "Expecting identifier at ");
        }
    }

    if (ptr_stars_count >= 0)
    { //fun_ptr
        if (cc->token != ')')
            LexExcept(cc, "Missing ')' at ");
        if (Lex(cc) != '(')
            LexExcept(cc, "Expecting '(' at ");
        fun_ptr = ParseFunJoin(cc, tmpc1, NULL, fsp_flags) + ptr_stars_count;
        tmpc1 = cmp.internal_types[RT_PTR] + ptr_stars_count;
    }
    ParseArrayDims(cc, mode, tmpad);

    tmpc2 = OptClassFwd(tmpc1);
    if (tmpc2->ptr_stars_count)
    {
        tmpc2 -= tmpc2->ptr_stars_count;
        if (tmpc2->type & HTT_INTERNAL_TYPE && !tmpc2->size)
            LexWarn(cc, "use \"U8 *\" instead of \"U0 *\" at ");
    }

    if (_mode)
        *_mode = mode;
    if (_fun_ptr)
        *_fun_ptr = fun_ptr;
    if (_tmpex)
        *_tmpex = tmpex;

    return tmpc1;
}

U0 ParseDotDotDot(CCompCtrl *cc, CHashFun *tmpf, I64 _reg)
{
    CMemberList *tmpm;
    CArrayDim   *tmpad;

    Bts(&tmpf->flags, Ff_DOT_DOT_DOT);

    Lex(cc);
    tmpm = MemberListNew(_reg);
    tmpm->flags = MLF_DOT_DOT_DOT;
    tmpm->member_class = cmp.internal_types[RT_I64];
    tmpm->str = StrNew("argc");
    tmpm->offset = tmpf->size;
    tmpm->size = 8;
    tmpf->size += 8;
    MemberAdd(cc, tmpm, tmpf, PRS1B_FUN_ARG);

    tmpm = MemberListNew(_reg);
    tmpm->flags = MLF_DOT_DOT_DOT;
    tmpm->member_class = cmp.internal_types[RT_I64];
    tmpm->str = StrNew("argv");
    tmpm->dim.total_count = 127; //arbitrary
    tmpm->dim.next = tmpad = MAlloc(sizeof(CArrayDim));
    tmpad->next = NULL;
    tmpad->count = 127; //arbitrary
    tmpad->total_count = 1;
    tmpm->offset = tmpf->size;
    tmpm->size = 8; //Close enough
    tmpf->size += 8;//Close enough
    MemberAdd(cc, tmpm, tmpf, PRS1B_FUN_ARG);

    if (cc->token == ')')
        Lex(cc);
}

U0 ParseVarList(CCompCtrl *cc, CHashClass *tmpc, I64 mode, I64 union_base=0)
{
    I64              i, k, old_flags = cc->flags, old_flags2, type, _reg;
    CHashClass      *tmpc1, *tmpc2;
    CHash           *tmph;
    CMemberList     *tmpm;
    CMemberListMeta *tmp_meta;
    U8              *machine_code;
    Bool             undef_array_size, first;

    cc->flags |= CCF_DONT_MAKE_RES;
    if (mode.u8[1] == PRS1B_CLASS)
        cc->flags |= CCF_CLASS_DOL_OFFSET;
    if ((mode.u8[1] != PRS1B_LOCAL_VAR && mode.u8[1] != PRS1B_STATIC_LOCAL_VAR || mode & PRSF_UNION) &&
            (cc->token == '(' || cc->token == '{'))
        Lex(cc);
    while (TRUE)
    {
        if (mode & PRSF_UNION)
            cc->class_dol_offset = union_base;
        else
            cc->class_dol_offset = tmpc->size;
        while (cc->token == ';')
            Lex(cc);
        while (cc->token == '$') {
            if (Lex(cc) != '=') //skip $
                LexExcept(cc, "Expecting '=' at ");
            Lex(cc); //skip =
            cc->class_dol_offset = LexExpression(cc);
            if (-cc->class_dol_offset > tmpc->neg_offset)
                tmpc->neg_offset = -cc->class_dol_offset;
            if (mode & PRSF_UNION)
                union_base = cc->class_dol_offset;
            else
                tmpc->size = cc->class_dol_offset;
            if (cc->token != ';')
                LexExcept(cc, "Missing ';' at");
            Lex(cc); //skip ;
        }
        if (cc->token == ')' || cc->token == '}')
        {
            Lex(cc);
            goto pvl_done;
        }
        _reg = REG_UNDEF;
pvl_restart1:
        switch (ParseKeyWord(cc))
        {
            case KW_REG:
                _reg = REG_ALLOC;
                if (Lex(cc) == TK_IDENT)
                {
                    k = DefineMatch(cc->cur_str, "ST_U64_REGS");
                    if (k >= 0)
                    {
                        _reg = k;
                        Lex(cc);
                    }
                }
                goto pvl_restart1;

            case KW_NOREG:
                _reg = REG_NONE;
                Lex(cc);
                goto pvl_restart1;
        }

        if (cc->token == TK_ELLIPSIS && mode.u8[1] == PRS1B_FUN_ARG)
        {
            ParseDotDotDot(cc, tmpc, _reg);
            goto pvl_done;
        }
        if (cc->token == TK_IDENT)
            tmph = cc->hash_entry;
        else
            tmph = NULL;
        if (!tmph)
            LexExcept(cc, "Expecting type at ");
        k = ParseKeyWord(cc);
        if (k == KW_UNION)
        {
            Lex(cc);
            ParseVarList(cc, tmpc, mode | PRSF_UNION, tmpc->size);
        }
        else
        {
            if (!(tmph->type & (HTT_CLASS | HTT_INTERNAL_TYPE)))
                LexExcept(cc, "Expecting type at ");
            first = TRUE;
pvl_restart2:
            tmpc1 = tmph;
            LexPush(cc);
            Lex(cc); //skip type or ','
            tmpm = MemberListNew(_reg);
            _reg = REG_UNDEF;
            if (mode.u8[1] == PRS1B_STATIC_LOCAL_VAR)
            {
                tmpm->flags |= MLF_STATIC;
                tmpm->reg = REG_NONE;
            }
            if (mode.u8[1] == PRS1B_FUN_ARG || mode.u8[1] == PRS1B_LOCAL_VAR)
            {
pvl_restart3:
                switch (ParseKeyWord(cc))
                {
                    case KW_REG:
                        tmpm->reg = REG_ALLOC;
                        LexPopNoRestore(cc);
                        LexPush(cc);
                        if (Lex(cc) == TK_IDENT)
                        {
                            k = DefineMatch(cc->cur_str, "ST_U64_REGS");
                            if (k >= 0)
                            {
                                tmpm->reg = k;
                                LexPopNoRestore(cc);
                                LexPush(cc);
                                Lex(cc);
                            }
                        }
                        goto pvl_restart3;

                    case KW_NOREG:
                        tmpm->reg = REG_NONE;
                        LexPopNoRestore(cc);
                        LexPush(cc);
                        Lex(cc);
                        goto pvl_restart3;
                }
            }
            tmpm->member_class = ParseType(cc, &tmpc1, &mode, tmpm, &tmpm->str, &tmpm->fun_ptr, NULL, &tmpm->dim, 0);
            if (tmpm->fun_ptr)
                tmpm->flags |= MLF_FUN;
            if (first)
                MemberAdd(cc, tmpm, tmpc, mode.u8[1]);
            else
                MemberAdd(cc, tmpm, tmpc, PRS1B_NULL);
            tmpc->member_count++;

            tmpc2 = tmpm->member_class;
            i = tmpc2->size * tmpm->dim.total_count;
            switch (mode.u8[1])
            {
                case PRS1B_STATIC_LOCAL_VAR:
                    if (i < 0)
                    {
                        i = 0;
                        undef_array_size = TRUE;
                    }
                    else
                        undef_array_size = FALSE;
                    if (mode & PRSF_UNION)
                        LexExcept(cc, "Static unions are not implemented ");
                    k = (i + 7) & ~7;
                    if (cc->flags & CCF_AOT_COMPILE)
                        tmpm->static_data = MAlloc(k);
                    else
                        tmpm->static_data = MAlloc(k, Fs->code_heap);
                    if (cc->flags & CCF_AOT_COMPILE)
                    {
                        tmpm->static_data_rip = cc->aotc->rip;
                        k >>= 3;
                        while (k--)
                            AOTStoreCodeU64(cc, 0);
                    }
                    else
                        if (sys_var_init_flag)
                            MemSet(tmpm->static_data, sys_var_init_val, k);
                    LexPopNoRestore(cc);
                    if (cc->token == '=')
                    {
                        cc->flags = cc->flags & ~CCF_DONT_MAKE_RES | old_flags & CCF_DONT_MAKE_RES;
                        if (undef_array_size)
                        {
                            LexPush(cc);
                            LexPush(cc);
                            Lex(cc); //skip =
                            ParseStaticInit(cc, tmpm, 1);
                            LexPopNoRestore(cc);
                            i = tmpc2->size * tmpm->dim.total_count;
                            k = (i + 7) & ~7;
                            if (cc->flags & CCF_AOT_COMPILE)
                            {
                                k >>= 3;
                                while (k--)
                                    AOTStoreCodeU64(cc, 0);
                            }
                            else
                                if (sys_var_init_flag)
                                    MemSet(tmpm->static_data, sys_var_init_val, k);
                            LexPopRestore(cc);
                        }
                        LexPush(cc);
                        Lex(cc); //skip =
                        ParseStaticInit(cc, tmpm, 2);
                        LexPopNoRestore(cc);
                        if (cc->flags & CCF_AOT_COMPILE)
                            for (k = 0; k < i; k++)
                                AOTStoreCodeU8At(cc, tmpm->static_data_rip + k, tmpm->static_data[k]);
                        tmpm->use_count = 0;
                        cc->flags |= CCF_DONT_MAKE_RES;
                    }
                    if (cc->flags & CCF_AOT_COMPILE)
                        Free(tmpm->static_data);
                    break;

                case PRS1B_LOCAL_VAR:
                    if (mode & PRSF_UNION)
                    {
                        if (union_base - tmpc->size<i)
                            i = union_base - i - tmpc->size;
                        else
                            i = 0;
                    }
                    if (i >= 8)
                        tmpc->size = (tmpc->size - i) & ~7;
                    else if (i >= 4)
                        tmpc->size = (tmpc->size - i) & ~3;
                    else if (i >= 2)
                        tmpc->size = (tmpc->size - i) & ~1;
                    else
                        tmpc->size -= i;
                    tmpm->offset = tmpc->size;
                    tmpm->size = i;
                    if (cc->token == '=')
                    {
                        cc->flags = cc->flags & ~CCF_DONT_MAKE_RES | old_flags & CCF_DONT_MAKE_RES;
                        LexPopRestore(cc);
                        Lex(cc);
                        if (!ParseExpression(cc, NULL, TRUE))
                            throw('Compiler');
                        tmpm->use_count = 0;
                        cc->flags |= CCF_DONT_MAKE_RES;
                    }
                    else
                        LexPopNoRestore(cc);
                    break;

                case PRS1B_FUN_ARG:
                    if (mode & PRSF_UNION)
                    {
                        tmpm->offset = union_base;
                        if (tmpc->size - union_base < 8)
                            tmpc->size = 8 + union_base;
                    }
                    else
                    {
                        tmpm->offset = tmpc->size;
                        tmpc->size += 8;
                    }
                    tmpm->size = 8;
                    if (cc->token == '=')
                    {
                        Lex(cc);
                        if (ParseKeyWord(cc) == KW_LASTCLASS)
                        {
                            tmpm->flags |= MLF_LASTCLASS;
                            Lex(cc);
                        }
                        else
                        {
                            old_flags2 = cc->flags;
                            cc->flags &= ~CCF_HAS_MISC_DATA;
                            machine_code = LexExpression2Bin(cc, &type);
                            if (!machine_code)
                                throw('Compiler');
                            tmpm->default_val = Call(machine_code);
                            tmpc2 = OptClassFwd(tmpc2);
                            if (tmpc2->raw_type == RT_F64)
                            {
                                if (type != RT_F64)
                                    tmpm->default_val(F64) = tmpm->default_val;
                            }
                            else
                            {
                                if (type == RT_F64)
                                    tmpm->default_val = tmpm->default_val(F64);
                            }
                            if (cc->flags & CCF_HAS_MISC_DATA)
                            {
                                tmpm->default_val = StrNew(tmpm->default_val);
                                tmpm->flags |= MLF_STR_DEFAULT_AVAILABLE;
                            }
                            Free(machine_code);
                            cc->flags |= old_flags2 & CCF_HAS_MISC_DATA;
                        }
                        tmpm->flags |= MLF_DEFAULT_AVAILABLE;
                    }
                    LexPopNoRestore(cc);
                    break;

                case PRS1B_CLASS:
                    if (mode & PRSF_UNION)
                    {
                        tmpm->offset = union_base;
                        if (tmpc->size - union_base < i)
                            tmpc->size = i + union_base;
                    }
                    else
                    {
                        tmpm->offset = tmpc->size;
                        tmpc->size += i;
                    }
                    tmpm->size = i;
                    if (mode & PRSF_UNION)
                        cc->class_dol_offset = union_base;
                    else
                        cc->class_dol_offset = tmpc->size;

                    while (cc->token == TK_IDENT)
                    {
                        tmp_meta = MAlloc(sizeof(CMemberListMeta));
                        tmp_meta->next = tmpm->meta;
                        tmpm->meta = tmp_meta;
                        tmp_meta->str = cc->cur_str;
                        tmp_meta->flags = 0;
                        cc->cur_str = NULL;
                        if (Lex(cc) == TK_STR)
                        {
                            tmp_meta->user_data = LexExtStr(cc);
                            tmp_meta->flags |= MLMF_IS_STR;
                        }
                        else
                            tmp_meta->user_data = LexExpression(cc);
                    }
                    LexPopNoRestore(cc);
                    break;
            }
            switch (cc->token)
            {
                case ',':
                    if (mode.u8[1] == PRS1B_FUN_ARG && !(mode & PRSF_UNION))
                        Lex(cc);
                    else
                    {
                        first = FALSE;
                        goto pvl_restart2;
                    }
                    break;

                case ')':
                case '}':
                    Lex(cc);
                    goto pvl_done;

                case ';':
                    cc->flags = cc->flags & ~CCF_DONT_MAKE_RES | old_flags & CCF_DONT_MAKE_RES;
                    Lex(cc);
                    cc->flags |= CCF_DONT_MAKE_RES;
                    if ((mode.u8[1] == PRS1B_LOCAL_VAR || mode.u8[1] == PRS1B_STATIC_LOCAL_VAR) && !(mode & PRSF_UNION))
                        goto pvl_done;
                    break;

                default:
                    LexExcept(cc, "Missing ';' at");
            }
        }
    }
pvl_done:
    cc->flags = cc->flags &
                ~(CCF_CLASS_DOL_OFFSET | CCF_DONT_MAKE_RES) | old_flags & (CCF_CLASS_DOL_OFFSET | CCF_DONT_MAKE_RES);
}