#define FRONTEND_IMPLEMENTATION #include "../frontend.h" #include "token.h" #define ROUND_IDX(idx) ((idx) % tokbuf->cap) tok_t* pop_tok(tok_buf_t* tokbuf) { if (tokbuf->size == 0) { error("no token to pop"); return NULL; } int idx = tokbuf->cur; tokbuf->cur = ROUND_IDX(idx + 1); tokbuf->size -= 1; return tokbuf->buf + idx; } void flush_peek_tok(tok_buf_t* tokbuf) { tokbuf->peek = tokbuf->cur; } void init_tokbuf(tok_buf_t *tokbuf, void *stream, get_tokbuf_func gettok) { tokbuf->cur = 0; tokbuf->end = 0; tokbuf->peek = 0; tokbuf->size = 0; tokbuf->stream = stream; tokbuf->gettok = gettok; tokbuf->buf = NULL; tokbuf->cap = 0; } tok_t *peek_tok(tok_buf_t *tokbuf) { int idx = tokbuf->peek; tokbuf->peek = ROUND_IDX(idx + 1); if (tokbuf->size >= tokbuf->cap) { error("peek too deep, outof array size"); } if (idx == tokbuf->end) { if (tokbuf->size == tokbuf->cap) { error("peek_tok buffer overflow"); } if (tokbuf->gettok == NULL) { error("peek_tok can not got tok"); } tokbuf->gettok(tokbuf->stream, &(tokbuf->buf[idx])); tokbuf->size++; tokbuf->end = tokbuf->peek; } return &(tokbuf->buf[idx]); } tok_type_t peek_tok_type(tok_buf_t* tokbuf) { return peek_tok(tokbuf)->type; } int expect_pop_tok(tok_buf_t* tokbuf, tok_type_t type) { flush_peek_tok(tokbuf); tok_t* tok = peek_tok(tokbuf); if (tok->type != type) { error("expected tok: %s, got %s", get_tok_name(type), get_tok_name(tok->type)); } else { pop_tok(tokbuf); } return 0; } // 生成字符串映射(根据需求选择#str或#name) static const char* token_strings[] = { // 普通token使用#str #define X(str, tok) [tok] = #str, TOKEN_TABLE #undef X // 关键字使用#name #define X(name, std, tok) [tok] = #name, KEYWORD_TABLE #undef X }; const char* get_tok_name(tok_type_t type) { return token_strings[type]; }