Skip to content

Commit 6bd61cb

Browse files
v1.0-stable
1 parent b3fccd3 commit 6bd61cb

6 files changed

Lines changed: 209 additions & 92 deletions

File tree

LScc.cpp

Lines changed: 112 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#include <fstream>
2-
#include <cstdlib>
3-
#include "compilation.h"
1+
#include "lscc.h"
42

3+
#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
4+
#else
5+
#error "compiler must be at c++17 to compile!"
6+
#endif
57
/*
68
todo:
79
@@ -15,11 +17,13 @@ struct token
1517
1618
typedef token1 token2
1719
20+
include recursivity
21+
1822
preprocessors
1923
2024
*/
2125

22-
std::map < string, Basetype > type_dict = {
26+
map < string, Basetype > type_dict = {
2327
{ "float", Basetype::_float },
2428
{ "int", Basetype::_int },
2529
{ "str", Basetype::_string },
@@ -28,7 +32,7 @@ std::map < string, Basetype > type_dict = {
2832
{ "any", Basetype::_any }
2933
};
3034

31-
std::map < string, Tokentypes > tokens_dict = {
35+
map < string, Tokentypes > tokens_dict = {
3236
{ "def", Tokentypes::definition },
3337
{ "end", Tokentypes::end },
3438
{ "$", Tokentypes::condition },
@@ -45,6 +49,7 @@ std::map < string, Tokentypes > tokens_dict = {
4549
{ "\n", Tokentypes::lf },
4650
{ ":", Tokentypes::colon },
4751
{ "extern", Tokentypes::_extern },
52+
{ "include", Tokentypes::_include },
4853
{ "with", Tokentypes::with },
4954
{ "#", Tokentypes::comment },
5055
{ "operator", Tokentypes::_operator },
@@ -73,134 +78,132 @@ vector<int> argument_order;
7378
vector<string> REG;
7479
vector<constant> spaces;
7580
vector<coperator> operators;
76-
vector<string> externs;
81+
vector<constant> externs;
82+
vector<string> includes_f;
7783
vector<string> pcllibs;
7884

79-
string fcout(string str) {
80-
string ostr = "";
81-
for (char chr : str) {
82-
if (chr < 20) {
83-
ostr += "\\" + to_string((int)chr);
84-
}
85-
else ostr += chr;
86-
}
87-
return ostr;
88-
}
85+
map<LsccArg, string> Args{
86+
{LsccArg::i, "" },
87+
{LsccArg::o, "" },
88+
{LsccArg::f, "" },
89+
{LsccArg::cc, "" },
90+
};
8991

90-
void print_t_array(const vector<token> a, std::ostream& o)
92+
string SplitFileName(const string& str)
9193
{
92-
size_t N = a.size();
93-
if (N > 0) {
94-
o << "{";
95-
for (std::size_t i = 0; i < N - 1; ++i)
96-
{
97-
o << fcout(a[i].t) << ", ";
98-
}
99-
o << fcout(a[N - 1].t) << "}\n";
100-
}
101-
else {
102-
o << "{}\n";
103-
}
94+
size_t found;
95+
found = str.find_last_of("/\\");
96+
return str.substr(0, found);
10497
}
10598

99+
106100
int main(int argc, char** argv)
107101
{
108-
string file;
109-
string ofile;
110102
string afile;
111-
string Fformat;
112-
string Cconvention;
113103
bool save = false;
114104
if (argc == 1) {
115105
cout << Error::errorTypeError << "LScc: fatal: no input file specified" << endl << Error::errorTypeNormal
116106
<< "\
117-
Usage: LScc[options...] \n\
107+
Usage: LScc [file] [options...] \n\
118108
\n\
119109
Options : \n\
120110
----compilation options---- \n\
121-
-i input file \n\
122111
-o output file | default: input file.obj \n\
123-
-cc calling convention[SysVi386, SysV, M64] | default: SysV \n\
124-
-f format[elf32, elf64, elfx32, win32, win64] | default: elf64 \n\
112+
-cc calling convention[SysVi386, SysV, M64] \n\
113+
-f format[elf32, elf64, elfx32, win32, win64] \n\
125114
-n no start function \n\
126115
-s save asm file \n\
127116
\n\
128117
----warnings options---- \n\
129118
--w-type disable type convertion warnings \n";
130119
}
131120
else {
132-
size_t in1 = in("-i", argv, argc);
133-
if (in1 != -1) {
134-
file = argv[in1 + 1];
135-
}
136-
else {
137-
cout << "Error: no input file specified!" << endl;
138-
// exit(1);
139-
}
121+
122+
Args[LsccArg::i] = argv[1];
140123

141-
in1 = in("-f", argv, argc);
124+
size_t in1 = in("-f", argv, argc);
142125
if (in1 != -1) {
143-
Fformat = argv[in1 + 1];
126+
Args[LsccArg::f] = argv[in1 + 1];
144127
}
145128
else {
146-
Fformat = "elf64";
129+
if (getenv("windir") != NULL) {
130+
if (sizeof(void*) == 8) {
131+
Args[LsccArg::f] = "win64";
132+
}
133+
else {
134+
Args[LsccArg::f] = "win32";
135+
}
136+
}
137+
else {
138+
if (sizeof(void*) == 8) {
139+
Args[LsccArg::f] = "elf64";
140+
}
141+
else {
142+
Args[LsccArg::f] = "elf32";
143+
}
144+
}
147145
}
148146

149147
in1 = in("-o", argv, argc);
150148
if (in1 != -1) {
151-
ofile = argv[in1 + 1];
152-
afile = string(file.substr(0, file.rfind('.'))) + ".asm";
149+
Args[LsccArg::o] = argv[in1 + 1];
150+
afile = string(Args[LsccArg::i].substr(0, Args[LsccArg::i].rfind('.'))) + ".asm";
153151
}
154152
else {
155-
string filewoext = file.substr(0, file.rfind('.'));
156-
ofile = filewoext + ".obj";
153+
string filewoext = Args[LsccArg::i].substr(0, Args[LsccArg::i].rfind('.'));
154+
Args[LsccArg::o] = filewoext + ".obj";
157155
afile = filewoext + ".asm";
158156
}
159157

160158
in1 = in("-s", argv, argc);
161159
if (in1 != -1) {
162-
save = true;
160+
Args[LsccArg::s] = "1";
163161
}
164162

165163
in1 = in("-cc", argv, argc);
166164
if (in1 != -1) {
167-
Cconvention = argv[in1 + 1];
165+
Args[LsccArg::cc] = argv[in1 + 1];
168166
}
169167
else {
170-
Cconvention = "SysV";
168+
if (getenv("windir") != NULL) {
169+
Args[LsccArg::cc] = "M64";
170+
}
171+
else {
172+
Args[LsccArg::cc] = "SysV";
173+
}
171174
}
172175

173176
in1 = in("--w-type", argv, argc);
174177
if (in1 != -1) {
175178
Error::enabledWarns[Error::typeWarn] = false;
176179
}
177180

178-
if (Fformat == "elf64" || Fformat == "win64") {
181+
if (Args[LsccArg::f] == "elf64" || Args[LsccArg::f] == "win64") {
179182
REG.insert(REG.end(), { "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "xmm0", "xmm1", "xmm2", "xmm3", "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d", "cr0", "cr2", "cr3", "cr4", "cr8" });
180183
}
181-
elif(Fformat == "elf32" || Fformat == "win32" || Fformat == "elfx32") {
184+
elif(Args[LsccArg::f] == "elf32" || Args[LsccArg::f] == "win32" || Args[LsccArg::f] == "elfx32") {
182185
REG.insert(REG.end(), { "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d", "cr0", "cr2", "cr3", "cr4", "cr8"});
183186
}
184187
else {
185-
cout << "Error: invalid format \"" << Fformat << "\" !" << endl;
188+
cout << "Error: invalid format \"" << Args[LsccArg::f] << "\" !" << endl;
186189
exit(1);
187190
}
188191

189-
if (Cconvention == "M64") {
192+
if (Args[LsccArg::cc] == "M64") {
190193
argument_order.insert(argument_order.end(), { 2, 3, 8, 9 });
191194
}
192-
elif(Cconvention == "SysV") {
195+
elif(Args[LsccArg::cc] == "SysV") {
193196
argument_order.insert(argument_order.end(), { 5, 4, 3, 2, 8, 9 });
194197
}
195-
elif(Cconvention == "SysVi386") {
198+
elif(Args[LsccArg::cc] == "SysVi386") {
196199
argument_order.clear();
197200
}
198201
else {
199-
cout << "Error: invalid calling convention \"" << Cconvention << "\" !" << endl;
202+
cout << "Error: invalid calling convention \"" << Args[LsccArg::cc] << "\" !" << endl;
200203
exit(1);
201204
}
202205

203-
vector<token> tokens = tokenize(file);
206+
vector<token> tokens = tokenize(Args[LsccArg::i]);
204207

205208
check_pcllibs(tokens);
206209

@@ -225,9 +228,50 @@ int main(int argc, char** argv)
225228
fuse_symbols(&tokens);
226229
identify_tokens(&tokens);
227230
check_externs(tokens);
228-
229-
for (string& e : externs) {
230-
section_text += "extern " + e + "\n";
231+
check_includes(tokens);
232+
233+
if (in("start", get_functions_name(tokens))) {
234+
if (Args[LsccArg::f] == "win64" || Args[LsccArg::f] == "win32") {
235+
section_text += "\
236+
GLOBAL WinMain\n\
237+
WinMain:\n\
238+
call start\n\
239+
ret\n\
240+
\n";
241+
}
242+
}
243+
244+
// compiling includes
245+
246+
for (string& e : includes_f) {
247+
if (e.size() <= 1) continue;
248+
compilation c;
249+
string ne = e.substr(1, e.size()-2);
250+
filesystem::path fileOption1 = (filesystem::current_path() / filesystem::path(ne));
251+
filesystem::path fileOption2 = (filesystem::path(Args[LsccArg::i]).parent_path() / filesystem::path(ne));
252+
vector<token> i_tokens;
253+
if (filesystem::exists(fileOption1)) {
254+
i_tokens = tokenize(fileOption1.string());
255+
}
256+
else {
257+
i_tokens = tokenize(fileOption2.string());
258+
}
259+
260+
check_pcllibs(i_tokens);
261+
fuse_symbols(&i_tokens);
262+
identify_tokens(&i_tokens);
263+
check_externs(i_tokens);
264+
check_includes(i_tokens); // not recussive yet
265+
vector<int> functions = get_functions(i_tokens);
266+
sort(functions.begin(), functions.end());
267+
functions.erase(unique(functions.begin(), functions.end()), functions.end());
268+
for (int f : functions) {
269+
section_text += c.compile_function(f, tokens);
270+
}
271+
}
272+
273+
for (constant& e : externs) {
274+
section_text += "extern " + e.name + "\n";
231275
}
232276

233277
compilation c;
@@ -249,13 +293,13 @@ int main(int argc, char** argv)
249293

250294
asFile.close();
251295

252-
system(string("nasm " + afile + " -f " + Fformat + " -o " + ofile).c_str());
296+
system(string("nasm " + afile + " -f " + Args[LsccArg::f] + " -o " + Args[LsccArg::o]).c_str());
253297

254298
if (!save) {
255299
remove(afile.c_str());
256300
}
257301

258-
cout << Error::errorTypeValid << "Successfully compiled \x1B[33m\"" << file << "\"\x1B[32m !" << Error::errorTypeNormal << endl;
302+
cout << Error::errorTypeValid << "Successfully compiled \x1B[33m\"" << Args[LsccArg::i] << "\"\x1B[32m !" << Error::errorTypeNormal << endl;
259303

260304
}
261305

0 commit comments

Comments
 (0)