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"
|
#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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,3 +5,4 @@ int main() {
|
||||||
1; 2;
|
1; 2;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue