U0 LexPutToken(CCompCtrl *cc)
{//Print cur token to StdOut. (Crude)
        '"';
        if (cc->token == TK_IDENT || cc->token == TK_STR)
                "%s", cc->cur_str;
        else if (cc->token == TK_I64)
                "INT:%X", cc->cur_i64;
        else if (cc->token == TK_CHAR_CONST)
                "U8:%X", cc->cur_i64;
        else if (cc->token == TK_F64)
                "FLOAT:%e", cc->cur_f64;
        else if (cc->token == '\n')
                "<NEW_LINE>";
        else if (Bt(char_bmp_displayable, cc->token))
                '' cc->token;
        else
        {
                "T:%X", cc->token;
        }
        "\" ";
}

U8 *LexPutLine(CCompCtrl *cc, U8 *start)
{//Print cur pos to end of line to StdOut.
        I64 ch;
        U8 *ptr;

        if (!start)
                return NULL;
        if (cc->lex_include_stack->flags & LFSF_DOC)
                return DocPutLine(cc->lex_include_stack->doc, start);
        else
        {
                ptr = start;
                while (ch = *ptr++)
                {
                        if (ch == '\n')
                        {
                                if (*ptr == '\r')
                                        ptr++;
                                break;
                        }
                        else if (ch == '\r')
                        {
                                if (*ptr == '\n')
                                        ptr++;
                                break;
                        }
                        '' ch;
                }
                if (!ch)
                        ptr--;
                '\n';
                return ptr;
        }

        return NULL;
}

U0 LexPutPos(CCompCtrl *cc)
{//Print token, line link and, then, LexPutLine().
        LexPutToken(cc);
        FixSet(cc->lex_include_stack->full_name, cc->lex_include_stack->line_num);
        if (IsRaw)
                "%s,%d ", cc->lex_include_stack->full_name, cc->lex_include_stack->line_num;
        else
        {
                PutFileLink(cc->lex_include_stack->full_name,, cc->lex_include_stack->line_num);
                SysErr("%s,%d\n", cc->lex_include_stack->full_name, cc->lex_include_stack->line_num);
                '' CH_SPACE;
        }
        LexPutLine(cc, cc->lex_include_stack->line_start);
}

U0 LexWarn(CCompCtrl *cc, U8 *str=NULL)
{//Print warn message, then, LexPutPos().
        if (str)
                PrintWarn(str);
        if (cc->htc.fun)
        {
                "in fun '%s'.\n", cc->htc.fun->str;
                if (IsRaw)
                        "%s\n", cc->htc.fun->src_link;
                else
                {
                        "$LK,\"%s\"$\n", cc->htc.fun->src_link;
                        SysErr("%s\n", cc->htc.fun->src_link);
                }
        }
        else
                LexPutPos(cc);
        cc->warning_count++;
}

U0 LexExcept(CCompCtrl *cc, U8 *str=NULL)
{//Print error message, LexPutPos() and throw exception.
        if (!Bt(&sys_run_level, RLf_SYSTEM_SERVER))
        {
                Raw(ON);
                "Note: Still in boot phase.\n";
        }
        if (str)
                PrintErr(str);
        if (!IsRaw)
                SysErr("Task:%08X %s\n", Fs,str);
        LexPutPos(cc);
        cc->error_count++;
        FlushMessages;
        if (!Bt(&sys_run_level, RLf_SYSTEM_SERVER))
                Debug("Type \"Fix;\"");
        throw('Compiler');
}

U0 UndefinedExtern()
{
        PrintErr("Undefined Extern\nat %P\n", Caller);
        throw('UndefExt');
}

U0 UnusedExternWarning(CCompCtrl *cc, CHashClass *tmpc)
{
        PrintWarn("Unused extern '%s'\n", tmpc->str);
        cc->warning_count++;
}

U0 ParenWarning(CCompCtrl *cc)
{
        if (Bt(&cc->opts, OPTf_WARN_PAREN) && !(cc->lex_include_stack->flags & LFSF_DEFINE))
                LexWarn(cc, "Unnecessary parenthesis ");
}

U0 ICClassPut(CHashClass *c)
{
        I64 i;

        if (!c)
                return;
        if (c->ptr_stars_count > 4)
        {
                PrintErr("put_class ptrcount=%d\n", c->ptr_stars_count);
                while (TRUE)
//TODO:
                        Yield;
        }
        for (i = 0; i < c->ptr_stars_count; i++)
                '*';
        c -= c->ptr_stars_count;
        if (c->str)
                "%s", c->str;
        else
        {
                PrintErr("put_class str=NULL\n");
                while (TRUE)
//TODO:
                        Yield;
        }
        '' CH_SPACE;
}

U0 ICArgPut(CICArg *a, I64 type_pointed_to)
{
        if (type_pointed_to)
                "[%Z](%Z) %Z ",
                a->type.raw_type, "ST_RAW_TYPES", type_pointed_to, "ST_RAW_TYPES", Bsr(a->type >> 8) + 1, "ST_TY_TYPES";
        else
                "%Z %Z ", a->type.raw_type, "ST_RAW_TYPES", Bsr(a->type >> 8) + 1, "ST_TY_TYPES";
        switch (Bsr(a->type))
        {
                case MDf_STACK:
                        "STACK";
                        break;

                case MDf_IMM:
                        "#%X", a->disp;
                        break;

                case MDf_REG:
                        "%Z", a->reg, "ST_U64_REGS";
                        break;

                case MDf_DISP:
                        "%X[%Z]", a->disp, a->reg, "ST_U64_REGS";
                        break;

                case MDf_RIP_DISP32:
                        "[%X]", a->disp;
                        break;

                case MDf_SIB:
                        if (a->disp)
                                "%X", a->disp;
                        if (a->reg == REG_RIP)
                                '[';
                        else
                                "[%Z+", a->reg & 15, "ST_U64_REGS";
                        "%Z", a->reg >> 8 & 15, "ST_U64_REGS";
                        switch (a->reg >> 14)
                        {
                                case 0: "]";    break;
                                case 1: "*2]";  break;
                                case 2: "*4]";  break;
                                case 3: "*8]";  break;
                        }
                        break;
        }
        '' CH_SPACE;
}

U0 ICPut(CCompCtrl *cc, CIntermediateCode *tmpi)
{
        I64 opcode = tmpi->ic_code, i;

        if (opcode >= IC_END_EXP && opcode != IC_NOP2)
        {
                "%15ts %016X ", intermediate_code_table[opcode].name, tmpi->ic_data;
                if (cc->pass)
                {
                        if (tmpi->res.type.mode)
                        {
                                "$PURPLE$RES:$FG$";
                                ICArgPut(&tmpi->res, 0);
                        }
                        if (tmpi->arg1.type.mode)
                        {
                                "$PURPLE$ARG1:$FG$";
                                if (intermediate_code_table[tmpi->ic_code].type         == IST_DEREF ||
                                                intermediate_code_table[tmpi->ic_code].type     == IST_ASSIGN)
                                        ICArgPut(&tmpi->arg1, tmpi->arg1_type_pointed_to);
                                else
                                        ICArgPut(&tmpi->arg1, 0);
                        }
                        if (tmpi->arg2.type.mode)
                        {
                                "$PURPLE$ARG2:$FG$";
                                ICArgPut(&tmpi->arg2, 0);
                        }
                        "$PURPLE$:$FG$";
                }
                ICClassPut(tmpi->ic_class);
                if (tmpi->ic_flags & ICF_LOCK)
                        "$BROWN$lock$FG$ ";
                if (tmpi->ic_flags & ICF_ARG2_TO_F64)
                        "$LTBLUE$a2d$FG$ ";
                if (tmpi->ic_flags & ICF_ARG2_TO_INT)
                        "$GREEN$a2i$FG$ ";
                if (tmpi->ic_flags & ICF_ARG1_TO_F64)
                        "$LTBLUE$a1d$FG$ ";
                if (tmpi->ic_flags & ICF_ARG1_TO_INT)
                        "$GREEN$a1i$FG$ ";
                if (tmpi->ic_flags & ICF_RES_TO_F64)
                        "$LTBLUE$rd$FG$ ";
                if (tmpi->ic_flags & ICF_RES_TO_INT)
                        "$GREEN$ri$FG$ ";
                if (tmpi->ic_flags & ICF_USE_F64)
                        "[F64] ";
                if (tmpi->ic_flags & ICF_USE_UNSIGNED)
                        "[unsigned] ";
                if (tmpi->ic_flags & ICF_USE_INT)
                        "[int] ";
                if (tmpi->ic_flags & ICF_RES_NOT_USED)
                        "NO_RES ";
                if (tmpi->ic_flags & ICF_BY_VAL)
                        "BY_VAL ";
                if (tmpi->ic_flags & ICF_PUSH_RES)
                        "PUSH ";
                if (tmpi->ic_flags & ICF_PUSH_CMP)
                        "PUSH_CMP ";
                if (tmpi->ic_flags & ICF_POP_CMP)
                        "POP_CMP ";
                if (tmpi->ic_flags & ICF_DEL_PREV_INS)
                        "DEL_PREV ";
                if (tmpi->ic_flags & ICF_PREV_DELETED)
                        "PREV_DEL ";
                for (i = 0; i < 3; i++)
                {
                        if (Bt(&tmpi->ic_flags, ICf_DONT_PUSH_FLOAT0 + i))
                                "DONT_PUSH#%d ", i;
                        if (Bt(&tmpi->ic_flags, ICf_DONT_POP_FLOAT0 + i))
                                "DONT_POP#%d ", i;
                }
                if (tmpi->ic_flags & ICF_ALT_TEMPLATE)
                        "ALT_TMP ";
                '\n';
        }
}