U8 *LexStatement2Bin(CCompCtrl *cc, I64 *_type, I64 comp_flags=0)
{//Compile one cc statement to bin code.
    I64          size, i, j, k, *res = INVALID_PTR;
    CCodeCtrl   *tmpcbh;

    if (_type)
        *_type = RT_I64;
    Btr(&cc->flags, CCf_PASS_TRACE_PRESENT);
    if (cc->aot_depth == 2)
        COCPush(cc);
    COCInit(cc);
    if (!ParseStatement(cc,,, comp_flags))
    {
        if (cc->coc.coc_head.next != &cc->coc.coc_head)
        {
            cc->coc.coc_head.last->ic_flags &= ~ICF_RES_NOT_USED;
            ICAdd(cc, IC_RETURN_VAL2, 0, 0);
            ICAdd(cc, IC_RET, 0, 0);
            if (res = COCCompile(cc, &size, NULL, _type))
            {
                if (cc->flags & CCF_AOT_COMPILE)
                {
                    j = cc->aotc->rip;
                    k = (size + 7) >> 3;
                    for (i = 0; i < k; i++)
                        AOTStoreCodeU64(cc, res[i]);
                    Free(res);
                    res = j;
                }
            }
        } //TODO: else del misc?
    }
    else //TODO: too dangerous to del Misc?
        QueueDel(&cc->coc.coc_head.next);
    if (cc->aot_depth == 2) {
        tmpcbh = COCPopNoFree(cc);
        COCAppend(cc, tmpcbh);
    }

    return res;
}

CAOT *CompJoin(CCompCtrl *cc, I64 comp_flags, U8 *map_name=NULL, U8 mapfile_drive_let=0)
{
    CAOTCtrl                *aotc, *old_aot = cc->aotc;
    I64                      i, j, l;
    U8                      *buf;
    CAOTBinBlk              *tmpbin;
    CAOTImportExport        *tmpie;
    Bool                     okay = TRUE;
    CLexHashTableContext    *htc = MAlloc(sizeof(CLexHashTableContext));
    CAOT                    *res = CAlloc(sizeof(CAOT)), *parent;

    if (parent = cc->aot)
    {
        res->parent_aot = parent;
        QueueInsert(res, parent->last);
    }
    else
        QueueInit(res);
    cc->aot = res;

    res->next_ie = res->last_ie = &res->next_ie;
    cc->aotc = aotc = CAlloc(sizeof(CAOTCtrl));
    cc->aot_depth++;

    aotc->bin = CAlloc(sizeof(CAOTBinBlk));
    aotc->max_align_bits = 0;
    aotc->org = INVALID_PTR;

    MemCopy(htc, &cc->htc, sizeof(CLexHashTableContext));
    if (cc->htc.fun)
        cc->htc.global_hash_table = HashTableNew(128);
    else
        cc->htc.global_hash_table = HashTableNew(1024);
    if (cc->flags & CCF_AOT_COMPILE)
    {
        cc->htc.define_hash_table = cc->htc.global_hash_table;
        if (cc->aot_depth <= 1)
            cc->htc.global_hash_table->next = cmp.asm_hash;
        else
            cc->htc.global_hash_table->next = htc->global_hash_table;
    }
    else
        cc->htc.global_hash_table->next = Fs->hash_table;
    cc->htc.hash_table_list = cc->htc.local_hash_table = HashTableNew(16);
    cc->htc.local_hash_table->next = cc->htc.global_hash_table;
    cc->htc.local_var_list = cc->htc.fun; //ZealC local variables
    cc->htc.fun = NULL;
    try
    {
        if (comp_flags & CMPF_LEX_FIRST)
            Lex(cc);
        if (!(comp_flags & CMPF_ONE_ASM_INS))
            comp_flags |= CMPF_PRS_SEMICOLON;
        if (cc->flags & CCF_AOT_COMPILE)
        {
            while (cc->token != TK_EOF)
            {
                buf = LexStatement2Bin(cc, NULL, comp_flags);
                if (buf != INVALID_PTR)
                {
                    tmpie = CAlloc(sizeof(CAOTImportExport));
                    tmpie->type = IET_MAIN;
                    tmpie->rip = buf;
                    QueueInsert(tmpie, res->last_ie);
                }
                if (comp_flags & CMPF_ASM_BLK)
                    break;
            }
        }
        else
            ParseStatement(cc,,, comp_flags);
        AOTGlobalsResolve(cc, res);
    }
    catch
    {
        if (Fs->except_ch == 'Compiler' && !(comp_flags & CMPF_ASM_BLK))
        {
            LexPutPos(cc);
            Fs->catch_except = TRUE;
        }
        okay = FALSE;
    }
    if (!okay)
    {
        if (cc->error_count < 1)
            cc->error_count = 1;
        cc->aot = res->parent_aot;
        Free(res);
        LinkedListDel(aotc->bin);
        res = NULL;
    }
    else
    {
        if (map_name)
            MapFileWrite(cc->htc.global_hash_table, map_name, mapfile_drive_let);
        HashTableDel(cc->htc.local_hash_table);
        HashTableDel(cc->htc.global_hash_table);

        if (!aotc->num_bin_U8s)
            res->buf = NULL;
        else
        {
            if (cc->flags & CCF_AOT_COMPILE)
                res->buf = MAlloc(aotc->num_bin_U8s);
            else
            {
                if (aotc->org == INVALID_PTR)
                    res->buf = MAlloc(aotc->num_bin_U8s, Fs->code_heap);
                else
                    res->buf = aotc->org;
            }
            res->aot_U8s = aotc->num_bin_U8s;
            tmpbin = aotc->bin;
            j = 0;
            l = aotc->num_bin_U8s;
            while (tmpbin)
            {
                i = l;
                if (i > AOT_BIN_BLK_SIZE)
                    i = AOT_BIN_BLK_SIZE;
                MemCopy(res->buf + j, tmpbin->body, i);
                j += i;
                l -= i;
                tmpbin = tmpbin->next;
            }
        }
        LinkedListDel(aotc->bin);
        res->abss = aotc->abss;
        res->heap_globals = aotc->heap_globals;
        res->max_align_bits = aotc->max_align_bits;
        res->org = aotc->org;
    }
    cc->aot = parent;
    MemCopy(&cc->htc, htc, sizeof(CLexHashTableContext));
    Free(htc);
    Free(aotc);
    cc->aotc = old_aot;
    cc->aot_depth--;

    return res;
}

CAOT *CompBuf(U8 *buf, U8 *map_name=NULL, I64 *error_count=NULL, I64 *warning_count=NULL, U8 mapfile_drive_let=0)
{
    CCompCtrl   *cc;
    CAOT        *res = NULL;

    cc = CompCtrlNew(buf, CCF_DONT_FREE_BUF);
    cc->flags |= CCF_AOT_COMPILE;
    QueueInsert(cc, Fs->last_cc);
    res = CompJoin(cc, CMPF_LEX_FIRST, map_name, mapfile_drive_let);
    if (error_count)
        *error_count = cc->error_count;
    if (warning_count)
        *warning_count = cc->warning_count;
    QueueRemove(cc);
    if (res)
        CompCtrlDel(cc);

    return res;
}

U0 CompFixUpJITAsm(CCompCtrl *cc, CAOT *tmpaot)
{
    I64                  i, rip2 = tmpaot->buf + tmpaot->rip, *str = NULL;
    U8                  *ptr;
    CCodeMisc           *g_lb;
    CAOTAbsAddr         *tmpa, *tmpa1;
    CAOTImportExport    *tmpie, *tmpie1;
    CHashExport         *tmpex;

    tmpa = tmpaot->abss;
    while (tmpa)
    {
        tmpa1 = tmpa->next;
        ptr = rip2 + tmpa->rip;
        switch [tmpa->type]
        {
            case AAT_ADD_U8:    *ptr(U8  *) += rip2; break;
            case AAT_SUB_U8:    *ptr(U8  *) -= rip2; break;
            case AAT_ADD_U16:   *ptr(U16 *) += rip2; break;
            case AAT_SUB_U16:   *ptr(U16 *) -= rip2; break;
            case AAT_ADD_U32:   *ptr(U32 *) += rip2; break;
            case AAT_SUB_U32:   *ptr(U32 *) -= rip2; break;
            case AAT_ADD_U64:   *ptr(I64 *) += rip2; break;
            case AAT_SUB_U64:   *ptr(I64 *) -= rip2; break;
        }
        Free(tmpa);
        tmpa = tmpa1;
    }
    tmpie = tmpaot->next_ie;
    while (tmpie != &tmpaot->next_ie)
    {
        tmpie1 = tmpie->next;
        if (tmpie->str)
        {
            Free(str);
            str = tmpie->str;
        }
        switch (tmpie->type)
        {
            case IET_REL32_EXPORT:
            case IET_IMM32_EXPORT:
            case IET_REL64_EXPORT:
            case IET_IMM64_EXPORT:
                tmpex = CAlloc(sizeof(CHashExport));
                tmpex->str = str;
                str = NULL;
                tmpex->type = HTT_EXPORT_SYS_SYM | HTF_IMM;
                if (tmpie->type == IET_IMM32_EXPORT || tmpie->type == IET_IMM64_EXPORT)
                    tmpex->val = tmpie->rip;
                else
                    tmpex->val = tmpie->rip + rip2;
                tmpex->src_link = tmpie->src_link;
                tmpie->src_link = NULL;
                HashAdd(tmpex, Fs->hash_table);
                SysSymImportsResolve(tmpex->str);
                break;

            case IET_REL_I0...IET_IMM_I64:
                if (tmpie->str)
                {
                    if (tmpie->flags & IEF_GOTO_LABEL)
                    {
                        if (!(g_lb = COCGoToLabelFind(cc, str)))
                            "Unresolved Reference:%s\n", str;
                        else
                        {
                            g_lb->use_count++;
                            g_lb = OptLabelFwd(g_lb);
                            i = g_lb->addr + tmpaot->buf;
                        }
                        tmpex = NULL;
                    }
                    else
                    {
                        if (!(tmpex = HashFind(str, Fs->hash_table, HTG_ALL - HTT_IMPORT_SYS_SYM)))
                            "Unresolved Reference:%s\n", str;
                        else
                        {
                            if (tmpex->type & HTT_FUN)
                                i = tmpex(CHashFun *)->exe_addr;
                            else if (tmpex->type & HTT_GLOBAL_VAR)
                                i = tmpex(CHashGlobalVar *)->data_addr;
                            else
                                i = tmpex->val;
                        }
                        g_lb = NULL;
                    }
                }
                if (tmpex || g_lb)
                {
                    ptr = tmpie->rip + rip2;
                    switch [tmpie->type]
                    {
                        case IET_REL_I0:
                        case IET_IMM_U0:
                            break;

                        case IET_REL_I8:
                            if (!(I8_MIN <= i - ptr - 1 <= I8_MAX))
                                LexExcept(cc, "Branch out of range at ");
                            *ptr(U8 *) = i - ptr - 1;
                            break;

                        case IET_IMM_U8:
                            *ptr(U8 *) = i;
                            break;

                        case IET_REL_I16:
                            if (!(I16_MIN <= i - ptr - 2 <= I16_MAX))
                                LexExcept(cc, "Branch out of range at ");
                            *ptr(U16 *) = i - ptr - 2;
                            break;

                        case IET_IMM_U16:
                            *ptr(U16 *) = i;
                            break;

                        case IET_REL_I32:
                            if (!(I32_MIN <= i - ptr - 4 <= I32_MAX))
                                LexExcept(cc, "Branch out of range at ");
                            *ptr(U32 *) = i - ptr - 4;
                            break;

                        case IET_IMM_U32:
                            *ptr(U32 *) = i;
                            break;

                        case IET_REL_I64:
                            *ptr(I64 *) = i - ptr - 8;
                            break;

                        case IET_IMM_I64:
                            *ptr(I64 *) = i;
                            break;
                    }
                }
                break;
        }
        Free(tmpie->src_link);
        Free(tmpie);
        tmpie = tmpie1;
    }
    Free(str);
    if (!cc->aot_depth && Bt(&cc->opts, OPTf_TRACE))
        Un(rip2, tmpaot->aot_U8s, 64);
    QueueRemove(tmpaot);
    Free(tmpaot);
}

U0 CompFixUpAOTAsm(CCompCtrl *cc, CAOT *tmpaot)
{
    CAOTCtrl            *aotc = cc->aotc;
    I64                  i, rip2 = tmpaot->rip + cc->aotc->rip;
    U8                  *ptr;
    CCodeMisc           *g_lb = NULL;
    CAOTAbsAddr         *tmpa, *tmpa1;
    CAOTImportExport    *tmpie, *tmpie1;

    tmpa = tmpaot->abss;
    while (tmpa)
    {
        tmpa1 = tmpa->next;
        tmpa->next = aotc->abss;
        ptr = tmpaot->buf + tmpaot->rip + tmpa->rip;
        switch [tmpa->type]
        {
            case AAT_ADD_U8:    *ptr(U8  *) += rip2;    break;
            case AAT_SUB_U8:    *ptr(U8  *) -= rip2;    break;
            case AAT_ADD_U16:   *ptr(U16 *) += rip2;    break;
            case AAT_SUB_U16:   *ptr(U16 *) -= rip2;    break;
            case AAT_ADD_U32:   *ptr(U32 *) += rip2;    break;
            case AAT_SUB_U32:   *ptr(U32 *) -= rip2;    break;
            case AAT_ADD_U64:   *ptr(I64 *) += rip2;    break;
            case AAT_SUB_U64:   *ptr(I64 *) -= rip2;    break;
        }
        aotc->abss = tmpa;
        tmpa->rip += rip2;
        tmpa = tmpa1;
    }

    tmpie = tmpaot->next_ie;
    while (tmpie != &tmpaot->next_ie)
    {
        tmpie1 = tmpie->next;
        QueueRemove(tmpie);
        if (IET_REL_I0 <= tmpie->type <= IET_IMM_I64)
        {
            if (tmpie->str)
            {
                if (tmpie->flags & IEF_GOTO_LABEL)
                {
                    if (!(g_lb = COCGoToLabelFind(cc, tmpie->str)))
                        "Unresolved Reference:%s\n", tmpie->str;
                    else
                    {
                        g_lb->use_count++;
                        g_lb = OptLabelFwd(g_lb);
                    }
                }
                else
                    g_lb = NULL;
            }
        }
        else
            g_lb = NULL;

        ptr = tmpaot->buf + tmpaot->rip + tmpie->rip;
        if (g_lb)
        {
            i = g_lb->addr + tmpaot->buf;
            switch [tmpie->type]
            {
                case IET_REL_I0:
                case IET_IMM_U0:
                    break;

                case IET_REL_I8:
                    if (!(I8_MIN <= i - ptr - 1 <= I8_MAX))
                        LexExcept(cc, "Branch out of range at ");
                    *ptr(U8 *) = i - ptr - 1;
                    break;

                case IET_IMM_U8:
                    *ptr(U8 *) = i;
                    break;

                case IET_REL_I16:
                    if (!(I16_MIN <= i - ptr - 2 <= I16_MAX))
                        LexExcept(cc, "Branch out of range at ");
                    *ptr(U16 *) = i - ptr - 2;
                    break;

                case IET_IMM_U16:
                    *ptr(U16 *) = i;
                    break;

                case IET_REL_I32:
                    if (!(I32_MIN <= i - ptr - 4 <= I32_MAX))
                        LexExcept(cc, "Branch out of range at ");
                    *ptr(U32 *) = i - ptr - 4;
                    break;

                case IET_IMM_U32:
                    *ptr(U32 *) = i;
                    break;

                case IET_REL_I64:
                    *ptr(I64 *) = i - ptr - 8;
                    break;

                case IET_IMM_I64:
                    *ptr(I64 *) = i;
                    break;
            }
            Free(tmpie->src_link);
            Free(tmpie);
        }
        else
        {
            switch (tmpie->type)
            {
                start:
                    case IET_REL32_EXPORT:
                    case IET_IMM32_EXPORT:
                    case IET_REL64_EXPORT:
                    case IET_IMM64_EXPORT:
                    case IET_IMM_U0:
                    case IET_IMM_U8:
                    case IET_IMM_U16:
                    case IET_IMM_U32:
                    case IET_IMM_I64:
                    case IET_REL_I0:
                        break;

                    case IET_REL_I8:    *ptr(U8  *) -= rip2;    break;
                    case IET_REL_I16:   *ptr(U16 *) -= rip2;    break;
                    case IET_REL_I32:   *ptr(U32 *) -= rip2;    break;
                    case IET_REL_I64:   *ptr(I64 *) -= rip2;    break;
                end:
                    tmpie->rip += rip2;
                    break;
            }
            tmpie->aot = NULL;
            QueueInsert(tmpie, tmpaot->parent_aot->last_ie);
        }
        tmpie = tmpie1;
    }
}

I64 Comp(U8 *filename, U8 *map_name=NULL, U8 *out_name=NULL, U8 mapfile_drive_let=0)
{//AOT Compile ZC or PRJ file and output ZXE file. Returns err_count.
    U8                  *ptr, *fbuf = NULL, *fbuf2 = NULL, *fbuf3 = NULL, *patch_table = MAlloc(0x20000);
    CAOT                *tmpaot;
    I64                  i, count, size = 0, error_count = 0, warning_count = 0, aot_U8s = 0;
    CZXE                *zxe;
    CAOTImportExport    *tmpie, *tmpie1;
    CAOTAbsAddr         *tmpa, *tmpa1;
    CAOTHeapGlobalRef   *tmphgr, *tmphgr1;
    CAOTHeapGlobal      *tmphg, *tmphg1;

    fbuf = ExtDefault(filename, "PRJ");
    fbuf2 = MStrPrint("#include \"%s\"", fbuf);
    if (map_name)
        fbuf3 = ExtDefault(map_name, "MAP");

    if (tmpaot = CompBuf(fbuf2, fbuf3, &error_count, &warning_count, mapfile_drive_let))
    {
        aot_U8s = tmpaot->aot_U8s;
        ptr = patch_table;
//See Load()
        count = 0;
        tmpa = tmpaot->abss;
        while (tmpa)
        {
            if (!(tmpa->type & IEF_IMM_NOT_REL))
                count++;
            tmpa = tmpa->next;
        }
        if (count)
        {
            *ptr++ = IET_ABS_ADDR;
            *ptr(U32 *)++ = count;
            *ptr++ = 0;
            tmpa = tmpaot->abss;
            while (tmpa)
            {
                tmpa1 = tmpa->next;
                if (!(tmpa->type & IEF_IMM_NOT_REL))
                    *ptr(U32 *)++ = tmpa->rip;
                Free(tmpa);
                tmpa = tmpa1;
            }
        }
        tmphg = tmpaot->heap_globals;
        while (tmphg)
        {
            tmphg1 = tmphg->next;
            count = 0;
            tmphgr = tmphg->references;
            while (tmphgr)
            {
                count++;
                tmphgr = tmphgr->next;
            }
            if (count)
            {
                *ptr++ = IET_DATA_HEAP;
                *ptr(U32 *)++ = count;
                if (tmphg->str)
                {
                    i = StrLen(tmphg->str);
                    MemCopy(ptr, tmphg->str, i + 1);
                    Free(tmphg->str);
                    ptr += i + 1;
                }
                else
                    *ptr++ = 0;
                *ptr(I64 *)++ = tmphg->size;
                tmphgr = tmphg->references;
                while (tmphgr)
                {
                    tmphgr1 = tmphgr->next;
                    *ptr(U32 *)++ = tmphgr->rip;
                    Free(tmphgr);
                    tmphgr = tmphgr1;
                }
            }
            Free(tmphg);
            tmphg = tmphg1;
        }

        //Do exports first
        tmpie = tmpaot->next_ie;
        while (tmpie != &tmpaot->next_ie)
        {
            tmpie1 = tmpie->next;
            if (!tmpie->type || IET_REL32_EXPORT <= tmpie->type <= IET_IMM64_EXPORT)
            {
                QueueRemove(tmpie);
                *ptr++ = tmpie->type;
                *ptr(U32 *)++ = tmpie->rip;
                if (tmpie->str)
                {
                    i = StrLen(tmpie->str);
                    MemCopy(ptr, tmpie->str, i + 1);
                    Free(tmpie->str);
                    ptr += i + 1;
                }
                else
                    *ptr++ = 0;
                Free(tmpie->src_link);
                Free(tmpie);
            }
            tmpie = tmpie1;
        }

        //Do imports second
        tmpie = tmpaot->next_ie;
        while (tmpie != &tmpaot->next_ie)
        {
            tmpie1 = tmpie->next;
            QueueRemove(tmpie);
            *ptr++ = tmpie->type;
            if (tmpie->aot)
                tmpie->rip += tmpie->aot->rip2;
            *ptr(U32 *)++ = tmpie->rip;
            if (tmpie->str)
            {
                i = StrLen(tmpie->str);
                MemCopy(ptr, tmpie->str, i + 1);
                Free(tmpie->str);
                ptr += i + 1;
            }
            else
                *ptr++ = 0;
            Free(tmpie->src_link);
            Free(tmpie);
            tmpie = tmpie1;
        }

        *ptr++ = IET_END;
        MemSet(ptr, 0, 16);
        i = ptr - patch_table;
//Needs 16 ALIGN
        size = (sizeof(CZXE) + aot_U8s + i + 15) & -16;
        zxe = MAlloc(size);
        zxe->jmp = 0xEB + 256 * (sizeof(CZXE) - 2);
#assert sizeof(CZXE) - 2 <= I8_MAX
        zxe->reserved = 0;
        zxe->signature = ZXE_SIGNATURE_VAL;
        zxe->org = tmpaot->org;
        zxe->module_align_bits = tmpaot->max_align_bits;
        zxe->patch_table_offset = sizeof(CZXE) + aot_U8s;
        zxe->file_size = size;
        MemCopy(zxe(U8 *) + sizeof(CZXE), tmpaot->buf, aot_U8s);
        MemCopy(zxe(U8 *) + sizeof(CZXE) + aot_U8s, patch_table, size - aot_U8s - sizeof(CZXE));
        Free(fbuf2);
        if (out_name)
            fbuf2 = ExtDefault(out_name, "ZXE");
        else
            fbuf2 = ExtChange(fbuf, "ZXE");
        FileWrite(fbuf2, zxe, size);
        Free(zxe);
        Free(tmpaot->buf);
        QueueDel(tmpaot);
        Free(tmpaot);
    }
    Free(patch_table);
    Free(fbuf);
    Free(fbuf2);
    Free(fbuf3);
    Print("Errs:%d Warns:%d Code:%X Size:%X\n", error_count, warning_count, aot_U8s, size);

    return error_count;
}

I64 ExePutS(U8 *buf, U8 *filename=NULL, I64 ccf_flags=0, CLexHashTableContext *htc=NULL)
{//JIT Compile and execute text from a puts("").
    I64          res;
    Bool         okay = TRUE;
    CCompCtrl   *cc;

    if (!filename)
        filename = blkdev.tmp_filename;
    cc = CompCtrlNew(buf, ccf_flags | CCF_DONT_FREE_BUF, filename);
    if (Fs->last_cc != &Fs->next_cc)
    {
        cc->opts = Fs->last_cc->opts;
        if (htc)
        {
            cc->flags = cc->flags & ~CCF_ASM_EXPRESSIONS | htc->old_flags & CCF_ASM_EXPRESSIONS;
            MemCopy(&cc->htc, htc, sizeof(CLexHashTableContext));
        }
    }
    QueueInsert(cc, Fs->last_cc);
    try
    {
        Lex(cc);
        res = ExeCmdLine(cc);
    }
    catch
    {
        if (Fs->except_ch == 'Compiler' || Fs->except_ch == 'Break')
        {
            Fs->catch_except = TRUE;
            okay = FALSE;
            res = 0;
        }
    }
    QueueRemove(cc);
    if (okay)
        CompCtrlDel(cc); //TODO: can crash
    return res;
}

I64 ExePrint(U8 *format, ...)
{//JIT Compile and execute text from a printf().
    I64 res;
    U8 *buf = StrPrintJoin(NULL, format, argc, argv);

    res = ExePutS(buf);
    Free(buf);

    return res;
}

I64 ExeFile(U8 *name, I64 ccf_flags=0)
{//JIT Compile and execute a file.
    I64 res;
    U8 *name2 = ExtDefault(name, "ZC"), *st = MStrPrint("#include \"%s\";", name2);

    res = ExePutS(st, name, ccf_flags);
    Free(st);
    Free(name2);

    return res;
}

I64 RunFile(U8 *name, I64 ccf_flags=0, ...)
{//ExeFile() with args using LastFun().
    ExeFile(name, ccf_flags);

    return LastFun(argc, argv);
}

I64 ExePutS2(U8 *buf, U8 *filename=NULL, I64 ccf_flags=0)
{//throws exceptions
    I64          res;
    CCompCtrl   *cc;

    if (!filename)
        filename = blkdev.tmp_filename;
    cc = CompCtrlNew(buf, ccf_flags | CCF_DONT_FREE_BUF, filename);
    if (Fs->last_cc != &Fs->next_cc)
        cc->opts = Fs->last_cc->opts;
    QueueInsert(cc, Fs->last_cc);
    Lex(cc);
    res = ExeCmdLine(cc);
    QueueRemove(cc);
    CompCtrlDel(cc);

    return res;
}

I64 ExePrint2(U8 *format, ...)
{//throws exceptions
    I64 res;
    U8 *buf = StrPrintJoin(NULL, format, argc, argv);

    res = ExePutS2(buf);
    Free(buf);

    return res;
}

I64 ExeFile2(U8 *name, I64 ccf_flags=0)
{//throws exceptions
    I64 res;
    U8 *name2 = ExtDefault(name, "ZC"), *st = MStrPrint("#include \"%s\";", name2);

    res = ExePutS2(st, name, ccf_flags);
    Free(st);
    Free(name2);

    return res;
}

I64 RunFile2(U8 *name, I64 ccf_flags=0, ...)
{//ExeFile2() with args using LastFun(). throws exceptions.
    ExeFile2(name, ccf_flags);

    return LastFun(argc, argv);
}

I64 StreamExePrint(U8 *format, ...)
{//Causes value from stream to be used in an #exe{} block.
    U8                      *buf = StrPrintJoin(NULL, format, argc, argv);
    I64                      res = 0;
    CLexHashTableContext    *htc;
    CCompCtrl               *cc = Fs->last_cc;

    if (cc == &Fs->next_cc)
        PrintErr("Not Compiling\n");
    else
    {
        if (!(cc->flags & CCF_EXE_BLK))
            LexExcept(cc, "StreamExePrint only allowed in AOT compiled #exe{} mode.");
        if (htc = cc->htc.next)
            res = ExePutS(buf,,, htc);
    }
    Free(buf);

    return res;
}

U0 CInit()
{
    CompLoadDefines;
    CompFillTables;
    QueueInit(&cmp.ic_nop);
    cmp.ic_nop.ic_class = cmp.internal_types[RT_I64];
    cmp.ic_nop.ic_code = IC_NOP1;
    AsmHashLoad;
    UAsmHashLoad;
}

CInit;