Skip to content

Commit 1a93c68

Browse files
authored
Merge pull request #1605 from Smit-create/c_back
Add --backend=c to directly run with C
2 parents a49f18f + eb0bd41 commit 1a93c68

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ inst/bin/*
8787
*_lines.txt
8888
*_ldd.txt
8989
*_lines.dat.txt
90+
*__tmp__generated__.c
9091

9192
### https://raw.github.com/github/gitignore/218a941be92679ce67d0484547e3e142b2f5f6f0/Global/macOS.gitignore
9293

ci/test.xsh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ if $WIN == "1":
1919
python run_tests.py --skip-run-with-dbg --no-color
2020
else:
2121
python run_tests.py
22+
src/bin/lpython examples/expr2.py
23+
src/bin/lpython --backend=c examples/expr2.py
2224
cd integration_tests
2325
python run_tests.py -j16 -b llvm cpython c wasm
2426

src/bin/lpython.cpp

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
307354
int 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

Comments
 (0)