Skip to content

Commit

Permalink
Merge pull request #1861 from Smit-create/i-1797
Browse files Browse the repository at this point in the history
@ccallable: Emit a header file with given name
  • Loading branch information
certik committed May 28, 2023
2 parents 0b31cff + cd20408 commit 9e8b2db
Show file tree
Hide file tree
Showing 35 changed files with 86 additions and 386 deletions.
9 changes: 9 additions & 0 deletions integration_tests/bindc_03.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ def h(q_void: CPtr) -> None:
print(el)
assert el == i * i + i%2


@ccallable(header="_test_bindc_03_my_header.h")
def test_emit_header_ccallable() -> i32:
i: i32 = 5
assert i == 5
i = i*5
return i + 10

def run():
a: CPtr
array_wrapped: ArrayWrapped = ArrayWrapped(a)
Expand All @@ -59,5 +67,6 @@ def run():
f(array_wrapped.array)
array_wrapped1 = array_wrapped
h(array_wrapped1.array)
assert test_emit_header_ccallable() == 35

run()
42 changes: 19 additions & 23 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <iostream>
#include <fstream>
#include <memory>

#include <libasr/asr.h>
Expand Down Expand Up @@ -655,29 +656,6 @@ R"(
#include <string.h>
#include <lfortran_intrinsics.h>
#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}
)";

std::string indent(indentation_level * indentation_spaces, ' ');
Expand Down Expand Up @@ -807,6 +785,24 @@ R"(
}
src = to_include + head + array_types_decls + unit_src +
ds_funcs_defined + util_funcs_defined;
if (!emit_headers.empty()) {
std::string to_includes_1 = "";
for (auto &s: headers) {
to_includes_1 += "#include <" + s + ">\n";
}
for (auto &f_name: emit_headers) {
std::ofstream out_file;
std::string out_src = to_includes_1 + head + f_name.second;
std::string ifdefs = f_name.first.substr(0, f_name.first.length() - 2);
std::transform(ifdefs.begin(), ifdefs.end(), ifdefs.begin(), ::toupper);
ifdefs += "_H";
out_src = "#ifndef " + ifdefs + "\n#define " + ifdefs + "\n\n" + out_src;
out_src += "\n\n#endif\n";
out_file.open(f_name.first);
out_file << out_src;
out_file.close();
}
}
}

void visit_Module(const ASR::Module_t &x) {
Expand Down
10 changes: 10 additions & 0 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class BaseCCPPVisitor : public ASR::BaseVisitor<Struct>
std::map<uint64_t, SymbolInfo> sym_info;
std::map<uint64_t, std::string> const_var_names;
std::map<int32_t, std::string> gotoid2name;
std::map<std::string, std::string> emit_headers;

// Output configuration:
// Use std::string or char*
Expand Down Expand Up @@ -622,6 +623,15 @@ R"(#include <stdio.h>
}
sub += "\n";
src = sub;
if (f_type->m_abi == ASR::abiType::BindC
&& f_type->m_deftype == ASR::deftypeType::Implementation) {
if (x.m_c_header) {
std::string header_name = std::string(x.m_c_header);
user_headers.insert(header_name);
emit_headers[header_name]+= "\n" + src;
src = "";
}
}
current_scope = current_scope_copy;
}

Expand Down
30 changes: 30 additions & 0 deletions src/libasr/runtime/lfortran_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,36 @@ typedef double _Complex double_complex_t;
#define LFORTRAN_API /* Nothing */
#endif



#ifndef ASSERT
#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#endif

#ifndef ASSERT_MSG
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}
#endif

LFORTRAN_API double _lfortran_sum(int n, double *v);
LFORTRAN_API void _lfortran_random_number(int n, double *v);
LFORTRAN_API double _lfortran_random();
Expand Down
6 changes: 3 additions & 3 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3809,9 +3809,9 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
AST::Call_t *call_d = AST::down_cast<AST::Call_t>(dec);
if (AST::is_a<AST::Name_t>(*call_d->m_func)) {
std::string name = AST::down_cast<AST::Name_t>(call_d->m_func)->m_id;
if (name == "ccall") {
if (name == "ccall" || "ccallable") {
current_procedure_abi_type = ASR::abiType::BindC;
current_procedure_interface = true;
if (name == "ccall") current_procedure_interface = true;
if (call_d->n_keywords > 0) {
for (size_t i=0; i < call_d->n_keywords; i++) {
if (std::string(call_d->m_keywords[i].m_arg) == "header") {
Expand All @@ -3820,7 +3820,7 @@ class SymbolTableVisitor : public CommonVisitor<SymbolTableVisitor> {
call_d->m_keywords[i].m_value)->m_value;
c_header_file = s2c(al, header_name);
} else {
throw SemanticError("header should be constant string in ccall",
throw SemanticError("header should be constant string in ccall/ccallable",
x.base.base.loc);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-bindc_06-a30d20f.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-bindc_06-a30d20f.stdout",
"stdout_hash": "e8983d6fcd2d2c6e975daae9aed736c86c8432adaed965caeef12cba",
"stdout_hash": "1592d4a00bd387b8ee0a53ab5671575310052fc871b4dfca170386fd",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
23 changes: 0 additions & 23 deletions tests/reference/c-bindc_06-a30d20f.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,6 @@
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}


struct dimension_descriptor
{
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-c_interop1-e215531.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-c_interop1-e215531.stdout",
"stdout_hash": "79bf04c21b0db44755fa1828851ba74ce803ba1748da76e0144e2908",
"stdout_hash": "6ff32cb0aeb8edf4f78af311a25512fc6f8f708e682ce94137f160ee",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
23 changes: 0 additions & 23 deletions tests/reference/c-c_interop1-e215531.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,6 @@
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}


struct dimension_descriptor
{
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-expr7-bb2692a.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-expr7-bb2692a.stdout",
"stdout_hash": "c5afb46e3538eeeff7e1b50eac49c6f2fa57468bb40d278b207ee60d",
"stdout_hash": "6ec5c40f07c1fb2fbfad9c3ff031e50cf077c0ad2412c7be962d9e93",
"stderr": "c-expr7-bb2692a.stderr",
"stderr_hash": "6e9790ac88db1a9ead8f64a91ba8a6605de67167037908a74b77be0c",
"returncode": 0
Expand Down
23 changes: 0 additions & 23 deletions tests/reference/c-expr7-bb2692a.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,6 @@
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}


struct dimension_descriptor
{
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-expr_01-28f449f.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-expr_01-28f449f.stdout",
"stdout_hash": "f7ff3e7ee6518de7ff6bc41aa1ab242c7dbf9fca4482e5de47209c42",
"stdout_hash": "54d2c8dc7b28702c7907cd829a3777bdc4f2cf13dc597113a0074839",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
23 changes: 0 additions & 23 deletions tests/reference/c-expr_01-28f449f.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,6 @@
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}


struct dimension_descriptor
{
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-expr_11-c452314.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-expr_11-c452314.stdout",
"stdout_hash": "3ff86fbef1a6ada1ca91694b6cf50b08d58abb9f3d32672698655b45",
"stdout_hash": "990486bcfab642985e506a1ee8ff20218e233b0d19035e8acf2d407c",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
23 changes: 0 additions & 23 deletions tests/reference/c-expr_11-c452314.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,6 @@
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
exit(1); \
} \
}
#define ASSERT_MSG(cond, msg) \
{ \
if (!(cond)) { \
printf("%s%s", "ASSERT failed: ", __FILE__); \
printf("%s%s", "\nfunction ", __func__); \
printf("%s%d%s", "(), line number ", __LINE__, " at \n"); \
printf("%s%s", #cond, "\n"); \
printf("%s", "ERROR MESSAGE:\n"); \
printf("%s%s", msg, "\n"); \
exit(1); \
} \
}


struct dimension_descriptor
{
Expand Down
2 changes: 1 addition & 1 deletion tests/reference/c-expr_12-93c7780.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"outfile": null,
"outfile_hash": null,
"stdout": "c-expr_12-93c7780.stdout",
"stdout_hash": "4a67164684f646b94101df4dba378f02ee7585d7087093459a791c39",
"stdout_hash": "eb0832038676f31ac362e2c3b4709d5f1b9a9be2ca9c5b13d1a29613",
"stderr": null,
"stderr_hash": null,
"returncode": 0
Expand Down
Loading

0 comments on commit 9e8b2db

Please sign in to comment.