@@ -16,6 +16,29 @@ bool command_exists(const std::string &cmd) {
1616 return std::system (test.c_str ()) == 0 ;
1717}
1818
19+ std::string platform () {
20+ #ifdef __APPLE__
21+ return " macos" ;
22+ #elif _WIN32
23+ return " windows"
24+ #elif __linux__
25+ return " linux" ;
26+ #endif
27+ return " unknown" ;
28+ }
29+
30+ std::string def () {
31+ std::string p = platform ();
32+ if (p != " linux" && p != " macos" ) {
33+ p = " linux" ;
34+ }
35+ return p;
36+ }
37+
38+ std::string white (const std::string &s) { return " \033 [1m" + s + " \033 [0m" ; }
39+ std::string red (const std::string &s) { return " \033 [1;31m" + s + " \033 [0m" ; }
40+ std::string blue (const std::string &s) { return " \033 [1;36m" + s + " \033 [0m" ; }
41+
1942void print_help (const std::string &name) {
2043 std::cout << " Usage: " << name << " <filename.av>\n " ;
2144 std::cout << " Options:\n " ;
@@ -25,6 +48,9 @@ void print_help(const std::string &name) {
2548 std::cout << " -ast: Prints the AST (without desugaring)\n " ;
2649 std::cout << " --ast: Prints the AST (after desugaring)\n " ;
2750 std::cout << " -s: Prints the asm\n " ;
51+ std::cout << " \n " ;
52+ std::cout << " Parameters:\n " ;
53+ std::cout << " -target=<platform>: default: " << white (def ()) << " , can be either linux or macos\n " ;
2854}
2955
3056void print_version () {
@@ -38,10 +64,6 @@ void print_version() {
3864#endif
3965}
4066
41- std::string white (const std::string &s) { return " \033 [1;37m" + s + " \033 [0m" ; }
42- std::string red (const std::string &s) { return " \033 [1;31m" + s + " \033 [0m" ; }
43- std::string blue (const std::string &s) { return " \033 [1;36m" + s + " \033 [0m" ; }
44-
4567std::vector<std::string> lines;
4668void print_error (std::ostream &os, std::string file, int r1, int c1, int r2, int c2, std::string err) {
4769 std::string l = std::to_string (r1);
@@ -76,6 +98,15 @@ void print_error(std::ostream &os, std::string file, int r1, int c1, int r2, int
7698 }
7799}
78100
101+ std::string nasm_platform (const std::string &platform) {
102+ if (platform == " linux" ) {
103+ return " elf64" ;
104+ } else if (platform == " macos" ) {
105+ return " macho64" ;
106+ }
107+ assert (false );
108+ }
109+
79110int main (int argc, char **_argv) {
80111 std::vector<std::string> argv (argc);
81112 for (int i = 0 ; i < argc; ++i) {
@@ -87,17 +118,41 @@ int main(int argc, char **_argv) {
87118 return 0 ;
88119 }
89120
90- std::vector<std::string> files ;
121+ std::vector<bool > used (argc) ;
91122 std::array<std::string, 6 > options{" -tokenize" , " -ast" , " -s" , " --help" , " --version" , " --ast" };
92123 std::array values{false , false , false , false , false , false };
93124 for (int i = 1 ; i < argc; ++i) {
94125 int it = std::find (options.begin (), options.end (), argv[i]) - options.begin ();
95126 if (it != options.size ()) {
127+ used[i] = true ;
96128 if (values[it]) {
97129 std::cerr << " warning: " << options[it] << " repeated\n " ;
98130 }
99131 values[it] = true ;
100- } else {
132+ }
133+ }
134+
135+ std::array<std::string, 1 > params{" -target=" };
136+ std::array<std::string, 1 > choices = {};
137+ for (int i = 1 ; i < argc; ++i) {
138+ int it = std::find_if (params.begin (), params.end (), [&](const std::string &s) { return argv[i].find (s) == 0 ; }) - params.begin ();
139+ if (it == params.size ()) {
140+ continue ;
141+ }
142+ used[i] = true ;
143+ if (!choices[it].empty ()) {
144+ std::cerr << red (" error: " ) << " parameter " << params[it].substr (0 , params[it].length () - 1 ) << " specified more than 1 time\n " ;
145+ return 1 ;
146+ }
147+ choices[it] = argv[i].substr (params[it].length ());
148+ }
149+ if (choices[0 ].empty ()) {
150+ choices[0 ] = def ();
151+ }
152+
153+ std::vector<std::string> files;
154+ for (int i = 1 ; i < argc; ++i) {
155+ if (!used[i]) {
101156 files.push_back (argv[i]);
102157 }
103158 }
@@ -111,6 +166,11 @@ int main(int argc, char **_argv) {
111166 return 0 ;
112167 }
113168
169+ if (choices[0 ] != " linux" && choices[0 ] != " macos" ) {
170+ std::cerr << red (" error: " ) << " value " << choices[0 ] << " for parameter " << params[0 ] << " is invalid\n " ;
171+ return 1 ;
172+ }
173+
114174 if (files.size () == 0 ) {
115175 std::cerr << red (" error: " ) << " no input file specified\n " ;
116176 return 1 ;
@@ -213,7 +273,7 @@ int main(int argc, char **_argv) {
213273 av::tokenizer tk (code);
214274 av::Node *root = av::parse (tk);
215275 av::desugar (root);
216- av::generate (root, std::cout);
276+ av::generate (root, av::platform_from_string (choices[ 0 ]), std::cout);
217277 delete root;
218278 return 0 ;
219279 } catch (av::Error e) {
@@ -238,12 +298,16 @@ int main(int argc, char **_argv) {
238298 }
239299 std::stringstream os;
240300 os << " section .text\n " ;
241- av::generate (root, os);
301+ av::generate (root, av::platform_from_string (choices[ 0 ]), os);
242302 os << " global _start\n " ;
243303 os << " _start:\n " ;
244304 os << " call main\n " ;
245305 os << " mov edi, eax\n " ;
246- os << " mov eax, 60\n " ;
306+ if (choices[0 ] == " linux" ) {
307+ os << " mov eax, 60\n " ;
308+ } else {
309+ os << " mov eax, 33554433\n " ;
310+ }
247311 os << " syscall\n " ;
248312 std::ofstream oss (argv[1 ] + " .asm" );
249313 oss << os.str ();
@@ -260,11 +324,17 @@ int main(int argc, char **_argv) {
260324 if (!command_exists (" nasm" )) {
261325 std::cerr << " warning: nasm is not installed, stopping at the assembly emission step\n " ;
262326 } else {
263- std::system ((" nasm -f elf64 " + argv[1 ] + " .asm -o " + argv[1 ] + " .o" ).c_str ());
327+ std::system ((" nasm -f " + nasm_platform (choices[ 0 ]) + " " + argv[1 ] + " .asm -o " + argv[1 ] + " .o" ).c_str ());
264328 if (!command_exists (" ld" )) {
265329 std::cerr << " warning: ld is not installed, stopping at the object linking step\n " ;
266330 } else {
267- std::system ((" ld " + argv[1 ] + " .o -o a.out" ).c_str ());
331+ if (choices[0 ] == " linux" ) {
332+ std::system ((" ld " + argv[1 ] + " .o -o a.out" ).c_str ());
333+ } else if (choices[0 ] == " macos" ) {
334+ std::system ((" ld -platform_version macos 13.0 13.0 -e _start " + argv[1 ] + " .o -o a.out 2>/dev/null" ).c_str ());
335+ } else {
336+ assert (false );
337+ }
268338 }
269339 }
270340}
0 commit comments