Bool Option(I64 num, Bool val)
{//Set compiler Option to val.
        return BEqual(&Fs->last_cc->opts, num, val);
}

Bool OptionGet(I64 num)
{//Get state of compiler option.
        return Bt(&Fs->last_cc->opts, num);
}

asm {
_LAST_FUN::             //See _CALL_IND
                                PUSH            RBP
                                MOV             RBP, RSP
                                PUSH            RSI
                                PUSH            RDI

                                XOR             RAX, RAX
                                MOV             RAX, FS:CTask.last_fun[RAX]
                                TEST            RAX, RAX
                                JZ                      @@10
                                MOV             RDX, U64 CHashFun.exe_addr[RAX]

                                MOV             RCX, U64 SF_ARG1[RBP] // argc
                                MOV             RSI, U64 SF_ARG2[RBP] // argv
                                SHL             RCX, 3
                                SUB             RSP, RCX
                                MOV             RDI, RSP
                                REP_MOVSB
                                TEST            RDX, RDX
                                JZ                      @@05

                                CALL            RDX
                                POP             RDI
                                POP             RSI
                                POP             RBP
                                RET1            16

@@05:                   MOV             RCX, U64 SF_ARG1[RBP] // argc
                                SHL             RCX, 3
                                ADD             RSP, RCX
                                XOR             RAX, RAX
@@10:                   POP             RDI
                                POP             RSI
                                POP             RBP
                                RET1            16
}
_extern _LAST_FUN I64 LastFun(I64 argc, I64 *argv); //Execute last fun with args.

I64 PassTrace(I64 i=0b10001111101)
{//Ctrls which optimizer passes are displayed.
        I64 old = Fs->last_cc->pass_trace;

        if (i)
                Fs->last_cc->saved_pass_trace = i;
        Fs->last_cc->pass_trace = i;

        return old;
}

Bool Trace(Bool val=ON)
{//Displays assembly code output from compiler.
        return Option(OPTf_TRACE, val);
}

Bool Echo(Bool val)
{//Displays text as it is being compiled.
        return Option(OPTf_ECHO, val);
}

U0 StreamPrint(U8 *format, ...)
{//Injects text into the compile stream. Used in #exe{} blocks.
        U8                      *buf = StrPrintJoin(NULL, format, argc, argv), *st;
        CCompCtrl       *cc = Fs->last_cc;
        CStreamBlk      *tmpe = cc->last_stream_blk;

        if (tmpe != &cc->next_stream_blk)
        {
                st = MStrPrint("%s%s", tmpe->body, buf);
                Free(tmpe->body);
                tmpe->body = st;
        }
        else
                PrintErr("No exe{} blk\n");
        Free(buf);
}

U0 StreamDir()
{
        U8 *dirname;

        if (dirname = DirFile(Fs->last_cc->lex_include_stack->full_name))
        {
                StreamPrint("\"%s\"", dirname);
                Free(dirname);
        }
}

CD2I32 *LexD2I32(CCompCtrl *cc, CD2I32 *p)
{//Not CosmiC. Sprite-like lex 2D point.
        if (cc->token != '(')
                LexExcept(cc, "Expecting '(' at ");
        Lex(cc); // Skip (
        p->x = LexExpressionI64(cc);
        if (cc->token != ',')
                LexExcept(cc, "Expecting ',' at ");
        Lex(cc); // Skip ,
        p->y = LexExpressionI64(cc);
        if (cc->token != ')')
                LexExcept(cc, "Expecting ')' at ");
        Lex(cc); // Skip )

        return p;
}

CD3I32 *LexD3I32(CCompCtrl *cc,CD3I32 *p)
{//Not CosmiC. Sprite-like lex 3D point.
        if (cc->token != '(')
                LexExcept(cc, "Expecting '(' at ");
        Lex(cc); // Skip (
        p->x = LexExpressionI64(cc);
        if (cc->token != ',')
                LexExcept(cc, "Expecting ',' at ");
        Lex(cc); // Skip ,
        p->y = LexExpressionI64(cc);
        if (cc->token != ',')
                LexExcept(cc, "Expecting ',' at ");
        Lex(cc); // Skip ,
        p->z = LexExpressionI64(cc);
        if (cc->token != ')')
                LexExcept(cc, "Expecting ')' at ");
        Lex(cc); // Skip )

        return p;
}

U8 *CmdLinePrompt()
{
        I64 i;
        U8 *res, *st;

        if (Fs->new_answer)
        {
                if (Fs->answer_type & ~1 != RT_I0)
                {
                        if (Fs->answer_type == RT_F64)
                                "%8.6fs ansf=%15.7g\n", Fs->answer_time, Fs->answer;
                        else
                                "%8.6fs ans=0x%08X=%d\n", Fs->answer_time, Fs->answer, Fs->answer;
                }
                else
                {
                        "%8.6fs\n", Fs->answer_time;
                        Fs->answer = 0;
                }
                Fs->new_answer = FALSE;
        }
        if (st = DirCur)
        {
                "%s", st;
                Free(st);
        }
        '>';
        if (IsDebugMode && IsRaw)
                RawDr;

        LBts(&Fs->task_flags, TASKf_CMD_LINE_PROMPT);
        st = StrGet(,, SGF_SHIFT_ESC_EXIT);
        LBtr(&Fs->task_flags, TASKf_CMD_LINE_PROMPT);

        i = StrLen(st);
        res = MAlloc(i + 1 + 2);
        MemCopy(res, st, i + 1);
        i--;
        while (i >= 0 && Bt(char_bmp_white_space, res[i]))
                i--;
        i++;
        if (i > 0 && res[i - 1] == ';')
                res[i++] = ';'; // The Lex goes one beyond
        res[i++] = '\n';        // #define goes to '\n'
        res[i] = 0;

        Free(st);

        return res;
}