Split preprocess() into smaller functions.

This commit is contained in:
Rui Ueyama 2018-08-25 05:50:00 +00:00
parent 5ef04d2867
commit 1c7ee31757
2 changed files with 78 additions and 48 deletions

View File

@ -2,71 +2,100 @@
#include "9cc.h" #include "9cc.h"
static Map *defined; static Map *macros;
static void append(Vector *v1, Vector *v2) { typedef struct Context {
for (int i = 0; i < v2->len; i++) Vector *input;
vec_push(v1, v2->data[i]); Vector *output;
int pos;
struct Context *next;
} Context;
static Context *ctx;
static Context *new_ctx(Context *next, Vector *input) {
Context *c = calloc(1, sizeof(Context));
c->input = input;
c->output = new_vec();
c->next = next;
return c;
}
static void append(Vector *v) {
for (int i = 0; i < v->len; i++)
vec_push(ctx->output, v->data[i]);
}
static void add(Token *t) { vec_push(ctx->output, t); }
static Token *next() {
assert(ctx->pos < ctx->input->len);
return ctx->input->data[ctx->pos++];
}
static bool eof() { return ctx->pos == ctx->input->len; }
static Token *get(int ty, char *msg) {
Token *t = next();
if (t->ty != ty)
bad_token(t, msg);
return t;
}
static void define() {
Token *t = get(TK_IDENT, "macro name expected");
char *name = t->name;
Vector *v = new_vec();
while (!eof()) {
t = next();
if (t->ty == '\n')
break;
vec_push(v, t);
}
map_put(macros, name, v);
}
static void include() {
Token *t = get(TK_STR, "string expected");
char *path = t->str;
get('\n', "newline expected");
append(tokenize(path, false));
} }
Vector *preprocess(Vector *tokens) { Vector *preprocess(Vector *tokens) {
if (!defined) if (!macros)
defined = new_map(); macros = new_map();
ctx = new_ctx(ctx, tokens);
Vector *v = new_vec(); while (!eof()) {
Token *t = next();
for (int i = 0; i < tokens->len;) {
Token *t = tokens->data[i++];
if (t->ty == TK_IDENT) { if (t->ty == TK_IDENT) {
Vector *macro = map_get(defined, t->name); Vector *macro = map_get(macros, t->name);
if (macro) if (macro)
append(v, macro); append(macro);
else else
vec_push(v, t); add(t);
continue; continue;
} }
if (t->ty != '#') { if (t->ty != '#') {
vec_push(v, t); add(t);
continue; continue;
} }
t = tokens->data[i++]; t = get(TK_IDENT, "identifier expected");
if (t->ty != TK_IDENT)
bad_token(t, "identifier expected");
if (!strcmp(t->name, "define")) { if (!strcmp(t->name, "define"))
t = tokens->data[i++]; define();
if (t->ty != TK_IDENT) else if (!strcmp(t->name, "include"))
bad_token(t, "macro name expected"); include();
char *name = t->name; else
bad_token(t, "unknown directive");
Vector *v2 = new_vec();
while (i < tokens->len) {
t = tokens->data[i++];
if (t->ty == '\n')
break;
vec_push(v2, t);
}
map_put(defined, name, v2);
continue;
}
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;
}
} }
Vector *v = ctx->output;
ctx = ctx->next;
return v; return v;
} }

View File

@ -5,3 +5,4 @@ int main() {
1; 2; 1; 2;
return 0; return 0;
} }