Implement #define but not function-like macro.

This commit is contained in:
Rui Ueyama 2018-08-25 05:16:07 +00:00
parent faeb010ea5
commit 5ef04d2867
2 changed files with 55 additions and 16 deletions

View File

@ -2,34 +2,71 @@
#include "9cc.h"
static Map *defined;
static void append(Vector *v1, Vector *v2) {
for (int i = 0; i < v2->len; i++)
vec_push(v1, v2->data[i]);
}
Vector *preprocess(Vector *tokens) {
if (!defined)
defined = new_map();
Vector *v = new_vec();
for (int i = 0; i < tokens->len;) {
Token *t = tokens->data[i];
Token *t = tokens->data[i++];
if (t->ty == TK_IDENT) {
Vector *macro = map_get(defined, t->name);
if (macro)
append(v, macro);
else
vec_push(v, t);
continue;
}
if (t->ty != '#') {
i++;
vec_push(v, t);
continue;
}
t = tokens->data[++i];
if (t->ty != TK_IDENT || strcmp(t->name, "include"))
bad_token(t, "'include' expected");
t = tokens->data[i++];
if (t->ty != TK_IDENT)
bad_token(t, "identifier expected");
t = tokens->data[++i];
if (t->ty != TK_STR)
bad_token(t, "string expected");
if (!strcmp(t->name, "define")) {
t = tokens->data[i++];
if (t->ty != TK_IDENT)
bad_token(t, "macro name expected");
char *name = t->name;
char *path = t->str;
Vector *v2 = new_vec();
while (i < tokens->len) {
t = tokens->data[i++];
if (t->ty == '\n')
break;
vec_push(v2, t);
}
t = tokens->data[++i];
if (t->ty != '\n')
bad_token(t, "newline expected");
map_put(defined, name, v2);
continue;
}
Vector *nv = tokenize(path, false);
for (int i = 0; i < nv->len; i++)
vec_push(v, nv->data[i]);
if (!strcmp(t->name, "include")) {
t = tokens->data[i++];
if (t->ty != TK_STR)
bad_token(t, "string expected");
char *path = t->str;
t = tokens->data[i++];
if (t->ty != '\n')
bad_token(t, "newline expected");
append(v, tokenize(path, false));
continue;
}
}
return v;
}

View File

@ -1 +1,3 @@
printf("OK\n");
#define OK "O%c\n", 'K'
printf(OK);