-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
146 lines (123 loc) · 3.12 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
#include <string>
#include <string_view>
#include <filesystem>
#include <cstring>
#include "Config.h"
#include "Allocator.h"
#include "PreProcessor.h"
#include "Parser.h"
#include "Compiler.h"
#include "BuiltinManager.h"
#include "VM.h"
PreProcessor *g_PreProcessor = nullptr;
Parser *g_Parser = nullptr;
Compiler *g_Compiler = nullptr;
VM *g_Vm = nullptr;
void SetBasePath(std::string_view path)
{
std::string curPath = std::filesystem::absolute(std::filesystem::path(path)).string();
#ifdef _WIN32
curPath = curPath.substr(0, curPath.find_last_of('\\') + 1);
#else
curPath = curPath.substr(0, curPath.find_last_of('/') + 1);
#endif
Config::GetInstance()->SetExecuteFilePath(curPath);
}
void Run(std::string_view content)
{
auto tokens = g_PreProcessor->PreProcess(content);
#ifndef NDEBUG
for (const auto &token : tokens)
std::cout << token << std::endl;
#endif
auto stmts = g_Parser->Parse(tokens);
#ifndef NDEBUG
for (const auto &stmt : stmts)
std::cout << stmt->Stringify() << std::endl;
#endif
auto fn = g_Compiler->Compile(stmts);
#ifndef NDEBUG
auto str = ObjectStringify(fn, true);
std::cout << str << std::endl;
//WriteFile(Config::GetInstance()->GetExecuteFilePath()+"TmpDump.txt",str);
#endif
for (auto stmt : stmts)
SAFE_DELETE(stmt);
g_Vm->Run(fn);
}
void Repl(std::string_view exePath)
{
SetBasePath(exePath);
std::string allLines;
std::string line;
std::cout << "> ";
while (getline(std::cin, line))
{
if (line == "exit")
return;
else if (line == "clear")
allLines.clear();
#ifdef COMPUTEDUCK_BUILD_WITH_LLVM
else if (line == "-nj" || line == "--no-jit")
Config::GetInstance()->SetUseJit(false);
#endif
else
{
allLines += line;
Run(allLines);
}
std::cout << "> ";
}
}
void RunFile(std::string_view path)
{
SetBasePath(path);
std::string content = ReadFile(path);
Run(content);
}
int32_t PrintUsage()
{
std::cout << "Usage: ComputeDuck [option]:" << std::endl;
std::cout << "-h or --help:show usage info." << std::endl;
std::cout << "-f or --file:run source file with a valid file path,like : ComputeDuck -f examples/array.cd." << std::endl;
#ifdef COMPUTEDUCK_BUILD_WITH_LLVM
std::cout << "-nj or --no-jit:not use jit compiler" << std::endl;
#endif
return EXIT_FAILURE;
}
#undef main
int32_t main(int argc, const char **argv)
{
std::string_view sourceFilePath;
for (size_t i = 0; i < argc; ++i)
{
if (strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "--file") == 0)
{
if (i + 1 < argc)
sourceFilePath = argv[++i];
else
return PrintUsage();
}
#ifdef COMPUTEDUCK_BUILD_WITH_LLVM
if (strcmp(argv[i], "-nj") == 0 || strcmp(argv[i], "--no-jit") == 0)
Config::GetInstance()->SetUseJit(false);
#endif
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
return PrintUsage();
}
Allocator::GetInstance()->Init();
g_PreProcessor = new PreProcessor();
g_Parser = new Parser();
g_Compiler = new Compiler();
g_Vm = new VM();
if (!sourceFilePath.empty())
RunFile(sourceFilePath);
else
Repl(argv[0]);
SAFE_DELETE(g_Vm);
SAFE_DELETE(g_Compiler);
SAFE_DELETE(g_Parser);
SAFE_DELETE(g_PreProcessor);
Allocator::GetInstance()->Destroy();
return 0;
}