From 29763316f753c789f412342111a0118ce7307375 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Thu, 5 Oct 2023 12:58:15 +0530 Subject: [PATCH 01/15] [asr->lpython] initial implementation --- integration_tests/run_tests.py | 2 +- run_tests.py | 6 + src/bin/lpython.cpp | 64 +++++- src/libasr/CMakeLists.txt | 1 + src/libasr/codegen/asr_to_lpython.cpp | 293 ++++++++++++++++++++++++++ src/libasr/codegen/asr_to_lpython.h | 15 ++ 6 files changed, 377 insertions(+), 4 deletions(-) create mode 100644 src/libasr/codegen/asr_to_lpython.cpp create mode 100644 src/libasr/codegen/asr_to_lpython.h diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index 5df4979e03..37d26ad067 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -6,7 +6,7 @@ # Initialization DEFAULT_THREADS_TO_USE = 8 # default no of threads is 8 -SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64', 'c_py', 'c_sym', 'cpython_sym', 'llvm_sym', 'llvm_py'] +SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64', 'c_py', 'c_sym', 'cpython_sym', 'llvm_sym', 'llvm_py', 'lpython'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) LPYTHON_PATH = f"{BASE_DIR}/../src/bin" diff --git a/run_tests.py b/run_tests.py index b55d6af851..4de76caba5 100755 --- a/run_tests.py +++ b/run_tests.py @@ -26,6 +26,7 @@ def is_included(backend): llvm_dbg = is_included("llvm_dbg") cpp = is_included("cpp") c = is_included("c") + lpython = is_included("lpython") is_cumulative = is_included("cumulative") wat = is_included("wat") run = is_included("run") @@ -133,6 +134,11 @@ def is_included(backend): else: run_test(filename, "c", "lpython --no-color --show-c {infile}", filename, update_reference, extra_args) + + if lpython: + run_test(filename, "lpython", "lpython --no-color --show-lpython {infile}", + filename, update_reference, extra_args) + if wat: run_test(filename, "wat", "lpython --no-color --show-wat {infile}", filename, update_reference, extra_args) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index bdc2b92aaf..9cf6b64dd6 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ using LCompilers::CompilerOptions; using LCompilers::LPython::parse_python_file; enum class Backend { - llvm, cpp, c, x86, wasm, wasm_x86, wasm_x64 + llvm, cpp, c, x86, wasm, wasm_x86, wasm_x64, lpython }; @@ -428,6 +429,50 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, return 0; } +int emit_lpython(const std::string &infile, + const std::string &runtime_library_dir, + CompilerOptions &compiler_options) +{ + Allocator al(4*1024); + LCompilers::diag::Diagnostics diagnostics; + LCompilers::LocationManager lm; + { + LCompilers::LocationManager::FileLocations fl; + fl.in_filename = infile; + lm.files.push_back(fl); + std::string input = LCompilers::read_file(infile); + lm.init_simple(input); + lm.file_ends.push_back(input.size()); + } + LCompilers::Result r = parse_python_file( + al, runtime_library_dir, infile, diagnostics, 0, compiler_options.new_parser); + std::cerr << diagnostics.render(lm, compiler_options); + if (!r.ok) { + return 1; + } + LCompilers::LPython::AST::ast_t* ast = r.result; + + diagnostics.diagnostics.clear(); + LCompilers::Result + r1 = LCompilers::LPython::python_ast_to_asr(al, lm, nullptr, *ast, diagnostics, compiler_options, true, "__main__", infile); + std::cerr << diagnostics.render(lm, compiler_options); + if (!r1.ok) { + LCOMPILERS_ASSERT(diagnostics.has_error()) + return 2; + } + LCompilers::ASR::TranslationUnit_t* asr = r1.result; + + diagnostics.diagnostics.clear(); + LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options); + std::cerr << diagnostics.render(lm, compiler_options); + if (!res.ok) { + LCOMPILERS_ASSERT(diagnostics.has_error()) + return 3; + } + std::cout << res.result; + return 0; +} + int emit_wat(const std::string &infile, const std::string &runtime_library_dir, CompilerOptions &compiler_options) @@ -1281,6 +1326,9 @@ int link_executable(const std::vector &infiles, return 10; } return 0; + //} else if (backend == Backend::lpython) { + // std::string CXX = "g++"; + // return 0; } else if (backend == Backend::x86) { std::string cmd = "cp " + infiles[0] + " " + outfile; int err = system(cmd.c_str()); @@ -1494,6 +1542,7 @@ int main(int argc, char *argv[]) bool show_asr = false; bool show_cpp = false; bool show_c = false; + bool show_lpython = false; bool show_document_symbols = false; bool show_errors = false; bool with_intrinsic_modules = false; @@ -1560,6 +1609,7 @@ int main(int argc, char *argv[]) app.add_flag("--show-llvm", show_llvm, "Show LLVM IR for the given file and exit"); app.add_flag("--show-cpp", show_cpp, "Show C++ translation source for the given python file and exit"); app.add_flag("--show-c", show_c, "Show C translation source for the given python file and exit"); + app.add_flag("--show-lpython", show_lpython, "Show Lpython translation source for the given python file and exit"); app.add_flag("--show-asm", show_asm, "Show assembly for the given file and exit"); app.add_flag("--show-wat", show_wat, "Show WAT (WebAssembly Text Format) and exit"); app.add_flag("--show-stacktrace", compiler_options.show_stacktrace, "Show internal stacktrace on compiler errors"); @@ -1577,7 +1627,7 @@ int main(int argc, char *argv[]) app.add_flag("--static", static_link, "Create a static executable"); app.add_flag("--no-warnings", compiler_options.no_warnings, "Turn off all warnings"); app.add_flag("--no-error-banner", compiler_options.no_error_banner, "Turn off error banner"); - app.add_option("--backend", arg_backend, "Select a backend (llvm, cpp, x86, wasm, wasm_x86, wasm_x64)")->capture_default_str(); + app.add_option("--backend", arg_backend, "Select a backend (llvm, cpp, x86, wasm, wasm_x86, wasm_x64, lpython)")->capture_default_str(); app.add_flag("--enable-bounds-checking", compiler_options.enable_bounds_checking, "Turn on index bounds checking"); app.add_flag("--openmp", compiler_options.openmp, "Enable openmp"); app.add_flag("--fast", compiler_options.fast, "Best performance (disable strict standard compliance)"); @@ -1714,6 +1764,8 @@ int main(int argc, char *argv[]) backend = Backend::c; } else if (arg_backend == "cpp") { backend = Backend::cpp; + //} else if (arg_backend == "lpython") { + // backend = Backend::lpython; } else if (arg_backend == "x86") { backend = Backend::x86; } else if (arg_backend == "wasm") { @@ -1723,7 +1775,7 @@ int main(int argc, char *argv[]) } else if (arg_backend == "wasm_x64") { backend = Backend::wasm_x64; } else { - std::cerr << "The backend must be one of: llvm, c, cpp, x86, wasm, wasm_x86, wasm_x64." << std::endl; + std::cerr << "The backend must be one of: llvm, c, cpp, lpython, x86, wasm, wasm_x86, wasm_x64." << std::endl; return 1; } @@ -1785,6 +1837,9 @@ int main(int argc, char *argv[]) return emit_c(arg_file, runtime_library_dir, lpython_pass_manager, compiler_options); } + if (show_lpython) { + return emit_lpython(arg_file, runtime_library_dir, compiler_options); + } if (show_wat) { return emit_wat(arg_file, runtime_library_dir, compiler_options); } @@ -1856,6 +1911,9 @@ int main(int argc, char *argv[]) } else if (backend == Backend::wasm_x86 || backend == Backend::wasm_x64) { err = compile_to_binary_wasm_to_x86(arg_file, outfile, runtime_library_dir, compiler_options, time_report, backend); + //} else if (backend == Backend::lpython) { + // err = compile_to_binary_lpython(arg_file, outfile, + // runtime_library_dir, compiler_options, time_report); } else if (backend == Backend::c) { std::string emit_file_name = basename + "__tmp__generated__.c"; err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index 058fd67d07..93dd00cc21 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -18,6 +18,7 @@ set(SRC codegen/asr_to_cpp.cpp codegen/asr_to_c.cpp codegen/asr_to_julia.cpp + codegen/asr_to_lpython.cpp codegen/asr_to_py.cpp codegen/x86_assembler.cpp codegen/asr_to_x86.cpp diff --git a/src/libasr/codegen/asr_to_lpython.cpp b/src/libasr/codegen/asr_to_lpython.cpp new file mode 100644 index 0000000000..31f19f92aa --- /dev/null +++ b/src/libasr/codegen/asr_to_lpython.cpp @@ -0,0 +1,293 @@ +#include +#include +#include +#include + +using LCompilers::ASR::is_a; +using LCompilers::ASR::down_cast; + +namespace LCompilers { + +class ASRToLpythonVisitor : public ASR::BaseVisitor +{ +public: + Allocator& al; + diag::Diagnostics& diag; + std::string s; + bool use_colors; + int indent_level; + std::string indent; + int indent_spaces; + // Following same order as Python 3.x + // https://docs.python.org/3/reference/expressions.html#expression-lists + int last_expr_precedence; + +public: + ASRToLpythonVisitor(Allocator& al, diag::Diagnostics& diag) + : al{ al } + , diag{ diag } + { } + + void inc_indent() { + indent_level++; + indent = std::string(indent_level*indent_spaces, ' '); + } + + void dec_indent() { + indent_level--; + indent = std::string(indent_level*indent_spaces, ' '); + } + + void visit_expr_with_last_precedence(const ASR::expr_t &x, int current_precedence) { + visit_expr(x); + if (last_expr_precedence == 18 || + last_expr_precedence < current_precedence) { + s = "(" + s + ")"; + } + } + + std::string binop2str(const ASR::binopType type) + { + switch (type) { + case (ASR::binopType::Add) : { + last_expr_precedence = 12; + return " + "; + } case (ASR::binopType::Sub) : { + last_expr_precedence = 12; + return " - "; + } case (ASR::binopType::Mul) : { + last_expr_precedence = 13; + return " * "; + } case (ASR::binopType::Div) : { + last_expr_precedence = 13; + return " / "; + // TODO: add an overload in is_op_overloaded + //} case (ASR::binopType::FloorDiv) : { + // last_expr_precedence = 13; + // return " // "; + //} case (ASR::binopType::Mod) : { + // last_expr_precedence = 13; + // return " % "; + } case (ASR::binopType::Pow) : { + last_expr_precedence = 15; + return " ** "; + } default : { + throw LCompilersException("Cannot represent the binary operator as a string"); + } + } + } + + std::string cmpop2str(const ASR::cmpopType type) + { + last_expr_precedence = 7; + switch (type) { + case (ASR::cmpopType::Eq) : return " == "; + case (ASR::cmpopType::NotEq) : return " != "; + case (ASR::cmpopType::Lt) : return " < "; + case (ASR::cmpopType::LtE) : return " <= "; + case (ASR::cmpopType::Gt) : return " > "; + case (ASR::cmpopType::GtE) : return " >= "; + default : throw LCompilersException("Cannot represent the boolean operator as a string"); + } + } + + std::string logicalbinop2str(const ASR::logicalbinopType type) + { + switch (type) { + case (ASR::logicalbinopType::And) : { + last_expr_precedence = 5; + return " and "; + } case (ASR::logicalbinopType::Or) : { + last_expr_precedence = 4; + return " or "; + //} case (ASR::logicalbinopType::Not) : { + // last_expr_precedence = 6; + // return " not "; + } default : { + throw LCompilersException("Cannot represent the boolean operator as a string"); + } + } + } + + // TODO: Bitwise operator + // TODO: Assignment operator + // TODO: Membership operator + // TODO: Identity operator + + template + void visit_body(const T &x, std::string &r, bool apply_indent=true) { + if (apply_indent) { + inc_indent(); + } + for (size_t i = 0; i < x.n_body; i++) { + visit_stmt(*x.m_body[i]); + r += s; + } + if (apply_indent) { + dec_indent(); + } + } + + std::string get_type(const ASR::ttype_t *t) { + std::string r = ""; + switch (t->type) { + case ASR::ttypeType::Integer : { + r = "int("; + r += std::to_string(down_cast(t)->m_kind); // TODO: confirm what's m_kind + r += ")"; + break; + } case ASR::ttypeType::Complex : { + r = "complex("; + r += std::to_string(down_cast(t)->m_kind); + r += ")"; + break; + } case ASR::ttypeType::Character : { + r = "chr("; + r += std::to_string(down_cast(t)->m_kind); + r += ")"; + break; + } case ASR::ttypeType::Logical : { + r = "bool("; + r += std::to_string(down_cast(t)->m_kind); + r += ")"; + break; + //} case ASR::ttypeType::Tuple : { // TODO: make it work + // r = "tuple("; + // r += std::to_string(down_cast(t)->m_kind); + // r = ")"; + // break; + //} case ASR::ttypeType::List : { + // r = "list("; + // r += "["; + // r += std::to_string(down_cast(t)->m_kind); + // r += "]"; + // r = ")"; + // break; + } case ASR::ttypeType::Array : { + r = get_type(down_cast(t)->m_type); + break; + } case ASR::ttypeType::Allocatable : { + r = get_type(down_cast(t)->m_type); + break; + } default : { + throw LCompilersException("The type `" + + ASRUtils::type_to_str_python(t) + "` is not handled yet"); + } + } + return r; + } + + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + std::string r = ""; + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + s = r; + } + + void visit_Module(const ASR::Module_t &x) { + // Generate code for the lpython function + std::string r; + r = "def"; + r += " "; + r.append(x.m_name); + r += "()"; + r += ":"; + r += "\n"; + inc_indent(); + r += "\n"; + dec_indent(); + r += "\n"; + s = r; + } + + void visit_Function(const ASR::Function_t &x) { + // Generate code for the lpython function + std::string r; + r = "def"; + r += " "; + r.append(x.m_name); + r += "("; + for (size_t i = 0; i < x.n_args; i++) { + visit_expr(*x.m_args[i]); + r += s; + } + r += ")"; + r += "\n"; + + inc_indent(); + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + + visit_body(x, r, true); + dec_indent(); + r += "\n"; + s = r; + } + + void visit_Program(const ASR::Program_t &x) { + // Generate code for main function + std::string r; + r = "if"; + r += " "; + r += "__name__"; + r += " == "; + r += "__main__"; + r += ":"; + r += "\n"; + inc_indent(); + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + r.append(x.m_name); + r += "()"; + r += "\n"; + + visit_body(x, r, true); + + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } + } + + dec_indent(); + r += "\n"; + s = r; + } + +}; + +std::string asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, + diag::Diagnostics& diag, CompilerOptions &co) { + ASRToLpythonVisitor v(al, diag); + v.visit_TranslationUnit(asr); + return v.s; +} + +} // namespace LCompilers diff --git a/src/libasr/codegen/asr_to_lpython.h b/src/libasr/codegen/asr_to_lpython.h new file mode 100644 index 0000000000..3b41a2b17d --- /dev/null +++ b/src/libasr/codegen/asr_to_lpython.h @@ -0,0 +1,15 @@ +#ifndef LPYTHON_ASR_TO_PYTHON_H +#define LPYTHON_ASR_TO_PYTHON_H + +#include +#include + +namespace LCompilers { + + // Convert ASR to Python source code + std::string asr_to_lpython(Allocator &al, ASR::TranslationUnit_t &asr, + diag::Diagnostics &diagnostics, CompilerOptions &co); + +} // namespace LCompilers + +#endif // LPYTHON_ASR_TO_PYTHON_H From 47f804f8285df1cc632bc2c2707c813158a57854 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 19 Dec 2023 13:15:10 +0530 Subject: [PATCH 02/15] use enums & minor fixes --- src/bin/lpython.cpp | 8 ++++- src/libasr/codegen/asr_to_lpython.cpp | 51 ++++++++++++++++++--------- src/libasr/codegen/asr_to_lpython.h | 5 +-- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 3c2343a590..e045e99175 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -410,6 +410,8 @@ int emit_lpython(const std::string &infile, LCompilers::LPython::AST::ast_t* ast = r.result; diagnostics.diagnostics.clear(); + + // AST -> ASR LCompilers::Result r1 = LCompilers::LPython::python_ast_to_asr(al, lm, nullptr, *ast, diagnostics, compiler_options, true, "__main__", infile); std::cerr << diagnostics.render(lm, compiler_options); @@ -420,7 +422,11 @@ int emit_lpython(const std::string &infile, LCompilers::ASR::TranslationUnit_t* asr = r1.result; diagnostics.diagnostics.clear(); - LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options); + + // ASR -> LPython + bool color = false; + int indent = 0; + LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options, color, indent); std::cerr << diagnostics.render(lm, compiler_options); if (!res.ok) { LCOMPILERS_ASSERT(diagnostics.has_error()) diff --git a/src/libasr/codegen/asr_to_lpython.cpp b/src/libasr/codegen/asr_to_lpython.cpp index 31f19f92aa..c196999985 100644 --- a/src/libasr/codegen/asr_to_lpython.cpp +++ b/src/libasr/codegen/asr_to_lpython.cpp @@ -8,6 +8,18 @@ using LCompilers::ASR::down_cast; namespace LCompilers { +enum Precedence { + Or = 4, + And = 5, + CmpOp = 7, + Add = 8, + Sub = 12, + UnaryMinus = 9, + Mul = 13, + Div = 13, + Pow = 15, +}; + class ASRToLpythonVisitor : public ASR::BaseVisitor { public: @@ -23,9 +35,10 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor int last_expr_precedence; public: - ASRToLpythonVisitor(Allocator& al, diag::Diagnostics& diag) - : al{ al } - , diag{ diag } + // TODO: check this constructor + ASRToLpythonVisitor(Allocator& al, diag::Diagnostics& diag, CompilerOptions &co, bool _use_colors, int _indent) + : al{ al }, diag{ diag }, use_colors{_use_colors}, indent_level{0}, + indent_spaces{_indent} { } void inc_indent() { @@ -50,16 +63,16 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor { switch (type) { case (ASR::binopType::Add) : { - last_expr_precedence = 12; + last_expr_precedence = Precedence::Add; return " + "; } case (ASR::binopType::Sub) : { - last_expr_precedence = 12; + last_expr_precedence = Precedence::Sub; return " - "; } case (ASR::binopType::Mul) : { - last_expr_precedence = 13; + last_expr_precedence = Precedence::Mul; return " * "; } case (ASR::binopType::Div) : { - last_expr_precedence = 13; + last_expr_precedence = Precedence::Div; return " / "; // TODO: add an overload in is_op_overloaded //} case (ASR::binopType::FloorDiv) : { @@ -69,7 +82,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor // last_expr_precedence = 13; // return " % "; } case (ASR::binopType::Pow) : { - last_expr_precedence = 15; + last_expr_precedence = Precedence::Pow; return " ** "; } default : { throw LCompilersException("Cannot represent the binary operator as a string"); @@ -79,7 +92,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor std::string cmpop2str(const ASR::cmpopType type) { - last_expr_precedence = 7; + last_expr_precedence = Precedence::CmpOp; switch (type) { case (ASR::cmpopType::Eq) : return " == "; case (ASR::cmpopType::NotEq) : return " != "; @@ -95,13 +108,13 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor { switch (type) { case (ASR::logicalbinopType::And) : { - last_expr_precedence = 5; + last_expr_precedence = Precedence::And; return " and "; } case (ASR::logicalbinopType::Or) : { - last_expr_precedence = 4; + last_expr_precedence = Precedence::Or; return " or "; //} case (ASR::logicalbinopType::Not) : { - // last_expr_precedence = 6; + // last_expr_precedence = Precedence::Not; // return " not "; } default : { throw LCompilersException("Cannot represent the boolean operator as a string"); @@ -283,10 +296,16 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor }; -std::string asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, - diag::Diagnostics& diag, CompilerOptions &co) { - ASRToLpythonVisitor v(al, diag); - v.visit_TranslationUnit(asr); +Result asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, + diag::Diagnostics& diagnostics, CompilerOptions &co, + bool color, int indent) { + ASRToLpythonVisitor v(al, diagnostics, co, color, indent); + try { + v.visit_TranslationUnit(asr); + } catch (const CodeGenError &e) { + diagnostics.diagnostics.push_back(e.d); + return Error(); + } return v.s; } diff --git a/src/libasr/codegen/asr_to_lpython.h b/src/libasr/codegen/asr_to_lpython.h index 3b41a2b17d..8a19b8dc84 100644 --- a/src/libasr/codegen/asr_to_lpython.h +++ b/src/libasr/codegen/asr_to_lpython.h @@ -7,8 +7,9 @@ namespace LCompilers { // Convert ASR to Python source code - std::string asr_to_lpython(Allocator &al, ASR::TranslationUnit_t &asr, - diag::Diagnostics &diagnostics, CompilerOptions &co); + Result asr_to_lpython(Allocator &al, ASR::TranslationUnit_t &asr, + diag::Diagnostics &diagnostics, CompilerOptions &co, + bool color, int indent); } // namespace LCompilers From f9dab0634e009c9b6c03d06453faa4cf5bc14e05 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 19 Dec 2023 22:04:06 +0530 Subject: [PATCH 03/15] CMakeLists.txt and fixes --- integration_tests/CMakeLists.txt | 9 +++++++++ src/bin/lpython.cpp | 9 ++++----- src/libasr/codegen/asr_to_lpython.cpp | 9 +++------ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index d5a477f006..f067ff490b 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -301,6 +301,15 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_NOM if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() + elseif(KIND STREQUAL "lpython") + # lpython test + execute_process(COMMAND ${LPYTHON} ${extra_arg} --backend lpython ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py) + if (lables) + set_tests_properties(${name} PROPERTIES LABELS "${labels}") + endif() + if (${fail}) + set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) + endif() endif() if (copy_to_bin) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index e045e99175..0816af9ead 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -1328,9 +1328,8 @@ int link_executable(const std::vector &infiles, return 10; } return 0; - //} else if (backend == Backend::lpython) { - // std::string CXX = "g++"; - // return 0; + } else if (backend == Backend::lpython) { + // TODO } else if (backend == Backend::x86) { std::string cmd = "cp " + infiles[0] + " " + outfile; int err = system(cmd.c_str()); @@ -1769,8 +1768,8 @@ int main(int argc, char *argv[]) backend = Backend::c; } else if (arg_backend == "cpp") { backend = Backend::cpp; - //} else if (arg_backend == "lpython") { - // backend = Backend::lpython; + } else if (arg_backend == "lpython") { + backend = Backend::lpython; } else if (arg_backend == "x86") { backend = Backend::x86; } else if (arg_backend == "wasm") { diff --git a/src/libasr/codegen/asr_to_lpython.cpp b/src/libasr/codegen/asr_to_lpython.cpp index c196999985..c3ede818ee 100644 --- a/src/libasr/codegen/asr_to_lpython.cpp +++ b/src/libasr/codegen/asr_to_lpython.cpp @@ -242,7 +242,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor visit_expr(*x.m_args[i]); r += s; } - r += ")"; + r += "):"; r += "\n"; inc_indent(); @@ -262,12 +262,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_Program(const ASR::Program_t &x) { // Generate code for main function std::string r; - r = "if"; + r = "def"; r += " "; - r += "__name__"; - r += " == "; - r += "__main__"; - r += ":"; + r += "main0():"; r += "\n"; inc_indent(); for (auto &item : x.m_symtab->get_scope()) { From 3fb4d26dbd3b60393c129ec79e4fa8fadf9dda30 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Wed, 20 Dec 2023 03:24:06 +0530 Subject: [PATCH 04/15] rename files, use python instead of lpython, remove backend --- integration_tests/CMakeLists.txt | 9 ----- integration_tests/run_tests.py | 2 +- run_tests.py | 6 ++-- src/bin/lpython.cpp | 25 +++++-------- src/libasr/CMakeLists.txt | 2 +- .../{asr_to_lpython.cpp => asr_to_python.cpp} | 36 +++---------------- .../{asr_to_lpython.h => asr_to_python.h} | 0 7 files changed, 18 insertions(+), 62 deletions(-) rename src/libasr/codegen/{asr_to_lpython.cpp => asr_to_python.cpp} (86%) rename src/libasr/codegen/{asr_to_lpython.h => asr_to_python.h} (100%) diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index f067ff490b..d5a477f006 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -301,15 +301,6 @@ macro(RUN_UTIL RUN_FAIL RUN_NAME RUN_FILE_NAME RUN_LABELS RUN_EXTRAFILES RUN_NOM if (${fail}) set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) endif() - elseif(KIND STREQUAL "lpython") - # lpython test - execute_process(COMMAND ${LPYTHON} ${extra_arg} --backend lpython ${CMAKE_CURRENT_SOURCE_DIR}/${file_name}.py) - if (lables) - set_tests_properties(${name} PROPERTIES LABELS "${labels}") - endif() - if (${fail}) - set_tests_properties(${name} PROPERTIES WILL_FAIL TRUE) - endif() endif() if (copy_to_bin) diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index 37d26ad067..5df4979e03 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -6,7 +6,7 @@ # Initialization DEFAULT_THREADS_TO_USE = 8 # default no of threads is 8 -SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64', 'c_py', 'c_sym', 'cpython_sym', 'llvm_sym', 'llvm_py', 'lpython'] +SUPPORTED_BACKENDS = ['llvm', 'c', 'wasm', 'cpython', 'x86', 'wasm_x86', 'wasm_x64', 'c_py', 'c_sym', 'cpython_sym', 'llvm_sym', 'llvm_py'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) LPYTHON_PATH = f"{BASE_DIR}/../src/bin" diff --git a/run_tests.py b/run_tests.py index e3b52903a6..e6df77d805 100755 --- a/run_tests.py +++ b/run_tests.py @@ -26,7 +26,7 @@ def is_included(backend): llvm_dbg = is_included("llvm_dbg") cpp = is_included("cpp") c = is_included("c") - lpython = is_included("lpython") + python = is_included("python") is_cumulative = is_included("cumulative") wat = is_included("wat") run = is_included("run") @@ -135,8 +135,8 @@ def is_included(backend): run_test(filename, "c", "lpython --no-color --show-c {infile}", filename, update_reference, extra_args) - if lpython: - run_test(filename, "lpython", "lpython --no-color --show-lpython {infile}", + if python: + run_test(filename, "python", "lpython --no-color --show-python {infile}", filename, update_reference, extra_args) if wat: diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 0816af9ead..80a8f15c87 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,7 +56,7 @@ using LCompilers::CompilerOptions; using LCompilers::LPython::parse_python_file; enum class Backend { - llvm, cpp, c, x86, wasm, wasm_x86, wasm_x64, lpython + llvm, cpp, c, x86, wasm, wasm_x86, wasm_x64, python }; @@ -386,7 +386,7 @@ int emit_c_to_file(const std::string &infile, const std::string &outfile, return 0; } -int emit_lpython(const std::string &infile, +int emit_python(const std::string &infile, const std::string &runtime_library_dir, CompilerOptions &compiler_options) { @@ -1328,8 +1328,6 @@ int link_executable(const std::vector &infiles, return 10; } return 0; - } else if (backend == Backend::lpython) { - // TODO } else if (backend == Backend::x86) { std::string cmd = "cp " + infiles[0] + " " + outfile; int err = system(cmd.c_str()); @@ -1543,7 +1541,7 @@ int main(int argc, char *argv[]) bool show_asr = false; bool show_cpp = false; bool show_c = false; - bool show_lpython = false; + bool show_python = false; bool show_document_symbols = false; bool show_errors = false; bool with_intrinsic_modules = false; @@ -1610,7 +1608,7 @@ int main(int argc, char *argv[]) app.add_flag("--show-llvm", show_llvm, "Show LLVM IR for the given file and exit"); app.add_flag("--show-cpp", show_cpp, "Show C++ translation source for the given python file and exit"); app.add_flag("--show-c", show_c, "Show C translation source for the given python file and exit"); - app.add_flag("--show-lpython", show_lpython, "Show Lpython translation source for the given python file and exit"); + app.add_flag("--show-python", show_python, "Show Python translation source for the given python file and exit"); app.add_flag("--show-asm", show_asm, "Show assembly for the given file and exit"); app.add_flag("--show-wat", show_wat, "Show WAT (WebAssembly Text Format) and exit"); app.add_flag("--show-stacktrace", compiler_options.show_stacktrace, "Show internal stacktrace on compiler errors"); @@ -1629,7 +1627,7 @@ int main(int argc, char *argv[]) app.add_flag("--static", static_link, "Create a static executable"); app.add_flag("--no-warnings", compiler_options.no_warnings, "Turn off all warnings"); app.add_flag("--no-error-banner", compiler_options.no_error_banner, "Turn off error banner"); - app.add_option("--backend", arg_backend, "Select a backend (llvm, cpp, x86, wasm, wasm_x86, wasm_x64, lpython)")->capture_default_str(); + app.add_option("--backend", arg_backend, "Select a backend (llvm, cpp, x86, wasm, wasm_x86, wasm_x64)")->capture_default_str(); app.add_flag("--enable-bounds-checking", compiler_options.enable_bounds_checking, "Turn on index bounds checking"); app.add_flag("--openmp", compiler_options.openmp, "Enable openmp"); app.add_flag("--fast", compiler_options.po.fast, "Best performance (disable strict standard compliance)"); @@ -1768,8 +1766,6 @@ int main(int argc, char *argv[]) backend = Backend::c; } else if (arg_backend == "cpp") { backend = Backend::cpp; - } else if (arg_backend == "lpython") { - backend = Backend::lpython; } else if (arg_backend == "x86") { backend = Backend::x86; } else if (arg_backend == "wasm") { @@ -1779,7 +1775,7 @@ int main(int argc, char *argv[]) } else if (arg_backend == "wasm_x64") { backend = Backend::wasm_x64; } else { - std::cerr << "The backend must be one of: llvm, c, cpp, lpython, x86, wasm, wasm_x86, wasm_x64." << std::endl; + std::cerr << "The backend must be one of: llvm, c, cpp, x86, wasm, wasm_x86, wasm_x64." << std::endl; return 1; } @@ -1845,8 +1841,8 @@ int main(int argc, char *argv[]) return emit_c(arg_file, runtime_library_dir, lpython_pass_manager, compiler_options); } - if (show_lpython) { - return emit_lpython(arg_file, runtime_library_dir, compiler_options); + if (show_python) { + return emit_python(arg_file, runtime_library_dir, compiler_options); } if (show_wat) { return emit_wat(arg_file, runtime_library_dir, compiler_options); @@ -1919,9 +1915,6 @@ int main(int argc, char *argv[]) } else if (backend == Backend::wasm_x86 || backend == Backend::wasm_x64) { err = compile_to_binary_wasm_to_x86(arg_file, outfile, runtime_library_dir, compiler_options, time_report, backend); - //} else if (backend == Backend::lpython) { - // err = compile_to_binary_lpython(arg_file, outfile, - // runtime_library_dir, compiler_options, time_report); } else if (backend == Backend::c) { std::string emit_file_name = basename + "__tmp__generated__.c"; err = emit_c_to_file(arg_file, emit_file_name, runtime_library_dir, diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index 65f83c37da..9ae6bee701 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -18,7 +18,7 @@ set(SRC codegen/asr_to_cpp.cpp codegen/asr_to_c.cpp codegen/asr_to_julia.cpp - codegen/asr_to_lpython.cpp + codegen/asr_to_python.cpp codegen/asr_to_fortran.cpp codegen/asr_to_py.cpp codegen/x86_assembler.cpp diff --git a/src/libasr/codegen/asr_to_lpython.cpp b/src/libasr/codegen/asr_to_python.cpp similarity index 86% rename from src/libasr/codegen/asr_to_lpython.cpp rename to src/libasr/codegen/asr_to_python.cpp index c3ede818ee..6aca8705f8 100644 --- a/src/libasr/codegen/asr_to_lpython.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include using LCompilers::ASR::is_a; using LCompilers::ASR::down_cast; @@ -35,8 +35,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor int last_expr_precedence; public: - // TODO: check this constructor - ASRToLpythonVisitor(Allocator& al, diag::Diagnostics& diag, CompilerOptions &co, bool _use_colors, int _indent) + ASRToLpythonVisitor(Allocator& al, diag::Diagnostics& diag, CompilerOptions& /*co*/, bool _use_colors, int _indent) : al{ al }, diag{ diag }, use_colors{_use_colors}, indent_level{0}, indent_spaces{_indent} { } @@ -74,13 +73,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::binopType::Div) : { last_expr_precedence = Precedence::Div; return " / "; - // TODO: add an overload in is_op_overloaded - //} case (ASR::binopType::FloorDiv) : { - // last_expr_precedence = 13; - // return " // "; - //} case (ASR::binopType::Mod) : { - // last_expr_precedence = 13; - // return " % "; } case (ASR::binopType::Pow) : { last_expr_precedence = Precedence::Pow; return " ** "; @@ -113,20 +105,12 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::logicalbinopType::Or) : { last_expr_precedence = Precedence::Or; return " or "; - //} case (ASR::logicalbinopType::Not) : { - // last_expr_precedence = Precedence::Not; - // return " not "; } default : { throw LCompilersException("Cannot represent the boolean operator as a string"); } } } - // TODO: Bitwise operator - // TODO: Assignment operator - // TODO: Membership operator - // TODO: Identity operator - template void visit_body(const T &x, std::string &r, bool apply_indent=true) { if (apply_indent) { @@ -146,7 +130,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor switch (t->type) { case ASR::ttypeType::Integer : { r = "int("; - r += std::to_string(down_cast(t)->m_kind); // TODO: confirm what's m_kind + r += std::to_string(down_cast(t)->m_kind); r += ")"; break; } case ASR::ttypeType::Complex : { @@ -164,18 +148,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += std::to_string(down_cast(t)->m_kind); r += ")"; break; - //} case ASR::ttypeType::Tuple : { // TODO: make it work - // r = "tuple("; - // r += std::to_string(down_cast(t)->m_kind); - // r = ")"; - // break; - //} case ASR::ttypeType::List : { - // r = "list("; - // r += "["; - // r += std::to_string(down_cast(t)->m_kind); - // r += "]"; - // r = ")"; - // break; } case ASR::ttypeType::Array : { r = get_type(down_cast(t)->m_type); break; @@ -294,7 +266,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor }; Result asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, - diag::Diagnostics& diagnostics, CompilerOptions &co, + diag::Diagnostics& diagnostics, CompilerOptions& co, bool color, int indent) { ASRToLpythonVisitor v(al, diagnostics, co, color, indent); try { diff --git a/src/libasr/codegen/asr_to_lpython.h b/src/libasr/codegen/asr_to_python.h similarity index 100% rename from src/libasr/codegen/asr_to_lpython.h rename to src/libasr/codegen/asr_to_python.h From 016da52c446262095a72533a064e37ad021f354b Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Wed, 20 Dec 2023 12:34:10 +0530 Subject: [PATCH 05/15] add tests --- tests/reference/python-complex1-f676023.json | 13 ++++++++++ .../reference/python-complex1-f676023.stdout | 9 +++++++ tests/reference/python-expr2-6b69018.json | 13 ++++++++++ tests/reference/python-expr2-6b69018.stdout | 6 +++++ tests/reference/python-expr_01-123410e.json | 13 ++++++++++ tests/reference/python-expr_01-123410e.stderr | 26 +++++++++++++++++++ tests/tests.toml | 3 +++ 7 files changed, 83 insertions(+) create mode 100644 tests/reference/python-complex1-f676023.json create mode 100644 tests/reference/python-complex1-f676023.stdout create mode 100644 tests/reference/python-expr2-6b69018.json create mode 100644 tests/reference/python-expr2-6b69018.stdout create mode 100644 tests/reference/python-expr_01-123410e.json create mode 100644 tests/reference/python-expr_01-123410e.stderr diff --git a/tests/reference/python-complex1-f676023.json b/tests/reference/python-complex1-f676023.json new file mode 100644 index 0000000000..26b3d7b6d3 --- /dev/null +++ b/tests/reference/python-complex1-f676023.json @@ -0,0 +1,13 @@ +{ + "basename": "python-complex1-f676023", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/complex1.py", + "infile_hash": "60b45de7b88ec768d70a3122b36545e9604a86504ed6e5d9d813c719", + "outfile": null, + "outfile_hash": null, + "stdout": "python-complex1-f676023.stdout", + "stdout_hash": "dd0d13182e8c14c21aeb38bab81105cb1b973c6f0c0f39d019198970", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-complex1-f676023.stdout b/tests/reference/python-complex1-f676023.stdout new file mode 100644 index 0000000000..2f465e1fda --- /dev/null +++ b/tests/reference/python-complex1-f676023.stdout @@ -0,0 +1,9 @@ +def __main__(): + + +def lpython_builtin(): + + +def main0(): +main_program() + diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json new file mode 100644 index 0000000000..0b4019652e --- /dev/null +++ b/tests/reference/python-expr2-6b69018.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr2-6b69018", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr2.py", + "infile_hash": "52d7d4d33553138f2cf55b9900047e5310c54d62e54b3ca1fa394024", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr2-6b69018.stdout", + "stdout_hash": "80f84c6042272b02da27b09a41c342a510a0e1cad85c7882dfe595b7", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout new file mode 100644 index 0000000000..846fc801d6 --- /dev/null +++ b/tests/reference/python-expr2-6b69018.stdout @@ -0,0 +1,6 @@ +def __main__(): + + +def main0(): +main_program() + diff --git a/tests/reference/python-expr_01-123410e.json b/tests/reference/python-expr_01-123410e.json new file mode 100644 index 0000000000..95c830b516 --- /dev/null +++ b/tests/reference/python-expr_01-123410e.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr_01-123410e", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr_01.py", + "infile_hash": "4284fe3a1b4dd3e5d1de1357a79e9a25b426ca245b4cc91cf99e8547", + "outfile": null, + "outfile_hash": null, + "stdout": null, + "stdout_hash": null, + "stderr": "python-expr_01-123410e.stderr", + "stderr_hash": "c48bf3950a62f0ef47f60bffcd24fab81f76a02560b590ddda0e574f", + "returncode": 1 +} \ No newline at end of file diff --git a/tests/reference/python-expr_01-123410e.stderr b/tests/reference/python-expr_01-123410e.stderr new file mode 100644 index 0000000000..ca4280f5f2 --- /dev/null +++ b/tests/reference/python-expr_01-123410e.stderr @@ -0,0 +1,26 @@ +Internal Compiler Error: Unhandled exception +Traceback (most recent call last): + Binary file "$DIR/src/bin/lpython", in _start() + File "./csu/../csu/libc-start.c", line 392, in __libc_start_main_impl() + File "./csu/../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main() + File "$DIR/src/bin/lpython.cpp", line 1845, in ?? + return emit_python(arg_file, runtime_library_dir, compiler_options); + File "$DIR/src/bin/lpython.cpp", line 429, in ?? + LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options, color, indent); + File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 273, in LCompilers::asr_to_lpython[abi:cxx11](Allocator&, LCompilers::ASR::TranslationUnit_t&, LCompilers::diag::Diagnostics&, LCompilers::CompilerOptions&, bool, int) + v.visit_TranslationUnit(asr); + File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 183, in LCompilers::ASRToLpythonVisitor::visit_TranslationUnit(LCompilers::ASR::TranslationUnit_t const&) + visit_symbol(*item.second); + File "$DIR/src/libasr/../libasr/asr.h", line 5060, in LCompilers::ASR::BaseVisitor::visit_symbol(LCompilers::ASR::symbol_t const&) + void visit_symbol(const symbol_t &b) { visit_symbol_t(b, self()); } + File "$DIR/src/libasr/../libasr/asr.h", line 4774, in ?? + case symbolType::Program: { v.visit_Program((const Program_t &)x); return; } + File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 252, in LCompilers::ASRToLpythonVisitor::visit_Program(LCompilers::ASR::Program_t const&) + visit_body(x, r, true); + File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 120, in void LCompilers::ASRToLpythonVisitor::visit_body(LCompilers::ASR::Program_t const&, std::__cxx11::basic_string, std::allocator >&, bool) + visit_stmt(*x.m_body[i]); + File "$DIR/src/libasr/../libasr/asr.h", line 5077, in LCompilers::ASR::BaseVisitor::visit_stmt(LCompilers::ASR::stmt_t const&) + void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); } + File "$DIR/src/libasr/../libasr/asr.h", line 4826, in ?? + case stmtType::SubroutineCall: { v.visit_SubroutineCall((const SubroutineCall_t &)x); return; } +LCompilersException: visit_SubroutineCall() not implemented diff --git a/tests/tests.toml b/tests/tests.toml index 9ed98dd2f7..63379ca8dc 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -21,6 +21,7 @@ cpp = true filename = "complex1.py" ast = true asr = true +python = true [[test]] filename = "complex2.py" @@ -62,6 +63,7 @@ ast = true asr = true cpp = true wat = true +python = true [[test]] filename = "expr4.py" @@ -141,6 +143,7 @@ ast = true asr = true llvm = true llvm_dbg = true +python = true [[test]] filename = "../integration_tests/array_01_decl.py" From a603db9bd4d978ccac874c5a0b2130ac72ee8ea4 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Sat, 20 Jan 2024 18:39:13 +0530 Subject: [PATCH 06/15] fix --- src/libasr/codegen/asr_to_python.cpp | 125 ++++++++++++------ tests/reference/python-complex1-f676023.json | 13 -- .../reference/python-complex1-f676023.stdout | 9 -- tests/reference/python-expr2-6b69018.json | 13 -- tests/reference/python-expr2-6b69018.stdout | 6 - tests/reference/python-expr_01-123410e.json | 13 -- tests/reference/python-expr_01-123410e.stderr | 26 ---- tests/tests.toml | 3 - 8 files changed, 87 insertions(+), 121 deletions(-) delete mode 100644 tests/reference/python-complex1-f676023.json delete mode 100644 tests/reference/python-complex1-f676023.stdout delete mode 100644 tests/reference/python-expr2-6b69018.json delete mode 100644 tests/reference/python-expr2-6b69018.stdout delete mode 100644 tests/reference/python-expr_01-123410e.json delete mode 100644 tests/reference/python-expr_01-123410e.stderr diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 6aca8705f8..5f726d83ec 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -164,13 +164,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { std::string r = ""; - for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { - visit_symbol(*item.second); - r += s; - } - } - for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); @@ -187,22 +180,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } - void visit_Module(const ASR::Module_t &x) { - // Generate code for the lpython function - std::string r; - r = "def"; - r += " "; - r.append(x.m_name); - r += "()"; - r += ":"; - r += "\n"; - inc_indent(); - r += "\n"; - dec_indent(); - r += "\n"; - s = r; - } - void visit_Function(const ASR::Function_t &x) { // Generate code for the lpython function std::string r; @@ -232,37 +209,109 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } void visit_Program(const ASR::Program_t &x) { - // Generate code for main function std::string r; - r = "def"; - r += " "; - r += "main0():"; - r += "\n"; - inc_indent(); + + // Generate code for nested functions for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { + if (is_a(*item.second)) { visit_symbol(*item.second); r += s; } } - r.append(x.m_name); - r += "()"; - r += "\n"; - visit_body(x, r, true); + visit_body(x, r, false); + // Generate code for main function + inc_indent(); + std::string r2; for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { - visit_symbol(*item.second); - r += s; + if (is_a(*item.second)) { + ASR::Variable_t* v = ASR::down_cast(item.second); + visit_Variable(*v); + r2 += s; } } - dec_indent(); + + r += "\n"; + s = r; + } + + void visit_Variable(const ASR::Variable_t &x) { + std::string r = indent; + switch (x.m_type->type) { + case ASR::ttypeType::Integer: { + ASR::Integer_t *i = down_cast(x.m_type); + r += x.m_name; + r += ": "; + r += std::to_string(i->m_kind); + break; + } + default: + throw LCompilersException("Type not implemented"); + } + r += "\n"; + s = r; + } + + void visit_Assignment(const ASR::Assignment_t &x) { + std::string r = indent; + visit_expr(*x.m_target); + r += s; + r += " = "; + visit_expr(*x.m_value); + r += s; r += "\n"; s = r; } + void visit_SubroutineCall(const ASR::SubroutineCall_t /*&x*/) { + std::string r = indent; + } + + void visit_Cast(const ASR::Cast_t &x) { + // TODO + visit_expr(*x.m_arg); + } + + void visit_Var(const ASR::Var_t &x) { + s = ASRUtils::symbol_name(x.m_v); + } + + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { + std::string r; + // TODO: Handle precedence based on the last_operator_precedence + r = "("; + visit_expr(*x.m_left); + r += s; + r += binop2str(x.m_op); + visit_expr(*x.m_right); + r += s; + r += ")"; + s = r; + } + + void visit_IntegerCompare(const ASR::IntegerCompare_t &x) { + std::string r; + // TODO: Handle precedence based on the last_operator_precedence + r = "("; + visit_expr(*x.m_left); + r += s; + r += cmpop2str(x.m_op); + visit_expr(*x.m_right); + r += s; + r += ")"; + s = r; + } + + void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { + s = std::to_string(x.m_n); + } + + void visit_RealConstant(const ASR::RealConstant_t &x) { + s = std::to_string(x.m_r); + } + }; Result asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, diff --git a/tests/reference/python-complex1-f676023.json b/tests/reference/python-complex1-f676023.json deleted file mode 100644 index 26b3d7b6d3..0000000000 --- a/tests/reference/python-complex1-f676023.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "basename": "python-complex1-f676023", - "cmd": "lpython --no-color --show-python {infile}", - "infile": "tests/complex1.py", - "infile_hash": "60b45de7b88ec768d70a3122b36545e9604a86504ed6e5d9d813c719", - "outfile": null, - "outfile_hash": null, - "stdout": "python-complex1-f676023.stdout", - "stdout_hash": "dd0d13182e8c14c21aeb38bab81105cb1b973c6f0c0f39d019198970", - "stderr": null, - "stderr_hash": null, - "returncode": 0 -} \ No newline at end of file diff --git a/tests/reference/python-complex1-f676023.stdout b/tests/reference/python-complex1-f676023.stdout deleted file mode 100644 index 2f465e1fda..0000000000 --- a/tests/reference/python-complex1-f676023.stdout +++ /dev/null @@ -1,9 +0,0 @@ -def __main__(): - - -def lpython_builtin(): - - -def main0(): -main_program() - diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json deleted file mode 100644 index 0b4019652e..0000000000 --- a/tests/reference/python-expr2-6b69018.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "basename": "python-expr2-6b69018", - "cmd": "lpython --no-color --show-python {infile}", - "infile": "tests/expr2.py", - "infile_hash": "52d7d4d33553138f2cf55b9900047e5310c54d62e54b3ca1fa394024", - "outfile": null, - "outfile_hash": null, - "stdout": "python-expr2-6b69018.stdout", - "stdout_hash": "80f84c6042272b02da27b09a41c342a510a0e1cad85c7882dfe595b7", - "stderr": null, - "stderr_hash": null, - "returncode": 0 -} \ No newline at end of file diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout deleted file mode 100644 index 846fc801d6..0000000000 --- a/tests/reference/python-expr2-6b69018.stdout +++ /dev/null @@ -1,6 +0,0 @@ -def __main__(): - - -def main0(): -main_program() - diff --git a/tests/reference/python-expr_01-123410e.json b/tests/reference/python-expr_01-123410e.json deleted file mode 100644 index 95c830b516..0000000000 --- a/tests/reference/python-expr_01-123410e.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "basename": "python-expr_01-123410e", - "cmd": "lpython --no-color --show-python {infile}", - "infile": "tests/expr_01.py", - "infile_hash": "4284fe3a1b4dd3e5d1de1357a79e9a25b426ca245b4cc91cf99e8547", - "outfile": null, - "outfile_hash": null, - "stdout": null, - "stdout_hash": null, - "stderr": "python-expr_01-123410e.stderr", - "stderr_hash": "c48bf3950a62f0ef47f60bffcd24fab81f76a02560b590ddda0e574f", - "returncode": 1 -} \ No newline at end of file diff --git a/tests/reference/python-expr_01-123410e.stderr b/tests/reference/python-expr_01-123410e.stderr deleted file mode 100644 index ca4280f5f2..0000000000 --- a/tests/reference/python-expr_01-123410e.stderr +++ /dev/null @@ -1,26 +0,0 @@ -Internal Compiler Error: Unhandled exception -Traceback (most recent call last): - Binary file "$DIR/src/bin/lpython", in _start() - File "./csu/../csu/libc-start.c", line 392, in __libc_start_main_impl() - File "./csu/../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main() - File "$DIR/src/bin/lpython.cpp", line 1845, in ?? - return emit_python(arg_file, runtime_library_dir, compiler_options); - File "$DIR/src/bin/lpython.cpp", line 429, in ?? - LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options, color, indent); - File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 273, in LCompilers::asr_to_lpython[abi:cxx11](Allocator&, LCompilers::ASR::TranslationUnit_t&, LCompilers::diag::Diagnostics&, LCompilers::CompilerOptions&, bool, int) - v.visit_TranslationUnit(asr); - File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 183, in LCompilers::ASRToLpythonVisitor::visit_TranslationUnit(LCompilers::ASR::TranslationUnit_t const&) - visit_symbol(*item.second); - File "$DIR/src/libasr/../libasr/asr.h", line 5060, in LCompilers::ASR::BaseVisitor::visit_symbol(LCompilers::ASR::symbol_t const&) - void visit_symbol(const symbol_t &b) { visit_symbol_t(b, self()); } - File "$DIR/src/libasr/../libasr/asr.h", line 4774, in ?? - case symbolType::Program: { v.visit_Program((const Program_t &)x); return; } - File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 252, in LCompilers::ASRToLpythonVisitor::visit_Program(LCompilers::ASR::Program_t const&) - visit_body(x, r, true); - File "$DIR/src/libasr/codegen/asr_to_python.cpp", line 120, in void LCompilers::ASRToLpythonVisitor::visit_body(LCompilers::ASR::Program_t const&, std::__cxx11::basic_string, std::allocator >&, bool) - visit_stmt(*x.m_body[i]); - File "$DIR/src/libasr/../libasr/asr.h", line 5077, in LCompilers::ASR::BaseVisitor::visit_stmt(LCompilers::ASR::stmt_t const&) - void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); } - File "$DIR/src/libasr/../libasr/asr.h", line 4826, in ?? - case stmtType::SubroutineCall: { v.visit_SubroutineCall((const SubroutineCall_t &)x); return; } -LCompilersException: visit_SubroutineCall() not implemented diff --git a/tests/tests.toml b/tests/tests.toml index 63379ca8dc..9ed98dd2f7 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -21,7 +21,6 @@ cpp = true filename = "complex1.py" ast = true asr = true -python = true [[test]] filename = "complex2.py" @@ -63,7 +62,6 @@ ast = true asr = true cpp = true wat = true -python = true [[test]] filename = "expr4.py" @@ -143,7 +141,6 @@ ast = true asr = true llvm = true llvm_dbg = true -python = true [[test]] filename = "../integration_tests/array_01_decl.py" From c2ab6364b42f131b9aa49d5829c2b9bcb79cc2f0 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Sat, 20 Jan 2024 20:46:05 +0530 Subject: [PATCH 07/15] add print visitor and fix program visitor --- src/libasr/codegen/asr_to_python.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 5f726d83ec..0298ac387d 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -223,12 +223,10 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor // Generate code for main function inc_indent(); - std::string r2; for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { - ASR::Variable_t* v = ASR::down_cast(item.second); - visit_Variable(*v); - r2 += s; + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; } } dec_indent(); @@ -254,6 +252,20 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_Print(const ASR::Print_t &x) { + std::string r; + r += "print("; + for (size_t i = 0; i < x.n_values; i++) { + visit_expr(*x.m_values[i]); + r += s; + if (i < x.n_values-1) + r += ", "; + } + r += ")"; + r += "\n"; + s = r; + } + void visit_Assignment(const ASR::Assignment_t &x) { std::string r = indent; visit_expr(*x.m_target); From be0f8e346dc515c38ae8b5c32bb878cb77dbc52e Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 13 Feb 2024 03:53:06 +0530 Subject: [PATCH 08/15] add visitors --- src/libasr/codegen/asr_to_python.cpp | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 0298ac387d..4425f90b7b 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -290,6 +290,57 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = ASRUtils::symbol_name(x.m_v); } + void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { + visit_symbol(*x.m_external); + } + + void visit_If(const ASR::If_t &x) { + std::string r = indent; + r += "if"; + visit_expr(*x.m_test); + r += s; + r += ":"; + r += "\n"; + inc_indent(); + for (size_t i = 0; i < x.n_body; i++) { + visit_stmt(*x.m_body[i]); + r += s; + } + dec_indent(); + if (x.n_orelse == 0) { + r += "\n"; + } else { + for (size_t i = 0; i < x.n_orelse; i++) { + r += "else:"; + r += "\n"; + inc_indent(); + visit_stmt(*x.m_orelse[i]); + r += s; + dec_indent(); + } + r += "\n"; + } + s = r; + } + + void visit_StringCompare(const ASR::StringCompare_t &x) { + std::string r; + r = "("; + visit_expr(*x.m_left); + r += s; + r += cmpop2str(x.m_op); + visit_expr(*x.m_right); + r += s; + r += ")"; + s = r; + } + + void visit_StringConstant(const ASR::StringConstant_t &x) { + s = "\""; + s.append(x.m_s); + s += "\""; + } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { std::string r; // TODO: Handle precedence based on the last_operator_precedence From 57dd71a38d33e3efb60daea24faca4e88460d13b Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 5 Mar 2024 13:22:43 +0530 Subject: [PATCH 09/15] fix syntax --- src/bin/lpython.cpp | 2 +- src/libasr/codegen/asr_to_python.cpp | 172 ++++++++++++++++++++------- src/libasr/codegen/asr_to_python.h | 2 +- 3 files changed, 128 insertions(+), 48 deletions(-) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 80a8f15c87..903d53c354 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -426,7 +426,7 @@ int emit_python(const std::string &infile, // ASR -> LPython bool color = false; int indent = 0; - LCompilers::Result res = LCompilers::asr_to_lpython(al, *asr, diagnostics, compiler_options, color, indent); + LCompilers::Result res = LCompilers::asr_to_python(al, *asr, diagnostics, compiler_options, color, indent); std::cerr << diagnostics.render(lm, compiler_options); if (!res.ok) { LCOMPILERS_ASSERT(diagnostics.has_error()) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 4425f90b7b..f8bc7b311f 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -9,15 +9,16 @@ using LCompilers::ASR::down_cast; namespace LCompilers { enum Precedence { - Or = 4, - And = 5, - CmpOp = 7, - Add = 8, - Sub = 12, - UnaryMinus = 9, + Exp = 15, + Pow = 15, + UnaryMinus = 14, Mul = 13, Div = 13, - Pow = 15, + Add = 12, + Sub = 12, + CmpOp = 7, + And = 5, + Or = 4, }; class ASRToLpythonVisitor : public ASR::BaseVisitor @@ -128,30 +129,29 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor std::string get_type(const ASR::ttype_t *t) { std::string r = ""; switch (t->type) { - case ASR::ttypeType::Integer : { - r = "int("; + case ASR::ttypeType::Integer: { + r = "i"; r += std::to_string(down_cast(t)->m_kind); - r += ")"; break; - } case ASR::ttypeType::Complex : { - r = "complex("; + } case ASR::ttypeType::Real: { + r += "f"; + r += std::to_string(down_cast(t)->m_kind); + break; + } case ASR::ttypeType::Complex: { + r = "c"; r += std::to_string(down_cast(t)->m_kind); - r += ")"; break; - } case ASR::ttypeType::Character : { - r = "chr("; + } case ASR::ttypeType::Character: { + r = "utf"; r += std::to_string(down_cast(t)->m_kind); - r += ")"; - break; - } case ASR::ttypeType::Logical : { - r = "bool("; + + r = "bool "; r += std::to_string(down_cast(t)->m_kind); - r += ")"; break; - } case ASR::ttypeType::Array : { + } case ASR::ttypeType::Array: { r = get_type(down_cast(t)->m_type); break; - } case ASR::ttypeType::Allocatable : { + } case ASR::ttypeType::Allocatable: { r = get_type(down_cast(t)->m_type); break; } default : { @@ -164,13 +164,24 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { std::string r = ""; + + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + r += "\n"; + } + } + for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); r += s; + r += "\n"; } } + // Main program for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); @@ -180,6 +191,23 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_Module(const ASR::Module_t &x) { + std::string r; + r = x.m_name; + + //std::vector func_name; + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + //ASR::Function_t *f = ASR::down_cast(item.second); + //func_name.push_back(item.first); + //visit_Function(item.second); + visit_symbol(*item.second); + r += s; + } + } + s = r; + } + void visit_Function(const ASR::Function_t &x) { // Generate code for the lpython function std::string r; @@ -190,6 +218,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor for (size_t i = 0; i < x.n_args; i++) { visit_expr(*x.m_args[i]); r += s; + if (i < x.n_args - 1) { + r += ", "; + } } r += "):"; r += "\n"; @@ -201,35 +232,64 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += s; } } + dec_indent(); visit_body(x, r, true); - dec_indent(); + r += "\n"; s = r; } void visit_Program(const ASR::Program_t &x) { std::string r; - +/* + r = "if "; + r += "__name__"; + r += " == "; + r += "__main__:"; + r += "\n"; + r += " "; + r.append(x.m_name); + r += "()"; +*/ // Generate code for nested functions - for (auto &item : x.m_symtab->get_scope()) { + /*for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); r += s; } + }*/ + + /*std::vector var_order = ASRUtils::determine_variable_declaration_order(x.m_symtab); + for (auto &item : var_order) { + ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); + if (is_a(*var_sym)) { + visit_symbol(*var_sym); + r += s; + } + }*/ +/* + inc_indent(); + for (auto &item : x.m_symtab->get_scope()) { + if (is_a(*item.second)) { + visit_symbol(*item.second); + r += s; + } } visit_body(x, r, false); - // Generate code for main function - inc_indent(); + dec_indent(); +*/ for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { + //ASR::Function_t *f = ASR::down_cast(item.second); + //visit_Function(*f); visit_symbol(*item.second); r += s; + r += "\n"; } } - dec_indent(); r += "\n"; s = r; @@ -237,23 +297,17 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_Variable(const ASR::Variable_t &x) { std::string r = indent; - switch (x.m_type->type) { - case ASR::ttypeType::Integer: { - ASR::Integer_t *i = down_cast(x.m_type); - r += x.m_name; - r += ": "; - r += std::to_string(i->m_kind); - break; - } - default: - throw LCompilersException("Type not implemented"); - } + r += x.m_name; + r += ": "; + r += get_type(x.m_type); + //r += " : "; + //r.append(x.m_name); r += "\n"; s = r; } void visit_Print(const ASR::Print_t &x) { - std::string r; + std::string r = indent; r += "print("; for (size_t i = 0; i < x.n_values; i++) { visit_expr(*x.m_values[i]); @@ -290,9 +344,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = ASRUtils::symbol_name(x.m_v); } - void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { + /*void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { visit_symbol(*x.m_external); - } + }*/ void visit_If(const ASR::If_t &x) { std::string r = indent; @@ -323,15 +377,30 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { + std::string r; + switch (x.m_intrinsic_id) { + //SET_INTRINSIC_NAME(Abs, "abs"); + default : { + throw LCompilersException("IntrinsicScalarFunction: `" + + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) + + "` is not implemented"); + } + } + LCOMPILERS_ASSERT(x.n_args == 1); + visit_expr(*x.m_args[0]); + r += "(" + s + ")"; + s = r; + } + void visit_StringCompare(const ASR::StringCompare_t &x) { std::string r; - r = "("; + r = " "; visit_expr(*x.m_left); r += s; r += cmpop2str(x.m_op); visit_expr(*x.m_right); r += s; - r += ")"; s = r; } @@ -375,12 +444,23 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = std::to_string(x.m_r); } + void visit_RealCompare(const ASR::RealCompare_t &x) { + std::string r; + r = "("; + visit_expr(*x.m_left); + r += s; + r += cmpop2str(x.m_op); + visit_expr(*x.m_right); + r += s; + r += ")"; + s = r; + } }; -Result asr_to_lpython(Allocator& al, ASR::TranslationUnit_t &asr, +Result asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr, diag::Diagnostics& diagnostics, CompilerOptions& co, bool color, int indent) { - ASRToLpythonVisitor v(al, diagnostics, co, color, indent); + ASRToLpythonVisitor v(al, diagnostics, co, color, indent=4); try { v.visit_TranslationUnit(asr); } catch (const CodeGenError &e) { diff --git a/src/libasr/codegen/asr_to_python.h b/src/libasr/codegen/asr_to_python.h index 8a19b8dc84..fa812a7fe3 100644 --- a/src/libasr/codegen/asr_to_python.h +++ b/src/libasr/codegen/asr_to_python.h @@ -7,7 +7,7 @@ namespace LCompilers { // Convert ASR to Python source code - Result asr_to_lpython(Allocator &al, ASR::TranslationUnit_t &asr, + Result asr_to_python(Allocator &al, ASR::TranslationUnit_t &asr, diag::Diagnostics &diagnostics, CompilerOptions &co, bool color, int indent); From cbbcd84263b78d9592425019646dd503cae00f41 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 5 Mar 2024 15:03:47 +0530 Subject: [PATCH 10/15] fix errors and add tests --- src/libasr/codegen/asr_to_python.cpp | 141 ++++++++++---------- tests/reference/python-expr2-6b69018.json | 13 ++ tests/reference/python-expr2-6b69018.stdout | 14 ++ tests/tests.toml | 1 + 4 files changed, 100 insertions(+), 69 deletions(-) create mode 100644 tests/reference/python-expr2-6b69018.json create mode 100644 tests/reference/python-expr2-6b69018.stdout diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index f8bc7b311f..216198d69d 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -51,7 +51,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor indent = std::string(indent_level*indent_spaces, ' '); } - void visit_expr_with_last_precedence(const ASR::expr_t &x, int current_precedence) { + void visit_expr_with_precedence(const ASR::expr_t &x, int current_precedence) { visit_expr(x); if (last_expr_precedence == 18 || last_expr_precedence < current_precedence) { @@ -129,24 +129,43 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor std::string get_type(const ASR::ttype_t *t) { std::string r = ""; switch (t->type) { - case ASR::ttypeType::Integer: { - r = "i"; - r += std::to_string(down_cast(t)->m_kind); + case ASR::ttypeType::Integer : { + std::string out; + out = std::to_string(down_cast(t)->m_kind); + if (out == "1") { + r += "i8"; + } else if (out == "2") { + r += "i16"; + } else if (out == "4") { + r += "i32"; + } else if (out == "8") { + r += "i64"; + } break; - } case ASR::ttypeType::Real: { - r += "f"; - r += std::to_string(down_cast(t)->m_kind); + } case ASR::ttypeType::Real : { + std::string out; + out = std::to_string(down_cast(t)->m_kind); + if (out == "4") { + r += "f32"; + } else if (out == "8") { + r += "f64"; + } break; - } case ASR::ttypeType::Complex: { - r = "c"; - r += std::to_string(down_cast(t)->m_kind); + } case ASR::ttypeType::Complex : { + std::string out; + out = std::to_string(down_cast(t)->m_kind); + if (out == "4") { + r += "c32"; + } else if (out == "8") { + r += "c64"; + } break; - } case ASR::ttypeType::Character: { + } case ASR::ttypeType::Character : { r = "utf"; r += std::to_string(down_cast(t)->m_kind); - - r = "bool "; - r += std::to_string(down_cast(t)->m_kind); + break; + } case ASR::ttypeType::Logical : { + r = "bool"; break; } case ASR::ttypeType::Array: { r = get_type(down_cast(t)->m_type); @@ -193,14 +212,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_Module(const ASR::Module_t &x) { std::string r; - r = x.m_name; - //std::vector func_name; for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { - //ASR::Function_t *f = ASR::down_cast(item.second); - //func_name.push_back(item.first); - //visit_Function(item.second); visit_symbol(*item.second); r += s; } @@ -242,49 +256,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_Program(const ASR::Program_t &x) { std::string r; -/* - r = "if "; - r += "__name__"; - r += " == "; - r += "__main__:"; - r += "\n"; - r += " "; - r.append(x.m_name); - r += "()"; -*/ - // Generate code for nested functions - /*for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { - visit_symbol(*item.second); - r += s; - } - }*/ - /*std::vector var_order = ASRUtils::determine_variable_declaration_order(x.m_symtab); - for (auto &item : var_order) { - ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); - if (is_a(*var_sym)) { - visit_symbol(*var_sym); - r += s; - } - }*/ -/* - inc_indent(); - for (auto &item : x.m_symtab->get_scope()) { - if (is_a(*item.second)) { - visit_symbol(*item.second); - r += s; - } - } - - visit_body(x, r, false); - - dec_indent(); -*/ for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { - //ASR::Function_t *f = ASR::down_cast(item.second); - //visit_Function(*f); visit_symbol(*item.second); r += s; r += "\n"; @@ -300,8 +274,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += x.m_name; r += ": "; r += get_type(x.m_type); - //r += " : "; - //r.append(x.m_name); r += "\n"; s = r; } @@ -344,10 +316,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = ASRUtils::symbol_name(x.m_v); } - /*void visit_ExternalSymbol(const ASR::ExternalSymbol_t &x) { - visit_symbol(*x.m_external); - }*/ - void visit_If(const ASR::If_t &x) { std::string r = indent; r += "if"; @@ -378,9 +346,9 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { - std::string r; + std::string out; switch (x.m_intrinsic_id) { - //SET_INTRINSIC_NAME(Abs, "abs"); + SET_INTRINSIC_NAME(Abs, "abs"); default : { throw LCompilersException("IntrinsicScalarFunction: `" + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) @@ -389,8 +357,8 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } LCOMPILERS_ASSERT(x.n_args == 1); visit_expr(*x.m_args[0]); - r += "(" + s + ")"; - s = r; + out += "(" + s + ")"; + s = out; } void visit_StringCompare(const ASR::StringCompare_t &x) { @@ -455,6 +423,41 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += ")"; s = r; } + + void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { + std::string r; + if (x.m_value) { + r += "True"; + } else { + r += "False"; + } + s = r; + } + + void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { + std::string r; + std::string m_op = logicalbinop2str(x.m_op); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); + r += s; + r += m_op; + visit_expr_with_precedence(*x.m_right, current_precedence); + r += s; + last_expr_precedence = current_precedence; + s = r; + } + + void visit_LogicalCompare(const ASR::LogicalCompare_t &x) { + std::string r; + r = "("; + visit_expr(*x.m_left); + r += s; + r += cmpop2str(x.m_op); + visit_expr(*x.m_right); + r += s; + r += ")"; + s = r; + } }; Result asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr, diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json new file mode 100644 index 0000000000..44922de477 --- /dev/null +++ b/tests/reference/python-expr2-6b69018.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr2-6b69018", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr2.py", + "infile_hash": "52d7d4d33553138f2cf55b9900047e5310c54d62e54b3ca1fa394024", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr2-6b69018.stdout", + "stdout_hash": "ca7adbdf0b04bccf53123c92c5dbf3eb368889b4edb9b81b9da00e3d", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout new file mode 100644 index 0000000000..556dd82557 --- /dev/null +++ b/tests/reference/python-expr2-6b69018.stdout @@ -0,0 +1,14 @@ +def test_boolOp(): + a: bool + b: bool + a = False + b = True + a = a and b + b = a or True + a = a or b + a = a and (b == b) + a = a and (b != b) + a = b or b + + + diff --git a/tests/tests.toml b/tests/tests.toml index b033615665..d806b9df31 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -62,6 +62,7 @@ ast = true asr = true cpp = true wat = true +python = true [[test]] filename = "expr4.py" From 34d7ec665adb11f06d5edcdafa0210c2e091ee7d Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 5 Mar 2024 15:11:17 +0530 Subject: [PATCH 11/15] remove extra newline --- src/libasr/codegen/asr_to_python.cpp | 2 -- tests/reference/python-expr2-6b69018.json | 2 +- tests/reference/python-expr2-6b69018.stdout | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 216198d69d..d674cdaeae 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -250,7 +250,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor visit_body(x, r, true); - r += "\n"; s = r; } @@ -261,7 +260,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor if (is_a(*item.second)) { visit_symbol(*item.second); r += s; - r += "\n"; } } diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json index 44922de477..6cd593f93f 100644 --- a/tests/reference/python-expr2-6b69018.json +++ b/tests/reference/python-expr2-6b69018.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr2-6b69018.stdout", - "stdout_hash": "ca7adbdf0b04bccf53123c92c5dbf3eb368889b4edb9b81b9da00e3d", + "stdout_hash": "c7c8637de6a616257bfcfc76c2fabe82e61a5e44eadb3a6bd1af9b63", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout index 556dd82557..c352186309 100644 --- a/tests/reference/python-expr2-6b69018.stdout +++ b/tests/reference/python-expr2-6b69018.stdout @@ -11,4 +11,3 @@ def test_boolOp(): a = b or b - From 88eaeb42c8054879e43ff95be417437c9dbca654 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Tue, 5 Mar 2024 16:21:57 +0530 Subject: [PATCH 12/15] add more visitors and tests --- src/libasr/codegen/asr_to_python.cpp | 86 +++++++++++++++++--- tests/reference/python-expr11-e6681c8.json | 13 +++ tests/reference/python-expr11-e6681c8.stdout | 10 +++ tests/reference/python-expr5-dee0e5c.json | 13 +++ tests/reference/python-expr5-dee0e5c.stdout | 7 ++ tests/reference/python-expr6-1a1d4fb.json | 13 +++ tests/reference/python-expr6-1a1d4fb.stdout | 9 ++ tests/tests.toml | 3 + 8 files changed, 144 insertions(+), 10 deletions(-) create mode 100644 tests/reference/python-expr11-e6681c8.json create mode 100644 tests/reference/python-expr11-e6681c8.stdout create mode 100644 tests/reference/python-expr5-dee0e5c.json create mode 100644 tests/reference/python-expr5-dee0e5c.stdout create mode 100644 tests/reference/python-expr6-1a1d4fb.json create mode 100644 tests/reference/python-expr6-1a1d4fb.stdout diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index d674cdaeae..cab49177bf 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -9,16 +9,18 @@ using LCompilers::ASR::down_cast; namespace LCompilers { enum Precedence { - Exp = 15, - Pow = 15, - UnaryMinus = 14, - Mul = 13, - Div = 13, + Or = 4, + And = 5, + Not = 6, + CmpOp = 7, Add = 12, Sub = 12, - CmpOp = 7, - And = 5, - Or = 4, + Mul = 13, + Div = 13, + BitNot = 14, + UnaryMinus = 14, + Exp = 15, + Pow = 15, }; class ASRToLpythonVisitor : public ASR::BaseVisitor @@ -161,8 +163,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } break; } case ASR::ttypeType::Character : { - r = "utf"; - r += std::to_string(down_cast(t)->m_kind); + r = "str"; break; } case ASR::ttypeType::Logical : { r = "bool"; @@ -406,6 +407,18 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = std::to_string(x.m_n); } + void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) { + visit_expr_with_precedence(*x.m_arg, 14); + s = "-" + s; + last_expr_precedence = Precedence::UnaryMinus; + } + + void visit_IntegerBitNot(const ASR::IntegerBitNot_t &x) { + visit_expr_with_precedence(*x.m_arg, 14); + s = "~" + s; + last_expr_precedence = Precedence::BitNot; + } + void visit_RealConstant(const ASR::RealConstant_t &x) { s = std::to_string(x.m_r); } @@ -422,6 +435,12 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) { + visit_expr_with_precedence(*x.m_arg, 14); + s = "-" + s; + last_expr_precedence = Precedence::UnaryMinus; + } + void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { std::string r; if (x.m_value) { @@ -456,6 +475,53 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += ")"; s = r; } + + void visit_LogicalNot(const ASR::LogicalNot_t &x) { + visit_expr_with_precedence(*x.m_arg, 6); + s = "not " + s; + last_expr_precedence = Precedence::Not; + } + + void visit_StringConcat(const ASR::StringConcat_t &x) { + this->visit_expr(*x.m_left); + std::string left = std::move(s); + this->visit_expr(*x.m_right); + std::string right = std::move(s); + s = left + " + " + right; + } + + void visit_StringRepeat(const ASR::StringRepeat_t &x) { + this->visit_expr(*x.m_left); + std::string left = std::move(s); + this->visit_expr(*x.m_right); + std::string right = std::move(s); + s = left + " * " + right; + } + + void visit_IfExp(const ASR::IfExp_t &x) { + std::string r; + visit_expr(*x.m_body); + r += s; + r += " if "; + visit_expr(*x.m_test); + r += s; + r += " else "; + visit_expr(*x.m_orelse); + r += s; + s = r; + } + + void visit_ComplexConstant(const ASR::ComplexConstant_t &x) { + std::string re = std::to_string(x.m_re); + std::string im = std::to_string(x.m_im); + s = "complex(" + re + ", " + im + ")"; + } + + void visit_ComplexUnaryMinus(const ASR::ComplexUnaryMinus_t &x) { + visit_expr_with_precedence(*x.m_arg, 14); + s = "-" + s; + last_expr_precedence = Precedence::UnaryMinus; + } }; Result asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr, diff --git a/tests/reference/python-expr11-e6681c8.json b/tests/reference/python-expr11-e6681c8.json new file mode 100644 index 0000000000..65280da800 --- /dev/null +++ b/tests/reference/python-expr11-e6681c8.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr11-e6681c8", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr11.py", + "infile_hash": "940f2d32759315dfb8d54ea50819f2bfef9737e486615703609fd47a", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr11-e6681c8.stdout", + "stdout_hash": "ed9438b7349f462f0de6fa7a1035c7266187fb4a2455f6fc83f029e8", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr11-e6681c8.stdout b/tests/reference/python-expr11-e6681c8.stdout new file mode 100644 index 0000000000..11b2ffc705 --- /dev/null +++ b/tests/reference/python-expr11-e6681c8.stdout @@ -0,0 +1,10 @@ +def test_StrOp_repeat(): + s: str + s = "a" * 2 + s = "a" * -1 + s = "test" * 5 + s = "bb" * 4 + s = "bb" * -40 + s = "a" * 3 * 3 + + diff --git a/tests/reference/python-expr5-dee0e5c.json b/tests/reference/python-expr5-dee0e5c.json new file mode 100644 index 0000000000..5cf281a38d --- /dev/null +++ b/tests/reference/python-expr5-dee0e5c.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr5-dee0e5c", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr5.py", + "infile_hash": "7bbb5f9dacb13556f99de8f2969f9089235fea372fc2f43fc9c4bb18", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr5-dee0e5c.stdout", + "stdout_hash": "cef56dbae8b4efd362ea96bcbdc080667fd46930c1d7cfbca92bbe8e", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr5-dee0e5c.stdout b/tests/reference/python-expr5-dee0e5c.stdout new file mode 100644 index 0000000000..b63878db76 --- /dev/null +++ b/tests/reference/python-expr5-dee0e5c.stdout @@ -0,0 +1,7 @@ +def test_StrOp_concat(): + s: str + s = "3" + "4" + s = "a " + "test" + s = "test" + "test" + "test" + + diff --git a/tests/reference/python-expr6-1a1d4fb.json b/tests/reference/python-expr6-1a1d4fb.json new file mode 100644 index 0000000000..943620ddb9 --- /dev/null +++ b/tests/reference/python-expr6-1a1d4fb.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr6-1a1d4fb", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr6.py", + "infile_hash": "1f3b5a7d997851264e679d58353346835eb450c608f6da7d2f5e5cd2", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr6-1a1d4fb.stdout", + "stdout_hash": "36caac53096fa6ae7e6bbac2ded68386bd3cc5f23e8934d6f2a56ad4", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr6-1a1d4fb.stdout b/tests/reference/python-expr6-1a1d4fb.stdout new file mode 100644 index 0000000000..3cc3cf2dba --- /dev/null +++ b/tests/reference/python-expr6-1a1d4fb.stdout @@ -0,0 +1,9 @@ +def test_ifexp(): + a: i32 + b: i32 + c: bool + a = 2 + b = 6 if (a == 2) else 8 + c = True if (b > 5) else False + + diff --git a/tests/tests.toml b/tests/tests.toml index d806b9df31..625db9aeb0 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -74,12 +74,14 @@ filename = "expr5.py" ast = true asr = true cpp = true +python = true [[test]] filename = "expr6.py" ast = true asr = true cpp = true +python = true [[test]] filename = "expr7.py" @@ -111,6 +113,7 @@ asr = true filename = "expr11.py" ast = true asr = true +python = true [[test]] filename = "expr12.py" From fdc33108206e7c943ac95b6fb925d8c9817fe68f Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Wed, 6 Mar 2024 00:11:58 +0530 Subject: [PATCH 13/15] address reviews --- src/libasr/codegen/asr_to_python.cpp | 138 ++++++++++++------- tests/expr17.py | 9 ++ tests/reference/python-expr11-e6681c8.json | 2 +- tests/reference/python-expr11-e6681c8.stdout | 4 +- tests/reference/python-expr6-1a1d4fb.json | 2 +- tests/reference/python-expr6-1a1d4fb.stdout | 4 +- 6 files changed, 100 insertions(+), 59 deletions(-) create mode 100644 tests/expr17.py diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index cab49177bf..c6079fc966 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -21,6 +21,7 @@ enum Precedence { UnaryMinus = 14, Exp = 15, Pow = 15, + Constant = 18, }; class ASRToLpythonVisitor : public ASR::BaseVisitor @@ -70,16 +71,16 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::binopType::Sub) : { last_expr_precedence = Precedence::Sub; return " - "; - } case (ASR::binopType::Mul) : { + } case (ASR::binopType::Mul) : { last_expr_precedence = Precedence::Mul; return " * "; - } case (ASR::binopType::Div) : { + } case (ASR::binopType::Div) : { last_expr_precedence = Precedence::Div; return " / "; - } case (ASR::binopType::Pow) : { + } case (ASR::binopType::Pow) : { last_expr_precedence = Precedence::Pow; return " ** "; - } default : { + } default : { throw LCompilersException("Cannot represent the binary operator as a string"); } } @@ -108,7 +109,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::logicalbinopType::Or) : { last_expr_precedence = Precedence::Or; return " or "; - } default : { + } default : { throw LCompilersException("Cannot represent the boolean operator as a string"); } } @@ -132,35 +133,16 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor std::string r = ""; switch (t->type) { case ASR::ttypeType::Integer : { - std::string out; - out = std::to_string(down_cast(t)->m_kind); - if (out == "1") { - r += "i8"; - } else if (out == "2") { - r += "i16"; - } else if (out == "4") { - r += "i32"; - } else if (out == "8") { - r += "i64"; - } + r += "i"; + r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8); break; } case ASR::ttypeType::Real : { - std::string out; - out = std::to_string(down_cast(t)->m_kind); - if (out == "4") { - r += "f32"; - } else if (out == "8") { - r += "f64"; - } + r += "f"; + r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8); break; } case ASR::ttypeType::Complex : { - std::string out; - out = std::to_string(down_cast(t)->m_kind); - if (out == "4") { - r += "c32"; - } else if (out == "8") { - r += "c64"; - } + r += "c"; + r += std::to_string(ASRUtils::extract_kind_from_ttype_t(t)*8); break; } case ASR::ttypeType::Character : { r = "str"; @@ -168,13 +150,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case ASR::ttypeType::Logical : { r = "bool"; break; - } case ASR::ttypeType::Array: { - r = get_type(down_cast(t)->m_type); - break; - } case ASR::ttypeType::Allocatable: { - r = get_type(down_cast(t)->m_type); - break; - } default : { + } default : { throw LCompilersException("The type `" + ASRUtils::type_to_str_python(t) + "` is not handled yet"); } @@ -302,8 +278,18 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } - void visit_SubroutineCall(const ASR::SubroutineCall_t /*&x*/) { + void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { std::string r = indent; + r += ASRUtils::symbol_name(x.m_name); + r += "("; + for (size_t i = 0; i < x.n_args; i++) { + visit_expr(*x.m_args[i].m_value); + r += s; + if (i < x.n_args - 1) + r += ", "; + } + r += ")\n"; + s = r; } void visit_Cast(const ASR::Cast_t &x) { @@ -317,11 +303,10 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_If(const ASR::If_t &x) { std::string r = indent; - r += "if"; + r += "if "; visit_expr(*x.m_test); r += s; - r += ":"; - r += "\n"; + r += ":\n"; inc_indent(); for (size_t i = 0; i < x.n_body; i++) { visit_stmt(*x.m_body[i]); @@ -332,14 +317,43 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += "\n"; } else { for (size_t i = 0; i < x.n_orelse; i++) { - r += "else:"; - r += "\n"; + r += indent + "else:\n"; inc_indent(); visit_stmt(*x.m_orelse[i]); r += s; dec_indent(); + r += "\n"; } - r += "\n"; + } + s = r; + } + + void visit_WhileLoop(const ASR::WhileLoop_t &x) { + std::string r = indent; + r += "while "; + visit_expr(*x.m_test); + r += s; + r += ":\n"; + visit_body(x, r); + s = r; + } + + void visit_NamedExpr(const ASR::NamedExpr_t &x) { + this->visit_expr(*x.m_target); + std::string t = std::move(s); + this->visit_expr(*x.m_value); + std::string v = std::move(s); + s = "(" + t + " := " + v + ")"; + } + + void visit_ExplicitDeallocate(const ASR::ExplicitDeallocate_t &x) { + std::string r; + r = "del "; + for (size_t i = 0; i < x.n_vars; i++) { + if (i > 0) { + r += ", "; + } + visit_expr(*x.m_vars[i]); } s = r; } @@ -363,11 +377,13 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_StringCompare(const ASR::StringCompare_t &x) { std::string r; r = " "; - visit_expr(*x.m_left); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += cmpop2str(x.m_op); - visit_expr(*x.m_right); + visit_expr_with_precedence(*x.m_right, current_precedence); r += s; + last_expr_precedence = current_precedence; s = r; } @@ -392,19 +408,21 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_IntegerCompare(const ASR::IntegerCompare_t &x) { std::string r; - // TODO: Handle precedence based on the last_operator_precedence r = "("; - visit_expr(*x.m_left); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += cmpop2str(x.m_op); - visit_expr(*x.m_right); + visit_expr_with_precedence(*x.m_right, current_precedence); r += s; + last_expr_precedence = current_precedence; r += ")"; s = r; } void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { s = std::to_string(x.m_n); + last_expr_precedence = Precedence::Constant; } void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) { @@ -421,16 +439,19 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_RealConstant(const ASR::RealConstant_t &x) { s = std::to_string(x.m_r); + last_expr_precedence = Precedence::Constant; } void visit_RealCompare(const ASR::RealCompare_t &x) { std::string r; r = "("; - visit_expr(*x.m_left); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += cmpop2str(x.m_op); - visit_expr(*x.m_right); + visit_expr_with_precedence(*x.m_right, current_precedence); r += s; + last_expr_precedence = current_precedence; r += ")"; s = r; } @@ -467,12 +488,14 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_LogicalCompare(const ASR::LogicalCompare_t &x) { std::string r; r = "("; - visit_expr(*x.m_left); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += cmpop2str(x.m_op); - visit_expr(*x.m_right); + visit_expr_with_precedence(*x.m_right, current_precedence); r += s; r += ")"; + last_expr_precedence = current_precedence; s = r; } @@ -498,6 +521,15 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = left + " * " + right; } + void visit_StringOrd(const ASR::StringOrd_t &x) { + std::string r; + r = "ord("; + visit_expr(*x.m_arg); + r += s; + r += ")"; + s = r; + } + void visit_IfExp(const ASR::IfExp_t &x) { std::string r; visit_expr(*x.m_body); diff --git a/tests/expr17.py b/tests/expr17.py new file mode 100644 index 0000000000..17b61150ea --- /dev/null +++ b/tests/expr17.py @@ -0,0 +1,9 @@ +def if_check(): + a: i32 + a = 4 + if a < 0: + print("negative value") + elif a > 0: + print("positive value") + else: + print("zero") diff --git a/tests/reference/python-expr11-e6681c8.json b/tests/reference/python-expr11-e6681c8.json index 65280da800..067b2c4518 100644 --- a/tests/reference/python-expr11-e6681c8.json +++ b/tests/reference/python-expr11-e6681c8.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr11-e6681c8.stdout", - "stdout_hash": "ed9438b7349f462f0de6fa7a1035c7266187fb4a2455f6fc83f029e8", + "stdout_hash": "6ae1afc8767434e703cfd38bbdd22275c73effa90a5e86c5c09bab5b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr11-e6681c8.stdout b/tests/reference/python-expr11-e6681c8.stdout index 11b2ffc705..da61c57b5a 100644 --- a/tests/reference/python-expr11-e6681c8.stdout +++ b/tests/reference/python-expr11-e6681c8.stdout @@ -1,10 +1,10 @@ def test_StrOp_repeat(): s: str s = "a" * 2 - s = "a" * -1 + s = "a" * -(1) s = "test" * 5 s = "bb" * 4 - s = "bb" * -40 + s = "bb" * -(40) s = "a" * 3 * 3 diff --git a/tests/reference/python-expr6-1a1d4fb.json b/tests/reference/python-expr6-1a1d4fb.json index 943620ddb9..19f8466558 100644 --- a/tests/reference/python-expr6-1a1d4fb.json +++ b/tests/reference/python-expr6-1a1d4fb.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr6-1a1d4fb.stdout", - "stdout_hash": "36caac53096fa6ae7e6bbac2ded68386bd3cc5f23e8934d6f2a56ad4", + "stdout_hash": "ec95e00f74a788634d49ee5a2e03efb366b52a9e011548dfec86fc7b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr6-1a1d4fb.stdout b/tests/reference/python-expr6-1a1d4fb.stdout index 3cc3cf2dba..116eb83e24 100644 --- a/tests/reference/python-expr6-1a1d4fb.stdout +++ b/tests/reference/python-expr6-1a1d4fb.stdout @@ -3,7 +3,7 @@ def test_ifexp(): b: i32 c: bool a = 2 - b = 6 if (a == 2) else 8 - c = True if (b > 5) else False + b = 6 if ((a) == (2)) else 8 + c = True if ((b) > (5)) else False From 69f1a9ebef717d74eed8db18f6e49195d8774863 Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Wed, 6 Mar 2024 16:04:08 +0530 Subject: [PATCH 14/15] fix and add more visitors --- src/libasr/codegen/asr_to_python.cpp | 90 ++++++++++++++++--- tests/reference/python-assert1-192ca6c.json | 13 +++ tests/reference/python-assert1-192ca6c.stdout | 7 ++ tests/reference/python-assign1-f87bafa.json | 13 +++ tests/reference/python-assign1-f87bafa.stdout | 15 ++++ tests/reference/python-expr2-6b69018.json | 2 +- tests/reference/python-expr2-6b69018.stdout | 4 +- tests/reference/python-expr4-161a0ec.json | 13 +++ tests/reference/python-expr4-161a0ec.stdout | 7 ++ tests/reference/python-expr6-1a1d4fb.json | 2 +- tests/reference/python-expr6-1a1d4fb.stdout | 4 +- tests/tests.toml | 3 + 12 files changed, 153 insertions(+), 20 deletions(-) create mode 100644 tests/reference/python-assert1-192ca6c.json create mode 100644 tests/reference/python-assert1-192ca6c.stdout create mode 100644 tests/reference/python-assign1-f87bafa.json create mode 100644 tests/reference/python-assign1-f87bafa.stdout create mode 100644 tests/reference/python-expr4-161a0ec.json create mode 100644 tests/reference/python-expr4-161a0ec.stdout diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index c6079fc966..3d527278cd 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -292,6 +292,25 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_FunctionCall(const ASR::FunctionCall_t &x) { + std::string r = indent; + if (x.m_original_name) { + r += ASRUtils::symbol_name(x.m_original_name); + } else { + r += ASRUtils::symbol_name(x.m_name); + } + + r += "("; + for (size_t i = 0; i < x.n_args; i++) { + visit_expr(*x.m_args[i].m_value); + r += s; + if (i < x.n_args - 1) + r += ", "; + } + r += ")"; + s = r; + } + void visit_Cast(const ASR::Cast_t &x) { // TODO visit_expr(*x.m_arg); @@ -347,13 +366,14 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } void visit_ExplicitDeallocate(const ASR::ExplicitDeallocate_t &x) { - std::string r; - r = "del "; + std::string r = indent; + r += "del "; for (size_t i = 0; i < x.n_vars; i++) { if (i > 0) { r += ", "; } visit_expr(*x.m_vars[i]); + r += s; } s = r; } @@ -376,7 +396,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_StringCompare(const ASR::StringCompare_t &x) { std::string r; - r = " "; int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); r += s; @@ -393,22 +412,25 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s += "\""; } + void visit_StringChr(const ASR::StringChr_t &x) { + visit_expr(*x.m_arg); + s = "chr(" + s + ")"; + } + void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { std::string r; - // TODO: Handle precedence based on the last_operator_precedence - r = "("; - visit_expr(*x.m_left); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += binop2str(x.m_op); - visit_expr(*x.m_right); + visit_expr_with_precedence(*x.m_right, current_precedence); r += s; - r += ")"; + last_expr_precedence = current_precedence; s = r; } void visit_IntegerCompare(const ASR::IntegerCompare_t &x) { std::string r; - r = "("; int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); r += s; @@ -416,7 +438,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor visit_expr_with_precedence(*x.m_right, current_precedence); r += s; last_expr_precedence = current_precedence; - r += ")"; s = r; } @@ -444,7 +465,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_RealCompare(const ASR::RealCompare_t &x) { std::string r; - r = "("; int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); r += s; @@ -452,7 +472,6 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor visit_expr_with_precedence(*x.m_right, current_precedence); r += s; last_expr_precedence = current_precedence; - r += ")"; s = r; } @@ -462,6 +481,19 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor last_expr_precedence = Precedence::UnaryMinus; } + void visit_RealBinOp(const ASR::RealBinOp_t &x) { + std::string r; + std::string m_op = binop2str(x.m_op); + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); + r += s; + r += m_op; + visit_expr_with_precedence(*x.m_right, current_precedence); + r += s; + last_expr_precedence = current_precedence; + s = r; + } + void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { std::string r; if (x.m_value) { @@ -487,14 +519,12 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor void visit_LogicalCompare(const ASR::LogicalCompare_t &x) { std::string r; - r = "("; int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); r += s; r += cmpop2str(x.m_op); visit_expr_with_precedence(*x.m_right, current_precedence); r += s; - r += ")"; last_expr_precedence = current_precedence; s = r; } @@ -530,6 +560,11 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_StringLen(const ASR::StringLen_t &x) { + visit_expr(*x.m_arg); + s += "len(" + s + ")"; + } + void visit_IfExp(const ASR::IfExp_t &x) { std::string r; visit_expr(*x.m_body); @@ -554,6 +589,33 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = "-" + s; last_expr_precedence = Precedence::UnaryMinus; } + + void visit_ComplexCompare(const ASR::ComplexCompare_t &x) { + std::string r; + int current_precedence = last_expr_precedence; + visit_expr_with_precedence(*x.m_left, current_precedence); + r += s; + r += cmpop2str(x.m_op); + visit_expr_with_precedence(*x.m_right, current_precedence); + r += s; + last_expr_precedence = current_precedence; + s = r; + } + + void visit_Assert(const ASR::Assert_t &x) { + std::string r = indent; + r += "assert "; + visit_expr(*x.m_test); + r += s; + if (x.m_msg) { + r += ", "; + visit_expr(*x.m_msg); + r += s; + } + r += "\n"; + s = r; + } + }; Result asr_to_python(Allocator& al, ASR::TranslationUnit_t &asr, diff --git a/tests/reference/python-assert1-192ca6c.json b/tests/reference/python-assert1-192ca6c.json new file mode 100644 index 0000000000..ed9457882f --- /dev/null +++ b/tests/reference/python-assert1-192ca6c.json @@ -0,0 +1,13 @@ +{ + "basename": "python-assert1-192ca6c", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/assert1.py", + "infile_hash": "0ff84ea5ccd3d0815cbb66e1c3d3acd61dee7257c98aa1a27ceeef3b", + "outfile": null, + "outfile_hash": null, + "stdout": "python-assert1-192ca6c.stdout", + "stdout_hash": "2120f9dd9a8d41e4d67cced7ceb14c4ded9d56335058f66b24cfe12e", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-assert1-192ca6c.stdout b/tests/reference/python-assert1-192ca6c.stdout new file mode 100644 index 0000000000..77016e73f3 --- /dev/null +++ b/tests/reference/python-assert1-192ca6c.stdout @@ -0,0 +1,7 @@ +def test_assert(): + a: i32 + a = 5 + assert (a) == (5), "a is not 5" + assert (a) != (10) + + diff --git a/tests/reference/python-assign1-f87bafa.json b/tests/reference/python-assign1-f87bafa.json new file mode 100644 index 0000000000..f4ce6903f8 --- /dev/null +++ b/tests/reference/python-assign1-f87bafa.json @@ -0,0 +1,13 @@ +{ + "basename": "python-assign1-f87bafa", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/assign1.py", + "infile_hash": "3b82a73e457bd65e85828b72d56596ca927e7c661e333691f154912b", + "outfile": null, + "outfile_hash": null, + "stdout": "python-assign1-f87bafa.stdout", + "stdout_hash": "6fa5f5e1492cac718631d3c05d27ab2ddda15dd2e56cc37a1ce188b9", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-assign1-f87bafa.stdout b/tests/reference/python-assign1-f87bafa.stdout new file mode 100644 index 0000000000..caa7aaf2a6 --- /dev/null +++ b/tests/reference/python-assign1-f87bafa.stdout @@ -0,0 +1,15 @@ +def test_augassign(): + a: str + r: i32 + s: i32 + r = 0 + r = (r) + (4) + s = 5 + r = (r) * (s) + r = (r) - (2) + s = 10 + r = r / s + a = "" + a = a + "test" + + diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json index 6cd593f93f..6599be6623 100644 --- a/tests/reference/python-expr2-6b69018.json +++ b/tests/reference/python-expr2-6b69018.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr2-6b69018.stdout", - "stdout_hash": "c7c8637de6a616257bfcfc76c2fabe82e61a5e44eadb3a6bd1af9b63", + "stdout_hash": "3c908e0ecff058aa122c1a7ebbd730bad2091dc99bb171e3d385815f", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout index c352186309..5e9a19cfc4 100644 --- a/tests/reference/python-expr2-6b69018.stdout +++ b/tests/reference/python-expr2-6b69018.stdout @@ -6,8 +6,8 @@ def test_boolOp(): a = a and b b = a or True a = a or b - a = a and (b == b) - a = a and (b != b) + a = a and b == b + a = a and b != b a = b or b diff --git a/tests/reference/python-expr4-161a0ec.json b/tests/reference/python-expr4-161a0ec.json new file mode 100644 index 0000000000..9823faecf8 --- /dev/null +++ b/tests/reference/python-expr4-161a0ec.json @@ -0,0 +1,13 @@ +{ + "basename": "python-expr4-161a0ec", + "cmd": "lpython --no-color --show-python {infile}", + "infile": "tests/expr4.py", + "infile_hash": "5cba7a5d589f54fc31463e48903d5b46604fb64e3e64ba215339047c", + "outfile": null, + "outfile_hash": null, + "stdout": "python-expr4-161a0ec.stdout", + "stdout_hash": "1378e1d01da96646ba0d45dbc6f5d30f7956e1c874c558df95a9f733", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/python-expr4-161a0ec.stdout b/tests/reference/python-expr4-161a0ec.stdout new file mode 100644 index 0000000000..a6a301dd99 --- /dev/null +++ b/tests/reference/python-expr4-161a0ec.stdout @@ -0,0 +1,7 @@ +def test_del(): + a: i32 + b: i32 + a = 4 + b = 20 + del a, b + diff --git a/tests/reference/python-expr6-1a1d4fb.json b/tests/reference/python-expr6-1a1d4fb.json index 19f8466558..f1eb23d77b 100644 --- a/tests/reference/python-expr6-1a1d4fb.json +++ b/tests/reference/python-expr6-1a1d4fb.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr6-1a1d4fb.stdout", - "stdout_hash": "ec95e00f74a788634d49ee5a2e03efb366b52a9e011548dfec86fc7b", + "stdout_hash": "f7e339254436fdf45988c26786265c1d00bfcc23c0c5419fc07c0e6c", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr6-1a1d4fb.stdout b/tests/reference/python-expr6-1a1d4fb.stdout index 116eb83e24..ccb26aa61f 100644 --- a/tests/reference/python-expr6-1a1d4fb.stdout +++ b/tests/reference/python-expr6-1a1d4fb.stdout @@ -3,7 +3,7 @@ def test_ifexp(): b: i32 c: bool a = 2 - b = 6 if ((a) == (2)) else 8 - c = True if ((b) > (5)) else False + b = 6 if (a) == (2) else 8 + c = True if (b) > (5) else False diff --git a/tests/tests.toml b/tests/tests.toml index 625db9aeb0..680811c993 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -68,6 +68,7 @@ python = true filename = "expr4.py" ast = true asr = true +python = true [[test]] filename = "expr5.py" @@ -254,11 +255,13 @@ ast = true asr = true cpp = true llvm = true +python = true [[test]] filename = "assign1.py" ast = true asr = true +python = true [[test]] filename = "assign2.py" From 9a617a038cb1be4b73ddefdde83141fa06ae4ebc Mon Sep 17 00:00:00 2001 From: Khushi Agrawal Date: Wed, 6 Mar 2024 23:00:18 +0530 Subject: [PATCH 15/15] address reviews --- src/libasr/codegen/asr_to_python.cpp | 20 ++++++++++++++------ tests/reference/python-expr2-6b69018.json | 2 +- tests/reference/python-expr2-6b69018.stdout | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index 3d527278cd..69f7a0bf4d 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -71,16 +71,16 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::binopType::Sub) : { last_expr_precedence = Precedence::Sub; return " - "; - } case (ASR::binopType::Mul) : { + } case (ASR::binopType::Mul) : { last_expr_precedence = Precedence::Mul; return " * "; - } case (ASR::binopType::Div) : { + } case (ASR::binopType::Div) : { last_expr_precedence = Precedence::Div; return " / "; - } case (ASR::binopType::Pow) : { + } case (ASR::binopType::Pow) : { last_expr_precedence = Precedence::Pow; return " ** "; - } default : { + } default : { throw LCompilersException("Cannot represent the binary operator as a string"); } } @@ -109,7 +109,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } case (ASR::logicalbinopType::Or) : { last_expr_precedence = Precedence::Or; return " or "; - } default : { + } default : { throw LCompilersException("Cannot represent the boolean operator as a string"); } } @@ -209,6 +209,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor for (size_t i = 0; i < x.n_args; i++) { visit_expr(*x.m_args[i]); r += s; + // TODO: Specify the datatype of the argument here if (i < x.n_args - 1) { r += ", "; } @@ -278,6 +279,11 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } + void visit_Return(const ASR::Return_t /*&x*/) { + // TODO: Handle cases for returning an expression/value + s = indent + "return" + "\n"; + } + void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { std::string r = indent; r += ASRUtils::symbol_name(x.m_name); @@ -293,7 +299,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor } void visit_FunctionCall(const ASR::FunctionCall_t &x) { - std::string r = indent; + std::string r = ""; if (x.m_original_name) { r += ASRUtils::symbol_name(x.m_original_name); } else { @@ -410,6 +416,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = "\""; s.append(x.m_s); s += "\""; + last_expr_precedence = Precedence::Constant; } void visit_StringChr(const ASR::StringChr_t &x) { @@ -502,6 +509,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor r += "False"; } s = r; + last_expr_precedence = Precedence::Constant; } void visit_LogicalBinOp(const ASR::LogicalBinOp_t &x) { diff --git a/tests/reference/python-expr2-6b69018.json b/tests/reference/python-expr2-6b69018.json index 6599be6623..784e5f3e6f 100644 --- a/tests/reference/python-expr2-6b69018.json +++ b/tests/reference/python-expr2-6b69018.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "python-expr2-6b69018.stdout", - "stdout_hash": "3c908e0ecff058aa122c1a7ebbd730bad2091dc99bb171e3d385815f", + "stdout_hash": "849450cb39ead48c1935431e54d989370ecece8c711f34e4ca38fd2b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/python-expr2-6b69018.stdout b/tests/reference/python-expr2-6b69018.stdout index 5e9a19cfc4..45bd2f5ccc 100644 --- a/tests/reference/python-expr2-6b69018.stdout +++ b/tests/reference/python-expr2-6b69018.stdout @@ -4,7 +4,7 @@ def test_boolOp(): a = False b = True a = a and b - b = a or True + b = a or (True) a = a or b a = a and b == b a = a and b != b