Skip to content

Commit

Permalink
support printing boolean in REPL (#2728)
Browse files Browse the repository at this point in the history
* support printing `boolean` in REPL

* fix failing test (wrongly written test)
  • Loading branch information
Vipul-Cariappa authored Jun 9, 2024
1 parent 8aadf8c commit 290c2b3
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/bin/lpython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,12 @@ int interactive_python_repl(
std::cout << std::setprecision(17) << "(" << r.c64.re << ", " << r.c64.im << ")" << std::endl;
break;
}
case (LCompilers::PythonCompiler::EvalResult::boolean) : {
if (verbose) std::cout << "Return type: logical" << std::endl;
if (verbose) section("Result:");
std::cout << (r.b ? "True" : "False") << std::endl;
break;
}
case (LCompilers::PythonCompiler::EvalResult::string) : {
if (verbose) std::cout << "Return type: str" << std::endl;
if (verbose) section("Result:");
Expand Down
2 changes: 2 additions & 0 deletions src/libasr/codegen/evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ std::string LLVMModule::get_return_type(const std::string &fn_name)
return "real4";
} else if (type->isDoubleTy()) {
return "real8";
} else if (type->isIntegerTy(1)) {
return "logical";
} else if (type->isIntegerTy(8)) {
return "integer1";
} else if (type->isIntegerTy(16)) {
Expand Down
17 changes: 17 additions & 0 deletions src/libasr/pass/global_stmts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ void pass_wrap_global_stmts(Allocator &al,
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Logical) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);

int a_kind = down_cast<ASR::Logical_t>(ASRUtils::expr_type(value))->m_kind;

type = ASRUtils::TYPE(ASR::make_Logical_t(al, loc, a_kind));
return_var = ASR::make_Variable_t(al, loc,
fn_scope, var_name, nullptr, 0, ASRUtils::intent_local, nullptr, nullptr,
ASR::storage_typeType::Default, type,
nullptr, ASR::abiType::BindC,
ASR::Public, ASR::presenceType::Required, false);
return_var_ref = EXPR(ASR::make_Var_t(al, loc,
down_cast<ASR::symbol_t>(return_var)));
fn_scope->add_symbol(std::string(var_name), down_cast<ASR::symbol_t>(return_var));
target = return_var_ref;
idx++;
} else if (ASRUtils::expr_type(value)->type == ASR::ttypeType::Real) {
s.from_str(al, fn_name_s + std::to_string(idx));
var_name = s.c_str(al);
Expand Down
4 changes: 4 additions & 0 deletions src/lpython/python_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ Result<PythonCompiler::EvalResult> PythonCompiler::evaluate(
result.type = EvalResult::complex8;
result.c64.re = r.real();
result.c64.im = r.imag();
} else if (return_type == "logical") {
bool r = e->execfn<bool>(run_fn);
result.type = EvalResult::boolean;
result.b = r;
} else if (return_type == "void") {
e->execfn<void>(run_fn);
result.type = EvalResult::statement;
Expand Down
2 changes: 2 additions & 0 deletions src/lpython/python_evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class PythonCompiler
real8,
complex4,
complex8,
boolean,
string,
statement,
none
Expand All @@ -58,6 +59,7 @@ class PythonCompiler
int64_t i64;
uint32_t u32;
uint64_t u64;
bool b;
float f32;
double f64;
char *str;
Expand Down
71 changes: 71 additions & 0 deletions src/lpython/tests/test_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,77 @@ TEST_CASE("PythonCompiler u16 declaration") {
CHECK(r.result.u32 == 45);
}

TEST_CASE("PythonCompiler boolean expressions") {
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("True");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(r.result.b);

r = e.evaluate2("False");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(!r.result.b);

r = e.evaluate2("False or True");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(r.result.b);

r = e.evaluate2("False and True");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(!r.result.b);
}

TEST_CASE("PythonCompiler boolean declaration") {
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("t: bool");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("t = True");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::statement);
r = e.evaluate2("t");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(r.result.b);

r = e.evaluate2("f: bool = False");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::none);
r = e.evaluate2("f");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(!r.result.b);

r = e.evaluate2("t or f");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(r.result.b);

r = e.evaluate2("t and f");
CHECK(r.ok);
CHECK(r.result.type == PythonCompiler::EvalResult::boolean);
CHECK(!r.result.b);
}

TEST_CASE("PythonCompiler string 1") {
CompilerOptions cu;
cu.po.disable_main = true;
Expand Down

0 comments on commit 290c2b3

Please sign in to comment.