From 72a19908d4f0c1aad46bd38ce6926dd60b9247e3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sun, 4 May 2025 18:24:49 +0900 Subject: support #define directive --- main.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- tests/026.sh | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 tests/026.sh diff --git a/main.c b/main.c index beaa35b..b61b16a 100644 --- a/main.c +++ b/main.c @@ -82,9 +82,16 @@ typedef struct Token { char* value; } TOKEN; +typedef struct Define { + char* from; + TOKEN* to; +} DEFINE; + TOKEN* tokenize(char* src, int len) { TOKEN* tokens = calloc(1024*1024, sizeof(TOKEN)); TOKEN* tok = tokens; + DEFINE* defines = calloc(1024, sizeof(DEFINE)); + DEFINE* def = defines; int pos = 0; while (pos < len) { char c = src[pos]; @@ -240,13 +247,50 @@ TOKEN* tokenize(char* src, int len) { } else if (strstr(src + start, "void") == src + start) { tok->kind = TK_K_VOID; } else { - tok->kind = TK_IDENT; + // TODO tok->value = calloc(pos - start + 1, sizeof(char)); memcpy(tok->value, src + start, pos - start); + int i = 0; + while (defines + i != def) { + if (strcmp(tok->value, defines[i].from) == 0) { + tok->kind = defines[i].to->kind; + tok->value = defines[i].to->value; + break; + } + i += 1; + } + if (defines + i == def) { + tok->kind = TK_IDENT; + } } tok += 1; } else if (isspace(c)) { pos += 1; + } else if (c == '#') { + // TODO: too ugly implementation! + pos += 1; + pos += 6; + while (isspace(src[pos])) { + pos += 1; + } + int start = pos; + while (isalnum(src[pos]) || src[pos] == '_') { + pos += 1; + } + def->from = calloc(pos - start + 1, sizeof(char)); + memcpy(def->from, src + start, pos - start); + while (isspace(src[pos])) { + pos += 1; + } + int start2 = pos; + while (isdigit(src[pos])) { + pos += 1; + } + def->to = calloc(1, sizeof(TOKEN)); + def->to->kind = TK_L_INT; + def->to->value = calloc(pos - start2 + 1, sizeof(char)); + memcpy(def->to->value, src + start2, pos - start2); + def += 1; } else { fatal_error("unknown token"); } diff --git a/tests/026.sh b/tests/026.sh new file mode 100644 index 0000000..cd4500e --- /dev/null +++ b/tests/026.sh @@ -0,0 +1,43 @@ +set -e + +cat <<'EOF' > expected +EOF +bash ../../test_diff.sh <<'EOF' +#define A 1 +int main() { + return 0; +} +EOF + +cat <<'EOF' > expected +1,2,3 +EOF +bash ../../test_diff.sh <<'EOF' +int printf(); + +#define A 1 +#define B 2 +#define C 3 + +int main() { + printf("%d,%d,%d\n", A, B, C); + return 0; +} +EOF + +cat <<'EOF' > expected +0,0,0,0 +EOF +bash ../../test_diff.sh <<'EOF' +int printf(); + +#define NULL 0 +#define TK_EOF 0 +#define TY_UNKNOWN 0 +#define AST_UNKNOWN 0 + +int main() { + printf("%d,%d,%d,%d\n", NULL, TK_EOF, TY_UNKNOWN, AST_UNKNOWN); + return 0; +} +EOF -- cgit v1.2.3-70-g09d2