From 0ebfcdd2f7087af0af50ab7732345a9f15ed8b9f Mon Sep 17 00:00:00 2001 From: Lubis Date: Fri, 12 Aug 2022 17:03:56 +0900 Subject: [PATCH 1/9] Refactoring and adding type params to (formerly) subroutine --- src/libasr/asr_utils.h | 13 +++++ src/lpython/semantics/python_ast_to_asr.cpp | 57 +++++++-------------- 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index caa6a8f548..b47fb6e7b2 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -1387,6 +1387,19 @@ static inline ASR::ttype_t* get_contained_type(ASR::ttype_t* asr_type) { } } +static inline ASR::ttype_t* get_type_parameter(ASR::ttype_t* t) { + switch (t->type) { + case ASR::ttypeType::TypeParameter: { + return t; + } + case ASR::ttypeType::List: { + ASR::List_t *tl = ASR::down_cast(t); + return get_type_parameter(tl->m_type); + } + default: throw LCompilersException("Cannot get type parameter from this type."); + } +} + class ReplaceArgVisitor: public ASR::BaseExprReplacer { private: diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 9e55bae10b..5b88bc158c 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -2271,6 +2271,8 @@ class SymbolTableVisitor : public CommonVisitor { bool current_procedure_interface = false; bool overload = false; std::set ps; + Vec tps; + tps.reserve(al, x.m_args.n_args); bool vectorize = false; if (x.n_decorator_list > 0) { for(size_t i=0; i { if (ASRUtils::is_generic(*arg_type)) { std::string param_name = ASRUtils::get_parameter_name(arg_type); ps.insert(param_name); + ASR::ttype_t *tp = ASRUtils::duplicate_type(al, ASRUtils::get_type_parameter(arg_type)); + tps.push_back(al, tp); } std::string arg_s = arg; @@ -2374,43 +2378,19 @@ class SymbolTableVisitor : public CommonVisitor { ASR::down_cast(return_var)); ASR::asr_t *return_var_ref = ASR::make_Var_t(al, x.base.base.loc, current_scope->get_symbol(return_var_name)); - if (ps.size() > 0) { - Vec type_params; - type_params.reserve(al, ps.size()); - for (auto &p: ps) { - std::string param = p; - ASR::ttype_t *type_p = ASRUtils::TYPE(ASR::make_TypeParameter_t(al, - x.base.base.loc, s2c(al, p), nullptr, 0)); - type_params.push_back(al, type_p); - } - tmp = ASR::make_Function_t( - al, x.base.base.loc, - /* a_symtab */ current_scope, - /* a_name */ s2c(al, sym_name), - /* a_args */ args.p, - /* n_args */ args.size(), - /* a_type_params */ type_params.p, - /* n_type_params */ type_params.size(), - /* a_body */ nullptr, - /* n_body */ 0, - /* a_return_var */ ASRUtils::EXPR(return_var_ref), - current_procedure_abi_type, - s_access, deftype, bindc_name, vectorize, false, false); - } else { - tmp = ASR::make_Function_t( - al, x.base.base.loc, - /* a_symtab */ current_scope, - /* a_name */ s2c(al, sym_name), - /* a_args */ args.p, - /* n_args */ args.size(), - /* a_type_params */ nullptr, - /* n_type_params */ 0, - /* a_body */ nullptr, - /* n_body */ 0, - /* a_return_var */ ASRUtils::EXPR(return_var_ref), - current_procedure_abi_type, - s_access, deftype, bindc_name, vectorize, false, false); - } + tmp = ASR::make_Function_t( + al, x.base.base.loc, + /* a_symtab */ current_scope, + /* a_name */ s2c(al, sym_name), + /* a_args */ args.p, + /* n_args */ args.size(), + /* a_type_params */ tps.p, + /* n_type_params */ tps.size(), + /* a_body */ nullptr, + /* n_body */ 0, + /* a_return_var */ ASRUtils::EXPR(return_var_ref), + current_procedure_abi_type, + s_access, deftype, bindc_name, vectorize, false, false); } else { throw SemanticError("Return variable must be an identifier (Name AST node) or an array (Subscript AST node)", x.m_returns->base.loc); @@ -2423,7 +2403,8 @@ class SymbolTableVisitor : public CommonVisitor { /* a_name */ s2c(al, sym_name), /* a_args */ args.p, /* n_args */ args.size(), - nullptr, 0, + /* a_type_params */ tps.p, + /* n_type_params */ tps.size(), /* a_body */ nullptr, /* n_body */ 0, nullptr, From cd435cdca586270073f497d71257ff25c16f61a0 Mon Sep 17 00:00:00 2001 From: Lubis Date: Sun, 14 Aug 2022 11:11:49 +0900 Subject: [PATCH 2/9] Update reference tests --- tests/reference/asr-generics_01-d616074.json | 2 +- tests/reference/asr-generics_01-d616074.stdout | 2 +- tests/reference/asr-generics_array_01-682b1b2.json | 2 +- tests/reference/asr-generics_array_01-682b1b2.stdout | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/reference/asr-generics_01-d616074.json b/tests/reference/asr-generics_01-d616074.json index 43bf9e825b..4d166472e1 100644 --- a/tests/reference/asr-generics_01-d616074.json +++ b/tests/reference/asr-generics_01-d616074.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_01-d616074.stdout", - "stdout_hash": "9f748f982d651e6706e00bbf46909c4661cf2be40e7ebd25b30ca7fe", + "stdout_hash": "996d4e1de29da6f9e90fadfb1687c6d81f5e9eaee27420db1a2692aa", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_01-d616074.stdout b/tests/reference/asr-generics_01-d616074.stdout index 33c0f7a977..803f022c83 100644 --- a/tests/reference/asr-generics_01-d616074.stdout +++ b/tests/reference/asr-generics_01-d616074.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), __lpython_generic_f_1: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Character 1 1 () []) Source Public Required .false.), x: (Variable 4 x In () () Default (Character 1 1 () []) Source Public Required .false.), y: (Variable 4 y In () () Default (Character 1 1 () []) Source Public Required .false.)}) __lpython_generic_f_1 [(Var 4 x) (Var 4 y)] [] [(= (Var 4 _lpython_return_variable) (StringConcat (Var 4 x) (Var 4 y) (Character 1 2 () []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "a" (Character 1 1 () []))) ((StringConstant "b" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "c" (Character 1 1 () []))) ((StringConstant "d" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), __lpython_generic_f_1: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Character 1 1 () []) Source Public Required .false.), x: (Variable 4 x In () () Default (Character 1 1 () []) Source Public Required .false.), y: (Variable 4 y In () () Default (Character 1 1 () []) Source Public Required .false.)}) __lpython_generic_f_1 [(Var 4 x) (Var 4 y)] [] [(= (Var 4 _lpython_return_variable) (StringConcat (Var 4 x) (Var 4 y) (Character 1 2 () []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "a" (Character 1 1 () []))) ((StringConstant "b" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "c" (Character 1 1 () []))) ((StringConstant "d" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T []) (TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) diff --git a/tests/reference/asr-generics_array_01-682b1b2.json b/tests/reference/asr-generics_array_01-682b1b2.json index f078783e1b..6ff5e3e858 100644 --- a/tests/reference/asr-generics_array_01-682b1b2.json +++ b/tests/reference/asr-generics_array_01-682b1b2.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_array_01-682b1b2.stdout", - "stdout_hash": "e953b223a6c2898132158d1f3bb381f02d5f1c03bc50d444d266cda2", + "stdout_hash": "417bc995c9624154c582f31d2ac95e2add9584b1f38373c4c90c9093", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_array_01-682b1b2.stdout b/tests/reference/asr-generics_array_01-682b1b2.stdout index bf421ba55e..1474a84e79 100644 --- a/tests/reference/asr-generics_array_01-682b1b2.stdout +++ b/tests/reference/asr-generics_array_01-682b1b2.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(SubroutineCall 1 use_array () [] ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), i: (Variable 2 i In () () Default (TypeParameter T []) Source Public Required .false.), lst: (Variable 2 lst InOut () () Default (TypeParameter T [(() ())]) Source Public Required .false.)}) f [(Var 2 lst) (Var 2 i)] [(TypeParameter T [])] [(= (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) (Var 2 i) ()) (= (Var 2 _lpython_return_variable) (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), use_array: (Function (SymbolTable 3 {__lpython_generic_f_0: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 4 i In () () Default (Integer 4 []) Source Public Required .false.), lst: (Variable 4 lst InOut () () Default (Integer 4 [(() ())]) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 4 lst) (Var 4 i)] [] [(= (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) (Var 4 i) ()) (= (Var 4 _lpython_return_variable) (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), array: (Variable 3 array Local () () Default (Integer 4 [((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 1 (Integer 4 [])))]) Source Public Required .false.), x: (Variable 3 x Local () () Default (Integer 4 []) Source Public Required .false.)}) use_array [] [] [(= (Var 3 x) (IntegerConstant 69 (Integer 4 [])) ()) (Print () [(FunctionCall 3 __lpython_generic_f_0 () [((Var 3 array)) ((Var 3 x))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.)}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(SubroutineCall 1 use_array () [] ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), i: (Variable 2 i In () () Default (TypeParameter T []) Source Public Required .false.), lst: (Variable 2 lst InOut () () Default (TypeParameter T [(() ())]) Source Public Required .false.)}) f [(Var 2 lst) (Var 2 i)] [(TypeParameter T [(() ())]) (TypeParameter T [])] [(= (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) (Var 2 i) ()) (= (Var 2 _lpython_return_variable) (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), use_array: (Function (SymbolTable 3 {__lpython_generic_f_0: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 4 i In () () Default (Integer 4 []) Source Public Required .false.), lst: (Variable 4 lst InOut () () Default (Integer 4 [(() ())]) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 4 lst) (Var 4 i)] [] [(= (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) (Var 4 i) ()) (= (Var 4 _lpython_return_variable) (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), array: (Variable 3 array Local () () Default (Integer 4 [((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 1 (Integer 4 [])))]) Source Public Required .false.), x: (Variable 3 x Local () () Default (Integer 4 []) Source Public Required .false.)}) use_array [] [] [(= (Var 3 x) (IntegerConstant 69 (Integer 4 [])) ()) (Print () [(FunctionCall 3 __lpython_generic_f_0 () [((Var 3 array)) ((Var 3 x))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.)}) []) From b56279f31cb4a5f8e4d36ac5f53118401365725a Mon Sep 17 00:00:00 2001 From: Lubis Date: Tue, 16 Aug 2022 02:34:20 +0900 Subject: [PATCH 3/9] Refactor to allow llvm compilation of generic subroutines --- integration_tests/CMakeLists.txt | 1 + integration_tests/generics_02.py | 13 +++ src/libasr/codegen/asr_to_llvm.cpp | 8 +- src/libasr/pass/instantiate_template.cpp | 31 +++---- src/lpython/semantics/python_ast_to_asr.cpp | 84 +++++++++++++++++++ tests/reference/asr-generics_02-e2ea5c9.json | 13 +++ .../reference/asr-generics_02-e2ea5c9.stderr | 29 +++++++ .../reference/asr-generics_02-e2ea5c9.stdout | 1 + tests/tests.toml | 4 + 9 files changed, 168 insertions(+), 16 deletions(-) create mode 100644 integration_tests/generics_02.py create mode 100644 tests/reference/asr-generics_02-e2ea5c9.json create mode 100644 tests/reference/asr-generics_02-e2ea5c9.stderr create mode 100644 tests/reference/asr-generics_02-e2ea5c9.stdout diff --git a/integration_tests/CMakeLists.txt b/integration_tests/CMakeLists.txt index e61654d7d1..022350976c 100644 --- a/integration_tests/CMakeLists.txt +++ b/integration_tests/CMakeLists.txt @@ -218,5 +218,6 @@ RUN(NAME test_str_comparison LABELS cpython llvm) RUN(NAME test_bit_length LABELS cpython llvm) RUN(NAME generics_01 LABELS cpython llvm) +RUN(NAME generics_02 LABELS cpython llvm) RUN(NAME generics_array_01 LABELS llvm) RUN(NAME test_statistics LABELS cpython llvm) diff --git a/integration_tests/generics_02.py b/integration_tests/generics_02.py new file mode 100644 index 0000000000..5e36813211 --- /dev/null +++ b/integration_tests/generics_02.py @@ -0,0 +1,13 @@ +from ltypes import TypeVar + +T = TypeVar('T') + +def swap(x: T, y: T): + temp: T + temp = x + x = y + y = temp + print(x) + print(y) + +swap(1,2) \ No newline at end of file diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 19942f59a9..61036d34c6 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -1008,7 +1008,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // Generate function prototypes for (auto &item : x.m_global_scope->get_scope()) { if (is_a(*item.second)) { - visit_Function(*ASR::down_cast(item.second)); + if (ASR::down_cast(item.second)->n_type_params == 0) { + visit_Function(*ASR::down_cast(item.second)); + } } } prototype_only = false; @@ -1028,7 +1030,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // Then do all the procedures for (auto &item : x.m_global_scope->get_scope()) { if (is_a(*item.second)) { - visit_symbol(*item.second); + if (ASR::down_cast(item.second)->n_type_params == 0) { + visit_symbol(*item.second); + } } } diff --git a/src/libasr/pass/instantiate_template.cpp b/src/libasr/pass/instantiate_template.cpp index b916e2700b..7b6a404f06 100644 --- a/src/libasr/pass/instantiate_template.cpp +++ b/src/libasr/pass/instantiate_template.cpp @@ -57,19 +57,22 @@ class FunctionInstantiator : public ASR::BaseExprStmtDuplicator( - (ASR::down_cast(x.m_return_var))->m_v); - std::string return_var_name = return_var->m_name; - ASR::ttype_t *return_param_type = ASRUtils::expr_type(x.m_return_var); - ASR::ttype_t *return_type = ASR::is_a(*return_param_type) ? - subs[ASR::down_cast(return_param_type)->m_param] : return_param_type; - ASR::asr_t *new_return_var = ASR::make_Variable_t(al, return_var->base.base.loc, - current_scope, s2c(al, return_var_name), return_var->m_intent, nullptr, nullptr, - return_var->m_storage, return_type, return_var->m_abi, return_var->m_access, - return_var->m_presence, return_var->m_value_attr); - current_scope->add_symbol(return_var_name, ASR::down_cast(new_return_var)); - ASR::asr_t *new_return_var_ref = ASR::make_Var_t(al, x.base.base.loc, - current_scope->get_symbol(return_var_name)); + ASR::expr_t *new_return_var_ref = nullptr; + if (x.m_return_var != nullptr) { + ASR::Variable_t *return_var = ASR::down_cast( + (ASR::down_cast(x.m_return_var))->m_v); + std::string return_var_name = return_var->m_name; + ASR::ttype_t *return_param_type = ASRUtils::expr_type(x.m_return_var); + ASR::ttype_t *return_type = ASR::is_a(*return_param_type) ? + subs[ASR::down_cast(return_param_type)->m_param] : return_param_type; + ASR::asr_t *new_return_var = ASR::make_Variable_t(al, return_var->base.base.loc, + current_scope, s2c(al, return_var_name), return_var->m_intent, nullptr, nullptr, + return_var->m_storage, return_type, return_var->m_abi, return_var->m_access, + return_var->m_presence, return_var->m_value_attr); + current_scope->add_symbol(return_var_name, ASR::down_cast(new_return_var)); + new_return_var_ref = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, + current_scope->get_symbol(return_var_name))); + } // Rebuild the symbol table for (auto const &sym_pair: x.m_symtab->get_scope()) { @@ -108,7 +111,7 @@ class FunctionInstantiator : public ASR::BaseExprStmtDuplicator { stemp = symtab->get_symbol(local_sym); } } + if (ASR::is_a(*s)) { + ASR::Function_t *func = ASR::down_cast(s); + if (func->n_type_params > 0) { + std::map subs; + for (size_t i=0; im_args[i]); + ASR::ttype_t *arg_type = ASRUtils::expr_type(args[i].m_value); + subs = check_type_substitution(subs, param_type, arg_type, loc); + } + + ASR::symbol_t *t = get_generic_function(subs, *func); + std::string new_call_name = call_name; + if (ASR::is_a(*t)) { + new_call_name = (ASR::down_cast(t))->m_name; + } + return make_call_helper(al, t, current_scope, args, new_call_name, loc); + } + if (ASR::down_cast(s)->m_return_var != nullptr) { + ASR::ttype_t *a_type = nullptr; + if( func->m_elemental && args.size() == 1 && + ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) { + a_type = ASRUtils::expr_type(args[0].m_value); + } else { + a_type = ASRUtils::expr_type(func->m_return_var); + a_type = handle_return_type(a_type, loc, args, func); + } + ASR::expr_t *value = nullptr; + if (ASRUtils::is_intrinsic_function2(func)) { + value = intrinsic_procedures.comptime_eval(call_name, al, loc, args); + } + if (args.size() != func->n_args) { + std::string fnd = std::to_string(args.size()); + std::string org = std::to_string(func->n_args); + diag.add(diag::Diagnostic( + "Number of arguments does not match in the function call", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label("(found: '" + fnd + "', expected: '" + org + "')", + {loc}) + }) + ); + throw SemanticAbort(); + } + Vec args_new; + args_new.reserve(al, func->n_args); + visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args); + ASR::asr_t* func_call_asr = ASR::make_FunctionCall_t(al, loc, stemp, + s_generic, args_new.p, args_new.size(), + a_type, value, nullptr); + if( ignore_return_value ) { + std::string dummy_ret_name = current_scope->get_unique_name("__lcompilers_dummy"); + ASR::asr_t* variable_asr = ASR::make_Variable_t(al, loc, current_scope, + s2c(al, dummy_ret_name), ASR::intentType::Local, + nullptr, nullptr, ASR::storage_typeType::Default, + a_type, ASR::abiType::Source, ASR::accessType::Public, + ASR::presenceType::Required, false); + ASR::symbol_t* variable_sym = ASR::down_cast(variable_asr); + current_scope->add_symbol(dummy_ret_name, variable_sym); + ASR::expr_t* variable_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, variable_sym)); + return ASR::make_Assignment_t(al, loc, variable_var, ASRUtils::EXPR(func_call_asr), nullptr); + } else { + return func_call_asr; + } + } else { + ASR::Function_t *func = ASR::down_cast(s); + if (args.size() != func->n_args) { + std::string fnd = std::to_string(args.size()); + std::string org = std::to_string(func->n_args); + diag.add(diag::Diagnostic( + "Number of arguments does not match in the function call", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label("(found: '" + fnd + "', expected: '" + org + "')", + {loc}) + }) + ); + throw SemanticAbort(); + } + Vec args_new; + args_new.reserve(al, func->n_args); + visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args); + return ASR::make_SubroutineCall_t(al, loc, stemp, + s_generic, args_new.p, args_new.size(), nullptr); + } + /* if (ASR::is_a(*s) && ASR::down_cast(s)->m_return_var != nullptr) { ASR::Function_t *func = ASR::down_cast(s); @@ -796,6 +879,7 @@ class CommonVisitor : public AST::BaseVisitor { visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args); return ASR::make_SubroutineCall_t(al, loc, stemp, s_generic, args_new.p, args_new.size(), nullptr); + */ } else if(ASR::is_a(*s)) { Vec args_new; args_new.reserve(al, args.size()); diff --git a/tests/reference/asr-generics_02-e2ea5c9.json b/tests/reference/asr-generics_02-e2ea5c9.json new file mode 100644 index 0000000000..bb920614a0 --- /dev/null +++ b/tests/reference/asr-generics_02-e2ea5c9.json @@ -0,0 +1,13 @@ +{ + "basename": "asr-generics_02-e2ea5c9", + "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", + "infile": "tests/../integration_tests/generics_02.py", + "infile_hash": "6f748cbf059da328ff092c08ad0063e639ba460eb481fadfadeebc51", + "outfile": null, + "outfile_hash": null, + "stdout": "asr-generics_02-e2ea5c9.stdout", + "stdout_hash": "f4786afb7bbad3bb3865af598e1e08481673b2b62f95b1b63ac53bd7", + "stderr": null, + "stderr_hash": null, + "returncode": 0 +} \ No newline at end of file diff --git a/tests/reference/asr-generics_02-e2ea5c9.stderr b/tests/reference/asr-generics_02-e2ea5c9.stderr new file mode 100644 index 0000000000..082f2c3c35 --- /dev/null +++ b/tests/reference/asr-generics_02-e2ea5c9.stderr @@ -0,0 +1,29 @@ +Internal Compiler Error: Unhandled exception +Traceback (most recent call last): + Binary file "$DIR/src/bin/lpython", in _start() + Binary file "/lib/x86_64-linux-gnu/libc.so.6", in __libc_start_main() + File "$DIR/src/bin/lpython.cpp", line 1011, in ?? + return emit_asr(arg_file, lpython_pass_manager, runtime_library_dir, + File "$DIR/src/bin/lpython.cpp", line 161, in ?? + compiler_options.disable_main, compiler_options.symtab_only, infile); + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 4588, in LFortran::LPython::python_ast_to_asr(Allocator&, LFortran::LPython::AST::ast_t&, LFortran::diag::Diagnostics&, bool, bool, bool, std::__cxx11::basic_string, std::allocator >) + ast_overload); + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 4514, in LFortran::LPython::body_visitor(Allocator&, LFortran::LPython::AST::Module_t const&, LFortran::diag::Diagnostics&, LFortran::ASR::asr_t*, bool, std::map, std::allocator > >&) + b.visit_Module(ast); + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 2746, in LFortran::LPython::BodyVisitor::visit_Module(LFortran::LPython::AST::Module_t const&) + visit_stmt(*x.m_body[i]); + File "$DIR/src/lpython/python_ast.h", line 1882, in LFortran::LPython::AST::BaseVisitor::visit_stmt(LFortran::LPython::AST::stmt_t const&) + void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); } + File "$DIR/src/lpython/python_ast.h", line 1772, in ?? + case stmtType::Expr: { v.visit_Expr((const Expr_t &)x); return; } + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 3847, in LFortran::LPython::BodyVisitor::visit_Expr(LFortran::LPython::AST::Expr_t const&) + tmp = make_call_helper(al, s, current_scope, args, call_name, + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 727, in LFortran::LPython::CommonVisitor::make_call_helper(Allocator&, LFortran::ASR::symbol_t*, LFortran::SymbolTable*, LFortran::Vec, std::__cxx11::basic_string, std::allocator >, LFortran::Location const&, bool) + ASR::symbol_t *t = get_generic_function(subs, *func); + File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 976, in LFortran::LPython::CommonVisitor::get_generic_function(std::map, std::allocator >, LFortran::ASR::ttype_t*, std::less, std::allocator > >, std::allocator, std::allocator > const, LFortran::ASR::ttype_t*> > >, LFortran::ASR::Function_t&) + t = pass_instantiate_generic_function(al, subs, current_scope, new_function_num, func); + File "$DIR/src/libasr/pass/instantiate_template.cpp", line 327, in LFortran::pass_instantiate_generic_function(Allocator&, std::map, std::allocator >, LFortran::ASR::ttype_t*, std::less, std::allocator > >, std::allocator, std::allocator > const, LFortran::ASR::ttype_t*> > >, LFortran::SymbolTable*, int, LFortran::ASR::Function_t&) + ASR::asr_t *new_function = tf.instantiate_Function(func); + File "$DIR/src/libasr/pass/instantiate_template.cpp", line 61, in LFortran::FunctionInstantiator::instantiate_Function(LFortran::ASR::Function_t&) + (ASR::down_cast(x.m_return_var))->m_v); +AssertFailed: f != nullptr diff --git a/tests/reference/asr-generics_02-e2ea5c9.stdout b/tests/reference/asr-generics_02-e2ea5c9.stdout new file mode 100644 index 0000000000..6bf9230752 --- /dev/null +++ b/tests/reference/asr-generics_02-e2ea5c9.stdout @@ -0,0 +1 @@ +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_swap_0: (Function (SymbolTable 3 {temp: (Variable 3 temp Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_swap_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 temp) (Var 3 x) ()) (= (Var 3 x) (Var 3 y) ()) (= (Var 3 y) (Var 3 temp) ()) (Print () [(Var 3 x)] () ()) (Print () [(Var 3 y)] () ())] () Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 5 {}) _lpython_main_program [] [] [(SubroutineCall 1 __lpython_generic_swap_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] ())] () Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 4 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), swap: (Function (SymbolTable 2 {temp: (Variable 2 temp Local () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) swap [(Var 2 x) (Var 2 y)] [(TypeParameter T []) (TypeParameter T [])] [(= (Var 2 temp) (Var 2 x) ()) (= (Var 2 x) (Var 2 y) ()) (= (Var 2 y) (Var 2 temp) ()) (Print () [(Var 2 x)] () ()) (Print () [(Var 2 y)] () ())] () Source Public Implementation () .false. .false. .false.)}) []) diff --git a/tests/tests.toml b/tests/tests.toml index 6d97422ec3..4336541a13 100644 --- a/tests/tests.toml +++ b/tests/tests.toml @@ -377,6 +377,10 @@ cpp = true filename = "../integration_tests/generics_01.py" asr = true +[[test]] +filename = "../integration_tests/generics_02.py" +asr = true + [[test]] filename = "../integration_tests/generics_array_01.py" asr = true From 35f08d0e6badbd5211c37536f6849dd0a2085565 Mon Sep 17 00:00:00 2001 From: Lubis Date: Tue, 16 Aug 2022 03:39:53 +0900 Subject: [PATCH 4/9] Refactor type parameters inclusion into function definitions, updates tests --- integration_tests/generics_01.py | 2 -- src/libasr/asr_utils.h | 16 ++++++++++++++++ src/lpython/semantics/python_ast_to_asr.cpp | 19 ++++++++++++++----- tests/reference/asr-generics_01-d616074.json | 4 ++-- .../reference/asr-generics_01-d616074.stdout | 2 +- tests/reference/asr-generics_02-e2ea5c9.json | 2 +- .../reference/asr-generics_02-e2ea5c9.stdout | 2 +- .../asr-generics_array_01-682b1b2.json | 2 +- .../asr-generics_array_01-682b1b2.stdout | 2 +- 9 files changed, 37 insertions(+), 14 deletions(-) diff --git a/integration_tests/generics_01.py b/integration_tests/generics_01.py index 57591d733e..310c04d7bb 100644 --- a/integration_tests/generics_01.py +++ b/integration_tests/generics_01.py @@ -6,5 +6,3 @@ def f(x: T, y: T) -> T: return x + y print(f(1,2)) -print(f("a","b")) -print(f("c","d")) diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index b47fb6e7b2..56ec6af347 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -1169,6 +1169,22 @@ static inline ASR::ttype_t* duplicate_type_without_dims(Allocator& al, const ASR return ASRUtils::TYPE(ASR::make_Integer_t(al, t->base.loc, tnew->m_kind, nullptr, 0)); } + case ASR::ttypeType::Real: { + ASR::Real_t* tnew = ASR::down_cast(t); + return ASRUtils::TYPE(ASR::make_Real_t(al, t->base.loc, + tnew->m_kind, nullptr, 0)); + } + case ASR::ttypeType::Character: { + ASR::Character_t* tnew = ASR::down_cast(t); + return ASRUtils::TYPE(ASR::make_Character_t(al, t->base.loc, + tnew->m_kind, tnew->m_len, tnew->m_len_expr, + nullptr, 0)); + } + case ASR::ttypeType::TypeParameter: { + ASR::TypeParameter_t* tp = ASR::down_cast(t); + return ASRUtils::TYPE(ASR::make_TypeParameter_t(al, t->base.loc, + tp->m_param, nullptr, 0)); + } default : throw LCompilersException("Not implemented " + std::to_string(t->type)); } } diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index fac7d5e942..e3d5304692 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -2354,7 +2354,6 @@ class SymbolTableVisitor : public CommonVisitor { current_procedure_abi_type = ASR::abiType::Source; bool current_procedure_interface = false; bool overload = false; - std::set ps; Vec tps; tps.reserve(al, x.m_args.n_args); bool vectorize = false; @@ -2393,10 +2392,20 @@ class SymbolTableVisitor : public CommonVisitor { ASR::ttype_t *arg_type = ast_expr_to_asr_type(x.base.base.loc, *x.m_args.m_args[i].m_annotation); // Set the function as generic if an argument is typed with a type parameter if (ASRUtils::is_generic(*arg_type)) { - std::string param_name = ASRUtils::get_parameter_name(arg_type); - ps.insert(param_name); - ASR::ttype_t *tp = ASRUtils::duplicate_type(al, ASRUtils::get_type_parameter(arg_type)); - tps.push_back(al, tp); + ASR::ttype_t *new_tt = ASRUtils::duplicate_type_without_dims(al, ASRUtils::get_type_parameter(arg_type)); + size_t current_size = tps.size(); + if (current_size == 0) { + tps.push_back(al, new_tt); + } else { + for (size_t i = 0; i < current_size; i++) { + ASR::TypeParameter_t *added_tp = ASR::down_cast(tps.p[i]); + std::string new_param = ASR::down_cast(new_tt)->m_param; + std::string added_param = added_tp->m_param; + if (added_param.compare(new_param) != 0) { + tps.push_back(al, new_tt); + } + } + } } std::string arg_s = arg; diff --git a/tests/reference/asr-generics_01-d616074.json b/tests/reference/asr-generics_01-d616074.json index 4d166472e1..56dcc9479a 100644 --- a/tests/reference/asr-generics_01-d616074.json +++ b/tests/reference/asr-generics_01-d616074.json @@ -2,11 +2,11 @@ "basename": "asr-generics_01-d616074", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/../integration_tests/generics_01.py", - "infile_hash": "0f59efff2093384b031f16a8473077c30aa7c53fc28041d87311de64", + "infile_hash": "8822c985a1b11c6c02fabc700c281ad017a8ed16525977c846e41eb4", "outfile": null, "outfile_hash": null, "stdout": "asr-generics_01-d616074.stdout", - "stdout_hash": "996d4e1de29da6f9e90fadfb1687c6d81f5e9eaee27420db1a2692aa", + "stdout_hash": "336288ef67802887ea4a9fb183babd474b0c67968bd5cc15bee9d4e0", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_01-d616074.stdout b/tests/reference/asr-generics_01-d616074.stdout index 803f022c83..d2456a96b0 100644 --- a/tests/reference/asr-generics_01-d616074.stdout +++ b/tests/reference/asr-generics_01-d616074.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), __lpython_generic_f_1: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Character 1 1 () []) Source Public Required .false.), x: (Variable 4 x In () () Default (Character 1 1 () []) Source Public Required .false.), y: (Variable 4 y In () () Default (Character 1 1 () []) Source Public Required .false.)}) __lpython_generic_f_1 [(Var 4 x) (Var 4 y)] [] [(= (Var 4 _lpython_return_variable) (StringConcat (Var 4 x) (Var 4 y) (Character 1 2 () []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "a" (Character 1 1 () []))) ((StringConstant "b" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "c" (Character 1 1 () []))) ((StringConstant "d" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T []) (TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 5 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 4 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) diff --git a/tests/reference/asr-generics_02-e2ea5c9.json b/tests/reference/asr-generics_02-e2ea5c9.json index bb920614a0..311573d1be 100644 --- a/tests/reference/asr-generics_02-e2ea5c9.json +++ b/tests/reference/asr-generics_02-e2ea5c9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_02-e2ea5c9.stdout", - "stdout_hash": "f4786afb7bbad3bb3865af598e1e08481673b2b62f95b1b63ac53bd7", + "stdout_hash": "5e109b8427357ce9883ef4927ac34a69330c4948dde307af0a92de9c", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_02-e2ea5c9.stdout b/tests/reference/asr-generics_02-e2ea5c9.stdout index 6bf9230752..c669a0f382 100644 --- a/tests/reference/asr-generics_02-e2ea5c9.stdout +++ b/tests/reference/asr-generics_02-e2ea5c9.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_swap_0: (Function (SymbolTable 3 {temp: (Variable 3 temp Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_swap_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 temp) (Var 3 x) ()) (= (Var 3 x) (Var 3 y) ()) (= (Var 3 y) (Var 3 temp) ()) (Print () [(Var 3 x)] () ()) (Print () [(Var 3 y)] () ())] () Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 5 {}) _lpython_main_program [] [] [(SubroutineCall 1 __lpython_generic_swap_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] ())] () Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 4 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), swap: (Function (SymbolTable 2 {temp: (Variable 2 temp Local () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) swap [(Var 2 x) (Var 2 y)] [(TypeParameter T []) (TypeParameter T [])] [(= (Var 2 temp) (Var 2 x) ()) (= (Var 2 x) (Var 2 y) ()) (= (Var 2 y) (Var 2 temp) ()) (Print () [(Var 2 x)] () ()) (Print () [(Var 2 y)] () ())] () Source Public Implementation () .false. .false. .false.)}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_swap_0: (Function (SymbolTable 3 {temp: (Variable 3 temp Local () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_swap_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 temp) (Var 3 x) ()) (= (Var 3 x) (Var 3 y) ()) (= (Var 3 y) (Var 3 temp) ()) (Print () [(Var 3 x)] () ()) (Print () [(Var 3 y)] () ())] () Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 5 {}) _lpython_main_program [] [] [(SubroutineCall 1 __lpython_generic_swap_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] ())] () Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 4 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), swap: (Function (SymbolTable 2 {temp: (Variable 2 temp Local () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) swap [(Var 2 x) (Var 2 y)] [(TypeParameter T [])] [(= (Var 2 temp) (Var 2 x) ()) (= (Var 2 x) (Var 2 y) ()) (= (Var 2 y) (Var 2 temp) ()) (Print () [(Var 2 x)] () ()) (Print () [(Var 2 y)] () ())] () Source Public Implementation () .false. .false. .false.)}) []) diff --git a/tests/reference/asr-generics_array_01-682b1b2.json b/tests/reference/asr-generics_array_01-682b1b2.json index 6ff5e3e858..f078783e1b 100644 --- a/tests/reference/asr-generics_array_01-682b1b2.json +++ b/tests/reference/asr-generics_array_01-682b1b2.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_array_01-682b1b2.stdout", - "stdout_hash": "417bc995c9624154c582f31d2ac95e2add9584b1f38373c4c90c9093", + "stdout_hash": "e953b223a6c2898132158d1f3bb381f02d5f1c03bc50d444d266cda2", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_array_01-682b1b2.stdout b/tests/reference/asr-generics_array_01-682b1b2.stdout index 1474a84e79..bf421ba55e 100644 --- a/tests/reference/asr-generics_array_01-682b1b2.stdout +++ b/tests/reference/asr-generics_array_01-682b1b2.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(SubroutineCall 1 use_array () [] ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), i: (Variable 2 i In () () Default (TypeParameter T []) Source Public Required .false.), lst: (Variable 2 lst InOut () () Default (TypeParameter T [(() ())]) Source Public Required .false.)}) f [(Var 2 lst) (Var 2 i)] [(TypeParameter T [(() ())]) (TypeParameter T [])] [(= (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) (Var 2 i) ()) (= (Var 2 _lpython_return_variable) (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), use_array: (Function (SymbolTable 3 {__lpython_generic_f_0: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 4 i In () () Default (Integer 4 []) Source Public Required .false.), lst: (Variable 4 lst InOut () () Default (Integer 4 [(() ())]) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 4 lst) (Var 4 i)] [] [(= (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) (Var 4 i) ()) (= (Var 4 _lpython_return_variable) (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), array: (Variable 3 array Local () () Default (Integer 4 [((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 1 (Integer 4 [])))]) Source Public Required .false.), x: (Variable 3 x Local () () Default (Integer 4 []) Source Public Required .false.)}) use_array [] [] [(= (Var 3 x) (IntegerConstant 69 (Integer 4 [])) ()) (Print () [(FunctionCall 3 __lpython_generic_f_0 () [((Var 3 array)) ((Var 3 x))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.)}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(SubroutineCall 1 use_array () [] ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), i: (Variable 2 i In () () Default (TypeParameter T []) Source Public Required .false.), lst: (Variable 2 lst InOut () () Default (TypeParameter T [(() ())]) Source Public Required .false.)}) f [(Var 2 lst) (Var 2 i)] [(TypeParameter T [])] [(= (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) (Var 2 i) ()) (= (Var 2 _lpython_return_variable) (ArrayItem (Var 2 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())]), use_array: (Function (SymbolTable 3 {__lpython_generic_f_0: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), i: (Variable 4 i In () () Default (Integer 4 []) Source Public Required .false.), lst: (Variable 4 lst InOut () () Default (Integer 4 [(() ())]) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 4 lst) (Var 4 i)] [] [(= (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) (Var 4 i) ()) (= (Var 4 _lpython_return_variable) (ArrayItem (Var 4 lst) [(() (IntegerConstant 0 (Integer 4 [])) ())] (Integer 4 []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), array: (Variable 3 array Local () () Default (Integer 4 [((IntegerConstant 0 (Integer 4 [])) (IntegerConstant 1 (Integer 4 [])))]) Source Public Required .false.), x: (Variable 3 x Local () () Default (Integer 4 []) Source Public Required .false.)}) use_array [] [] [(= (Var 3 x) (IntegerConstant 69 (Integer 4 [])) ()) (Print () [(FunctionCall 3 __lpython_generic_f_0 () [((Var 3 array)) ((Var 3 x))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.)}) []) From a0b983bb58df5e6f0adc6975ac0012066012d885 Mon Sep 17 00:00:00 2001 From: Lubis Date: Thu, 18 Aug 2022 00:28:03 +0900 Subject: [PATCH 5/9] Updated tests --- integration_tests/generics_01.py | 2 ++ tests/reference/asr-generics_01-d616074.json | 4 +-- .../reference/asr-generics_01-d616074.stdout | 2 +- .../reference/asr-generics_02-e2ea5c9.stderr | 29 ------------------- tests/reference/cpp-expr3-9c516d4.json | 13 --------- 5 files changed, 5 insertions(+), 45 deletions(-) delete mode 100644 tests/reference/asr-generics_02-e2ea5c9.stderr delete mode 100644 tests/reference/cpp-expr3-9c516d4.json diff --git a/integration_tests/generics_01.py b/integration_tests/generics_01.py index 310c04d7bb..668a660535 100644 --- a/integration_tests/generics_01.py +++ b/integration_tests/generics_01.py @@ -6,3 +6,5 @@ def f(x: T, y: T) -> T: return x + y print(f(1,2)) +print(f("a","b")) +print(f("c","d")) \ No newline at end of file diff --git a/tests/reference/asr-generics_01-d616074.json b/tests/reference/asr-generics_01-d616074.json index 56dcc9479a..8614089c65 100644 --- a/tests/reference/asr-generics_01-d616074.json +++ b/tests/reference/asr-generics_01-d616074.json @@ -2,11 +2,11 @@ "basename": "asr-generics_01-d616074", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/../integration_tests/generics_01.py", - "infile_hash": "8822c985a1b11c6c02fabc700c281ad017a8ed16525977c846e41eb4", + "infile_hash": "31be30b9dc205898cd50f371f39c81bbc31149a0823043f0597f07b3", "outfile": null, "outfile_hash": null, "stdout": "asr-generics_01-d616074.stdout", - "stdout_hash": "336288ef67802887ea4a9fb183babd474b0c67968bd5cc15bee9d4e0", + "stdout_hash": "9f748f982d651e6706e00bbf46909c4661cf2be40e7ebd25b30ca7fe", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_01-d616074.stdout b/tests/reference/asr-generics_01-d616074.stdout index d2456a96b0..33c0f7a977 100644 --- a/tests/reference/asr-generics_01-d616074.stdout +++ b/tests/reference/asr-generics_01-d616074.stdout @@ -1 +1 @@ -(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 5 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 4 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) +(TranslationUnit (SymbolTable 1 {T: (Variable 1 T Local () () Default (TypeParameter T []) Source Public Required .false.), __lpython_generic_f_0: (Function (SymbolTable 3 {_lpython_return_variable: (Variable 3 _lpython_return_variable ReturnVar () () Default (Integer 4 []) Source Public Required .false.), x: (Variable 3 x In () () Default (Integer 4 []) Source Public Required .false.), y: (Variable 3 y In () () Default (Integer 4 []) Source Public Required .false.)}) __lpython_generic_f_0 [(Var 3 x) (Var 3 y)] [] [(= (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) Add (Var 3 y) (Integer 4 []) ()) ()) (Return)] (Var 3 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), __lpython_generic_f_1: (Function (SymbolTable 4 {_lpython_return_variable: (Variable 4 _lpython_return_variable ReturnVar () () Default (Character 1 1 () []) Source Public Required .false.), x: (Variable 4 x In () () Default (Character 1 1 () []) Source Public Required .false.), y: (Variable 4 y In () () Default (Character 1 1 () []) Source Public Required .false.)}) __lpython_generic_f_1 [(Var 4 x) (Var 4 y)] [] [(= (Var 4 _lpython_return_variable) (StringConcat (Var 4 x) (Var 4 y) (Character 1 2 () []) ()) ()) (Return)] (Var 4 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), _lpython_main_program: (Function (SymbolTable 6 {}) _lpython_main_program [] [] [(Print () [(FunctionCall 1 __lpython_generic_f_0 () [((IntegerConstant 1 (Integer 4 []))) ((IntegerConstant 2 (Integer 4 [])))] (Integer 4 []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "a" (Character 1 1 () []))) ((StringConstant "b" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ()) (Print () [(FunctionCall 1 __lpython_generic_f_1 () [((StringConstant "c" (Character 1 1 () []))) ((StringConstant "d" (Character 1 1 () [])))] (Character 1 1 () []) () ())] () ())] () Source Public Implementation () .false. .false. .false.), f: (Function (SymbolTable 2 {_lpython_return_variable: (Variable 2 _lpython_return_variable ReturnVar () () Default (TypeParameter T []) Source Public Required .false.), x: (Variable 2 x In () () Default (TypeParameter T []) Source Public Required .false.), y: (Variable 2 y In () () Default (TypeParameter T []) Source Public Required .false.)}) f [(Var 2 x) (Var 2 y)] [(TypeParameter T [])] [(= (Var 2 _lpython_return_variable) (TemplateBinOp (Var 2 x) Add (Var 2 y) (TypeParameter T []) ()) ()) (Return)] (Var 2 _lpython_return_variable) Source Public Implementation () .false. .false. .false.), main_program: (Program (SymbolTable 5 {}) main_program [] [(SubroutineCall 1 _lpython_main_program () [] ())])}) []) diff --git a/tests/reference/asr-generics_02-e2ea5c9.stderr b/tests/reference/asr-generics_02-e2ea5c9.stderr deleted file mode 100644 index 082f2c3c35..0000000000 --- a/tests/reference/asr-generics_02-e2ea5c9.stderr +++ /dev/null @@ -1,29 +0,0 @@ -Internal Compiler Error: Unhandled exception -Traceback (most recent call last): - Binary file "$DIR/src/bin/lpython", in _start() - Binary file "/lib/x86_64-linux-gnu/libc.so.6", in __libc_start_main() - File "$DIR/src/bin/lpython.cpp", line 1011, in ?? - return emit_asr(arg_file, lpython_pass_manager, runtime_library_dir, - File "$DIR/src/bin/lpython.cpp", line 161, in ?? - compiler_options.disable_main, compiler_options.symtab_only, infile); - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 4588, in LFortran::LPython::python_ast_to_asr(Allocator&, LFortran::LPython::AST::ast_t&, LFortran::diag::Diagnostics&, bool, bool, bool, std::__cxx11::basic_string, std::allocator >) - ast_overload); - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 4514, in LFortran::LPython::body_visitor(Allocator&, LFortran::LPython::AST::Module_t const&, LFortran::diag::Diagnostics&, LFortran::ASR::asr_t*, bool, std::map, std::allocator > >&) - b.visit_Module(ast); - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 2746, in LFortran::LPython::BodyVisitor::visit_Module(LFortran::LPython::AST::Module_t const&) - visit_stmt(*x.m_body[i]); - File "$DIR/src/lpython/python_ast.h", line 1882, in LFortran::LPython::AST::BaseVisitor::visit_stmt(LFortran::LPython::AST::stmt_t const&) - void visit_stmt(const stmt_t &b) { visit_stmt_t(b, self()); } - File "$DIR/src/lpython/python_ast.h", line 1772, in ?? - case stmtType::Expr: { v.visit_Expr((const Expr_t &)x); return; } - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 3847, in LFortran::LPython::BodyVisitor::visit_Expr(LFortran::LPython::AST::Expr_t const&) - tmp = make_call_helper(al, s, current_scope, args, call_name, - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 727, in LFortran::LPython::CommonVisitor::make_call_helper(Allocator&, LFortran::ASR::symbol_t*, LFortran::SymbolTable*, LFortran::Vec, std::__cxx11::basic_string, std::allocator >, LFortran::Location const&, bool) - ASR::symbol_t *t = get_generic_function(subs, *func); - File "$DIR/src/lpython/semantics/python_ast_to_asr.cpp", line 976, in LFortran::LPython::CommonVisitor::get_generic_function(std::map, std::allocator >, LFortran::ASR::ttype_t*, std::less, std::allocator > >, std::allocator, std::allocator > const, LFortran::ASR::ttype_t*> > >, LFortran::ASR::Function_t&) - t = pass_instantiate_generic_function(al, subs, current_scope, new_function_num, func); - File "$DIR/src/libasr/pass/instantiate_template.cpp", line 327, in LFortran::pass_instantiate_generic_function(Allocator&, std::map, std::allocator >, LFortran::ASR::ttype_t*, std::less, std::allocator > >, std::allocator, std::allocator > const, LFortran::ASR::ttype_t*> > >, LFortran::SymbolTable*, int, LFortran::ASR::Function_t&) - ASR::asr_t *new_function = tf.instantiate_Function(func); - File "$DIR/src/libasr/pass/instantiate_template.cpp", line 61, in LFortran::FunctionInstantiator::instantiate_Function(LFortran::ASR::Function_t&) - (ASR::down_cast(x.m_return_var))->m_v); -AssertFailed: f != nullptr diff --git a/tests/reference/cpp-expr3-9c516d4.json b/tests/reference/cpp-expr3-9c516d4.json deleted file mode 100644 index fa9e9258d6..0000000000 --- a/tests/reference/cpp-expr3-9c516d4.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "basename": "cpp-expr3-9c516d4", - "cmd": "lpython --no-color --show-cpp {infile}", - "infile": "tests/expr3.py", - "infile_hash": "4fbbd9ddebefcc9afdd6fdc17e16313fafc5b3e214595d6ad62c10cb", - "outfile": null, - "outfile_hash": null, - "stdout": null, - "stdout_hash": null, - "stderr": "cpp-expr3-9c516d4.stderr", - "stderr_hash": "715f5ea03b41d70718afea8c302485a5cf9e2602b87293bebd147d43", - "returncode": 2 -} \ No newline at end of file From a4d99a46657981375cc1abb95a10172ce171122c Mon Sep 17 00:00:00 2001 From: Lubis Date: Thu, 18 Aug 2022 13:36:59 +0900 Subject: [PATCH 6/9] Refactoring --- src/libasr/pass/instantiate_template.cpp | 3 +- src/lpython/semantics/python_ast_to_asr.cpp | 93 ++------------------- 2 files changed, 8 insertions(+), 88 deletions(-) diff --git a/src/libasr/pass/instantiate_template.cpp b/src/libasr/pass/instantiate_template.cpp index 7b6a404f06..a2317c6b7f 100644 --- a/src/libasr/pass/instantiate_template.cpp +++ b/src/libasr/pass/instantiate_template.cpp @@ -63,8 +63,7 @@ class FunctionInstantiator : public ASR::BaseExprStmtDuplicator(x.m_return_var))->m_v); std::string return_var_name = return_var->m_name; ASR::ttype_t *return_param_type = ASRUtils::expr_type(x.m_return_var); - ASR::ttype_t *return_type = ASR::is_a(*return_param_type) ? - subs[ASR::down_cast(return_param_type)->m_param] : return_param_type; + ASR::ttype_t *return_type = substitute_type(return_param_type); ASR::asr_t *new_return_var = ASR::make_Variable_t(al, return_var->base.base.loc, current_scope, s2c(al, return_var_name), return_var->m_intent, nullptr, nullptr, return_var->m_storage, return_type, return_var->m_abi, return_var->m_access, diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index e3d5304692..acddcdf9c6 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -796,90 +796,6 @@ class CommonVisitor : public AST::BaseVisitor { return ASR::make_SubroutineCall_t(al, loc, stemp, s_generic, args_new.p, args_new.size(), nullptr); } - /* - if (ASR::is_a(*s) && - ASR::down_cast(s)->m_return_var != nullptr) { - ASR::Function_t *func = ASR::down_cast(s); - if (func->n_type_params == 0) { - ASR::ttype_t *a_type = nullptr; - if( func->m_elemental && args.size() == 1 && - ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) { - a_type = ASRUtils::expr_type(args[0].m_value); - } else { - a_type = ASRUtils::expr_type(func->m_return_var); - a_type = handle_return_type(a_type, loc, args, func); - } - ASR::expr_t *value = nullptr; - if (ASRUtils::is_intrinsic_function2(func)) { - value = intrinsic_procedures.comptime_eval(call_name, al, loc, args); - } - if (args.size() != func->n_args) { - std::string fnd = std::to_string(args.size()); - std::string org = std::to_string(func->n_args); - diag.add(diag::Diagnostic( - "Number of arguments does not match in the function call", - diag::Level::Error, diag::Stage::Semantic, { - diag::Label("(found: '" + fnd + "', expected: '" + org + "')", - {loc}) - }) - ); - throw SemanticAbort(); - } - Vec args_new; - args_new.reserve(al, func->n_args); - visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args); - ASR::asr_t* func_call_asr = ASR::make_FunctionCall_t(al, loc, stemp, - s_generic, args_new.p, args_new.size(), - a_type, value, nullptr); - if( ignore_return_value ) { - std::string dummy_ret_name = current_scope->get_unique_name("__lcompilers_dummy"); - ASR::asr_t* variable_asr = ASR::make_Variable_t(al, loc, current_scope, - s2c(al, dummy_ret_name), ASR::intentType::Local, - nullptr, nullptr, ASR::storage_typeType::Default, - a_type, ASR::abiType::Source, ASR::accessType::Public, - ASR::presenceType::Required, false); - ASR::symbol_t* variable_sym = ASR::down_cast(variable_asr); - current_scope->add_symbol(dummy_ret_name, variable_sym); - ASR::expr_t* variable_var = ASRUtils::EXPR(ASR::make_Var_t(al, loc, variable_sym)); - return ASR::make_Assignment_t(al, loc, variable_var, ASRUtils::EXPR(func_call_asr), nullptr); - } else { - return func_call_asr; - } - } else { - std::map subs; - for (size_t i=0; im_args[i]); - ASR::ttype_t *arg_type = ASRUtils::expr_type(args[i].m_value); - subs = check_type_substitution(subs, param_type, arg_type, loc); - } - - ASR::symbol_t *t = get_generic_function(subs, *func); - std::string new_call_name = call_name; - if (ASR::is_a(*t)) { - new_call_name = (ASR::down_cast(t))->m_name; - } - return make_call_helper(al, t, current_scope, args, new_call_name, loc); - } - } else if (ASR::is_a(*s)) { - ASR::Function_t *func = ASR::down_cast(s); - if (args.size() != func->n_args) { - std::string fnd = std::to_string(args.size()); - std::string org = std::to_string(func->n_args); - diag.add(diag::Diagnostic( - "Number of arguments does not match in the function call", - diag::Level::Error, diag::Stage::Semantic, { - diag::Label("(found: '" + fnd + "', expected: '" + org + "')", - {loc}) - }) - ); - throw SemanticAbort(); - } - Vec args_new; - args_new.reserve(al, func->n_args); - visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args); - return ASR::make_SubroutineCall_t(al, loc, stemp, - s_generic, args_new.p, args_new.size(), nullptr); - */ } else if(ASR::is_a(*s)) { Vec args_new; args_new.reserve(al, args.size()); @@ -2397,14 +2313,19 @@ class SymbolTableVisitor : public CommonVisitor { if (current_size == 0) { tps.push_back(al, new_tt); } else { + bool not_found = true; for (size_t i = 0; i < current_size; i++) { ASR::TypeParameter_t *added_tp = ASR::down_cast(tps.p[i]); std::string new_param = ASR::down_cast(new_tt)->m_param; std::string added_param = added_tp->m_param; - if (added_param.compare(new_param) != 0) { - tps.push_back(al, new_tt); + if (added_param.compare(new_param) == 0) { + not_found = false; + break; } } + if (not_found) { + tps.push_back(al, new_tt); + } } } From d522be6d4dfd52eb80a213838733a82b19bab320 Mon Sep 17 00:00:00 2001 From: Lubis Date: Thu, 18 Aug 2022 13:44:45 +0900 Subject: [PATCH 7/9] Modify function instantiation to accept names, not number --- src/libasr/pass/instantiate_template.cpp | 17 +++++++---------- src/libasr/pass/instantiate_template.h | 2 +- src/lpython/semantics/python_ast_to_asr.cpp | 5 +++-- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/libasr/pass/instantiate_template.cpp b/src/libasr/pass/instantiate_template.cpp index a2317c6b7f..952256bed8 100644 --- a/src/libasr/pass/instantiate_template.cpp +++ b/src/libasr/pass/instantiate_template.cpp @@ -11,23 +11,20 @@ class FunctionInstantiator : public ASR::BaseExprStmtDuplicator subs; - int new_function_num; + std::string new_func_name; FunctionInstantiator(Allocator &al, std::map subs, - SymbolTable *current_scope, int new_function_num): + SymbolTable *current_scope, std::string new_func_name): BaseExprStmtDuplicator(al), current_scope{current_scope}, subs{subs}, - new_function_num{new_function_num} + new_func_name{new_func_name} {} ASR::asr_t* instantiate_Function(ASR::Function_t &x) { SymbolTable *parent_scope = current_scope; current_scope = al.make_new(parent_scope); - std::string func_name = x.m_name; - func_name = "__lpython_generic_" + func_name + "_" + std::to_string(new_function_num); - Vec args; args.reserve(al, x.n_args); for (size_t i=0; i(result); - parent_scope->add_symbol(func_name, t); + parent_scope->add_symbol(new_func_name, t); current_scope = parent_scope; return result; @@ -324,8 +321,8 @@ class FunctionInstantiator : public ASR::BaseExprStmtDuplicator subs, - SymbolTable *current_scope, int new_function_num, ASR::Function_t &func) { - FunctionInstantiator tf(al, subs, current_scope, new_function_num); + SymbolTable *current_scope, std::string new_func_name, ASR::Function_t &func) { + FunctionInstantiator tf(al, subs, current_scope, new_func_name); ASR::asr_t *new_function = tf.instantiate_Function(func); return ASR::down_cast(new_function); } diff --git a/src/libasr/pass/instantiate_template.h b/src/libasr/pass/instantiate_template.h index 0c9d9130ae..f6752da200 100644 --- a/src/libasr/pass/instantiate_template.h +++ b/src/libasr/pass/instantiate_template.h @@ -6,7 +6,7 @@ namespace LFortran { ASR::symbol_t* pass_instantiate_generic_function(Allocator &al, std::map subs, - SymbolTable *current_scope, int new_function_num, ASR::Function_t &func); + SymbolTable *current_scope, std::string new_func_name, ASR::Function_t &func); } #endif // LFORTRAN_PASS_TEMPLATE_VISITOR_H \ No newline at end of file diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index acddcdf9c6..127e6bcc9c 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -888,8 +888,9 @@ class CommonVisitor : public AST::BaseVisitor { new_function_num = 0; } generic_func_nums[func_name] = new_function_num + 1; - generic_func_subs["__lpython_generic_" + func_name + "_" + std::to_string(new_function_num)] = subs; - t = pass_instantiate_generic_function(al, subs, current_scope, new_function_num, func); + std::string new_func_name = "__lpython_generic_" + func_name + "_" + std::to_string(new_function_num); + generic_func_subs[new_func_name] = subs; + t = pass_instantiate_generic_function(al, subs, current_scope, new_func_name, func); return t; } From 3a00c204b34dd1af547909a15bdfcfdc4e05a8e8 Mon Sep 17 00:00:00 2001 From: Lubis Date: Thu, 18 Aug 2022 16:27:41 +0900 Subject: [PATCH 8/9] Removed whitespace --- src/lpython/semantics/python_ast_to_asr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index 127e6bcc9c..8f70605531 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -775,7 +775,7 @@ class CommonVisitor : public AST::BaseVisitor { return ASR::make_Assignment_t(al, loc, variable_var, ASRUtils::EXPR(func_call_asr), nullptr); } else { return func_call_asr; - } + } } else { ASR::Function_t *func = ASR::down_cast(s); if (args.size() != func->n_args) { From a47dda0ea55ca69a959ce9e070407326ebd7bd1b Mon Sep 17 00:00:00 2001 From: Lubis Date: Thu, 18 Aug 2022 16:36:04 +0900 Subject: [PATCH 9/9] Reverted generics test and update test --- integration_tests/generics_01.py | 2 +- tests/reference/asr-generics_01-d616074.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_tests/generics_01.py b/integration_tests/generics_01.py index 668a660535..57591d733e 100644 --- a/integration_tests/generics_01.py +++ b/integration_tests/generics_01.py @@ -7,4 +7,4 @@ def f(x: T, y: T) -> T: print(f(1,2)) print(f("a","b")) -print(f("c","d")) \ No newline at end of file +print(f("c","d")) diff --git a/tests/reference/asr-generics_01-d616074.json b/tests/reference/asr-generics_01-d616074.json index 8614089c65..43bf9e825b 100644 --- a/tests/reference/asr-generics_01-d616074.json +++ b/tests/reference/asr-generics_01-d616074.json @@ -2,7 +2,7 @@ "basename": "asr-generics_01-d616074", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/../integration_tests/generics_01.py", - "infile_hash": "31be30b9dc205898cd50f371f39c81bbc31149a0823043f0597f07b3", + "infile_hash": "0f59efff2093384b031f16a8473077c30aa7c53fc28041d87311de64", "outfile": null, "outfile_hash": null, "stdout": "asr-generics_01-d616074.stdout",