Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ASR verify pass error while using Interactive #2706

Merged
merged 13 commits into from
Jun 8, 2024
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ if (WITH_LCOMPILERS_FAST_ALLOC)
add_definitions("-DLCOMPILERS_FAST_ALLOC=1")
endif()

# copy runtime files
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython/lpython.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython/lpython.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/cmath.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/cmath.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_builtin.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_builtin.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_intrinsic_numpy.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_intrinsic_numpy.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/lpython_parser.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/lpython_parser.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/math.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/math.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/os.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/os.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/platform.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/platform.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/random.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/random.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/statistics.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/statistics.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/sys.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/sys.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/runtime/time.py" "${CMAKE_CURRENT_BINARY_DIR}/src/runtime/time.py")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if its a good idea to copy these. As of now, where does lpython look for these? Can we update lpython to look into the correct location?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copying is the safest thing to do. Right now it uses relative path from the executable's location to figure out the runtime file's path.

The reason I say it is a safe option is because the user building the LPython may set the CMAKE_CURRENT_BINARY_DIR to a completely different folder. For example, in Windows, I may want to store the source files in D drive and the compiled executable in C drive.


# LLVM
set(WITH_LLVM no CACHE BOOL "Build with LLVM support")
set(WITH_TARGET_AARCH64 no CACHE BOOL "Enable target AARCH64")
Expand Down
11 changes: 8 additions & 3 deletions src/libasr/asr_scopes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <libasr/asr_scopes.h>
#include <libasr/asr_utils.h>
#include <libasr/pass/pass_utils.h>

std::string lcompilers_unique_ID;

Expand Down Expand Up @@ -39,9 +40,13 @@ void SymbolTable::mark_all_variables_external(Allocator &al) {
case (ASR::symbolType::Function) : {
ASR::Function_t *v = ASR::down_cast<ASR::Function_t>(a.second);
ASR::FunctionType_t* v_func_type = ASR::down_cast<ASR::FunctionType_t>(v->m_function_signature);
v_func_type->m_abi = ASR::abiType::Interactive;
v->m_body = nullptr;
v->n_body = 0;
if (v_func_type->m_abi != ASR::abiType::Interactive) {
v_func_type->m_abi = ASR::abiType::Interactive;
v->m_body = nullptr;
v->n_body = 0;
PassUtils::UpdateDependenciesVisitor ud(al);
ud.visit_Function(*v);
}
break;
}
case (ASR::symbolType::Module) : {
Expand Down
5 changes: 5 additions & 0 deletions src/libasr/asr_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ class VerifyVisitor : public BaseWalkVisitor<VerifyVisitor>
}

void visit_Function(const Function_t &x) {
ASR::FunctionType_t* x_func_type = ASR::down_cast<ASR::FunctionType_t>(x.m_function_signature);
if (x_func_type->m_abi == abiType::Interactive) {
require(x.n_body == 0,
"The Function::n_body should be 0 if abi set to Interactive");
}
std::vector<std::string> function_dependencies_copy = function_dependencies;
function_dependencies.clear();
function_dependencies.reserve(x.n_dependencies);
Expand Down
129 changes: 129 additions & 0 deletions src/lpython/tests/test_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,25 @@ TEST_CASE("PythonCompiler 1") {
CHECK(r.result.i32 == 1);
}

TEST_CASE("PythonCompiler 2") {
CompilerOptions cu;
cu.po.disable_main = true;
cu.emit_debug_line_column = false;
cu.generate_object_code = false;
cu.interactive = true;
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
PythonCompiler e(cu);
LCompilers::Result<PythonCompiler::EvalResult>

r = e.evaluate2("i: i32 = 3 % 2");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("i");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == 1);
}

TEST_CASE("PythonCompiler i32 expressions") {
CompilerOptions cu;
cu.po.disable_main = true;
Expand Down Expand Up @@ -844,6 +863,7 @@ TEST_CASE("PythonCompiler u32 declaration") {
r = e.evaluate2("i: u32");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);

r = e.evaluate2("i = u32(5)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::statement);
Expand Down Expand Up @@ -1270,3 +1290,112 @@ TEST_CASE("PythonCompiler u16 declaration") {
CHECK(r.result.type == PythonCompiler::EvalResult::unsignedInteger2);
CHECK(r.result.u32 == 45);
}

TEST_CASE("PythonCompiler asr verify 1") {
CompilerOptions cu;
cu.po.disable_main = true;
cu.emit_debug_line_column = false;
cu.generate_object_code = false;
cu.interactive = true;
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
PythonCompiler e(cu);
LCompilers::Result<PythonCompiler::EvalResult>
r = e.evaluate2("i: i32 = 3 % 2");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("i");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == 1);
}

TEST_CASE("PythonCompiler asr verify 2") {
CompilerOptions cu;
cu.po.disable_main = true;
cu.emit_debug_line_column = false;
cu.generate_object_code = false;
cu.interactive = true;
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
PythonCompiler e(cu);
LCompilers::Result<PythonCompiler::EvalResult>
r = e.evaluate2(R"(
def is_even(x: i32) -> i32:
if x % 2 == 0:
return 1
return 0
)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("is_even(4)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == 1);
r = e.evaluate2("is_even(3)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == 0);
}

TEST_CASE("PythonCompiler asr verify 3") {
CompilerOptions cu;
cu.po.disable_main = true;
cu.emit_debug_line_column = false;
cu.generate_object_code = false;
cu.interactive = true;
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
PythonCompiler e(cu);
LCompilers::Result<PythonCompiler::EvalResult>

r = e.evaluate2(R"(
def addi(x: i32, y: i32) -> i32:
return x + y
)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2(R"(
def subi(x: i32, y: i32) -> i32:
return addi(x, -y)
)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("addi(2, 3)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == 5);
r = e.evaluate2("subi(2, 3)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::integer4);
CHECK(r.result.i32 == -1);
}

TEST_CASE("PythonCompiler asr verify 4") {
CompilerOptions cu;
cu.po.disable_main = true;
cu.emit_debug_line_column = false;
cu.generate_object_code = false;
cu.interactive = true;
cu.po.runtime_library_dir = LCompilers::LPython::get_runtime_library_dir();
PythonCompiler e(cu);
LCompilers::Result<PythonCompiler::EvalResult>

r = e.evaluate2(R"(
def addr(x: f64, y: f64) -> f64:
return x + y
)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2(R"(
def subr(x: f64, y: f64) -> f64:
return addr(x, -y)
)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("addr(2.5, 3.5)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::real8);
CHECK(r.result.f64 == 6);
r = e.evaluate2("subr(2.5, 3.5)");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::real8);
CHECK(r.result.f64 == -1);
}
Loading
Loading