mirror of https://github.com/rui314/9cc.git
Split preprocess() into smaller functions.
This commit is contained in:
parent
5ef04d2867
commit
1c7ee31757
125
preprocess.c
125
preprocess.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -5,3 +5,4 @@ int main() {
|
|||
1; 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue