aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-04 18:24:49 +0900
committernsfisis <nsfisis@gmail.com>2025-05-04 18:24:49 +0900
commit72a19908d4f0c1aad46bd38ce6926dd60b9247e3 (patch)
treee8a0ce03303cdc5106ca507fa7ccf7e1cb34cdf8
parent7954a9925a76d45a665934944d80b09638c8340b (diff)
downloadP4Dcc-72a19908d4f0c1aad46bd38ce6926dd60b9247e3.tar.gz
P4Dcc-72a19908d4f0c1aad46bd38ce6926dd60b9247e3.tar.zst
P4Dcc-72a19908d4f0c1aad46bd38ce6926dd60b9247e3.zip
support #define directive
-rw-r--r--main.c46
-rw-r--r--tests/026.sh43
2 files changed, 88 insertions, 1 deletions
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