1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#include "chibicc.h"
typedef enum {
FILE_NONE, FILE_C, FILE_ASM, FILE_OBJ, FILE_AR, FILE_DSO,
} FileType;
char *base_file;
StringArray include_paths;
bool opt_fcommon = false;
bool opt_fpic;
static FILE *open_file(char *path) {
if (!path || strcmp(path, "-") == 0)
return stdout;
FILE *out = fopen(path, "w");
if (!out)
error("cannot open output file: %s: %s", path, strerror(errno));
return out;
}
static Token *must_tokenize_file(char *path) {
Token *tok = tokenize_file(path);
if (!tok)
error("%s: %s", path, strerror(errno));
return tok;
}
static Token *append_tokens(Token *tok1, Token *tok2) {
if (!tok1 || tok1->kind == TK_EOF)
return tok2;
Token *t = tok1;
while (t->next->kind != TK_EOF)
t = t->next;
t->next = tok2;
return tok1;
}
static void cc1(char *base_file) {
Token *tok = NULL;
// Tokenize and parse.
Token *tok2 = must_tokenize_file(base_file);
tok = append_tokens(tok, tok2);
tok = preprocess(tok);
Obj *prog = parse(tok);
// Open a temporary output buffer.
char *buf;
size_t buflen;
FILE *output_buf = open_memstream(&buf, &buflen);
// Traverse the AST to emit assembly.
typegen(prog, output_buf);
codegen(prog, output_buf);
fclose(output_buf);
// Write the asembly text to a file.
FILE *out = open_file("/dev/stdout");
fwrite(buf, buflen, 1, out);
fclose(out);
}
int main(int argc, char **argv) {
assert(argc == 2);
base_file = argv[1];
cc1(argv[1]);
return 0;
}
|