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/*
68todo:
79
@@ -15,11 +17,13 @@ struct token
1517
1618typedef token1 token2
1719
20+ include recursivity
21+
1822preprocessors
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;
7378vector<string> REG ;
7479vector<constant> spaces;
7580vector<coperator> operators;
76- vector<string> externs;
81+ vector<constant> externs;
82+ vector<string> includes_f;
7783vector<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+
106100int 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