⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcc.c

📁 一个GNU的C语言编译器源代码,源代码过万行.
💻 C
📖 第 1 页 / 共 5 页
字号:
        sprintf(p, "%Lu", cv->ull);        break;    case TOK_CCHAR:    case TOK_LCHAR:        cstr_ccat(&cstr_buf, '\'');        add_char(&cstr_buf, cv->i);        cstr_ccat(&cstr_buf, '\'');        cstr_ccat(&cstr_buf, '\0');        break;    case TOK_PPNUM:        cstr = cv->cstr;        len = cstr->size - 1;        for(i=0;i<len;i++)            add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);        cstr_ccat(&cstr_buf, '\0');        break;    case TOK_STR:    case TOK_LSTR:        cstr = cv->cstr;        cstr_ccat(&cstr_buf, '\"');        if (v == TOK_STR) {            len = cstr->size - 1;            for(i=0;i<len;i++)                add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);        } else {            len = (cstr->size / sizeof(int)) - 1;            for(i=0;i<len;i++)                add_char(&cstr_buf, ((int *)cstr->data)[i]);        }        cstr_ccat(&cstr_buf, '\"');        cstr_ccat(&cstr_buf, '\0');        break;    case TOK_LT:        v = '<';        goto addv;    case TOK_GT:        v = '>';        goto addv;    case TOK_A_SHL:        return strcpy(p, "<<=");    case TOK_A_SAR:        return strcpy(p, ">>=");    default:        if (v < TOK_IDENT) {            /* search in two bytes table */            q = tok_two_chars;            while (*q) {                if (q[2] == v) {                    *p++ = q[0];                    *p++ = q[1];                    *p = '\0';                    return buf;                }                q += 3;            }        addv:            *p++ = v;            *p = '\0';        } else if (v < tok_ident) {            return table_ident[v - TOK_IDENT]->str;        } else if (v >= SYM_FIRST_ANOM) {            /* special name for anonymous symbol */            sprintf(p, "L.%u", v - SYM_FIRST_ANOM);        } else {            /* should never happen */            return NULL;        }        break;    }    return cstr_buf.data;}/* push, without hashing */static Sym *sym_push2(Sym **ps, int v, int t, int c){    Sym *s;    s = tcc_malloc(sizeof(Sym));    s->v = v;    s->type.t = t;    s->c = c;    s->next = NULL;    /* add in stack */    s->prev = *ps;    *ps = s;    return s;}/* find a symbol and return its associated structure. 's' is the top   of the symbol stack */static Sym *sym_find2(Sym *s, int v){    while (s) {        if (s->v == v)            return s;        s = s->prev;    }    return NULL;}/* structure lookup */static inline Sym *struct_find(int v){    v -= TOK_IDENT;    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))        return NULL;    return table_ident[v]->sym_struct;}/* find an identifier */static inline Sym *sym_find(int v){    v -= TOK_IDENT;    if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))        return NULL;    return table_ident[v]->sym_identifier;}/* push a given symbol on the symbol stack */static Sym *sym_push(int v, CType *type, int r, int c){    Sym *s, **ps;    TokenSym *ts;    if (local_stack)        ps = &local_stack;    else        ps = &global_stack;    s = sym_push2(ps, v, type->t, c);    s->type.ref = type->ref;    s->r = r;    /* don't record fields or anonymous symbols */    /* XXX: simplify */    if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {        /* record symbol in token array */        ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];        if (v & SYM_STRUCT)            ps = &ts->sym_struct;        else            ps = &ts->sym_identifier;        s->prev_tok = *ps;        *ps = s;    }    return s;}/* push a global identifier */static Sym *global_identifier_push(int v, int t, int c){    Sym *s, **ps;    s = sym_push2(&global_stack, v, t, c);    /* don't record anonymous symbol */    if (v < SYM_FIRST_ANOM) {        ps = &table_ident[v - TOK_IDENT]->sym_identifier;        /* modify the top most local identifier, so that           sym_identifier will point to 's' when popped */        while (*ps != NULL)            ps = &(*ps)->prev_tok;        s->prev_tok = NULL;        *ps = s;    }    return s;}/* pop symbols until top reaches 'b' */static void sym_pop(Sym **ptop, Sym *b){    Sym *s, *ss, **ps;    TokenSym *ts;    int v;    s = *ptop;    while(s != b) {        ss = s->prev;        v = s->v;        /* remove symbol in token array */        /* XXX: simplify */        if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {            ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];            if (v & SYM_STRUCT)                ps = &ts->sym_struct;            else                ps = &ts->sym_identifier;            *ps = s->prev_tok;        }        tcc_free(s);        s = ss;    }    *ptop = b;}/* I/O layer */BufferedFile *tcc_open(TCCState *s1, const char *filename){    int fd;    BufferedFile *bf;    fd = open(filename, O_RDONLY);    if (fd < 0)        return NULL;    bf = tcc_malloc(sizeof(BufferedFile));    if (!bf) {        close(fd);        return NULL;    }    bf->fd = fd;    bf->buf_ptr = bf->buffer;    bf->buf_end = bf->buffer;    bf->buffer[0] = CH_EOB; /* put eob symbol */    pstrcpy(bf->filename, sizeof(bf->filename), filename);    bf->line_num = 1;    bf->ifndef_macro = 0;    bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;    //    printf("opening '%s'\n", filename);    return bf;}void tcc_close(BufferedFile *bf){    total_lines += bf->line_num;    close(bf->fd);    tcc_free(bf);}/* fill input buffer and peek next char */static int tcc_peekc_slow(BufferedFile *bf){    int len;    /* only tries to read if really end of buffer */    if (bf->buf_ptr >= bf->buf_end) {        if (bf->fd != -1) {#if defined(PARSE_DEBUG)            len = 8;#else            len = IO_BUF_SIZE;#endif            len = read(bf->fd, bf->buffer, len);            if (len < 0)                len = 0;        } else {            len = 0;        }        total_bytes += len;        bf->buf_ptr = bf->buffer;        bf->buf_end = bf->buffer + len;        *bf->buf_end = CH_EOB;    }    if (bf->buf_ptr < bf->buf_end) {        return bf->buf_ptr[0];    } else {        bf->buf_ptr = bf->buf_end;        return CH_EOF;    }}/* return the current character, handling end of block if necessary   (but not stray) */static int handle_eob(void){    return tcc_peekc_slow(file);}/* read next char from current input file and handle end of input buffer */static inline void inp(void){    ch = *(++(file->buf_ptr));    /* end of buffer/file handling */    if (ch == CH_EOB)        ch = handle_eob();}/* handle '\[\r]\n' */static void handle_stray(void){    while (ch == '\\') {        inp();        if (ch == '\n') {            file->line_num++;            inp();        } else if (ch == '\r') {            inp();            if (ch != '\n')                goto fail;            file->line_num++;            inp();        } else {        fail:            error("stray '\\' in program");        }    }}/* skip the stray and handle the \\n case. Output an error if   incorrect char after the stray */static int handle_stray1(uint8_t *p){    int c;    if (p >= file->buf_end) {        file->buf_ptr = p;        c = handle_eob();        p = file->buf_ptr;        if (c == '\\')            goto parse_stray;    } else {    parse_stray:        file->buf_ptr = p;        ch = *p;        handle_stray();        p = file->buf_ptr;        c = *p;    }    return c;}/* handle just the EOB case, but not stray */#define PEEKC_EOB(c, p)\{\    p++;\    c = *p;\    if (c == '\\') {\        file->buf_ptr = p;\        c = handle_eob();\        p = file->buf_ptr;\    }\}/* handle the complicated stray case */#define PEEKC(c, p)\{\    p++;\    c = *p;\    if (c == '\\') {\        c = handle_stray1(p);\        p = file->buf_ptr;\    }\}/* input with '\[\r]\n' handling. Note that this function cannot   handle other characters after '\', so you cannot call it inside   strings or comments */static void minp(void){    inp();    if (ch == '\\')         handle_stray();}/* single line C++ comments */static uint8_t *parse_line_comment(uint8_t *p){    int c;    p++;    for(;;) {        c = *p;        if (c == '\n' || c == CH_EOF) {            break;        } else if (c == '\\') {            PEEKC_EOB(c, p);            if (c == '\n') {                file->line_num++;                PEEKC_EOB(c, p);            } else if (c == '\r') {                PEEKC_EOB(c, p);                if (c == '\n') {                    file->line_num++;                    PEEKC_EOB(c, p);                }            }        } else {            p++;        }    }    return p;}/* C comments */static uint8_t *parse_comment(uint8_t *p){    int c;        p++;    for(;;) {        /* fast skip loop */        for(;;) {            c = *p;            if (c == '\n' || c == '*' || c == '\\')                break;            p++;            c = *p;            if (c == '\n' || c == '*' || c == '\\')                break;            p++;        }        /* now we can handle all the cases */        if (c == '\n') {            file->line_num++;            p++;        } else if (c == '*') {            p++;            for(;;) {                c = *p;                if (c == '*') {                    p++;                } else if (c == '/') {                    goto end_of_comment;                } else if (c == '\\') {                    file->buf_ptr = p;                    c = handle_eob();                    p = file->buf_ptr;                    if (c == '\\') {                        /* skip '\[\r]\n', otherwise just skip the stray */                        while (c == '\\') {                            PEEKC_EOB(c, p);                            if (c == '\n') {                                file->line_num++;                                PEEKC_EOB(c, p);                            } else if (c == '\r') {                                PEEKC_EOB(c, p);                                if (c == '\n') {                                    file->line_num++;                                    PEEKC_EOB(c, p);                                }                            } else {                                goto after_star;                            }                        }                    }                } else {                    break;                }            }        after_star: ;        } else {            /* stray, eob or eof */            file->buf_ptr = p;            c = handle_eob();            p = file->buf_ptr;            if (c == CH_EOF) {                error("unexpected end of file in comment");            } else if (c == '\\') {                p++;            }        }    } end_of_comment:    p++;    return p;}#define cinp minp/* space exlcuding newline */static inline int is_space(int ch){    return ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f' || ch == '\r';}static inline void skip_spaces(void){    while (is_space(ch))        cinp();}/* parse a string without interpreting escapes */static uint8_t *parse_pp_string(uint8_t *p,                                int sep, CString *str){    int c;    p++;    for(;;) {        c = *p;        if (c == sep) {            break;        } else if (c == '\\') {            file->buf_ptr = p;            c = handle_eob();            p = file->buf_ptr;            if (c == CH_EOF) {            unterminated_string:                /* XXX: indicate line number of start of string */                error("missing terminating %c character", sep);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -