From 81224d7ddb6953149cc2ea3cb5aacff3fb5cc089 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 24 May 2024 19:44:00 +0530 Subject: [PATCH 1/5] printing top level expressions --- src/lpython/python_evaluator.cpp | 37 ++++++++++++++++++++- src/lpython/semantics/python_ast_to_asr.cpp | 14 +++++--- 2 files changed, 46 insertions(+), 5 deletions(-) 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..5cf3b217b2 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6693,10 +6693,16 @@ 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) { + // In Interactive mode + if ((tmp) && (!ASR::is_a(*tmp))) { + LCOMPILERS_ASSERT(ASR::is_a(*tmp)); + tmp = nullptr; + } + } else if (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; } From 4ff446a6aee754c1450180427a06d5a762b75272 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 24 May 2024 19:44:20 +0530 Subject: [PATCH 2/5] test cases for i32 and i64 --- src/lpython/tests/test_llvm.cpp | 152 +++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index fce86f1788..ad0d24a11b 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -608,7 +608,7 @@ define float @f() CHECK(std::abs(r - 8) < 1e-6); } -TEST_CASE("PythonCompiler 1") { +TEST_CASE("PythonCompiler i32 expressions") { CompilerOptions cu; cu.po.disable_main = true; cu.emit_debug_line_column = false; @@ -617,7 +617,155 @@ TEST_CASE("PythonCompiler 1") { 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::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); + + 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.i64 == 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); } From d7e9451d1a293b373d4b2f723d4acbd33b880866 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Fri, 24 May 2024 19:52:55 +0530 Subject: [PATCH 3/5] fix typo --- src/lpython/tests/test_llvm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index ad0d24a11b..1c1eccfcdd 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -641,7 +641,7 @@ TEST_CASE("PythonCompiler i32 expressions") { r = e.evaluate2("3 ** 3"); CHECK(r.ok); CHECK(r.result.type == PythonCompiler::EvalResult::integer4); - CHECK(r.result.i64 == 27); + CHECK(r.result.i32 == 27); r = e.evaluate2("4 // 2"); CHECK(r.ok); From 22efacfa663c6b0c27449d4a447a2bfdb40cab86 Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Sat, 25 May 2024 10:35:00 +0530 Subject: [PATCH 4/5] update according to code review suggestions --- src/lpython/semantics/python_ast_to_asr.cpp | 1 - src/lpython/tests/test_llvm.cpp | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 5cf3b217b2..4085ffd09a 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6696,7 +6696,6 @@ class BodyVisitor : public CommonVisitor { if (eval_count > 0) { // In Interactive mode if ((tmp) && (!ASR::is_a(*tmp))) { - LCOMPILERS_ASSERT(ASR::is_a(*tmp)); tmp = nullptr; } } else if (tmp && !ASR::is_a(*tmp)) { diff --git a/src/lpython/tests/test_llvm.cpp b/src/lpython/tests/test_llvm.cpp index 1c1eccfcdd..08e37634d6 100644 --- a/src/lpython/tests/test_llvm.cpp +++ b/src/lpython/tests/test_llvm.cpp @@ -608,6 +608,21 @@ define float @f() CHECK(std::abs(r - 8) < 1e-6); } +TEST_CASE("PythonCompiler 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 + r = e.evaluate2("1"); + 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; From 49f46c6afb738859482e50912ce52b8461c372ec Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Sun, 26 May 2024 18:55:35 +0530 Subject: [PATCH 5/5] Update src/lpython/semantics/python_ast_to_asr.cpp Co-authored-by: Shaikh Ubaid --- src/lpython/semantics/python_ast_to_asr.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 4085ffd09a..d1c324d237 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -6693,12 +6693,7 @@ class BodyVisitor : public CommonVisitor { } this->visit_expr(*x.m_value); - if (eval_count > 0) { - // In Interactive mode - if ((tmp) && (!ASR::is_a(*tmp))) { - tmp = nullptr; - } - } else 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.