-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.cpp
161 lines (151 loc) · 5.39 KB
/
main.cpp
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "logger/logger.h"
#include "compiler/preprocessor.h"
#include "compiler/lexer.h"
#include "compiler/syntaxer.h"
#include "compiler/mir.h"
#include "compiler/optimization.h"
#include "config.h"
#include "assembler.h"
#define MAIN_TAG "main"
static const char *outputFileName = nullptr;
static const char *sourceFileName = nullptr;
static Arch targetArch = ARCH_ARM64;
static Platform targetPlatform = PLATFORM_LINUX;
static int optimizationLevel = -1;
static int outputAssembly = 0;
static int sharedLib = 0;
static int fpic = 0;
static void version() {
printf("\n");
printf(" __ \n"
" /\\ \\ \n"
" _____ __ _ __\\ \\ \\/'\\ \n"
"/\\ '__`\\ /'__`\\ /\\`'__\\ \\ , < \n"
"\\ \\ \\L\\ \\/\\ \\L\\.\\_\\ \\ \\/ \\ \\ \\\\`\\ \n"
" \\ \\ ,__/\\ \\__/.\\_\\\\ \\_\\ \\ \\_\\ \\_\\\n"
" \\ \\ \\/ \\/__/\\/_/ \\/_/ \\/_/\\/_/\n"
" \\ \\_\\ \n"
" \\/_/ \n");
printf("park's c compiler kit\n");
printf("version %s\n", PROJECT_VERSION);
printf("build time:%s %s\n", __DATE__, __TIME__);
}
static void usage(int exitcode) {
version();
fprintf(exitcode ? stderr : stdout,
"Usage: pcc -[options] <file>\n\n"
" -o <filename> \toutput file path\n"
" -O<number> \toptimization level\n"
" -a <target-arch> \ttarget cpu inst (arm64, x86_64)\n"
" -p <target-platform> \ttarget os platform (linux, macos, windows, bare)\n"
" -shared \twrapper as shared lib\n"
" -h \tprint this help\n"
"\n"
);
exit(exitcode);
}
void processParams(int argc, char **argv) {
for (;;) {
int opt = getopt(argc, argv, "O:o:a:p:s:f:Shv");
if (opt == -1)
break;
switch (opt) {
case 'O':
optimizationLevel = atoi(optarg);
logd(MAIN_TAG, "[+] optimize level=%d", optimizationLevel);
break;
case 'S':
logd(MAIN_TAG, "[+] output assembly");
outputAssembly = 1;
break;
case 'o':
logd(MAIN_TAG, "[+] output file=%s", optarg);
outputFileName = optarg;
break;
case 'a':
logd(MAIN_TAG, "[+] target architecture=%s", optarg);
targetArch = ARCH_UNKNOWN;
if (strcmp(optarg, "arm64") == 0) {
targetArch = ARCH_ARM64;
} else if (strcmp(optarg, "x86_64") == 0) {
targetArch = ARCH_X86_64;
}
break;
case 'p':
logd(MAIN_TAG, "[+] target platform=%s", optarg);
targetPlatform = PLATFORM_UNKNOWN;
if (strcmp(optarg, "linux") == 0) {
targetPlatform = PLATFORM_LINUX;
} else if (strcmp(optarg, "macos") == 0) {
targetPlatform = PLATFORM_MACOS;
} else if (strcmp(optarg, "windows") == 0) {
targetPlatform = PLATFORM_WINDOWS;
} else if (strcmp(optarg, "bare") == 0) {
targetPlatform = PLATFORM_BARE;
}
break;
case 'f':
if (optarg != nullptr && strcmp("pic", optarg) == 0) {
logd(MAIN_TAG, "[+] position independent code (fPIC)");
fpic = 1;
}
break;
case 'h':
logd(MAIN_TAG, "[+] show help");
usage(0);
break;
case 'v':
version();
exit(0);
break;
case 's':
if (optarg != nullptr && strcmp("hared", optarg) == 0) {
logd(MAIN_TAG, "[+] generate shared library");
sharedLib = 1;
}
break;
default:
loge(MAIN_TAG, "[-] unknown opt=%d, arg=%s", opt, optarg);
usage(1);
}
}
if (targetArch == ARCH_UNKNOWN) {
loge(MAIN_TAG, "unknown arch");
usage(1);
}
if (targetPlatform == PLATFORM_UNKNOWN) {
loge(MAIN_TAG, "unknown platform");
usage(1);
}
// Ensure that the input source file is provided
if (optind != argc - 1) {
usage(1);
}
sourceFileName = argv[optind];
logd(MAIN_TAG, "[+] input file name=%s", sourceFileName);
// Further processing logic (such as handling default behaviors or flags) goes here
}
int main(int argc, char **argv) {
initLogger();
processParams(argc, argv);
ProcessedSource *source = preprocess(sourceFileName);
Token *tokens = buildTokens(source);
releasePreProcessorMemory();
printTokenStack(tokens);
AstProgram *program = buildAst(tokens);
releaseLexerMemory();
Mir *mir = generateMir(program);
releaseAstMemory();
mir = optimize(mir, optimizationLevel);
printMir(mir);
generateTargetFile(mir,
targetArch,
targetPlatform,
sharedLib,
outputFileName);
return 0;
}