2020-08-18 03:41:59 +03:00
|
|
|
#include "chibicc.h"
|
|
|
|
|
2020-03-30 03:30:06 +03:00
|
|
|
static bool is_hash(Token *tok) {
|
|
|
|
return tok->at_bol && equal(tok, "#");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Visit all tokens in `tok` while evaluating preprocessing
|
|
|
|
// macros and directives.
|
|
|
|
static Token *preprocess2(Token *tok) {
|
|
|
|
Token head = {};
|
|
|
|
Token *cur = &head;
|
|
|
|
|
|
|
|
while (tok->kind != TK_EOF) {
|
|
|
|
// Pass through if it is not a "#".
|
|
|
|
if (!is_hash(tok)) {
|
|
|
|
cur = cur->next = tok;
|
|
|
|
tok = tok->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
tok = tok->next;
|
|
|
|
|
|
|
|
// `#`-only line is legal. It's called a null directive.
|
|
|
|
if (tok->at_bol)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
error_tok(tok, "invalid preprocessor directive");
|
|
|
|
}
|
|
|
|
|
|
|
|
cur->next = tok;
|
|
|
|
return head.next;
|
|
|
|
}
|
|
|
|
|
2020-08-18 03:41:59 +03:00
|
|
|
// Entry point function of the preprocessor.
|
|
|
|
Token *preprocess(Token *tok) {
|
2020-03-30 03:30:06 +03:00
|
|
|
tok = preprocess2(tok);
|
2020-08-18 03:41:59 +03:00
|
|
|
convert_keywords(tok);
|
|
|
|
return tok;
|
|
|
|
}
|