diff --git a/src/lpython/python_evaluator.cpp b/src/lpython/python_evaluator.cpp index 9db6d0ec7b..9e1452b4e9 100644 --- a/src/lpython/python_evaluator.cpp +++ b/src/lpython/python_evaluator.cpp @@ -119,13 +119,48 @@ Result PythonCompiler::evaluate( } bool call_run_fn = false; + std::string return_type; if (m->get_return_type(run_fn) != "none") { call_run_fn = true; + return_type = m->get_return_type(run_fn); } e->add_module(std::move(m)); if (call_run_fn) { - e->voidfn(run_fn); + if (return_type == "integer4") { + int32_t r = e->int32fn(run_fn); + result.type = EvalResult::integer4; + result.i32 = r; + } else if (return_type == "integer8") { + int64_t r = e->int64fn(run_fn); + result.type = EvalResult::integer8; + result.i64 = r; + } else if (return_type == "real4") { + float r = e->floatfn(run_fn); + result.type = EvalResult::real4; + result.f32 = r; + } else if (return_type == "real8") { + double r = e->doublefn(run_fn); + result.type = EvalResult::real8; + result.f64 = r; + } else if (return_type == "complex4") { + std::complex r = e->complex4fn(run_fn); + result.type = EvalResult::complex4; + result.c32.re = r.real(); + result.c32.im = r.imag(); + } else if (return_type == "complex8") { + std::complex r = e->complex8fn(run_fn); + result.type = EvalResult::complex8; + result.c64.re = r.real(); + result.c64.im = r.imag(); + } else if (return_type == "void") { + e->voidfn(run_fn); + result.type = EvalResult::statement; + } else if (return_type == "none") { + result.type = EvalResult::none; + } else { + throw LCompilersException("FortranEvaluator::evaluate(): Return type not supported"); + } } if (call_run_fn) { diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 221ac09ce4..d1c324d237 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6693,10 +6693,10 @@ class BodyVisitor : public CommonVisitor { } this->visit_expr(*x.m_value); - // If tmp is a statement and not an expression - // never cast into expression using ASRUtils::EXPR - // Just ignore and exit the function naturally. - if( tmp && !ASR::is_a(*tmp) ) { + if (eval_count == 0 && tmp && !ASR::is_a(*tmp)) { + // If tmp is a statement and not an expression + // never cast into expression using ASRUtils::EXPR + // Just ignore and exit the function naturally. LCOMPILERS_ASSERT(ASR::is_a(*tmp)); tmp = nullptr; } diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index fce86f1788..08e37634d6 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -619,5 +619,168 @@ TEST_CASE("PythonCompiler 1") { LCompilers::Result r = e.evaluate2("1"); CHECK(r.ok); - CHECK(r.result.type == PythonCompiler::EvalResult::none); // TODO: change to integer4 and check the value once printing top level expressions is implemented + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 1); +} + +TEST_CASE("PythonCompiler i32 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 + + r = e.evaluate2("1"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 1); + + r = e.evaluate2("1 + 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 3); + + r = e.evaluate2("1 - 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == -1); + + r = e.evaluate2("1 * 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 2); + + r = e.evaluate2("3 ** 3"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 27); + + r = e.evaluate2("4 // 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 2); + + r = e.evaluate2("4 / 2"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::real8); + CHECK(r.result.f64 == 2); +} + +TEST_CASE("PythonCompiler i32 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 + + r = e.evaluate2("i: i32"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("i = 5"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::statement); + r = e.evaluate2("i"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 5); + + r = e.evaluate2("j: i32 = 9"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("j"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 9); + + r = e.evaluate2("i + j"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer4); + CHECK(r.result.i32 == 14); +} + +TEST_CASE("PythonCompiler i64 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 + + r = e.evaluate2("i64(1)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 1); + + r = e.evaluate2("i64(1) + i64(2)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 3); + + r = e.evaluate2("i64(1) - i64(2)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == -1); + + r = e.evaluate2("i64(1) * i64(2)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 2); + + r = e.evaluate2("i64(3) ** i64(3)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 27); + + r = e.evaluate2("i64(4) // i64(2)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 2); + + r = e.evaluate2("i64(4) / i64(2)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::real8); + CHECK(r.result.f64 == 2); +} + +TEST_CASE("PythonCompiler i64 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 + + r = e.evaluate2("i: i64"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("i = i64(5)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::statement); + r = e.evaluate2("i"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 5); + + r = e.evaluate2("j: i64 = i64(9)"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::none); + r = e.evaluate2("j"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 9); + + r = e.evaluate2("i + j"); + CHECK(r.ok); + CHECK(r.result.type == PythonCompiler::EvalResult::integer8); + CHECK(r.result.i64 == 14); }