diff --git a/grammar/Python.asdl b/grammar/Python.asdl index b0720ded01..85fb170651 100644 --- a/grammar/Python.asdl +++ b/grammar/Python.asdl @@ -83,6 +83,8 @@ module LPython | ConstantBool(bool value, string? kind) | ConstantFloat(float value, string? kind) | ConstantComplex(float re, float im, string? kind) + | ConstantEllipsis(string? kind) + | ConstantNone(string? kind) -- the following expression can appear in assignment context | Attribute(expr value, identifier attr, expr_context ctx) diff --git a/run_tests.py b/run_tests.py index 53d4a5ea38..de83f8d2f3 100755 --- a/run_tests.py +++ b/run_tests.py @@ -49,6 +49,7 @@ def main(): mod_to_asr = test.get("mod_to_asr", False) llvm = test.get("llvm", False) cpp = test.get("cpp", False) + c = test.get("c", False) obj = test.get("obj", False) x86 = test.get("x86", False) bin_ = test.get("bin", False) @@ -83,6 +84,10 @@ def main(): run_test("cpp", "lpython --no-color --show-cpp {infile}", filename, update_reference, extra_args) + if c: + run_test("c", "lpython --no-color --show-c {infile}", + filename, update_reference, extra_args) + if tokens: run_test("tokens", "lpython --no-color --show-tokens {infile} -o {outfile}", filename, update_reference, extra_args) diff --git a/src/bin/lpython.cpp b/src/bin/lpython.cpp index 4a12b71d01..5e3e298ac2 100644 --- a/src/bin/lpython.cpp +++ b/src/bin/lpython.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -223,6 +224,46 @@ int emit_cpp(const std::string &infile, return 0; } +int emit_c(const std::string &infile, + const std::string &runtime_library_dir, + CompilerOptions &compiler_options) +{ + Allocator al(4*1024); + LFortran::diag::Diagnostics diagnostics; + LFortran::LocationManager lm; + lm.in_filename = infile; + std::string input = LFortran::read_file(infile); + lm.init_simple(input); + LFortran::Result r = parse_python_file( + al, runtime_library_dir, infile, diagnostics, compiler_options.new_parser); + std::cerr << diagnostics.render(input, lm, compiler_options); + if (!r.ok) { + return 1; + } + LFortran::LPython::AST::ast_t* ast = r.result; + + diagnostics.diagnostics.clear(); + LFortran::Result + r1 = LFortran::LPython::python_ast_to_asr(al, *ast, diagnostics, true, + compiler_options.symtab_only); + std::cerr << diagnostics.render(input, lm, compiler_options); + if (!r1.ok) { + LFORTRAN_ASSERT(diagnostics.has_error()) + return 2; + } + LFortran::ASR::TranslationUnit_t* asr = r1.result; + + diagnostics.diagnostics.clear(); + auto res = LFortran::asr_to_c(al, *asr, diagnostics); + std::cerr << diagnostics.render(input, lm, compiler_options); + if (!res.ok) { + LFORTRAN_ASSERT(diagnostics.has_error()) + return 3; + } + std::cout << res.result; + return 0; +} + #ifdef HAVE_LFORTRAN_LLVM int emit_llvm(const std::string &infile, @@ -542,6 +583,7 @@ int main(int argc, char *argv[]) bool show_ast = false; bool show_asr = false; bool show_cpp = false; + bool show_c = false; bool with_intrinsic_modules = false; std::string arg_pass; bool arg_no_color = false; @@ -595,6 +637,7 @@ int main(int argc, char *argv[]) app.add_flag("--show-asr", show_asr, "Show ASR for the given python file and exit"); 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-asm", show_asm, "Show assembly for the given file and exit"); app.add_flag("--show-stacktrace", compiler_options.show_stacktrace, "Show internal stacktrace on compiler errors"); app.add_flag("--with-intrinsic-mods", with_intrinsic_modules, "Show intrinsic modules in ASR"); @@ -787,6 +830,9 @@ int main(int argc, char *argv[]) if (show_cpp) { return emit_cpp(arg_file, runtime_library_dir, compiler_options); } + if (show_c) { + return emit_c(arg_file, runtime_library_dir, compiler_options); + } if (show_llvm) { #ifdef HAVE_LFORTRAN_LLVM return emit_llvm(arg_file, runtime_library_dir, compiler_options); diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index 96334a860f..a106faad38 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -16,6 +16,7 @@ configure_file(config.h.in config.h) set(SRC codegen/asr_to_cpp.cpp + codegen/asr_to_c.cpp codegen/asr_to_py.cpp codegen/x86_assembler.cpp codegen/asr_to_x86.cpp diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp new file mode 100644 index 0000000000..8854922069 --- /dev/null +++ b/src/libasr/codegen/asr_to_c.cpp @@ -0,0 +1,470 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace LFortran { + +std::string convert_dims_c(size_t n_dims, ASR::dimension_t *m_dims) +{ + std::string dims; + for (size_t i=0; i(*start) && ASR::is_a(*end)) { + ASR::IntegerConstant_t *s = ASR::down_cast(start); + ASR::IntegerConstant_t *e = ASR::down_cast(end); + if (s->m_n == 1) { + dims += "[" + std::to_string(e->m_n) + "]"; + } else { + throw CodeGenError("Lower dimension must be 1 for now"); + } + } else { + dims += "[ /* FIXME symbolic dimensions */ ]"; + } + } else { + throw CodeGenError("Dimension type not supported"); + } + } + return dims; +} + +std::string format_type_c(const std::string &dims, const std::string &type, + const std::string &name, bool use_ref, bool /*dummy*/) +{ + std::string fmt; + if (dims.size() == 0) { + std::string ref; + if (use_ref) ref = "&"; + fmt = type + " " + ref + name; + } else { + throw CodeGenError("Dimensions is not supported yet."); + } + return fmt; +} + +class ASRToCVisitor : public BaseCCPPVisitor +{ +public: + + ASRToCVisitor(diag::Diagnostics &diag) : BaseCCPPVisitor(diag) {} + + std::string convert_variable_decl(const ASR::Variable_t &v) + { + std::string sub; + bool use_ref = (v.m_intent == LFortran::ASRUtils::intent_out || v.m_intent == LFortran::ASRUtils::intent_inout); + bool dummy = LFortran::ASRUtils::is_arg_dummy(v.m_intent); + if (ASRUtils::is_pointer(v.m_type)) { + ASR::ttype_t *t2 = ASR::down_cast(v.m_type)->m_type; + if (ASRUtils::is_integer(*t2)) { + ASR::Integer_t *t = ASR::down_cast(t2); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + sub = format_type_c(dims, "int *", v.m_name, use_ref, dummy); + } else { + diag.codegen_error_label("Type number '" + + std::to_string(v.m_type->type) + + "' not supported", {v.base.base.loc}, ""); + throw Abort(); + } + } else { + if (ASRUtils::is_integer(*v.m_type)) { + ASR::Integer_t *t = ASR::down_cast(v.m_type); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + std::string type_name = "int"; + if (t->m_kind == 8) type_name = "long long"; + sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + } else if (ASRUtils::is_real(*v.m_type)) { + ASR::Real_t *t = ASR::down_cast(v.m_type); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + std::string type_name = "float"; + if (t->m_kind == 8) type_name = "double"; + sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + } else if (ASRUtils::is_complex(*v.m_type)) { + ASR::Complex_t *t = ASR::down_cast(v.m_type); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + std::string type_name = "float complex"; + if (t->m_kind == 8) type_name = "double complex"; + sub = format_type_c(dims, type_name, v.m_name, use_ref, dummy); + } else if (ASRUtils::is_logical(*v.m_type)) { + ASR::Logical_t *t = ASR::down_cast(v.m_type); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + sub = format_type_c(dims, "bool", v.m_name, use_ref, dummy); + } else if (ASRUtils::is_character(*v.m_type)) { + // TODO + } else if (ASR::is_a(*v.m_type)) { + ASR::Derived_t *t = ASR::down_cast(v.m_type); + std::string dims = convert_dims_c(t->n_dims, t->m_dims); + sub = format_type_c(dims, "struct", v.m_name, use_ref, dummy); + if (v.m_symbolic_value) { + this->visit_expr(*v.m_symbolic_value); + std::string init = src; + sub += "=" + init; + } + } else { + diag.codegen_error_label("Type number '" + + std::to_string(v.m_type->type) + + "' not supported", {v.base.base.loc}, ""); + throw Abort(); + } + } + return sub; + } + + + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + // All loose statements must be converted to a function, so the items + // must be empty: + LFORTRAN_ASSERT(x.n_items == 0); + std::string unit_src = ""; + indentation_level = 0; + indentation_spaces = 4; + + std::string headers = +R"(#include +#include +#include +#include +)"; + unit_src += headers; + + + // TODO: We need to pre-declare all functions first, then generate code + // Otherwise some function might not be found. + + { + // Process intrinsic modules in the right order + std::vector build_order + = LFortran::ASRUtils::determine_module_dependencies(x); + for (auto &item : build_order) { + LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item) + != x.m_global_scope->get_scope().end()); + if (startswith(item, "lfortran_intrinsic")) { + ASR::symbol_t *mod = x.m_global_scope->get_symbol(item); + visit_symbol(*mod); + unit_src += src; + } + } + } + + // Process procedures first: + for (auto &item : x.m_global_scope->get_scope()) { + if (ASR::is_a(*item.second) + || ASR::is_a(*item.second)) { + visit_symbol(*item.second); + unit_src += src; + } + } + + // Then do all the modules in the right order + std::vector build_order + = LFortran::ASRUtils::determine_module_dependencies(x); + for (auto &item : build_order) { + LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item) + != x.m_global_scope->get_scope().end()); + if (!startswith(item, "lfortran_intrinsic")) { + ASR::symbol_t *mod = x.m_global_scope->get_symbol(item); + visit_symbol(*mod); + unit_src += src; + } + } + + // Then the main program: + for (auto &item : x.m_global_scope->get_scope()) { + if (ASR::is_a(*item.second)) { + visit_symbol(*item.second); + unit_src += src; + } + } + + src = unit_src; + } + + void visit_Program(const ASR::Program_t &x) { + // Generate code for nested subroutines and functions first: + std::string contains; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Subroutine_t *s = ASR::down_cast(item.second); + visit_Subroutine(*s); + contains += src; + } + if (ASR::is_a(*item.second)) { + ASR::Function_t *s = ASR::down_cast(item.second); + visit_Function(*s); + contains += src; + } + } + + // Generate code for the main program + indentation_level += 1; + std::string indent1(indentation_level*indentation_spaces, ' '); + indentation_level += 1; + std::string indent(indentation_level*indentation_spaces, ' '); + std::string decl; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + decl += convert_variable_decl(*v) + ";\n"; + } + } + + std::string body; + for (size_t i=0; ivisit_stmt(*x.m_body[i]); + body += src; + } + + src = contains + + "int main(int argc, char* argv[])\n{\n" + + decl + body + + indent1 + "return 0;\n}\n"; + indentation_level -= 2; + } + + void visit_Function(const ASR::Function_t &x) { + if (std::string(x.m_name) == "size" && intrinsic_module ) { + // Intrinsic function `size` + SymbolInfo s; + s.intrinsic_function = true; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + src = ""; + return; + } else if (( + std::string(x.m_name) == "int" || + std::string(x.m_name) == "char" || + std::string(x.m_name) == "present" || + std::string(x.m_name) == "len" || + std::string(x.m_name) == "not" + ) && intrinsic_module) { + // Intrinsic function `int` + SymbolInfo s; + s.intrinsic_function = true; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + src = ""; + return; + } else { + SymbolInfo s; + s.intrinsic_function = false; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + } + std::string sub; + ASR::Variable_t *return_var = LFortran::ASRUtils::EXPR2VAR(x.m_return_var); + if (ASRUtils::is_integer(*return_var->m_type)) { + bool is_int = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_int) { + sub = "int "; + } else { + sub = "long long "; + } + } else if (ASRUtils::is_real(*return_var->m_type)) { + bool is_float = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_float) { + sub = "float "; + } else { + sub = "double "; + } + } else if (ASRUtils::is_logical(*return_var->m_type)) { + sub = "bool "; + } else if (ASRUtils::is_character(*return_var->m_type)) { + sub = "char * "; + } else if (ASRUtils::is_complex(*return_var->m_type)) { + bool is_float = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_float) { + sub = "float complex "; + } else { + sub = "double complex "; + } + } else { + throw CodeGenError("Return type not supported"); + } + sub = sub + std::string(x.m_name) + "("; + for (size_t i=0; im_intent)); + sub += convert_variable_decl(*arg); + if (i < x.n_args-1) sub += ", "; + } + sub += ")"; + if (x.m_abi == ASR::abiType::BindC) { + sub += ";\n"; + } else { + sub += "\n"; + + indentation_level += 1; + std::string indent(indentation_level*indentation_spaces, ' '); + std::string decl; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + if (v->m_intent == LFortran::ASRUtils::intent_local || v->m_intent == LFortran::ASRUtils::intent_return_var) { + decl += indent + convert_variable_decl(*v) + ";\n"; + } + } + } + + current_function = &x; + std::string body; + + for (size_t i=0; ivisit_stmt(*x.m_body[i]); + body += src; + } + current_function = nullptr; + bool visited_return = false; + + if (x.n_body > 0 && ASR::is_a(*x.m_body[x.n_body-1])) { + visited_return = true; + } + + if(!visited_return) { + body += indent + "return " + + LFortran::ASRUtils::EXPR2VAR(x.m_return_var)->m_name + + ";\n"; + } + + if (decl.size() > 0 || body.size() > 0) { + sub += "{\n" + decl + body + "}\n"; + } else { + sub[sub.size()-1] = ';'; + sub += "\n"; + } + indentation_level -= 1; + } + sub += "\n"; + src = sub; + } + + void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { + if (x.m_value == true) { + src = "true"; + } else { + src = "false"; + } + last_expr_precedence = 2; + } + + void visit_Cast(const ASR::Cast_t &x) { + visit_expr(*x.m_arg); + switch (x.m_kind) { + case (ASR::cast_kindType::IntegerToReal) : { + src = "(float)(" + src + ")"; + break; + } + case (ASR::cast_kindType::RealToInteger) : { + src = "(int)(" + src + ")"; + break; + } + case (ASR::cast_kindType::RealToReal) : { + // In C++, we do not need to cast float to float explicitly: + // src = src; + break; + } + case (ASR::cast_kindType::IntegerToInteger) : { + // In C++, we do not need to cast int <-> long long explicitly: + // src = src; + break; + } + case (ASR::cast_kindType::ComplexToComplex) : { + break; + } + case (ASR::cast_kindType::ComplexToReal) : { + src = "creal(" + src + ")"; + break; + } + case (ASR::cast_kindType::LogicalToInteger) : { + src = "(int)(" + src + ")"; + break; + } + default : throw CodeGenError("Cast kind " + std::to_string(x.m_kind) + " not implemented"); + } + last_expr_precedence = 2; + } + + std::string get_print_type(ASR::ttype_t *t) { + switch (t->type) { + case ASR::ttypeType::Integer: { + ASR::Integer_t *i = (ASR::Integer_t*)t; + switch (i->m_kind) { + case 1: { return "%d"; } + case 2: { return "%d"; } + case 4: { return "%d"; } + case 8: { return "%lli"; } + default: { throw LFortranException("Integer kind not supported"); } + } + } + case ASR::ttypeType::Real: { + ASR::Real_t *r = (ASR::Real_t*)t; + switch (r->m_kind) { + case 4: { return "%f"; } + case 8: { return "%lf"; } + default: { throw LFortranException("Float kind not supported"); } + } + } + case ASR::ttypeType::Logical: { + return "%d"; + } + case ASR::ttypeType::Character: { + return "%s"; + } + default : throw LFortranException("Not implemented"); + } + } + + void visit_Print(const ASR::Print_t &x) { + std::string indent(indentation_level*indentation_spaces, ' '); + std::string out = indent + "printf(\""; + std::vector v; + for (size_t i=0; ivisit_expr(*x.m_values[i]); + out += get_print_type(ASRUtils::expr_type(x.m_values[i])); + if (i+1!=x.n_values) { + out += " "; + } + v.push_back(src); + } + out += "\\n\""; + if (!v.empty()) { + for (auto s: v) { + out += ", " + s; + } + } + out += ");\n"; + src = out; + } + + void visit_ErrorStop(const ASR::ErrorStop_t & /* x */) { + std::string indent(indentation_level*indentation_spaces, ' '); + src = indent + "fprintf(stderr, \"ERROR STOP\");\n"; + src += indent + "exit(1);\n"; + } + +}; + +Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, + diag::Diagnostics &diagnostics) +{ + pass_unused_functions(al, asr); + ASRToCVisitor v(diagnostics); + try { + v.visit_asr((ASR::asr_t &)asr); + } catch (const CodeGenError &e) { + diagnostics.diagnostics.push_back(e.d); + return Error(); + } catch (const Abort &) { + return Error(); + } + return v.src; +} + +} // namespace LFortran diff --git a/src/libasr/codegen/asr_to_c.h b/src/libasr/codegen/asr_to_c.h new file mode 100644 index 0000000000..1ab27dff06 --- /dev/null +++ b/src/libasr/codegen/asr_to_c.h @@ -0,0 +1,13 @@ +#ifndef LFORTRAN_ASR_TO_C_H +#define LFORTRAN_ASR_TO_C_H + +#include + +namespace LFortran { + + Result asr_to_c(Allocator &al, ASR::TranslationUnit_t &asr, + diag::Diagnostics &diagnostics); + +} // namespace LFortran + +#endif // LFORTRAN_ASR_TO_C_H diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h new file mode 100644 index 0000000000..66841557e1 --- /dev/null +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -0,0 +1,1007 @@ +#ifndef LFORTRAN_ASR_TO_C_CPP_H +#define LFORTRAN_ASR_TO_C_CPP_H + +/* + * Common code to be used in both of: + * + * * asr_to_cpp.cpp + * * asr_to_c.cpp + * + * In particular, a common base class visitor with visitors that are identical + * for both C and C++ code generation. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +namespace LFortran { + +namespace { + + // Local exception that is only used in this file to exit the visitor + // pattern and caught later (not propagated outside) + class CodeGenError + { + public: + diag::Diagnostic d; + public: + CodeGenError(const std::string &msg) + : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::CodeGen)} + { } + }; + + class Abort {}; + +} + +// Platform dependent fast unique hash: +static uint64_t get_hash(ASR::asr_t *node) +{ + return (uint64_t)node; +} + +struct SymbolInfo +{ + bool needs_declaration = true; + bool intrinsic_function = false; +}; + +template +class BaseCCPPVisitor : public ASR::BaseVisitor +{ +private: + Derived& self() { return static_cast(*this); } +public: + diag::Diagnostics &diag; + std::string src; + int indentation_level; + int indentation_spaces; + // The precedence of the last expression, using the table: + // https://en.cppreference.com/w/cpp/language/operator_precedence + int last_expr_precedence; + bool intrinsic_module = false; + const ASR::Function_t *current_function = nullptr; + std::map sym_info; + + BaseCCPPVisitor(diag::Diagnostics &diag) : diag{diag} {} + + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + // All loose statements must be converted to a function, so the items + // must be empty: + LFORTRAN_ASSERT(x.n_items == 0); + std::string unit_src = ""; + indentation_level = 0; + indentation_spaces = 4; + + std::string headers = +R"(#include +#include +#include +#include +)"; + unit_src += headers; + + + // TODO: We need to pre-declare all functions first, then generate code + // Otherwise some function might not be found. + + { + // Process intrinsic modules in the right order + std::vector build_order + = LFortran::ASRUtils::determine_module_dependencies(x); + for (auto &item : build_order) { + LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item) + != x.m_global_scope->get_scope().end()); + if (startswith(item, "lfortran_intrinsic")) { + ASR::symbol_t *mod = x.m_global_scope->get_symbol(item); + self().visit_symbol(*mod); + unit_src += src; + } + } + } + + // Process procedures first: + for (auto &item : x.m_global_scope->get_scope()) { + if (ASR::is_a(*item.second) + || ASR::is_a(*item.second)) { + self().visit_symbol(*item.second); + unit_src += src; + } + } + + // Then do all the modules in the right order + std::vector build_order + = LFortran::ASRUtils::determine_module_dependencies(x); + for (auto &item : build_order) { + LFORTRAN_ASSERT(x.m_global_scope->get_scope().find(item) + != x.m_global_scope->get_scope().end()); + if (!startswith(item, "lfortran_intrinsic")) { + ASR::symbol_t *mod = x.m_global_scope->get_symbol(item); + self().visit_symbol(*mod); + unit_src += src; + } + } + + // Then the main program: + for (auto &item : x.m_global_scope->get_scope()) { + if (ASR::is_a(*item.second)) { + self().visit_symbol(*item.second); + unit_src += src; + } + } + + src = unit_src; + } + + void visit_Module(const ASR::Module_t &x) { + if (startswith(x.m_name, "lfortran_intrinsic_")) { + intrinsic_module = true; + } else { + intrinsic_module = false; + } + // Generate code for nested subroutines and functions first: + std::string contains; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Subroutine_t *s = ASR::down_cast(item.second); + self().visit_Subroutine(*s); + contains += src; + } + if (ASR::is_a(*item.second)) { + ASR::Function_t *s = ASR::down_cast(item.second); + self().visit_Function(*s); + contains += src; + } + } + src = contains; + intrinsic_module = false; + } + + void visit_Program(const ASR::Program_t &x) { + // Generate code for nested subroutines and functions first: + std::string contains; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Subroutine_t *s = ASR::down_cast(item.second); + visit_Subroutine(*s); + contains += src; + } + if (ASR::is_a(*item.second)) { + ASR::Function_t *s = ASR::down_cast(item.second); + visit_Function(*s); + contains += src; + } + } + + // Generate code for the main program + indentation_level += 1; + std::string indent1(indentation_level*indentation_spaces, ' '); + indentation_level += 1; + std::string indent(indentation_level*indentation_spaces, ' '); + std::string decl; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + decl += self().convert_variable_decl(*v) + ";\n"; + } + } + + std::string body; + for (size_t i=0; im_intent)); + sub += self().convert_variable_decl(*arg); + if (i < x.n_args-1) sub += ", "; + } + sub += ")\n"; + + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + if (v->m_intent == LFortran::ASRUtils::intent_local) { + SymbolInfo s; + s.needs_declaration = true; + sym_info[get_hash((ASR::asr_t*)v)] = s; + } + } + } + + std::string body; + for (size_t i=0; iget_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + if (v->m_intent == LFortran::ASRUtils::intent_local) { + if (sym_info[get_hash((ASR::asr_t*) v)].needs_declaration) { + std::string indent(indentation_level*indentation_spaces, ' '); + decl += indent; + decl += self().convert_variable_decl(*v) + ";\n"; + } + } + } + } + + sub += "{\n" + decl + body + "}\n\n"; + src = sub; + indentation_level -= 1; + } + + void visit_Function(const ASR::Function_t &x) { + if (std::string(x.m_name) == "size" && intrinsic_module ) { + // Intrinsic function `size` + SymbolInfo s; + s.intrinsic_function = true; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + src = ""; + return; + } else if (( + std::string(x.m_name) == "int" || + std::string(x.m_name) == "char" || + std::string(x.m_name) == "present" || + std::string(x.m_name) == "len" || + std::string(x.m_name) == "not" + ) && intrinsic_module) { + // Intrinsic function `int` + SymbolInfo s; + s.intrinsic_function = true; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + src = ""; + return; + } else { + SymbolInfo s; + s.intrinsic_function = false; + sym_info[get_hash((ASR::asr_t*)&x)] = s; + } + std::string sub; + ASR::Variable_t *return_var = LFortran::ASRUtils::EXPR2VAR(x.m_return_var); + if (ASRUtils::is_integer(*return_var->m_type)) { + bool is_int = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_int) { + sub = "int "; + } else { + sub = "long long "; + } + } else if (ASRUtils::is_real(*return_var->m_type)) { + bool is_float = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_float) { + sub = "float "; + } else { + sub = "double "; + } + } else if (ASRUtils::is_logical(*return_var->m_type)) { + sub = "bool "; + } else if (ASRUtils::is_character(*return_var->m_type)) { + sub = "char * "; + } else if (ASRUtils::is_complex(*return_var->m_type)) { + bool is_float = ASR::down_cast(return_var->m_type)->m_kind == 4; + if (is_float) { + sub = "float complex "; + } else { + sub = "double complex "; + } + } else { + throw CodeGenError("Return type not supported"); + } + sub = sub + std::string(x.m_name) + "("; + for (size_t i=0; im_intent)); + sub += self().convert_variable_decl(*arg); + if (i < x.n_args-1) sub += ", "; + } + sub += ")"; + if (x.m_abi == ASR::abiType::BindC) { + sub += ";\n"; + } else { + sub += "\n"; + + indentation_level += 1; + std::string indent(indentation_level*indentation_spaces, ' '); + std::string decl; + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::Variable_t *v = ASR::down_cast(item.second); + if (v->m_intent == LFortran::ASRUtils::intent_local || v->m_intent == LFortran::ASRUtils::intent_return_var) { + decl += indent + self().convert_variable_decl(*v) + ";\n"; + } + } + } + + current_function = &x; + std::string body; + + for (size_t i=0; i 0 && ASR::is_a(*x.m_body[x.n_body-1])) { + visited_return = true; + } + + if(!visited_return) { + body += indent + "return " + + LFortran::ASRUtils::EXPR2VAR(x.m_return_var)->m_name + + ";\n"; + } + + if (decl.size() > 0 || body.size() > 0) { + sub += "{\n" + decl + body + "}\n"; + } else { + sub[sub.size()-1] = ';'; + sub += "\n"; + } + indentation_level -= 1; + } + sub += "\n"; + src = sub; + } + + void visit_FunctionCall(const ASR::FunctionCall_t &x) { + ASR::Function_t *fn = ASR::down_cast( + LFortran::ASRUtils::symbol_get_past_external(x.m_name)); + std::string fn_name = fn->m_name; + if (sym_info[get_hash((ASR::asr_t*)fn)].intrinsic_function) { + if (fn_name == "size") { + LFORTRAN_ASSERT(x.n_args > 0); + self().visit_expr(*x.m_args[0].m_value); + std::string var_name = src; + std::string args; + if (x.n_args == 1) { + args = "0"; + } else { + for (size_t i=1; i 0); + self().visit_expr(*x.m_args[0].m_value); + src = "(int)" + src; + } else if (fn_name == "not") { + LFORTRAN_ASSERT(x.n_args > 0); + self().visit_expr(*x.m_args[0].m_value); + src = "!(" + src + ")"; + } else { + throw CodeGenError("Intrinsic function '" + fn_name + + "' not implemented"); + } + } else { + std::string args; + for (size_t i=0; i(*x.m_target)) { + target = LFortran::ASRUtils::EXPR2VAR(x.m_target)->m_name; + } else if (ASR::is_a(*x.m_target)) { + visit_ArrayRef(*ASR::down_cast(x.m_target)); + target = src; + } else { + LFORTRAN_ASSERT(false) + } + self().visit_expr(*x.m_value); + std::string value = src; + std::string indent(indentation_level*indentation_spaces, ' '); + src = indent + target + " = " + value + ";\n"; + } + + void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { + src = std::to_string(x.m_n); + last_expr_precedence = 2; + } + + void visit_RealConstant(const ASR::RealConstant_t &x) { + src = std::to_string(x.m_r); + last_expr_precedence = 2; + } + + + void visit_StringConstant(const ASR::StringConstant_t &x) { + src = "\"" + std::string(x.m_s) + "\""; + last_expr_precedence = 2; + } + + void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { + if (x.m_value == true) { + src = "true"; + } else { + src = "false"; + } + last_expr_precedence = 2; + } + + void visit_Var(const ASR::Var_t &x) { + const ASR::symbol_t *s = ASRUtils::symbol_get_past_external(x.m_v); + src = ASR::down_cast(s)->m_name; + last_expr_precedence = 2; + } + + void visit_ArrayRef(const ASR::ArrayRef_t &x) { + const ASR::symbol_t *s = ASRUtils::symbol_get_past_external(x.m_v); + std::string out = ASR::down_cast(s)->m_name; + out += "["; + for (size_t i=0; i long long explicitly: + // src = src; + break; + } + case (ASR::cast_kindType::ComplexToComplex) : { + break; + } + case (ASR::cast_kindType::ComplexToReal) : { + src = "creal(" + src + ")"; + break; + } + case (ASR::cast_kindType::LogicalToInteger) : { + src = "(int)(" + src + ")"; + break; + } + default : throw CodeGenError("Cast kind " + std::to_string(x.m_kind) + " not implemented"); + } + last_expr_precedence = 2; + } + + void visit_Compare(const ASR::Compare_t &x) { + self().visit_expr(*x.m_left); + std::string left = std::move(src); + int left_precedence = last_expr_precedence; + self().visit_expr(*x.m_right); + std::string right = std::move(src); + int right_precedence = last_expr_precedence; + switch (x.m_op) { + case (ASR::cmpopType::Eq) : { last_expr_precedence = 10; break; } + case (ASR::cmpopType::Gt) : { last_expr_precedence = 9; break; } + case (ASR::cmpopType::GtE) : { last_expr_precedence = 9; break; } + case (ASR::cmpopType::Lt) : { last_expr_precedence = 9; break; } + case (ASR::cmpopType::LtE) : { last_expr_precedence = 9; break; } + case (ASR::cmpopType::NotEq): { last_expr_precedence = 10; break; } + default : LFORTRAN_ASSERT(false); // should never happen + } + if (left_precedence <= last_expr_precedence) { + src += left; + } else { + src += "(" + left + ")"; + } + src += ASRUtils::cmpop_to_str(x.m_op); + if (right_precedence <= last_expr_precedence) { + src += right; + } else { + src += "(" + right + ")"; + } + } + + void visit_UnaryOp(const ASR::UnaryOp_t &x) { + self().visit_expr(*x.m_operand); + int expr_precedence = last_expr_precedence; + if (x.m_type->type == ASR::ttypeType::Integer) { + if (x.m_op == ASR::unaryopType::UAdd) { + // src = src; + // Skip unary plus, keep the previous precedence + } else if (x.m_op == ASR::unaryopType::USub) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "-" + src; + } else { + src = "-(" + src + ")"; + } + } else if (x.m_op == ASR::unaryopType::Invert) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "~" + src; + } else { + src = "~(" + src + ")"; + } + + } else if (x.m_op == ASR::unaryopType::Not) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "!" + src; + } else { + src = "!(" + src + ")"; + } + } else { + throw CodeGenError("Unary type not implemented yet for Integer"); + } + return; + } else if (x.m_type->type == ASR::ttypeType::Real) { + if (x.m_op == ASR::unaryopType::UAdd) { + // src = src; + // Skip unary plus, keep the previous precedence + } else if (x.m_op == ASR::unaryopType::USub) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "-" + src; + } else { + src = "-(" + src + ")"; + } + } else if (x.m_op == ASR::unaryopType::Not) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "!" + src; + } else { + src = "!(" + src + ")"; + } + } else { + throw CodeGenError("Unary type not implemented yet for Real"); + } + return; + } else if (x.m_type->type == ASR::ttypeType::Logical) { + if (x.m_op == ASR::unaryopType::Not) { + last_expr_precedence = 3; + if (expr_precedence <= last_expr_precedence) { + src = "!" + src; + } else { + src = "!(" + src + ")"; + } + return; + } else { + throw CodeGenError("Unary type not implemented yet for Logical"); + } + } else { + throw CodeGenError("UnaryOp: type not supported yet"); + } + } + + void visit_BinOp(const ASR::BinOp_t &x) { + self().visit_expr(*x.m_left); + std::string left = std::move(src); + int left_precedence = last_expr_precedence; + self().visit_expr(*x.m_right); + std::string right = std::move(src); + int right_precedence = last_expr_precedence; + switch (x.m_op) { + case (ASR::binopType::Add) : { last_expr_precedence = 6; break; } + case (ASR::binopType::Sub) : { last_expr_precedence = 6; break; } + case (ASR::binopType::Mul) : { last_expr_precedence = 5; break; } + case (ASR::binopType::Div) : { last_expr_precedence = 5; break; } + case (ASR::binopType::Pow) : { + src = "std::pow(" + left + ", " + right + ")"; + return; + } + default: throw CodeGenError("BinOp: operator not implemented yet"); + } + src = ""; + if (left_precedence == 3) { + src += "(" + left + ")"; + } else { + if (left_precedence <= last_expr_precedence) { + src += left; + } else { + src += "(" + left + ")"; + } + } + src += ASRUtils::binop_to_str(x.m_op); + if (right_precedence == 3) { + src += "(" + right + ")"; + } else if (x.m_op == ASR::binopType::Sub) { + if (right_precedence < last_expr_precedence) { + src += right; + } else { + src += "(" + right + ")"; + } + } else { + if (right_precedence <= last_expr_precedence) { + src += right; + } else { + src += "(" + right + ")"; + } + } + } + + void visit_BoolOp(const ASR::BoolOp_t &x) { + self().visit_expr(*x.m_left); + std::string left = std::move(src); + int left_precedence = last_expr_precedence; + self().visit_expr(*x.m_right); + std::string right = std::move(src); + int right_precedence = last_expr_precedence; + switch (x.m_op) { + case (ASR::boolopType::And): { + last_expr_precedence = 14; + break; + } + case (ASR::boolopType::Or): { + last_expr_precedence = 15; + break; + } + case (ASR::boolopType::NEqv): { + last_expr_precedence = 10; + break; + } + case (ASR::boolopType::Eqv): { + last_expr_precedence = 10; + break; + } + default : throw CodeGenError("Unhandled switch case"); + } + + if (left_precedence <= last_expr_precedence) { + src += left; + } else { + src += "(" + left + ")"; + } + src += ASRUtils::boolop_to_str(x.m_op); + if (right_precedence <= last_expr_precedence) { + src += right; + } else { + src += "(" + right + ")"; + } + } + + std::string get_print_type(ASR::ttype_t *t) { + switch (t->type) { + case ASR::ttypeType::Integer: { + ASR::Integer_t *i = (ASR::Integer_t*)t; + switch (i->m_kind) { + case 1: { return "%d"; } + case 2: { return "%d"; } + case 4: { return "%d"; } + case 8: { return "%lli"; } + default: { throw LFortranException("Integer kind not supported"); } + } + } + case ASR::ttypeType::Real: { + ASR::Real_t *r = (ASR::Real_t*)t; + switch (r->m_kind) { + case 4: { return "%f"; } + case 8: { return "%lf"; } + default: { throw LFortranException("Float kind not supported"); } + } + } + case ASR::ttypeType::Logical: { + return "%d"; + } + case ASR::ttypeType::Character: { + return "%s"; + } + default : throw LFortranException("Not implemented"); + } + } + + void visit_Print(const ASR::Print_t &x) { + std::string indent(indentation_level*indentation_spaces, ' '); + std::string out = indent + "printf(\""; + std::vector v; + for (size_t i=0; im_return_var)->m_name + + ";\n"; + } else { + src = indent + "return;\n"; + } + } + + void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) { + // Ignore for now + src = ""; + } + + void visit_Stop(const ASR::Stop_t & /* x */) { + std::string indent(indentation_level*indentation_spaces, ' '); + src = indent + "exit(0);\n"; + } + + void visit_ImpliedDoLoop(const ASR::ImpliedDoLoop_t &/*x*/) { + std::string indent(indentation_level*indentation_spaces, ' '); + std::string out = indent + " /* FIXME: implied do loop */ "; + src = out; + last_expr_precedence = 2; + } + + void visit_DoLoop(const ASR::DoLoop_t &x) { + std::string indent(indentation_level*indentation_spaces, ' '); + std::string out = indent + "for ("; + ASR::Variable_t *loop_var = LFortran::ASRUtils::EXPR2VAR(x.m_head.m_v); + std::string lvname=loop_var->m_name; + ASR::expr_t *a=x.m_head.m_start; + ASR::expr_t *b=x.m_head.m_end; + ASR::expr_t *c=x.m_head.m_increment; + LFORTRAN_ASSERT(a); + LFORTRAN_ASSERT(b); + int increment; + if (!c) { + increment = 1; + } else { + if (c->type == ASR::exprType::IntegerConstant) { + increment = ASR::down_cast(c)->m_n; + } else if (c->type == ASR::exprType::UnaryOp) { + ASR::UnaryOp_t *u = ASR::down_cast(c); + LFORTRAN_ASSERT(u->m_op == ASR::unaryopType::USub); + LFORTRAN_ASSERT(u->m_operand->type == ASR::exprType::IntegerConstant); + increment = - ASR::down_cast(u->m_operand)->m_n; + } else { + throw CodeGenError("Do loop increment type not supported"); + } + } + std::string cmp_op; + if (increment > 0) { + cmp_op = "<="; + } else { + cmp_op = ">="; + } + + out += lvname + "="; + self().visit_expr(*a); + out += src + "; " + lvname + cmp_op; + self().visit_expr(*b); + out += src + "; " + lvname; + if (increment == 1) { + out += "++"; + } else if (increment == -1) { + out += "--"; + } else { + out += "+=" + std::to_string(increment); + } + out += ") {\n"; + indentation_level += 1; + for (size_t i=0; i( + LFortran::ASRUtils::symbol_get_past_external(x.m_name)); + std::string out = indent + s->m_name + "("; + for (size_t i=0; i(*x.m_args[i].m_value)) { + ASR::Variable_t *arg = LFortran::ASRUtils::EXPR2VAR(x.m_args[i].m_value); + std::string arg_name = arg->m_name; + out += arg_name; + } else { + self().visit_expr(*x.m_args[i].m_value); + out += src; + } + if (i < x.n_args-1) out += ", "; + } + out += ");\n"; + src = out; + } + +}; + +} // namespace LFortran + +#endif // LFORTRAN_ASR_TO_C_CPP_H diff --git a/src/libasr/codegen/asr_to_cpp.cpp b/src/libasr/codegen/asr_to_cpp.cpp index 6899b9c9c8..5ee51e0e30 100644 --- a/src/libasr/codegen/asr_to_cpp.cpp +++ b/src/libasr/codegen/asr_to_cpp.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -12,36 +13,6 @@ namespace LFortran { -namespace { - - // Local exception that is only used in this file to exit the visitor - // pattern and caught later (not propagated outside) - class CodeGenError - { - public: - diag::Diagnostic d; - public: - CodeGenError(const std::string &msg) - : d{diag::Diagnostic(msg, diag::Level::Error, diag::Stage::CodeGen)} - { } - }; - - class Abort {}; - -} - -// Platform dependent fast unique hash: -uint64_t get_hash(ASR::asr_t *node) -{ - return (uint64_t)node; -} - -struct SymbolInfo -{ - bool needs_declaration = true; - bool intrinsic_function = false; -}; - std::string convert_dims(size_t n_dims, ASR::dimension_t *m_dims) { std::string dims; @@ -90,21 +61,10 @@ std::string format_type(const std::string &dims, const std::string &type, return fmt; } -class ASRToCPPVisitor : public ASR::BaseVisitor +class ASRToCPPVisitor : public BaseCCPPVisitor { public: - diag::Diagnostics &diag; - std::map sym_info; - std::string src; - int indentation_level; - int indentation_spaces; - // The precedence of the last expression, using the table: - // https://en.cppreference.com/w/cpp/language/operator_precedence - int last_expr_precedence; - bool intrinsic_module = false; - const ASR::Function_t *current_function = nullptr; - - ASRToCPPVisitor(diag::Diagnostics &diag) : diag{diag} {} + ASRToCPPVisitor(diag::Diagnostics &diag) : BaseCCPPVisitor(diag) {} std::string convert_variable_decl(const ASR::Variable_t &v) { @@ -258,30 +218,6 @@ Kokkos::View from_std_vector(const std::vector &v) src = unit_src; } - void visit_Module(const ASR::Module_t &x) { - if (startswith(x.m_name, "lfortran_intrinsic_")) { - intrinsic_module = true; - } else { - intrinsic_module = false; - } - // Generate code for nested subroutines and functions first: - std::string contains; - for (auto &item : x.m_symtab->get_scope()) { - if (ASR::is_a(*item.second)) { - ASR::Subroutine_t *s = ASR::down_cast(item.second); - visit_Subroutine(*s); - contains += src; - } - if (ASR::is_a(*item.second)) { - ASR::Function_t *s = ASR::down_cast(item.second); - visit_Function(*s); - contains += src; - } - } - src = contains; - intrinsic_module = false; - } - void visit_Program(const ASR::Program_t &x) { // Generate code for nested subroutines and functions first: std::string contains; @@ -332,53 +268,6 @@ Kokkos::View from_std_vector(const std::vector &v) indentation_level -= 2; } - void visit_Subroutine(const ASR::Subroutine_t &x) { - indentation_level += 1; - std::string sub = "void " + std::string(x.m_name) + "("; - for (size_t i=0; im_intent)); - sub += convert_variable_decl(*arg); - if (i < x.n_args-1) sub += ", "; - } - sub += ")\n"; - - for (auto &item : x.m_symtab->get_scope()) { - if (ASR::is_a(*item.second)) { - ASR::Variable_t *v = ASR::down_cast(item.second); - if (v->m_intent == LFortran::ASRUtils::intent_local) { - SymbolInfo s; - s.needs_declaration = true; - sym_info[get_hash((ASR::asr_t*)v)] = s; - } - } - } - - std::string body; - for (size_t i=0; ivisit_stmt(*x.m_body[i]); - body += src; - } - - std::string decl; - for (auto &item : x.m_symtab->get_scope()) { - if (ASR::is_a(*item.second)) { - ASR::Variable_t *v = ASR::down_cast(item.second); - if (v->m_intent == LFortran::ASRUtils::intent_local) { - if (sym_info[get_hash((ASR::asr_t*) v)].needs_declaration) { - std::string indent(indentation_level*indentation_spaces, ' '); - decl += indent; - decl += convert_variable_decl(*v) + ";\n"; - } - } - } - } - - sub += "{\n" + decl + body + "}\n\n"; - src = sub; - indentation_level -= 1; - } - void visit_Function(const ASR::Function_t &x) { if (std::string(x.m_name) == "size" && intrinsic_module ) { // Intrinsic function `size` @@ -492,98 +381,6 @@ Kokkos::View from_std_vector(const std::vector &v) src = sub; } - void visit_FunctionCall(const ASR::FunctionCall_t &x) { - ASR::Function_t *fn = ASR::down_cast( - LFortran::ASRUtils::symbol_get_past_external(x.m_name)); - std::string fn_name = fn->m_name; - if (sym_info[get_hash((ASR::asr_t*)fn)].intrinsic_function) { - if (fn_name == "size") { - LFORTRAN_ASSERT(x.n_args > 0); - visit_expr(*x.m_args[0].m_value); - std::string var_name = src; - std::string args; - if (x.n_args == 1) { - args = "0"; - } else { - for (size_t i=1; i 0); - visit_expr(*x.m_args[0].m_value); - src = "(int)" + src; - } else if (fn_name == "not") { - LFORTRAN_ASSERT(x.n_args > 0); - visit_expr(*x.m_args[0].m_value); - src = "!(" + src + ")"; - } else if (fn_name == "len") { - LFORTRAN_ASSERT(x.n_args > 0); - visit_expr(*x.m_args[0].m_value); - src = "(" + src + ").size()"; - } else { - throw CodeGenError("Intrinsic function '" + fn_name - + "' not implemented"); - } - } else { - std::string args; - for (size_t i=0; i(*x.m_target)) { - target = LFortran::ASRUtils::EXPR2VAR(x.m_target)->m_name; - } else if (ASR::is_a(*x.m_target)) { - visit_ArrayRef(*ASR::down_cast(x.m_target)); - target = src; - } else { - LFORTRAN_ASSERT(false) - } - this->visit_expr(*x.m_value); - std::string value = src; - std::string indent(indentation_level*indentation_spaces, ' '); - src = indent + target + " = " + value + ";\n"; - } - - void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { - src = std::to_string(x.m_n); - last_expr_precedence = 2; - } - - void visit_RealConstant(const ASR::RealConstant_t &x) { - src = std::to_string(x.m_r); - last_expr_precedence = 2; - } - void visit_ComplexConstructor(const ASR::ComplexConstructor_t &x) { this->visit_expr(*x.m_re); std::string re = src; @@ -596,11 +393,6 @@ Kokkos::View from_std_vector(const std::vector &v) last_expr_precedence = 2; } - void visit_StringConstant(const ASR::StringConstant_t &x) { - src = "\"" + std::string(x.m_s) + "\""; - last_expr_precedence = 2; - } - 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); @@ -633,30 +425,6 @@ Kokkos::View from_std_vector(const std::vector &v) last_expr_precedence = 2; } - void visit_Var(const ASR::Var_t &x) { - const ASR::symbol_t *s = ASRUtils::symbol_get_past_external(x.m_v); - src = ASR::down_cast(s)->m_name; - last_expr_precedence = 2; - } - - void visit_ArrayRef(const ASR::ArrayRef_t &x) { - const ASR::symbol_t *s = ASRUtils::symbol_get_past_external(x.m_v); - std::string out = ASR::down_cast(s)->m_name; - out += "["; - for (size_t i=0; i from_std_vector(const std::vector &v) last_expr_precedence = 2; } - void visit_Compare(const ASR::Compare_t &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::cmpopType::Eq) : { last_expr_precedence = 10; break; } - case (ASR::cmpopType::Gt) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::GtE) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::Lt) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::LtE) : { last_expr_precedence = 9; break; } - case (ASR::cmpopType::NotEq): { last_expr_precedence = 10; break; } - default : LFORTRAN_ASSERT(false); // should never happen - } - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - src += ASRUtils::cmpop_to_str(x.m_op); - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - - void visit_UnaryOp(const ASR::UnaryOp_t &x) { - this->visit_expr(*x.m_operand); - int expr_precedence = last_expr_precedence; - if (x.m_type->type == ASR::ttypeType::Integer) { - if (x.m_op == ASR::unaryopType::UAdd) { - // src = src; - // Skip unary plus, keep the previous precedence - } else if (x.m_op == ASR::unaryopType::USub) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "-" + src; - } else { - src = "-(" + src + ")"; - } - } else if (x.m_op == ASR::unaryopType::Invert) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "~" + src; - } else { - src = "~(" + src + ")"; - } - - } else if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - } else { - throw CodeGenError("Unary type not implemented yet for Integer"); - } - return; - } else if (x.m_type->type == ASR::ttypeType::Real) { - if (x.m_op == ASR::unaryopType::UAdd) { - // src = src; - // Skip unary plus, keep the previous precedence - } else if (x.m_op == ASR::unaryopType::USub) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "-" + src; - } else { - src = "-(" + src + ")"; - } - } else if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - } else { - throw CodeGenError("Unary type not implemented yet for Real"); - } - return; - } else if (x.m_type->type == ASR::ttypeType::Logical) { - if (x.m_op == ASR::unaryopType::Not) { - last_expr_precedence = 3; - if (expr_precedence <= last_expr_precedence) { - src = "!" + src; - } else { - src = "!(" + src + ")"; - } - return; - } else { - throw CodeGenError("Unary type not implemented yet for Logical"); - } - } else { - throw CodeGenError("UnaryOp: type not supported yet"); - } - } - - void visit_BinOp(const ASR::BinOp_t &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::binopType::Add) : { last_expr_precedence = 6; break; } - case (ASR::binopType::Sub) : { last_expr_precedence = 6; break; } - case (ASR::binopType::Mul) : { last_expr_precedence = 5; break; } - case (ASR::binopType::Div) : { last_expr_precedence = 5; break; } - case (ASR::binopType::Pow) : { - src = "std::pow(" + left + ", " + right + ")"; - return; - } - default: throw CodeGenError("BinOp: operator not implemented yet"); - } - src = ""; - if (left_precedence == 3) { - src += "(" + left + ")"; - } else { - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - } - src += ASRUtils::binop_to_str(x.m_op); - if (right_precedence == 3) { - src += "(" + right + ")"; - } else if (x.m_op == ASR::binopType::Sub) { - if (right_precedence < last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } else { - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - } - void visit_StringConcat(const ASR::StringConcat_t &x) { this->visit_expr(*x.m_left); std::string left = std::move(src); @@ -882,46 +503,6 @@ Kokkos::View from_std_vector(const std::vector &v) } } - void visit_BoolOp(const ASR::BoolOp_t &x) { - this->visit_expr(*x.m_left); - std::string left = std::move(src); - int left_precedence = last_expr_precedence; - this->visit_expr(*x.m_right); - std::string right = std::move(src); - int right_precedence = last_expr_precedence; - switch (x.m_op) { - case (ASR::boolopType::And): { - last_expr_precedence = 14; - break; - } - case (ASR::boolopType::Or): { - last_expr_precedence = 15; - break; - } - case (ASR::boolopType::NEqv): { - last_expr_precedence = 10; - break; - } - case (ASR::boolopType::Eqv): { - last_expr_precedence = 10; - break; - } - default : throw CodeGenError("Unhandled switch case"); - } - - if (left_precedence <= last_expr_precedence) { - src += left; - } else { - src += "(" + left + ")"; - } - src += ASRUtils::boolop_to_str(x.m_op); - if (right_precedence <= last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } - } - void visit_ArrayConstant(const ASR::ArrayConstant_t &x) { std::string out = "from_std_vector({"; for (size_t i=0; i from_std_vector(const std::vector &v) src = out; } - void visit_Allocate(const ASR::Allocate_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - std::string out = indent + "// FIXME: allocate("; - for (size_t i=0; i from_std_vector(const std::vector &v) src = out; } - void visit_WhileLoop(const ASR::WhileLoop_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - std::string out = indent + "while ("; - visit_expr(*x.m_test); - out += src + ") {\n"; - indentation_level += 1; - for (size_t i=0; ivisit_stmt(*x.m_body[i]); - out += src; - } - out += indent + "}\n"; - indentation_level -= 1; - src = out; - } - - void visit_Exit(const ASR::Exit_t & /* x */) { - std::string indent(indentation_level*indentation_spaces, ' '); - src = indent + "break;\n"; - } - - void visit_Cycle(const ASR::Cycle_t & /* x */) { - std::string indent(indentation_level*indentation_spaces, ' '); - src = indent + "continue;\n"; - } - - void visit_Return(const ASR::Return_t & /* x */) { - std::string indent(indentation_level*indentation_spaces, ' '); - if (current_function) { - src = indent + "return " - + LFortran::ASRUtils::EXPR2VAR(current_function->m_return_var)->m_name - + ";\n"; - } else { - src = indent + "return;\n"; - } - } - - void visit_GoToTarget(const ASR::GoToTarget_t & /* x */) { - // Ignore for now - src = ""; - } - - void visit_Stop(const ASR::Stop_t & /* x */) { - std::string indent(indentation_level*indentation_spaces, ' '); - src = indent + "exit(0);\n"; - } - - void visit_ImpliedDoLoop(const ASR::ImpliedDoLoop_t &/*x*/) { - std::string indent(indentation_level*indentation_spaces, ' '); - std::string out = indent + " /* FIXME: implied do loop */ "; - src = out; - last_expr_precedence = 2; - } - - void visit_DoLoop(const ASR::DoLoop_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - std::string out = indent + "for ("; - ASR::Variable_t *loop_var = LFortran::ASRUtils::EXPR2VAR(x.m_head.m_v); - std::string lvname=loop_var->m_name; - ASR::expr_t *a=x.m_head.m_start; - ASR::expr_t *b=x.m_head.m_end; - ASR::expr_t *c=x.m_head.m_increment; - LFORTRAN_ASSERT(a); - LFORTRAN_ASSERT(b); - int increment; - if (!c) { - increment = 1; - } else { - if (c->type == ASR::exprType::IntegerConstant) { - increment = ASR::down_cast(c)->m_n; - } else if (c->type == ASR::exprType::UnaryOp) { - ASR::UnaryOp_t *u = ASR::down_cast(c); - LFORTRAN_ASSERT(u->m_op == ASR::unaryopType::USub); - LFORTRAN_ASSERT(u->m_operand->type == ASR::exprType::IntegerConstant); - increment = - ASR::down_cast(u->m_operand)->m_n; - } else { - throw CodeGenError("Do loop increment type not supported"); - } - } - std::string cmp_op; - if (increment > 0) { - cmp_op = "<="; - } else { - cmp_op = ">="; - } - - out += lvname + "="; - visit_expr(*a); - out += src + "; " + lvname + cmp_op; - visit_expr(*b); - out += src + "; " + lvname; - if (increment == 1) { - out += "++"; - } else if (increment == -1) { - out += "--"; - } else { - out += "+=" + std::to_string(increment); - } - out += ") {\n"; - indentation_level += 1; - for (size_t i=0; ivisit_stmt(*x.m_body[i]); - out += src; - } - out += indent + "}\n"; - indentation_level -= 1; - src = out; - } - void visit_DoConcurrentLoop(const ASR::DoConcurrentLoop_t &x) { std::string indent(indentation_level*indentation_spaces, ' '); std::string out = indent + "Kokkos::parallel_for("; @@ -1159,65 +576,6 @@ Kokkos::View from_std_vector(const std::vector &v) src += indent + "exit(1);\n"; } - void visit_If(const ASR::If_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - std::string out = indent + "if ("; - visit_expr(*x.m_test); - out += src + ") {\n"; - indentation_level += 1; - for (size_t i=0; ivisit_stmt(*x.m_body[i]); - out += src; - } - out += indent + "}"; - if (x.n_orelse == 0) { - out += "\n"; - } else { - out += " else {\n"; - for (size_t i=0; ivisit_stmt(*x.m_orelse[i]); - out += src; - } - out += indent + "}\n"; - } - indentation_level -= 1; - src = out; - } - - void visit_IfExp(const ASR::IfExp_t &x) { - // IfExp is like a ternary operator in c++ - // test ? body : orelse; - std::string out = "("; - visit_expr(*x.m_test); - out += src + ") ? ("; - visit_expr(*x.m_body); - out += src + ") : ("; - visit_expr(*x.m_orelse); - out += src + ")"; - src = out; - last_expr_precedence = 16; - } - - void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { - std::string indent(indentation_level*indentation_spaces, ' '); - ASR::Subroutine_t *s = ASR::down_cast( - LFortran::ASRUtils::symbol_get_past_external(x.m_name)); - std::string out = indent + s->m_name + "("; - for (size_t i=0; i(*x.m_args[i].m_value)) { - ASR::Variable_t *arg = LFortran::ASRUtils::EXPR2VAR(x.m_args[i].m_value); - std::string arg_name = arg->m_name; - out += arg_name; - } else { - this->visit_expr(*x.m_args[i].m_value); - out += src; - } - if (i < x.n_args-1) out += ", "; - } - out += ");\n"; - src = out; - } - }; Result asr_to_cpp(Allocator &al, ASR::TranslationUnit_t &asr, diff --git a/src/lpython/parser/parser.yy b/src/lpython/parser/parser.yy index 451a621837..1c94e848bd 100644 --- a/src/lpython/parser/parser.yy +++ b/src/lpython/parser/parser.yy @@ -234,6 +234,7 @@ void yyerror(YYLTYPE *yyloc, LFortran::Parser &p, const std::string &msg) %type primary %type sep %type sep_one +%type string // Precedence @@ -471,9 +472,10 @@ if_statement ; for_statement - : KW_FOR expr KW_IN expr ":" sep statements { $$ = FOR_01($2, $4, $7, @$); } - | KW_FOR expr KW_IN expr ":" sep statements KW_ELSE ":" sep statements { - $$ = FOR_02($2, $4, $7, $11, @$); } + : KW_FOR tuple_item KW_IN expr ":" sep statements { + $$ = FOR_01($2, $4, $7, @$); } + | KW_FOR tuple_item KW_IN expr ":" sep statements KW_ELSE ":" + sep statements { $$ = FOR_02($2, $4, $7, $11, @$); } ; except_statement @@ -519,8 +521,8 @@ decorators_opt ; decorators - : decorators "@" expr TK_NEWLINE { $$ = $1; LIST_ADD($$, $3); } - | "@" expr TK_NEWLINE { LIST_NEW($$); LIST_ADD($$, $2); } + : decorators "@" expr sep { $$ = $1; LIST_ADD($$, $3); } + | "@" expr sep { LIST_NEW($$); LIST_ADD($$, $2); } ; parameter @@ -587,9 +589,9 @@ async_func_def ; async_for_stmt - : KW_ASYNC KW_FOR expr KW_IN expr ":" sep statements { + : KW_ASYNC KW_FOR tuple_item KW_IN expr ":" sep statements { $$ = ASYNC_FOR_01($3, $5, $8, @$); } - | KW_ASYNC KW_FOR expr KW_IN expr ":" sep statements KW_ELSE ":" sep + | KW_ASYNC KW_FOR tuple_item KW_IN expr ":" sep statements KW_ELSE ":" sep statements { $$ = ASYNC_FOR_02($3, $5, $8, $12, @$); } ; @@ -609,7 +611,7 @@ slice_item | expr ":" { $$ = SLICE_01( $1, nullptr, nullptr, @$); } | ":" expr { $$ = SLICE_01(nullptr, $2, nullptr, @$); } | expr ":" expr { $$ = SLICE_01( $1, $3, nullptr, @$); } - | ":" ":" { $$ = SLICE_01(nullptr, nullptr, nullptr, @$); } + | ":" ":" { $$ = SLICE_01(nullptr, nullptr, nullptr, @$); } | ":" ":" expr { $$ = SLICE_01(nullptr, nullptr, $3, @$); } | expr ":" ":" { $$ = SLICE_01( $1, nullptr, nullptr, @$); } | ":" expr ":" { $$ = SLICE_01(nullptr, $2, nullptr, @$); } @@ -667,10 +669,14 @@ function_call | primary "(" keyword_items ")" { $$ = CALL_03($1, $3, @$); } ; +string + : string TK_STRING { $$ = STRING2($1, $2, @$); } // TODO + | TK_STRING { $$ = STRING1($1, @$); } + expr : id { $$ = $1; } | TK_INTEGER { $$ = INTEGER($1, @$); } - | TK_STRING { $$ = STRING($1, @$); } + | string { $$ = $1; } | TK_REAL { $$ = FLOAT($1, @$); } | TK_IMAG_NUM { $$ = COMPLEX($1, @$); } | TK_TRUE { $$ = BOOL(true, @$); } @@ -682,7 +688,7 @@ expr | "{" expr_list "}" { $$ = SET($2, @$); } | "{" expr_list "," "}" { $$ = SET($2, @$); } | id "[" tuple_list "]" { $$ = SUBSCRIPT_01($1, $3, @$); } - | TK_STRING "[" tuple_list "]" { $$ = SUBSCRIPT_02($1, $3, @$); } + | string "[" tuple_list "]" { $$ = SUBSCRIPT_02($1, $3, @$); } | expr "." id { $$ = ATTRIBUTE_REF($1, $3, @$); } | "{" "}" { $$ = DICT_01(@$); } | "{" dict_list "}" { $$ = DICT_02($2, @$); } diff --git a/src/lpython/parser/semantics.h b/src/lpython/parser/semantics.h index 20c65e5d29..cc0539c193 100644 --- a/src/lpython/parser/semantics.h +++ b/src/lpython/parser/semantics.h @@ -139,20 +139,24 @@ static inline Vec SET_EXPR_CTX_02(Vec x, expr_contextType ctx) { #define NON_LOCAL(names, l) make_Nonlocal_t(p.m_a, l, \ REDUCE_ARGS(p.m_a, names), names.size()) -static inline Vec SET_STORE(Vec x) { - for (size_t i=0; i < x.size(); i++) { - if(is_a(*EXPR(x[i]))) { - size_t n_elts = down_cast2(x[i])->n_elts; - for(size_t j=0; j < n_elts; j++) { - SET_EXPR_CTX_01( - (ast_t *) down_cast2(x[0])->m_elts[j], Store); - } +static inline ast_t *SET_STORE_01(ast_t *x) { + if(is_a(*EXPR(x))) { + size_t n_elts = down_cast2(x)->n_elts; + for(size_t i=0; i < n_elts; i++) { + SET_EXPR_CTX_01( + (ast_t *) down_cast2(x)->m_elts[i], Store); } } return x; } +static inline Vec SET_STORE_02(Vec x) { + for (size_t i=0; i < x.size(); i++) { + SET_STORE_01(x[i]); + } + return x; +} #define ASSIGNMENT(targets, val, l) make_Assign_t(p.m_a, l, \ - EXPRS(SET_EXPR_CTX_02(SET_STORE(targets), Store)), targets.size(), \ + EXPRS(SET_EXPR_CTX_02(SET_STORE_02(targets), Store)), targets.size(), \ EXPR(val), nullptr) static inline ast_t* TUPLE_02(Allocator &al, Location &l, Vec elts) { @@ -233,10 +237,10 @@ int dot_count = 0; EXPR(e), STMTS(stmt), stmt.size(), STMTS(A2LIST(p.m_a, orelse)), 1) #define FOR_01(target, iter, stmts, l) make_For_t(p.m_a, l, \ - EXPR(SET_EXPR_CTX_01(target, Store)), EXPR(iter), \ + EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \ STMTS(stmts), stmts.size(), nullptr, 0, nullptr) #define FOR_02(target, iter, stmts, orelse, l) make_For_t(p.m_a, l, \ - EXPR(SET_EXPR_CTX_01(target, Store)), EXPR(iter), \ + EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \ STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), nullptr) #define TRY_01(stmts, except, l) make_Try_t(p.m_a, l, \ @@ -384,10 +388,10 @@ static inline Args *FUNC_ARGS(Allocator &al, Location &l, STMTS(stmts), stmts.size(), nullptr, 0, EXPR(return), nullptr) #define ASYNC_FOR_01(target, iter, stmts, l) make_AsyncFor_t(p.m_a, l, \ - EXPR(SET_EXPR_CTX_01(target, Store)), EXPR(iter), \ + EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \ STMTS(stmts), stmts.size(), nullptr, 0, nullptr) #define ASYNC_FOR_02(target, iter, stmts, orelse, l) make_AsyncFor_t(p.m_a, l, \ - EXPR(SET_EXPR_CTX_01(target, Store)), EXPR(iter), \ + EXPR(SET_EXPR_CTX_01(SET_STORE_01(target), Store)), EXPR(iter), \ STMTS(stmts), stmts.size(), STMTS(orelse), orelse.size(), nullptr) #define ASYNC_WITH(items, body, l) make_AsyncWith_t(p.m_a, l, \ @@ -409,11 +413,17 @@ Vec MERGE_EXPR(Allocator &al, ast_t *x, ast_t *y) { #define COMPARE(x, op, y, l) make_Compare_t(p.m_a, l, \ EXPR(x), cmpopType::op, EXPRS(A2LIST(p.m_a, y)), 1) +char* concat_string(Allocator &al, ast_t *a, char *b) { + char *s = down_cast2(a)->m_value; + return LFortran::s2c(al, std::string(s) + std::string(b)); +} + #define SYMBOL(x, l) make_Name_t(p.m_a, l, \ x.c_str(p.m_a), expr_contextType::Load) // `x.int_n` is of type BigInt but we store the int64_t directly in AST #define INTEGER(x, l) make_ConstantInt_t(p.m_a, l, x, nullptr) -#define STRING(x, l) make_ConstantStr_t(p.m_a, l, x.c_str(p.m_a), nullptr) +#define STRING1(x, l) make_ConstantStr_t(p.m_a, l, x.c_str(p.m_a), nullptr) +#define STRING2(x, y, l) make_ConstantStr_t(p.m_a, l, concat_string(p.m_a, x, y.c_str(p.m_a)), nullptr) #define FLOAT(x, l) make_ConstantFloat_t(p.m_a, l, x, nullptr) #define COMPLEX(x, l) make_ConstantComplex_t(p.m_a, l, 0, x, nullptr) #define BOOL(x, l) make_ConstantBool_t(p.m_a, l, x, nullptr) @@ -452,7 +462,7 @@ expr_t* CHECK_TUPLE(expr_t *x) { #define SUBSCRIPT_01(value, slice, l) make_Subscript_t(p.m_a, l, \ EXPR(value), CHECK_TUPLE(EXPR(slice)), expr_contextType::Load) #define SUBSCRIPT_02(s, slice, l) make_Subscript_t(p.m_a, l, \ - EXPR(STRING(s, l)), CHECK_TUPLE(EXPR(slice)), expr_contextType::Load) + EXPR(s), CHECK_TUPLE(EXPR(slice)), expr_contextType::Load) static inline ast_t* SLICE(Allocator &al, Location &l, ast_t *lower, ast_t *upper, ast_t *_step) { diff --git a/src/runtime/lpython_parser.py b/src/runtime/lpython_parser.py index 2ad5ad90a3..4f3f8adb77 100644 --- a/src/runtime/lpython_parser.py +++ b/src/runtime/lpython_parser.py @@ -50,6 +50,10 @@ def visit_Constant(self, node): elif isinstance(node.value, complex): new_node = python_ast.ConstantComplex(node.value.real, node.value.imag, node.kind) + elif isinstance(node.value, Ellipsis.__class__): + new_node = python_ast.ConstantEllipsis(node.kind) + elif isinstance(node.value, None.__class__): + new_node = python_ast.ConstantNone(node.kind) else: print(type(node.value)) raise Exception("Unsupported Constant type") @@ -116,9 +120,13 @@ def __init__(self): self.s = "0 " def write_int8(self, i): + assert i >= 0 self.s += str(i) + " " def write_int64(self, i): + if i < 0: + i += 2**64 + assert i >= 0 self.s += str(i) + " " def write_float64(self, f): diff --git a/tests/loop1.py b/tests/loop1.py index 976639d586..c57e481e4a 100644 --- a/tests/loop1.py +++ b/tests/loop1.py @@ -35,5 +35,6 @@ def main0(): i = test_factorial_2(4) j: i64 j = test_factorial_3(5) + print(i, j) main0() diff --git a/tests/parser/ellipsis1.py b/tests/parser/ellipsis1.py new file mode 100644 index 0000000000..23f4436da8 --- /dev/null +++ b/tests/parser/ellipsis1.py @@ -0,0 +1,37 @@ +import numpy as np +from typing import Callable + +array = np.random.rand(2, 2, 2, 2) +print(array[..., 0]) +print(array[Ellipsis, 0]) + +def inject(get_next_item: Callable[..., str]) -> None: + ... + +def foo(x: ...) -> None: + ... + +class flow: + def __understand__(self, name: str, value: ...) -> None: ... + +def foo(x = ...): + return x + +def test(): + ... + +class Todo: + ... + +x = [1, [2, [...], 3]] +l = [..., 1, 2, 3] + +if x is ...: + pass + +def partial(func: Callable[..., str], *args) -> Callable[..., str]: + pass + +class xyz: + abc: str = ... + def __init__(self, name: str=...) -> None: ... diff --git a/tests/parser/for1.py b/tests/parser/for1.py index 3a5b12d165..24d7e87f23 100644 --- a/tests/parser/for1.py +++ b/tests/parser/for1.py @@ -31,3 +31,12 @@ sum: i32 = 0 for j in range(5): sum += j + +for _, x in y: + pass + +for (x, y) in z: + pass + +for i, a in enumerate([4, 5, 6, 7]): + print(i, ": ", a) diff --git a/tests/parser/function_def1.py b/tests/parser/function_def1.py index 063ef83683..c3f2b4726b 100644 --- a/tests/parser/function_def1.py +++ b/tests/parser/function_def1.py @@ -33,6 +33,11 @@ def tri_recursion(k): def test(a: i32) -> i32: return a + 10 +@overload +# Comment +def test(a: i64) -> i64: + return a + 10 + @overload def test(a: bool) -> i32: if a: diff --git a/tests/parser/statements1.py b/tests/parser/statements1.py index 74c922405c..33569e9482 100644 --- a/tests/parser/statements1.py +++ b/tests/parser/statements1.py @@ -63,6 +63,20 @@ 12+3j .12+.001j "String" +"String " "String" +'String ' 'String' +'String ' "String" +"String " "String"[1:] +x = ("String " +"String") +x = ("String " + +"String") +x = ("String " \ +"String") +x = "String " \ +"String" +x = "String " +"String" True False diff --git a/tests/reference/asr-loop1-10d3109.json b/tests/reference/asr-loop1-10d3109.json index bba8d1ea0c..8d9932597e 100644 --- a/tests/reference/asr-loop1-10d3109.json +++ b/tests/reference/asr-loop1-10d3109.json @@ -2,11 +2,11 @@ "basename": "asr-loop1-10d3109", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/loop1.py", - "infile_hash": "e50c7161122d599991fafb072d5db8fe7e54d017d56a5c1951a210ca", + "infile_hash": "a27a0e48b7c6291be0b0847f5e7a30c591c7168a9004395156d57dbd", "outfile": null, "outfile_hash": null, "stdout": "asr-loop1-10d3109.stdout", - "stdout_hash": "5d36cb7c4513f77c3490bbc704a8a965aba5caca2d0ab82c35f52c3b", + "stdout_hash": "78b22cbace48a9537748d96d36191446a7713ee8a39e80a67f20e0dd", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-loop1-10d3109.stdout b/tests/reference/asr-loop1-10d3109.stdout index a36fb3e5c1..bce2dbe504 100644 --- a/tests/reference/asr-loop1-10d3109.stdout +++ b/tests/reference/asr-loop1-10d3109.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {_lpython_main_program: (Subroutine (SymbolTable 7 {}) _lpython_main_program [] [(SubroutineCall 1 main0 () [] ())] Source Public Implementation () .false. .false.), main0: (Subroutine (SymbolTable 5 {i: (Variable 5 i Local () () Default (Integer 4 []) Source Public Required .false.), j: (Variable 5 j Local () () Default (Integer 8 []) Source Public Required .false.)}) main0 [] [(= (Var 5 i) (FunctionCall 1 test_factorial_1 () [((IntegerConstant 4 (Integer 4 [])))] (Integer 4 []) () ()) ()) (= (Var 5 i) (FunctionCall 1 test_factorial_2 () [((IntegerConstant 4 (Integer 4 [])))] (Integer 4 []) () ()) ()) (= (Var 5 j) (FunctionCall 1 test_factorial_3 () [((IntegerConstant 5 (Integer 4 [])))] (Integer 8 []) () ()) ())] Source Public Implementation () .false. .false.), main_program: (Program (SymbolTable 6 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), test_factorial_1: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), result: (Variable 2 result Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 2 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_1 [(Var 2 x)] [(If (Compare (Var 2 x) Lt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 2 _lpython_return_variable) (IntegerConstant 0 (Integer 4 [])) ()) (Return)] []) (= (Var 2 result) (IntegerConstant 1 (Integer 4 [])) ()) (WhileLoop (Compare (Var 2 x) Gt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 2 result) (BinOp (Var 2 result) Mul (Var 2 x) (Integer 4 []) () ()) ()) (= (Var 2 x) (BinOp (Var 2 x) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())]) (= (Var 2 _lpython_return_variable) (Var 2 result) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation ()), test_factorial_2: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 3 i Local () () Default (Integer 4 []) Source Public Required .false.), result: (Variable 3 result Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_2 [(Var 3 x)] [(= (Var 3 result) (IntegerConstant 1 (Integer 4 [])) ()) (DoLoop ((Var 3 i) (IntegerConstant 1 (Integer 4 [])) (BinOp (BinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 1 (Integer 4 []))) [(= (Var 3 result) (BinOp (Var 3 result) Mul (Var 3 i) (Integer 4 []) () ()) ())]) (= (Var 3 _lpython_return_variable) (Var 3 result) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation ()), test_factorial_3: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 8 []) Source Public Required .false.), result: (Variable 4 result Local () () Default (Integer 8 []) Source Public Required .false.), x: (Variable 4 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_3 [(Var 4 x)] [(If (Compare (Var 4 x) Lt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 4 _lpython_return_variable) (Cast (IntegerConstant 0 (Integer 4 [])) IntegerToInteger (Integer 8 []) ()) ()) (Return)] []) (= (Var 4 result) (Cast (IntegerConstant 1 (Integer 4 [])) IntegerToInteger (Integer 8 []) ()) ()) (WhileLoop (Compare (Var 4 x) Gt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 4 result) (BinOp (Var 4 result) Mul (Cast (Var 4 x) IntegerToInteger (Integer 8 []) ()) (Integer 8 []) () ()) ()) (= (Var 4 x) (BinOp (Var 4 x) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())]) (= (Var 4 _lpython_return_variable) (Var 4 result) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation ())}) []) +(TranslationUnit (SymbolTable 1 {_lpython_main_program: (Subroutine (SymbolTable 7 {}) _lpython_main_program [] [(SubroutineCall 1 main0 () [] ())] Source Public Implementation () .false. .false.), main0: (Subroutine (SymbolTable 5 {i: (Variable 5 i Local () () Default (Integer 4 []) Source Public Required .false.), j: (Variable 5 j Local () () Default (Integer 8 []) Source Public Required .false.)}) main0 [] [(= (Var 5 i) (FunctionCall 1 test_factorial_1 () [((IntegerConstant 4 (Integer 4 [])))] (Integer 4 []) () ()) ()) (= (Var 5 i) (FunctionCall 1 test_factorial_2 () [((IntegerConstant 4 (Integer 4 [])))] (Integer 4 []) () ()) ()) (= (Var 5 j) (FunctionCall 1 test_factorial_3 () [((IntegerConstant 5 (Integer 4 [])))] (Integer 8 []) () ()) ()) (Print () [(Var 5 i) (Var 5 j)])] Source Public Implementation () .false. .false.), main_program: (Program (SymbolTable 6 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), test_factorial_1: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), result: (Variable 2 result Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 2 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_1 [(Var 2 x)] [(If (Compare (Var 2 x) Lt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 2 _lpython_return_variable) (IntegerConstant 0 (Integer 4 [])) ()) (Return)] []) (= (Var 2 result) (IntegerConstant 1 (Integer 4 [])) ()) (WhileLoop (Compare (Var 2 x) Gt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 2 result) (BinOp (Var 2 result) Mul (Var 2 x) (Integer 4 []) () ()) ()) (= (Var 2 x) (BinOp (Var 2 x) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())]) (= (Var 2 _lpython_return_variable) (Var 2 result) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation ()), test_factorial_2: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 3 i Local () () Default (Integer 4 []) Source Public Required .false.), result: (Variable 3 result Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_2 [(Var 3 x)] [(= (Var 3 result) (IntegerConstant 1 (Integer 4 [])) ()) (DoLoop ((Var 3 i) (IntegerConstant 1 (Integer 4 [])) (BinOp (BinOp (Var 3 x) Add (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) (IntegerConstant 1 (Integer 4 []))) [(= (Var 3 result) (BinOp (Var 3 result) Mul (Var 3 i) (Integer 4 []) () ()) ())]) (= (Var 3 _lpython_return_variable) (Var 3 result) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation ()), test_factorial_3: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 8 []) Source Public Required .false.), result: (Variable 4 result Local () () Default (Integer 8 []) Source Public Required .false.), x: (Variable 4 x In () () Default (Integer 4 []) Source Public Required .false.)}) test_factorial_3 [(Var 4 x)] [(If (Compare (Var 4 x) Lt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 4 _lpython_return_variable) (Cast (IntegerConstant 0 (Integer 4 [])) IntegerToInteger (Integer 8 []) ()) ()) (Return)] []) (= (Var 4 result) (Cast (IntegerConstant 1 (Integer 4 [])) IntegerToInteger (Integer 8 []) ()) ()) (WhileLoop (Compare (Var 4 x) Gt (IntegerConstant 0 (Integer 4 [])) (Logical 4 []) () ()) [(= (Var 4 result) (BinOp (Var 4 result) Mul (Cast (Var 4 x) IntegerToInteger (Integer 8 []) ()) (Integer 8 []) () ()) ()) (= (Var 4 x) (BinOp (Var 4 x) Sub (IntegerConstant 1 (Integer 4 [])) (Integer 4 []) () ()) ())]) (= (Var 4 _lpython_return_variable) (Var 4 result) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation ())}) []) diff --git a/tests/reference/ast-ellipsis1-4f6c4dd.json b/tests/reference/ast-ellipsis1-4f6c4dd.json new file mode 100644 index 0000000000..0e042fd21c --- /dev/null +++ b/tests/reference/ast-ellipsis1-4f6c4dd.json @@ -0,0 +1,13 @@ +{ + "basename": "ast-ellipsis1-4f6c4dd", + "cmd": "lpython --show-ast --no-color {infile} -o {outfile}", + "infile": "tests/parser/ellipsis1.py", + "infile_hash": "24df29cba718c679016f3758a2eccafbeb9cfebd56265fd8da16bee1", + "outfile": null, + "outfile_hash": null, + "stdout": "ast-ellipsis1-4f6c4dd.stdout", + "stdout_hash": "99ae0e12fd8efcd71433e66f10ba7ba5b59e165ddd5ded0072593b12", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/ast-ellipsis1-4f6c4dd.stdout b/tests/reference/ast-ellipsis1-4f6c4dd.stdout new file mode 100644 index 0000000000..51aa9eb229 --- /dev/null +++ b/tests/reference/ast-ellipsis1-4f6c4dd.stdout @@ -0,0 +1 @@ +(Module [(Import [(numpy np)]) (ImportFrom typing [(Callable ())] 0) (Assign [(Name array Store)] (Call (Attribute (Attribute (Name np Load) random Load) rand Load) [(ConstantInt 2 ()) (ConstantInt 2 ()) (ConstantInt 2 ()) (ConstantInt 2 ())] []) ()) (Expr (Call (Name print Load) [(Subscript (Name array Load) (Tuple [(ConstantEllipsis ()) (ConstantInt 0 ())] Load) Load)] [])) (Expr (Call (Name print Load) [(Subscript (Name array Load) (Tuple [(Name Ellipsis Load) (ConstantInt 0 ())] Load) Load)] [])) (FunctionDef inject ([] [(get_next_item (Subscript (Name Callable Load) (Tuple [(ConstantEllipsis ()) (Name str Load)] Load) Load) ())] [] [] [] [] []) [(Expr (ConstantEllipsis ()))] [] (ConstantNone ()) ()) (FunctionDef foo ([] [(x (ConstantEllipsis ()) ())] [] [] [] [] []) [(Expr (ConstantEllipsis ()))] [] (ConstantNone ()) ()) (ClassDef flow [] [] [(FunctionDef __understand__ ([] [(self () ()) (name (Name str Load) ()) (value (ConstantEllipsis ()) ())] [] [] [] [] []) [(Expr (ConstantEllipsis ()))] [] (ConstantNone ()) ())] []) (FunctionDef foo ([] [(x () ())] [] [] [] [] [(ConstantEllipsis ())]) [(Return (Name x Load))] [] () ()) (FunctionDef test ([] [] [] [] [] [] []) [(Expr (ConstantEllipsis ()))] [] () ()) (ClassDef Todo [] [] [(Expr (ConstantEllipsis ()))] []) (Assign [(Name x Store)] (List [(ConstantInt 1 ()) (List [(ConstantInt 2 ()) (List [(ConstantEllipsis ())] Load) (ConstantInt 3 ())] Load)] Load) ()) (Assign [(Name l Store)] (List [(ConstantEllipsis ()) (ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())] Load) ()) (If (Compare (Name x Load) Is [(ConstantEllipsis ())]) [(Pass)] []) (FunctionDef partial ([] [(func (Subscript (Name Callable Load) (Tuple [(ConstantEllipsis ()) (Name str Load)] Load) Load) ())] [(args () ())] [] [] [] []) [(Pass)] [] (Subscript (Name Callable Load) (Tuple [(ConstantEllipsis ()) (Name str Load)] Load) Load) ()) (ClassDef xyz [] [] [(AnnAssign (Name abc Store) (Name str Load) (ConstantEllipsis ()) 1) (FunctionDef __init__ ([] [(self () ()) (name (Name str Load) ())] [] [] [] [] [(ConstantEllipsis ())]) [(Expr (ConstantEllipsis ()))] [] (ConstantNone ()) ())] [])] []) diff --git a/tests/reference/ast-loop1-194a137.json b/tests/reference/ast-loop1-194a137.json index 6247241ab5..dee5dc4f67 100644 --- a/tests/reference/ast-loop1-194a137.json +++ b/tests/reference/ast-loop1-194a137.json @@ -2,11 +2,11 @@ "basename": "ast-loop1-194a137", "cmd": "lpython --show-ast --no-color {infile} -o {outfile}", "infile": "tests/loop1.py", - "infile_hash": "e50c7161122d599991fafb072d5db8fe7e54d017d56a5c1951a210ca", + "infile_hash": "a27a0e48b7c6291be0b0847f5e7a30c591c7168a9004395156d57dbd", "outfile": null, "outfile_hash": null, "stdout": "ast-loop1-194a137.stdout", - "stdout_hash": "0cc09fa5ddfef0db3b9115837fa64f543e814e01e7e4d1c94ebc7b78", + "stdout_hash": "fe2925f8d0ffd327d1626c46f2c6681d1a83ff5cd15011ef25f25d6d", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast-loop1-194a137.stdout b/tests/reference/ast-loop1-194a137.stdout index cfedd9abb8..2e84c72c75 100644 --- a/tests/reference/ast-loop1-194a137.stdout +++ b/tests/reference/ast-loop1-194a137.stdout @@ -1 +1 @@ -(Module [(FunctionDef test_factorial_1 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(If (Compare (Name x Load) Lt [(ConstantInt 0 ())]) [(Return (ConstantInt 0 ()))] []) (AnnAssign (Name result Store) (Name i32 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (While (Compare (Name x Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name x Load)) ()) (AugAssign (Name x Store) Sub (ConstantInt 1 ()))] []) (Return (Name result Load))] [] (Name i32 Load) ()) (FunctionDef test_factorial_2 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(AnnAssign (Name result Store) (Name i32 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (AnnAssign (Name i Store) (Name i32 Load) () 1) (For (Name i Store) (Call (Name range Load) [(ConstantInt 1 ()) (BinOp (Name x Load) Add (ConstantInt 1 ()))] []) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name i Load)) ())] [] ()) (Return (Name result Load))] [] (Name i32 Load) ()) (FunctionDef test_factorial_3 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(If (Compare (Name x Load) Lt [(ConstantInt 0 ())]) [(Return (ConstantInt 0 ()))] []) (AnnAssign (Name result Store) (Name i64 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (While (Compare (Name x Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name x Load)) ()) (AugAssign (Name x Store) Sub (ConstantInt 1 ()))] []) (Return (Name result Load))] [] (Name i64 Load) ()) (FunctionDef main0 ([] [] [] [] [] [] []) [(AnnAssign (Name i Store) (Name i32 Load) () 1) (Assign [(Name i Store)] (Call (Name test_factorial_1 Load) [(ConstantInt 4 ())] []) ()) (Assign [(Name i Store)] (Call (Name test_factorial_2 Load) [(ConstantInt 4 ())] []) ()) (AnnAssign (Name j Store) (Name i64 Load) () 1) (Assign [(Name j Store)] (Call (Name test_factorial_3 Load) [(ConstantInt 5 ())] []) ())] [] () ()) (Expr (Call (Name main0 Load) [] []))] []) +(Module [(FunctionDef test_factorial_1 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(If (Compare (Name x Load) Lt [(ConstantInt 0 ())]) [(Return (ConstantInt 0 ()))] []) (AnnAssign (Name result Store) (Name i32 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (While (Compare (Name x Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name x Load)) ()) (AugAssign (Name x Store) Sub (ConstantInt 1 ()))] []) (Return (Name result Load))] [] (Name i32 Load) ()) (FunctionDef test_factorial_2 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(AnnAssign (Name result Store) (Name i32 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (AnnAssign (Name i Store) (Name i32 Load) () 1) (For (Name i Store) (Call (Name range Load) [(ConstantInt 1 ()) (BinOp (Name x Load) Add (ConstantInt 1 ()))] []) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name i Load)) ())] [] ()) (Return (Name result Load))] [] (Name i32 Load) ()) (FunctionDef test_factorial_3 ([] [(x (Name i32 Load) ())] [] [] [] [] []) [(If (Compare (Name x Load) Lt [(ConstantInt 0 ())]) [(Return (ConstantInt 0 ()))] []) (AnnAssign (Name result Store) (Name i64 Load) () 1) (Assign [(Name result Store)] (ConstantInt 1 ()) ()) (While (Compare (Name x Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name result Load) Mult (Name x Load)) ()) (AugAssign (Name x Store) Sub (ConstantInt 1 ()))] []) (Return (Name result Load))] [] (Name i64 Load) ()) (FunctionDef main0 ([] [] [] [] [] [] []) [(AnnAssign (Name i Store) (Name i32 Load) () 1) (Assign [(Name i Store)] (Call (Name test_factorial_1 Load) [(ConstantInt 4 ())] []) ()) (Assign [(Name i Store)] (Call (Name test_factorial_2 Load) [(ConstantInt 4 ())] []) ()) (AnnAssign (Name j Store) (Name i64 Load) () 1) (Assign [(Name j Store)] (Call (Name test_factorial_3 Load) [(ConstantInt 5 ())] []) ()) (Expr (Call (Name print Load) [(Name i Load) (Name j Load)] []))] [] () ()) (Expr (Call (Name main0 Load) [] []))] []) diff --git a/tests/reference/ast_new-for1-887432e.json b/tests/reference/ast_new-for1-887432e.json index 8d7d022088..c09bcbb01c 100644 --- a/tests/reference/ast_new-for1-887432e.json +++ b/tests/reference/ast_new-for1-887432e.json @@ -2,11 +2,11 @@ "basename": "ast_new-for1-887432e", "cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", "infile": "tests/parser/for1.py", - "infile_hash": "60515a1800d4a8b1a2cad5ad7b23f75f2510e1d369e94065f01c0844", + "infile_hash": "a05c8da4019ead83ba9840212112e467f7a8968896b55d0122962b7f", "outfile": null, "outfile_hash": null, "stdout": "ast_new-for1-887432e.stdout", - "stdout_hash": "438c7ad856655fd2f666faab754e58f11179a800975359501be7b8fa", + "stdout_hash": "616164b90733fae6f26818243182810e9864ad8499e1d2c591b27cf3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast_new-for1-887432e.stdout b/tests/reference/ast_new-for1-887432e.stdout index 2c953bb81a..27482121ff 100644 --- a/tests/reference/ast_new-for1-887432e.stdout +++ b/tests/reference/ast_new-for1-887432e.stdout @@ -1 +1 @@ -(Module [(ImportFrom ltypes [(i32 ())] 0) (For (Name x Store) (Name fruits Load) [(Expr (Call (Name print Load) [(Name x Load)] []))] [] ()) (For (Name x Store) (Name fruits Load) [(Expr (Call (Name print Load) [(Name x Load)] [])) (If (Compare (Name x Load) Eq [(ConstantStr "banana" ())]) [(Break)] [])] [] ()) (For (Name x Store) (ConstantStr "banana" ()) [(Expr (Call (Name print Load) [(Name x Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 6 ())] []) [(Expr (Call (Name print Load) [(Name i Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 2 ()) (ConstantInt 30 ()) (ConstantInt 3 ())] []) [(Expr (Call (Name print Load) [(Name i Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(If (Compare (Name i Load) Eq [(ConstantInt 3 ())]) [(Continue)] []) (Expr (Call (Name print Load) [(Name i Load)] []))] [(Expr (Call (Name print Load) [(ConstantStr "Finally Completed!" ())] []))] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(For (Name j Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(Expr (Call (Name print Load) [(Name i Load) (Name j Load)] []))] [] ())] [] ()) (AnnAssign (Name sum Store) (Name i32 Load) (ConstantInt 0 ()) 1) (For (Name j Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(AugAssign (Name sum Store) Add (Name j Load))] [] ())] []) +(Module [(ImportFrom ltypes [(i32 ())] 0) (For (Name x Store) (Name fruits Load) [(Expr (Call (Name print Load) [(Name x Load)] []))] [] ()) (For (Name x Store) (Name fruits Load) [(Expr (Call (Name print Load) [(Name x Load)] [])) (If (Compare (Name x Load) Eq [(ConstantStr "banana" ())]) [(Break)] [])] [] ()) (For (Name x Store) (ConstantStr "banana" ()) [(Expr (Call (Name print Load) [(Name x Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 6 ())] []) [(Expr (Call (Name print Load) [(Name i Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 2 ()) (ConstantInt 30 ()) (ConstantInt 3 ())] []) [(Expr (Call (Name print Load) [(Name i Load)] []))] [] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(If (Compare (Name i Load) Eq [(ConstantInt 3 ())]) [(Continue)] []) (Expr (Call (Name print Load) [(Name i Load)] []))] [(Expr (Call (Name print Load) [(ConstantStr "Finally Completed!" ())] []))] ()) (For (Name i Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(For (Name j Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(Expr (Call (Name print Load) [(Name i Load) (Name j Load)] []))] [] ())] [] ()) (AnnAssign (Name sum Store) (Name i32 Load) (ConstantInt 0 ()) 1) (For (Name j Store) (Call (Name range Load) [(ConstantInt 5 ())] []) [(AugAssign (Name sum Store) Add (Name j Load))] [] ()) (For (Tuple [(Name _ Store) (Name x Store)] Store) (Name y Load) [(Pass)] [] ()) (For (Tuple [(Name x Store) (Name y Store)] Store) (Name z Load) [(Pass)] [] ()) (For (Tuple [(Name i Store) (Name a Store)] Store) (Call (Name enumerate Load) [(List [(ConstantInt 4 ()) (ConstantInt 5 ()) (ConstantInt 6 ()) (ConstantInt 7 ())] Load)] []) [(Expr (Call (Name print Load) [(Name i Load) (ConstantStr ": " ()) (Name a Load)] []))] [] ())] []) diff --git a/tests/reference/ast_new-function_def1-1a872df.json b/tests/reference/ast_new-function_def1-1a872df.json index c484665423..013bebf758 100644 --- a/tests/reference/ast_new-function_def1-1a872df.json +++ b/tests/reference/ast_new-function_def1-1a872df.json @@ -2,11 +2,11 @@ "basename": "ast_new-function_def1-1a872df", "cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", "infile": "tests/parser/function_def1.py", - "infile_hash": "4224c0bffeb39c449abfeba907eba690ee5ff15f9514c9a0c0922a92", + "infile_hash": "9dc3cbaa399b8013e99cf165c76d468cf48edde757daafc4069cda40", "outfile": null, "outfile_hash": null, "stdout": "ast_new-function_def1-1a872df.stdout", - "stdout_hash": "19677f67c936f188ba070291048c6dd20a815c5fe66c13570051b3e7", + "stdout_hash": "62bdf27fa9795b9cad94f2747ac48dfac223ef7401dc9af0b445c5a8", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast_new-function_def1-1a872df.stdout b/tests/reference/ast_new-function_def1-1a872df.stdout index d5823785ed..d383b67a1c 100644 --- a/tests/reference/ast_new-function_def1-1a872df.stdout +++ b/tests/reference/ast_new-function_def1-1a872df.stdout @@ -3,4 +3,4 @@ the person passed in as a parameter " ())) (Expr (Call (Name print Load) [(BinOp (BinOp (ConstantStr "Hello, " ()) Add (Name name Load)) Add (ConstantStr ". Good morning!" ()))] []))] [] () ()) (FunctionDef absolute_value ([] [(num () ())] [] [] [] [] []) [(Expr (ConstantStr "This function returns the absolute - value of the entered number" ())) (If (Compare (Name num Load) GtE [(ConstantInt 0 ())]) [(Return (Name num Load))] [(Return (UnaryOp USub (Name num Load)))])] [] () ()) (FunctionDef combine ([] [(fname () ()) (lname () ())] [] [] [] [] []) [(Expr (Call (Name print Load) [(BinOp (BinOp (Name fname Load) Add (ConstantStr " " ())) Add (Name lname Load))] []))] [] () ()) (FunctionDef tri_recursion ([] [(k () ())] [] [] [] [] []) [(If (Compare (Name k Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name k Load) Add (Call (Name tri_recursion Load) [(BinOp (Name k Load) Sub (ConstantInt 1 ()))] [])) ()) (Expr (Call (Name print Load) [(Name result Load)] []))] [(Assign [(Name result Store)] (ConstantInt 0 ()) ())]) (Return (Name result Load))] [] () ()) (FunctionDef test ([] [(a (Name i32 Load) ())] [] [] [] [] []) [(Return (BinOp (Name a Load) Add (ConstantInt 10 ())))] [(Name overload Load)] (Name i32 Load) ()) (FunctionDef test ([] [(a (Name bool Load) ())] [] [] [] [] []) [(If (Name a Load) [(Return (ConstantInt 10 ()))] []) (Return (UnaryOp USub (ConstantInt 10 ())))] [(Name overload Load)] (Name i32 Load) ()) (FunctionDef check ([] [] [] [] [] [] []) [(Expr (Call (Name greet Load) [(ConstantStr "Xyz" ())] [])) (Expr (Call (Name print Load) [(Call (Name absolute_value Load) [(ConstantInt 2 ())] [])] [])) (Expr (Call (Name combine Load) [(ConstantStr "LPython" ()) (ConstantStr "Compiler" ())] [])) (Expr (Call (Name print Load) [(ConstantStr "Recursion Example Results: " ())] [])) (Expr (Call (Name tri_recursion Load) [(ConstantInt 6 ())] [])) (Expr (Call (Name print Load) [(Call (Name test Load) [(ConstantInt 15 ())] [])] [])) (Expr (Call (Name print Load) [(Call (Name test Load) [(ConstantBool .true. ())] [])] []))] [] () ()) (Expr (Call (Name check Load) [] []))] []) + value of the entered number" ())) (If (Compare (Name num Load) GtE [(ConstantInt 0 ())]) [(Return (Name num Load))] [(Return (UnaryOp USub (Name num Load)))])] [] () ()) (FunctionDef combine ([] [(fname () ()) (lname () ())] [] [] [] [] []) [(Expr (Call (Name print Load) [(BinOp (BinOp (Name fname Load) Add (ConstantStr " " ())) Add (Name lname Load))] []))] [] () ()) (FunctionDef tri_recursion ([] [(k () ())] [] [] [] [] []) [(If (Compare (Name k Load) Gt [(ConstantInt 0 ())]) [(Assign [(Name result Store)] (BinOp (Name k Load) Add (Call (Name tri_recursion Load) [(BinOp (Name k Load) Sub (ConstantInt 1 ()))] [])) ()) (Expr (Call (Name print Load) [(Name result Load)] []))] [(Assign [(Name result Store)] (ConstantInt 0 ()) ())]) (Return (Name result Load))] [] () ()) (FunctionDef test ([] [(a (Name i32 Load) ())] [] [] [] [] []) [(Return (BinOp (Name a Load) Add (ConstantInt 10 ())))] [(Name overload Load)] (Name i32 Load) ()) (FunctionDef test ([] [(a (Name i64 Load) ())] [] [] [] [] []) [(Return (BinOp (Name a Load) Add (ConstantInt 10 ())))] [(Name overload Load)] (Name i64 Load) ()) (FunctionDef test ([] [(a (Name bool Load) ())] [] [] [] [] []) [(If (Name a Load) [(Return (ConstantInt 10 ()))] []) (Return (UnaryOp USub (ConstantInt 10 ())))] [(Name overload Load)] (Name i32 Load) ()) (FunctionDef check ([] [] [] [] [] [] []) [(Expr (Call (Name greet Load) [(ConstantStr "Xyz" ())] [])) (Expr (Call (Name print Load) [(Call (Name absolute_value Load) [(ConstantInt 2 ())] [])] [])) (Expr (Call (Name combine Load) [(ConstantStr "LPython" ()) (ConstantStr "Compiler" ())] [])) (Expr (Call (Name print Load) [(ConstantStr "Recursion Example Results: " ())] [])) (Expr (Call (Name tri_recursion Load) [(ConstantInt 6 ())] [])) (Expr (Call (Name print Load) [(Call (Name test Load) [(ConstantInt 15 ())] [])] [])) (Expr (Call (Name print Load) [(Call (Name test Load) [(ConstantBool .true. ())] [])] []))] [] () ()) (Expr (Call (Name check Load) [] []))] []) diff --git a/tests/reference/ast_new-statements1-e081093.json b/tests/reference/ast_new-statements1-e081093.json index 7d8dd92fb0..7f8bdb6564 100644 --- a/tests/reference/ast_new-statements1-e081093.json +++ b/tests/reference/ast_new-statements1-e081093.json @@ -2,11 +2,11 @@ "basename": "ast_new-statements1-e081093", "cmd": "lpython --show-ast --new-parser --no-color {infile} -o {outfile}", "infile": "tests/parser/statements1.py", - "infile_hash": "3e48966892256280de0dab6742541e3f6b06af13c3161609bad5a35e", + "infile_hash": "7db69bcb75890d3456083fca500a074cd0f410a3b6333dbe68bc8543", "outfile": null, "outfile_hash": null, "stdout": "ast_new-statements1-e081093.stdout", - "stdout_hash": "0fdc62df9ba823b70dba771bcd8df40203b07f347800fd3333c05b3e", + "stdout_hash": "212ee41d38af63bdaf1402f51a9f611bcc292462f82af27515b92f7b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/ast_new-statements1-e081093.stdout b/tests/reference/ast_new-statements1-e081093.stdout index 5ac2e60374..8624512052 100644 --- a/tests/reference/ast_new-statements1-e081093.stdout +++ b/tests/reference/ast_new-statements1-e081093.stdout @@ -1 +1 @@ -(Module [(Pass) (Break) (Continue) (Raise () ()) (Raise (Call (Name NameError Load) [(ConstantStr "String" ())] []) ()) (Raise (Name RuntimeError Load) (Name exc Load)) (Assert (Compare (Call (Name len Load) [(Name marks Load)] []) NotEq [(ConstantInt 0 ())]) (ConstantStr "List is empty." ())) (Assert (Compare (Name x Load) Eq [(ConstantStr "String" ())]) ()) (Assign [(Name x Store)] (ConstantInt 1 ()) ()) (Assign [(Tuple [(Name x Store) (Name y Store)] Store)] (Call (Name x Load) [] []) ()) (Assign [(Name x Store) (Name y Store)] (ConstantInt 1 ()) ()) (Assign [(Tuple [(Name x Store) (Name y Store)] Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assign [(Subscript (Name x Load) (Name i Load) Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (AugAssign (Name x Store) Add (ConstantInt 1 ())) (AnnAssign (Name x Store) (Name i64 Load) () 1) (AnnAssign (Name y Store) (Name i32 Load) (ConstantInt 1 ()) 1) (Delete [(Name x Del)]) (Delete [(Tuple [] Del)]) (Delete [(Tuple [(Name x Del) (Name y Del)] Del)]) (Delete [(Tuple [(Name x Del) (Name y Del)] Del)]) (Delete [(Name x Del) (Name y Del)]) (Delete [(Name x Del) (Name y Del)]) (Return ()) (Return (BinOp (Name a Load) Add (Name b Load))) (Return (Call (Name x Load) [(Name a Load)] [])) (Return (Tuple [] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Global [a]) (Global [a b]) (Nonlocal [a]) (Nonlocal [a b]) (Expr (ConstantInt 123 ())) (Expr (UnaryOp USub (ConstantInt 123 ()))) (Expr (UnaryOp USub (ConstantInt 291 ()))) (Expr (ConstantInt 6844 ())) (Expr (UnaryOp USub (ConstantInt 83 ()))) (Expr (ConstantInt 87 ())) (Expr (UnaryOp USub (ConstantInt 13 ()))) (Expr (ConstantInt 13 ())) (Expr (ConstantFloat 123.000000 ())) (Expr (ConstantFloat 123.450000 ())) (Expr (ConstantFloat 123400000000.000000 ())) (Expr (BinOp (ConstantInt 12 ()) Add (ConstantComplex 0.000000 3.000000 ()))) (Expr (BinOp (ConstantFloat 0.120000 ()) Add (ConstantComplex 0.000000 0.001000 ()))) (Expr (ConstantStr "String" ())) (Expr (ConstantBool .true. ())) (Expr (ConstantBool .false. ())) (Expr (BinOp (BinOp (Name x Load) Add (Name y Load)) Mult (Name z Load))) (Expr (BinOp (Name x Load) Sub (Name y Load))) (Expr (BinOp (Name x Load) Mult (Name y Load))) (Expr (BinOp (Name x Load) Div (Name y Load))) (Expr (BinOp (Name x Load) Mod (Name y Load))) (Expr (UnaryOp USub (Name y Load))) (Expr (UnaryOp UAdd (Name y Load))) (Expr (UnaryOp Invert (Name y Load))) (Expr (BinOp (Name x Load) Pow (Name y Load))) (Expr (BinOp (Name x Load) FloorDiv (Name y Load))) (Expr (BinOp (Name x Load) MatMult (Name y Load))) (Expr (BinOp (Name x Load) BitAnd (Name y Load))) (Expr (BinOp (Name x Load) BitOr (Name y Load))) (Expr (BinOp (Name x Load) BitXor (Name y Load))) (Expr (BinOp (Name x Load) LShift (Name y Load))) (Expr (BinOp (Name x Load) RShift (Name y Load))) (Expr (Compare (Name x Load) Eq [(Name y Load)])) (Expr (Compare (Name x Load) NotEq [(Name y Load)])) (Expr (Compare (Name x Load) Lt [(Name y Load)])) (Expr (Compare (Name x Load) LtE [(Name y Load)])) (Expr (Compare (Name x Load) Gt [(Name y Load)])) (Expr (Compare (Name x Load) GtE [(Name y Load)])) (AnnAssign (Name i Store) (Name i32 Load) (ConstantInt 4 ()) 1) (If (Compare (ConstantInt 2 ()) Gt [(Name i Load)]) [(Pass)] []) (If (Compare (Name i Load) Gt [(ConstantInt 5 ())]) [(Break)] []) (If (BoolOp And [(Compare (Name i Load) Eq [(ConstantInt 5 ())]) (Compare (Name i Load) Lt [(ConstantInt 10 ())])]) [(Assign [(Name i Store)] (ConstantInt 3 ()) ())] []) (For (Name i Store) (Call (Name range Load) [(Name N Load)] []) [(Assign [(Subscript (Name c Load) (Name i Load) Store)] (BinOp (Subscript (Name a Load) (Name i Load) Load) Add (BinOp (Name scalar Load) Mult (Subscript (Name b Load) (Name i Load) Load))) ())] [] ()) (Assign [(Name x Store)] (NamedExpr (Name y Store) (ConstantInt 0 ())) ()) (If (NamedExpr (Name a Store) (Call (Name ord Load) [(ConstantStr "3" ())] [])) [(Assign [(Name x Store)] (ConstantInt 1 ()) ())] []) (Assign [(Name a Store)] (Set [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())]) ())] []) +(Module [(Pass) (Break) (Continue) (Raise () ()) (Raise (Call (Name NameError Load) [(ConstantStr "String" ())] []) ()) (Raise (Name RuntimeError Load) (Name exc Load)) (Assert (Compare (Call (Name len Load) [(Name marks Load)] []) NotEq [(ConstantInt 0 ())]) (ConstantStr "List is empty." ())) (Assert (Compare (Name x Load) Eq [(ConstantStr "String" ())]) ()) (Assign [(Name x Store)] (ConstantInt 1 ()) ()) (Assign [(Tuple [(Name x Store) (Name y Store)] Store)] (Call (Name x Load) [] []) ()) (Assign [(Name x Store) (Name y Store)] (ConstantInt 1 ()) ()) (Assign [(Tuple [(Name x Store) (Name y Store)] Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assign [(Subscript (Name x Load) (Name i Load) Store)] (Tuple [(ConstantInt 1 ()) (ConstantInt 2 ())] Load) ()) (Assign [(Tuple [(Name x Store) (Name y Store) (Name z Store)] Store)] (Name t Load) ()) (Assign [(Tuple [(Name x Store) (Name y Store) (Name z Store)] Store)] (Name t Load) ()) (Assign [(Tuple [(Name x Store)] Store)] (Name t Load) ()) (Assign [(Tuple [(Name x Store)] Store)] (Name t Load) ()) (AugAssign (Name x Store) Add (ConstantInt 1 ())) (AnnAssign (Name x Store) (Name i64 Load) () 1) (AnnAssign (Name y Store) (Name i32 Load) (ConstantInt 1 ()) 1) (Delete [(Name x Del)]) (Delete [(Tuple [] Del)]) (Delete [(Tuple [(Name x Del) (Name y Del)] Del)]) (Delete [(Tuple [(Name x Del) (Name y Del)] Del)]) (Delete [(Name x Del) (Name y Del)]) (Delete [(Name x Del) (Name y Del)]) (Return ()) (Return (BinOp (Name a Load) Add (Name b Load))) (Return (Call (Name x Load) [(Name a Load)] [])) (Return (Tuple [] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Return (Tuple [(Name x Load) (Name y Load)] Load)) (Global [a]) (Global [a b]) (Nonlocal [a]) (Nonlocal [a b]) (Expr (ConstantInt 123 ())) (Expr (UnaryOp USub (ConstantInt 123 ()))) (Expr (UnaryOp USub (ConstantInt 291 ()))) (Expr (ConstantInt 6844 ())) (Expr (UnaryOp USub (ConstantInt 83 ()))) (Expr (ConstantInt 87 ())) (Expr (UnaryOp USub (ConstantInt 13 ()))) (Expr (ConstantInt 13 ())) (Expr (ConstantFloat 123.000000 ())) (Expr (ConstantFloat 123.450000 ())) (Expr (ConstantFloat 123400000000.000000 ())) (Expr (BinOp (ConstantInt 12 ()) Add (ConstantComplex 0.000000 3.000000 ()))) (Expr (BinOp (ConstantFloat 0.120000 ()) Add (ConstantComplex 0.000000 0.001000 ()))) (Expr (ConstantStr "String" ())) (Expr (ConstantStr "String String" ())) (Expr (ConstantStr "String String" ())) (Expr (ConstantStr "String String" ())) (Expr (Subscript (ConstantStr "String String" ()) (Slice (ConstantInt 1 ()) () ()) Load)) (Assign [(Name x Store)] (ConstantStr "String String" ()) ()) (Assign [(Name x Store)] (BinOp (ConstantStr "String " ()) Add (ConstantStr "String" ())) ()) (Assign [(Name x Store)] (ConstantStr "String String" ()) ()) (Assign [(Name x Store)] (ConstantStr "String String" ()) ()) (Assign [(Name x Store)] (ConstantStr "String " ()) ()) (Expr (ConstantStr "String" ())) (Expr (ConstantBool .true. ())) (Expr (ConstantBool .false. ())) (Expr (BinOp (BinOp (Name x Load) Add (Name y Load)) Mult (Name z Load))) (Expr (BinOp (Name x Load) Sub (Name y Load))) (Expr (BinOp (Name x Load) Mult (Name y Load))) (Expr (BinOp (Name x Load) Div (Name y Load))) (Expr (BinOp (Name x Load) Mod (Name y Load))) (Expr (UnaryOp USub (Name y Load))) (Expr (UnaryOp UAdd (Name y Load))) (Expr (UnaryOp Invert (Name y Load))) (Expr (BinOp (Name x Load) Pow (Name y Load))) (Expr (BinOp (Name x Load) FloorDiv (Name y Load))) (Expr (BinOp (Name x Load) MatMult (Name y Load))) (Expr (BinOp (Name x Load) BitAnd (Name y Load))) (Expr (BinOp (Name x Load) BitOr (Name y Load))) (Expr (BinOp (Name x Load) BitXor (Name y Load))) (Expr (BinOp (Name x Load) LShift (Name y Load))) (Expr (BinOp (Name x Load) RShift (Name y Load))) (Expr (Compare (Name x Load) Eq [(Name y Load)])) (Expr (Compare (Name x Load) NotEq [(Name y Load)])) (Expr (Compare (Name x Load) Lt [(Name y Load)])) (Expr (Compare (Name x Load) LtE [(Name y Load)])) (Expr (Compare (Name x Load) Gt [(Name y Load)])) (Expr (Compare (Name x Load) GtE [(Name y Load)])) (AnnAssign (Name i Store) (Name i32 Load) (ConstantInt 4 ()) 1) (If (Compare (ConstantInt 2 ()) Gt [(Name i Load)]) [(Pass)] []) (If (Compare (Name i Load) Gt [(ConstantInt 5 ())]) [(Break)] []) (If (BoolOp And [(Compare (Name i Load) Eq [(ConstantInt 5 ())]) (Compare (Name i Load) Lt [(ConstantInt 10 ())])]) [(Assign [(Name i Store)] (ConstantInt 3 ()) ())] []) (For (Name i Store) (Call (Name range Load) [(Name N Load)] []) [(Assign [(Subscript (Name c Load) (Name i Load) Store)] (BinOp (Subscript (Name a Load) (Name i Load) Load) Add (BinOp (Name scalar Load) Mult (Subscript (Name b Load) (Name i Load) Load))) ())] [] ()) (Assign [(Name x Store)] (NamedExpr (Name y Store) (ConstantInt 0 ())) ()) (If (NamedExpr (Name a Store) (Call (Name ord Load) [(ConstantStr "3" ())] [])) [(Assign [(Name x Store)] (ConstantInt 1 ()) ())] []) (Assign [(Name a Store)] (Set [(ConstantInt 1 ()) (ConstantInt 2 ()) (ConstantInt 3 ())]) ())] []) diff --git a/tests/reference/c-loop1-3e341c7.json b/tests/reference/c-loop1-3e341c7.json new file mode 100644 index 0000000000..cd02588b9e --- /dev/null +++ b/tests/reference/c-loop1-3e341c7.json @@ -0,0 +1,13 @@ +{ + "basename": "c-loop1-3e341c7", + "cmd": "lpython --no-color --show-c {infile}", + "infile": "tests/loop1.py", + "infile_hash": "a27a0e48b7c6291be0b0847f5e7a30c591c7168a9004395156d57dbd", + "outfile": null, + "outfile_hash": null, + "stdout": "c-loop1-3e341c7.stdout", + "stdout_hash": "ca5ae2d44ccd8b76aa54ec6c9523f8ae90205238f0b99dc14d6c0e71", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/c-loop1-3e341c7.stdout b/tests/reference/c-loop1-3e341c7.stdout new file mode 100644 index 0000000000..2c37ca0c2f --- /dev/null +++ b/tests/reference/c-loop1-3e341c7.stdout @@ -0,0 +1,71 @@ +#include +#include +#include +#include +void _lpython_main_program() +{ + main0(); +} + +void main0() +{ + int i; + long long j; + i = test_factorial_1(4); + i = test_factorial_2(4); + j = test_factorial_3(5); + printf("%d %lli\n", i, j); +} + +int test_factorial_1(int x) +{ + int _lpython_return_variable; + int result; + if (x < 0) { + _lpython_return_variable = 0; + return _lpython_return_variable; + } + result = 1; + while (x > 0) { + result = result*x; + x = x - 1; + } + _lpython_return_variable = result; + return _lpython_return_variable; +} + +int test_factorial_2(int x) +{ + int _lpython_return_variable; + int i; + int result; + result = 1; + for (i=1; i<=x + 1 - 1; i++) { + result = result*i; + } + _lpython_return_variable = result; + return _lpython_return_variable; +} + +long long test_factorial_3(int x) +{ + long long _lpython_return_variable; + long long result; + if (x < 0) { + _lpython_return_variable = 0; + return _lpython_return_variable; + } + result = 1; + while (x > 0) { + result = result*x; + x = x - 1; + } + _lpython_return_variable = result; + return _lpython_return_variable; +} + +int main(int argc, char* argv[]) +{ + _lpython_main_program(); + return 0; +} diff --git a/tests/reference/cpp-loop1-0a8cf3b.json b/tests/reference/cpp-loop1-0a8cf3b.json index 964faa5b04..baf322f4af 100644 --- a/tests/reference/cpp-loop1-0a8cf3b.json +++ b/tests/reference/cpp-loop1-0a8cf3b.json @@ -2,11 +2,11 @@ "basename": "cpp-loop1-0a8cf3b", "cmd": "lpython --no-color --show-cpp {infile}", "infile": "tests/loop1.py", - "infile_hash": "e50c7161122d599991fafb072d5db8fe7e54d017d56a5c1951a210ca", + "infile_hash": "a27a0e48b7c6291be0b0847f5e7a30c591c7168a9004395156d57dbd", "outfile": null, "outfile_hash": null, "stdout": "cpp-loop1-0a8cf3b.stdout", - "stdout_hash": "79bcbb41c038ebb668a632a270d4ef7247bca02ceba219d7c9212b8f", + "stdout_hash": "c66205b4ecb49a0230d42af74e349dc313754f650801a9420008f99e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/cpp-loop1-0a8cf3b.stdout b/tests/reference/cpp-loop1-0a8cf3b.stdout index 754ec73bbc..a94e7ee986 100644 --- a/tests/reference/cpp-loop1-0a8cf3b.stdout +++ b/tests/reference/cpp-loop1-0a8cf3b.stdout @@ -29,6 +29,7 @@ void main0() i = test_factorial_1(4); i = test_factorial_2(4); j = test_factorial_3(5); + std::cout << i << j << std::endl; } int test_factorial_1(int x) diff --git a/tests/tests.toml b/tests/tests.toml index e0f45a8a2a..1c815283ee 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -144,6 +144,7 @@ filename = "loop1.py" ast = true asr = true cpp = true +c = true [[test]] filename = "loop2.py" @@ -318,6 +319,10 @@ ast_new = true filename = "parser/slice1.py" ast_new = true +[[test]] +filename = "parser/ellipsis1.py" +ast = true + # tests/errors [[test]]