@@ -304,6 +304,53 @@ int emit_c(const std::string &infile,
304304 return 0 ;
305305}
306306
307+ int emit_c_to_file (const std::string &infile, const std::string &outfile,
308+ const std::string &runtime_library_dir,
309+ CompilerOptions &compiler_options)
310+ {
311+ Allocator al (4 *1024 );
312+ LCompilers::diag::Diagnostics diagnostics;
313+ LCompilers::LocationManager lm;
314+ {
315+ LCompilers::LocationManager::FileLocations fl;
316+ fl.in_filename = infile;
317+ lm.files .push_back (fl);
318+ std::string input = LCompilers::read_file (infile);
319+ lm.init_simple (input);
320+ lm.file_ends .push_back (input.size ());
321+ }
322+ LCompilers::Result<LCompilers::LPython::AST ::ast_t *> r = parse_python_file (
323+ al, runtime_library_dir, infile, diagnostics, 0 , compiler_options.new_parser );
324+ std::cerr << diagnostics.render (lm, compiler_options);
325+ if (!r.ok ) {
326+ return 1 ;
327+ }
328+ LCompilers::LPython::AST ::ast_t * ast = r.result ;
329+
330+ diagnostics.diagnostics .clear ();
331+ LCompilers::Result<LCompilers::ASR ::TranslationUnit_t*>
332+ r1 = LCompilers::LPython::python_ast_to_asr (al, lm, *ast, diagnostics, compiler_options, true , infile);
333+ std::cerr << diagnostics.render (lm, compiler_options);
334+ if (!r1.ok ) {
335+ LCOMPILERS_ASSERT (diagnostics.has_error ())
336+ return 2 ;
337+ }
338+ LCompilers::ASR ::TranslationUnit_t* asr = r1.result ;
339+
340+ diagnostics.diagnostics .clear ();
341+ auto res = LCompilers::asr_to_c (al, *asr, diagnostics, compiler_options, 0 );
342+ std::cerr << diagnostics.render (lm, compiler_options);
343+ if (!res.ok ) {
344+ LCOMPILERS_ASSERT (diagnostics.has_error ())
345+ return 3 ;
346+ }
347+ FILE *fp;
348+ fp = fopen (outfile.c_str (), " w" );
349+ fputs (res.result .c_str (), fp);
350+ fclose (fp);
351+ return 0 ;
352+ }
353+
307354int emit_wat (const std::string &infile,
308355 const std::string &runtime_library_dir,
309356 CompilerOptions &compiler_options)
@@ -996,7 +1043,7 @@ int link_executable(const std::vector<std::string> &infiles,
9961043 const std::string &outfile,
9971044 const std::string &runtime_library_dir, Backend backend,
9981045 bool static_executable, bool kokkos,
999- CompilerOptions &compiler_options)
1046+ CompilerOptions &compiler_options, const std::string &rtlib_header_dir )
10001047{
10011048 /*
10021049 The `gcc` line for dynamic linking that is constructed below:
@@ -1116,14 +1163,27 @@ int link_executable(const std::vector<std::string> &infiles,
11161163 for (auto &s : infiles) {
11171164 cmd += s + " " ;
11181165 }
1119- cmd += + " -L" ;
1166+ cmd += " -L" ;
11201167 cmd += " " + post_options + " -lm" ;
11211168 int err = system (cmd.c_str ());
11221169 if (err) {
11231170 std::cout << " The command '" + cmd + " ' failed." << std::endl;
11241171 return 10 ;
11251172 }
11261173 return 0 ;
1174+ } else if (backend == Backend::c) {
1175+ std::string CXX = " gcc" ;
1176+ std::string cmd = CXX + " -o " + outfile + " " ;
1177+ for (auto &s : infiles) {
1178+ cmd += s + " " ;
1179+ }
1180+ cmd += " -I " + rtlib_header_dir;
1181+ int err = system (cmd.c_str ());
1182+ if (err) {
1183+ std::cout << " The command '" + cmd + " ' failed." << std::endl;
1184+ return 10 ;
1185+ }
1186+ return 0 ;
11271187 } else if (backend == Backend::x86) {
11281188 std::string cmd = " cp " + infiles[0 ] + " " + outfile;
11291189 int err = system (cmd.c_str ());
@@ -1679,14 +1739,19 @@ int main(int argc, char *argv[])
16791739 } else if (backend == Backend::wasm_x86 || backend == Backend::wasm_x64) {
16801740 err = compile_to_binary_wasm_to_x86 (arg_file, outfile,
16811741 runtime_library_dir, compiler_options, time_report, backend);
1742+ } else if (backend == Backend::c) {
1743+ std::string emit_file_name = basename + " __tmp__generated__.c" ;
1744+ err = emit_c_to_file (arg_file, emit_file_name, runtime_library_dir, compiler_options);
1745+ err = link_executable ({emit_file_name}, outfile, runtime_library_dir,
1746+ backend, static_link, true , compiler_options, rtlib_header_dir);
16821747 } else if (backend == Backend::llvm) {
16831748#ifdef HAVE_LFORTRAN_LLVM
16841749 std::string tmp_o = outfile + " .tmp.o" ;
16851750 err = compile_python_to_object_file (arg_file, tmp_o, runtime_library_dir,
16861751 lpython_pass_manager, compiler_options, time_report);
16871752 if (err != 0 ) return err;
16881753 err = link_executable ({tmp_o}, outfile, runtime_library_dir,
1689- backend, static_link, true , compiler_options);
1754+ backend, static_link, true , compiler_options, rtlib_header_dir );
16901755 if (err != 0 ) return err;
16911756
16921757#ifdef HAVE_RUNTIME_STACKTRACE
@@ -1742,7 +1807,7 @@ int main(int argc, char *argv[])
17421807 return 0 ;
17431808 } else {
17441809 return link_executable (arg_files, outfile, runtime_library_dir,
1745- backend, static_link, true , compiler_options);
1810+ backend, static_link, true , compiler_options, rtlib_header_dir );
17461811 }
17471812 } catch (const LCompilers::LCompilersException &e) {
17481813 std::cerr << " Internal Compiler Error: Unhandled exception" << std::endl;
0 commit comments