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"
static Map *defined;
static Map *macros;
static void append(Vector *v1, Vector *v2) {
for (int i = 0; i < v2->len; i++)
vec_push(v1, v2->data[i]);
typedef struct Context {
Vector *input;
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) {
if (!defined)
defined = new_map();
if (!macros)
macros = new_map();
ctx = new_ctx(ctx, tokens);
Vector *v = new_vec();
for (int i = 0; i < tokens->len;) {
Token *t = tokens->data[i++];
while (!eof()) {
Token *t = next();
if (t->ty == TK_IDENT) {
Vector *macro = map_get(defined, t->name);
Vector *macro = map_get(macros, t->name);
if (macro)
append(v, macro);
append(macro);
else
vec_push(v, t);
add(t);
continue;
}
if (t->ty != '#') {
vec_push(v, t);
add(t);
continue;
}
t = tokens->data[i++];
if (t->ty != TK_IDENT)
bad_token(t, "identifier expected");
t = get(TK_IDENT, "identifier 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;
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;
}
if (!strcmp(t->name, "define"))
define();
else if (!strcmp(t->name, "include"))
include();
else
bad_token(t, "unknown directive");
}
Vector *v = ctx->output;
ctx = ctx->next;
return v;
}

View File

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