-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
83 lines (70 loc) · 2.31 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
#include <string>
#include <cstdio>
#include <llvm/Support/CommandLine.h>
#include "ASTnode.h"
#include "grammar.hpp"
#include "codegen.h"
#include "objgen.h"
ASTnode* rootNode;
std::string errmsg;
void Error(std::string prefix) {
printf("%s:\n", prefix.c_str());
if(errmsg.size()>0) {
printf("\t%s\n", errmsg.c_str());
}
exit(0);
}
int main(int argc, char** argv) {
llvm::cl::ResetCommandLineParser();
llvm::cl::opt<std::string> OutputFilename("o",
llvm::cl::desc("Specify output filename"), llvm::cl::value_desc("filename"));
llvm::cl::opt<bool> AST("ast", llvm::cl::desc("Print ast structure"));
llvm::cl::opt<bool> EmitLLVM("emit-llvm", llvm::cl::desc("Output IR code"));
llvm::cl::opt<std::string> InputFilename(llvm::cl::Positional, llvm::cl::desc("<input file>"));
llvm::cl::opt<bool> Help("h", llvm::cl::desc("Display available options"));
llvm::cl::ParseCommandLineOptions(argc, argv);
if(Help) {
llvm::cl::PrintHelpMessage();
return 0;
}
if(InputFilename.size() != 0) {
FILE* _ = freopen(InputFilename.c_str(), "r", stdin);
if(_ == nullptr) {
Error("Failed to open file!");
}
} else {
printf("input file required!");
return 0;
}
std::string output_filename;
if(OutputFilename.size() != 0) {
output_filename = OutputFilename;
} else {
output_filename = InputFilename + ".out";
}
int ret;
ret = yyparse();
if(ret) Error("AST generate Error");
if(AST) {
rootNode->Traverse(2);
}
CodegenContext context;
ret = GenerateCode(context, rootNode);
if(ret) Error("IRCode generate Error");
if(EmitLLVM) {
std::error_code EC;
llvm::raw_fd_ostream dest(output_filename, EC, llvm::sys::fs::OF_None);
EXCEPT_MSG_RET(!EC, "Can not open file: " + EC.message(), -1);
context.module->print(dest, nullptr);
return 0;
}
std::string objname = output_filename+".o";
ret = GenerateObject(context, objname);
if(ret) Error("Object generate Error");
std::string cmdline = "g++ -no-pie -o " + output_filename + " " + objname;
if(system(cmdline.c_str()) != 0)
Error("Executable generate Error");
cmdline = "rm " + objname;
system(cmdline.c_str());
return 0;
}