diff --git a/.gitignore b/.gitignore index 267f5ee03c..5b860ba55d 100644 --- a/.gitignore +++ b/.gitignore @@ -187,6 +187,7 @@ extsrc/ tmp/ tmpdebug/ gentests/ +inst/ ## Ninja build.ninja diff --git a/build0.sh b/build0.sh index 7218d748b7..a69126a45e 100755 --- a/build0.sh +++ b/build0.sh @@ -13,6 +13,8 @@ python src/libasr/asdl_cpp.py grammar/Python.asdl src/lpython/python_ast.h python src/libasr/asdl_cpp.py src/libasr/ASR.asdl src/libasr/asr.h # Generate a wasm_visitor.h from src/libasr/wasm_instructions.txt (C++) python src/libasr/wasm_instructions_visitor.py +# Generate the intrinsic_function_registry_util.h (C++) +python src/libasr/intrinsic_func_registry_util_gen.py # Generate the tokenizer and parser (cd src/lpython/parser && re2c -W -b tokenizer.re -o tokenizer.cpp) diff --git a/integration_tests/symbolics_11.py b/integration_tests/symbolics_11.py index 0db1030209..49696c09c2 100644 --- a/integration_tests/symbolics_11.py +++ b/integration_tests/symbolics_11.py @@ -16,4 +16,4 @@ def test_extraction_of_elements(): print(ele1, ele2, ele3, ele4) print(l1[0], l1[1], l1[2], l1[3]) -test_extraction_of_elements() \ No newline at end of file +test_extraction_of_elements() diff --git a/integration_tests/test_c_interop_01.py b/integration_tests/test_c_interop_01.py index 8bef275267..278e49a7ea 100644 --- a/integration_tests/test_c_interop_01.py +++ b/integration_tests/test_c_interop_01.py @@ -9,14 +9,6 @@ def _lfortran_dsin(x: f64) -> f64: def _lfortran_ssin(x: f32) -> f32: pass -@ccall -def _lfortran_bgt32(i: i32, j: i32) -> i32: - pass - -@ccall -def _lfortran_bgt64(i: i64, j: i64) -> i32: - pass - #@ccall #def _lfortran_random_number(n: i64, v: f64[:]): # pass @@ -28,9 +20,4 @@ def test_c_callbacks(): assert abs(_lfortran_ssin(f32(pi)) - f32(0.0)) < f32(1e-6) assert abs(_lfortran_ssin(f32(pi/2.0)) - f32(1.0)) < f32(1e-6) - assert _lfortran_bgt32(3, 4) == 0 - assert _lfortran_bgt32(4, 3) == 1 - assert _lfortran_bgt64(i64(3), i64(4)) == 0 - assert _lfortran_bgt64(i64(4), i64(3)) == 1 - test_c_callbacks() diff --git a/integration_tests/test_list_reserve.py b/integration_tests/test_list_reserve.py index 9c074c351d..f359d7547d 100644 --- a/integration_tests/test_list_reserve.py +++ b/integration_tests/test_list_reserve.py @@ -6,25 +6,25 @@ def test_list_reserve(): i: i32 reserve(l1, 100) - for i in range(50): - l1.append(i) - assert len(l1) == i + 1 + # for i in range(50): + # l1.append(i) + # assert len(l1) == i + 1 - reserve(l1, 150) + # reserve(l1, 150) - for i in range(50): - l1.pop(0) - assert len(l1) == 49 - i + # for i in range(50): + # l1.pop(0) + # assert len(l1) == 49 - i - reserve(l2, 100) - for i in range(50): - l2.append([(f64(i * i), str(i), (i, f64(i + 1))), (f64(i), str(i), (i, f64(i)))]) - assert len(l2) == i + 1 + # reserve(l2, 100) + # for i in range(50): + # l2.append([(f64(i * i), str(i), (i, f64(i + 1))), (f64(i), str(i), (i, f64(i)))]) + # assert len(l2) == i + 1 - reserve(l2, 150) + # reserve(l2, 150) - for i in range(50): - l2.pop(0) - assert len(l2) == 49 - i + # for i in range(50): + # l2.pop(0) + # assert len(l2) == 49 - i test_list_reserve() diff --git a/integration_tests/test_list_reverse.py b/integration_tests/test_list_reverse.py index 35d1feeeaa..ca8595756c 100644 --- a/integration_tests/test_list_reverse.py +++ b/integration_tests/test_list_reverse.py @@ -36,7 +36,7 @@ def test_list_reverse(): l3.reverse() assert l3 == l4 j += 0.1 - + l5 = ["abcd", "efgh", "ijkl"] for s in l5: l6.reverse() @@ -44,7 +44,7 @@ def test_list_reverse(): l7.append(s) l6.reverse() assert l6 == l7 - + l8 = [[1, 2], [3, 4, 5], [6, 7, 8, 9], [10]] l8.reverse() assert l8 == [[10], [6, 7, 8, 9], [3, 4, 5], [1, 2]] @@ -54,4 +54,4 @@ def test_list_reverse(): assert l9 == [(5, 6.0, "ghi"), (3, 4.0, "def"), (1, 2.0, "abc")] -test_list_reverse() \ No newline at end of file +test_list_reverse() diff --git a/integration_tests/test_str_attributes.py b/integration_tests/test_str_attributes.py index b211014a69..0a55e9e801 100755 --- a/integration_tests/test_str_attributes.py +++ b/integration_tests/test_str_attributes.py @@ -1,10 +1,13 @@ def capitalize(): s: str s = "tom and jerry" + print(s.capitalize()) assert s.capitalize() == "Tom and jerry" s = "12wddd" + print(s) assert s.capitalize() == s s = " tom and jerry" + print(s.capitalize()) assert s.capitalize() == s assert "empty string" .capitalize() == "Empty string" assert "".capitalize() == "" @@ -76,14 +79,17 @@ def count(): sub: str s = "ABC ABCDAB ABCDABCDABDE" sub = "ABC" + print(s.count(sub), s.count("ABC")) assert s.count(sub) == 4 assert s.count("ABC") == 4 - + sub = "AB" + print(s.count(sub), s.count("AB")) assert s.count(sub) == 6 assert s.count("AB") == 6 sub = "ABC" + print("ABC ABCDAB ABCDABCDABDE".count(sub), "ABC ABCDAB ABCDABCDABDE".count("ABC")) assert "ABC ABCDAB ABCDABCDABDE".count(sub) == 4 assert "ABC ABCDAB ABCDABCDABDE".count("ABC") == 4 @@ -342,7 +348,7 @@ def is_title(): res4: bool = d.istitle() res5: bool = e.istitle() assert res == True - assert res2 == False + assert res2 == False assert res3 == False assert res4 == True assert res5 == False diff --git a/run_tests.py b/run_tests.py index 8f2e980550..9366396345 100755 --- a/run_tests.py +++ b/run_tests.py @@ -10,7 +10,7 @@ def single_test(test, verbose, no_llvm, skip_run_with_dbg, skip_cpptranslate, update_reference, - no_color, specific_backends=None, excluded_backends=None): + verify_hash, no_color, specific_backends=None, excluded_backends=None): filename = test["filename"] def is_included(backend): return test.get(backend, False) \ diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl index 020354c612..d31b2d95dd 100644 --- a/src/libasr/ASR.asdl +++ b/src/libasr/ASR.asdl @@ -1,177 +1,30 @@ -- Abstract Semantic Representation (ASR) definition --- The aim of ASR is to represent all semantics in a non-redundant way, and that --- has all the semantic information available locally, so that the backend can --- do a single pass over ASR and have all the information at hand to generate --- code. --- --- ASR is always semantically valid Fortran code. It is as far from the original --- Fortran language code as possible (i.e. everything is explicitly figured out, --- all semantic information gathered and readily available locally from each ASR --- node), while ensuring no semantic information was lost (no lowering was --- done), so one can still generate Fortran code from ASR that will be logically --- equivalent to the original code. --- --- ASR can be used to do Fortran level transformations (such as optimizations). - --- ASDL's builtin types are: --- * identifier --- * int (signed integers of infinite precision) --- * string --- We extend these by: --- * bool (.true. / .false.) --- * float (floating point number of infinite precision) --- * symbol_table (scoped Symbol Table implementation) --- * node (any ASR node) --- --- Note: `symbol_table` contains `identifier` -> `symbol` mappings. +-- Documenations are available at: +-- https://github.com/lfortran/lfortran/tree/main/doc/src/asr/asr.md module ASR { unit = TranslationUnit(symbol_table symtab, node* items) --- # Documentation for the symbol type - --- Each symbol has either `symtab` (local symbol table) or `parent_symtab` --- (where this symbol is stored). One can get to parent_symtab via symtab, so --- only one is present. - --- Each symbol has a `name` for easy lookup of the name of the symbol when only --- having a pointer to it. - --- abi=Source means the symbol's implementation is included (full ASR), --- otherwise it is external (interface ASR, such as procedure interface). - --- SubroutineCall/FunctionCall store the actual final resolved subroutine or --- function (`name` member). They also store the original symbol --- (`original_name`), which can be one of: null, GenericProcedure or --- ExternalSymbol. - --- When a module is compiled, it is parsed into full ASR, an object file is --- produced, the full ASR (abi=Source, "body" is non-empty) is transformed into --- interface ASR (abi=LFortran, "body" is empty). Both interface and full ASR --- is saved into the mod file. - --- When a module is used, it is first looked up in the symbol table (as either --- full or interface ASR) and used if it is present. Otherwise a mod file is --- found on the disk, loaded (as either full or interface ASR for LFortran's --- mod file, depending on LFortran's compiler options; or for GFortran's mod --- file the corresponding interface ASR is constructed with abi=GFortran) and --- used. After the ASR is loaded, the symbols that are used are represented as --- ExternalSymbols in the current scope of the symbol table. - --- ExternalSymbol represents symbols that cannot be looked up in the current --- scoped symbol table. As an example, if a variable is defined in a module, --- but used in a nested subroutine, that is not an external symbol --- because it can be resolved in the current symbol table (nested subroutine) --- by following the parents. However if a symbol is used from a different --- module, then it is an external symbol, because usual symbol resolution by --- going to the parents will not find the definition. The `module_name` member --- is the name of the module the symbol is in, the `scope_names` is a list of --- names if the symbol is in a nested symbol table. For example if it is a --- local variable in a function `f` that is nested in function `g`, then --- `scope_names=[g, f]`. - --- REPL: each cell is parsed into full ASR, compiled + executed, the full ASR --- is transformed into interface ASR (abi=LFortran) and kept in the symbol --- table. A new cell starts with an empty symbol table, whose parent symbol --- table is the previous cell. That allows function / declaration shadowing. - - symbol - = Program(symbol_table symtab, identifier name, identifier* dependencies, - stmt* body) - | Module(symbol_table symtab, identifier name, identifier* dependencies, - bool loaded_from_mod, bool intrinsic) - | Function(symbol_table symtab, identifier name, ttype function_signature, - identifier* dependencies, expr* args, stmt* body, expr? return_var, - access access, bool deterministic, bool side_effect_free, string? module_file) - | GenericProcedure(symbol_table parent_symtab, identifier name, - symbol* procs, access access) - | CustomOperator(symbol_table parent_symtab, identifier name, - symbol* procs, access access) - | ExternalSymbol(symbol_table parent_symtab, identifier name, - symbol external, identifier module_name, identifier* scope_names, - identifier original_name, access access) - | StructType(symbol_table symtab, identifier name, identifier* dependencies, - identifier* members, abi abi, access access, bool is_packed, bool is_abstract, - call_arg* initializers, expr? alignment, symbol? parent) - | EnumType(symbol_table symtab, identifier name, identifier* dependencies, - identifier* members, abi abi, access access, enumtype enum_value_type, - ttype type, symbol? parent) - | UnionType(symbol_table symtab, identifier name, identifier* dependencies, - identifier* members, abi abi, access access, call_arg* initializers, symbol? parent) - | Variable(symbol_table parent_symtab, identifier name, identifier* dependencies, - intent intent, expr? symbolic_value, expr? value, storage_type storage, - ttype type, symbol? type_declaration, - abi abi, access access, presence presence, bool value_attr) + = Program(symbol_table symtab, identifier name, identifier* dependencies, stmt* body) + | Module(symbol_table symtab, identifier name, identifier* dependencies, bool loaded_from_mod, bool intrinsic) + | Function(symbol_table symtab, identifier name, ttype function_signature, identifier* dependencies, expr* args, stmt* body, expr? return_var, access access, bool deterministic, bool side_effect_free, string? module_file) + | GenericProcedure(symbol_table parent_symtab, identifier name, symbol* procs, access access) + | CustomOperator(symbol_table parent_symtab, identifier name, symbol* procs, access access) + | ExternalSymbol(symbol_table parent_symtab, identifier name, symbol external, identifier module_name, identifier* scope_names, identifier original_name, access access) + | StructType(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, bool is_packed, bool is_abstract, call_arg* initializers, expr? alignment, symbol? parent) + | EnumType(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, enumtype enum_value_type, ttype type, symbol? parent) + | UnionType(symbol_table symtab, identifier name, identifier* dependencies, identifier* members, abi abi, access access, call_arg* initializers, symbol? parent) + | Variable(symbol_table parent_symtab, identifier name, identifier* dependencies, intent intent, expr? symbolic_value, expr? value, storage_type storage, ttype type, symbol? type_declaration, abi abi, access access, presence presence, bool value_attr) | ClassType(symbol_table symtab, identifier name, abi abi, access access) - | ClassProcedure(symbol_table parent_symtab, identifier name, identifier? self_argument, - identifier proc_name, symbol proc, abi abi, bool is_deferred) + | ClassProcedure(symbol_table parent_symtab, identifier name, identifier? self_argument, identifier proc_name, symbol proc, abi abi, bool is_deferred, bool is_nopass) | AssociateBlock(symbol_table symtab, identifier name, stmt* body) | Block(symbol_table symtab, identifier name, stmt* body) - | Requirement(symbol_table symtab, identifier name, identifier* args, - require_instantiation* requires) - | Template(symbol_table symtab, identifier name, identifier* args, - require_instantiation* requires) - -storage_type = Default | Save | Parameter -access = Public | Private -intent = Local | In | Out | InOut | ReturnVar | Unspecified -deftype = Implementation | Interface -presence = Required | Optional - --- # Documentation for the ABI type - --- External Yes: the symbol's implementation is not part of ASR, the --- symbol is just an interface (e.g., subroutine/function interface, or variable --- marked as external, not allocated by this ASR). - --- External No: the symbol's implementation is part of ASR (e.g., --- subroutine/function body is included, variables must be allocated). - --- abi=Source: The symbol's implementation is included in ASR, the backend is --- free to use any ABI it wants (it might also decide to inline or eliminate --- the code in optimizations). - --- abi=LFortranModule/GFortranModule/BindC: the symbol's implementation is --- stored as machine code in some object file that must be linked in. It --- uses the specified ABI (one of LFortran module, GFortran module or C ABI). --- An interface that uses `iso_c_binding` and `bind(c)` is represented using --- abi=BindC. - --- abi=BindPython: the symbol's implementation is --- stored in text format in the user source code file. --- The symbol is executed using the CPython interpreter. --- LPython manages the conversion of arguments to be passed to such symbols --- and also converts the return values from such symbols. - --- abi=BindJS: the symbol's implementation is --- available with Javascript. --- This abi type is to be mainly used with the WASM Backend. - --- abi=Interactive: the symbol's implementation has been provided by the --- previous REPL execution (e.g., if LLVM backend is used for the interactive --- mode, the previous execution generated machine code for this symbol's --- implementation that was loaded into memory). Note: this option might be --- converted/eliminated to just use LFortran ABI in the future. - --- abi=Intrinsic: the symbol's implementation is implicitly provided by the --- language itself as an intrinsic function. That means the backend is free to --- implement it in any way it wants. The function does not have a body, it is --- just an interface. - -abi -- External ABI - = Source -- No Unspecified - | LFortranModule -- Yes LFortran - | GFortranModule -- Yes GFortran - | BindC -- Yes C - | BindPython -- Yes Python - | BindJS -- Yes Javascript - | Interactive -- Yes Unspecified - | Intrinsic -- Yes Unspecified - + | Requirement(symbol_table symtab, identifier name, identifier* args, require_instantiation* requires) + | Template(symbol_table symtab, identifier name, identifier* args, require_instantiation* requires) stmt = Allocate(alloc_arg* args, expr? stat, expr? errmsg, expr? source) @@ -180,44 +33,31 @@ stmt | Assignment(expr target, expr value, stmt? overloaded) | Associate(expr target, expr value) | Cycle(identifier? stmt_name) - -- deallocates if allocated otherwise throws a runtime error | ExplicitDeallocate(expr* vars) - -- deallocates if allocated otherwise does nothing | ImplicitDeallocate(expr* vars) | DoConcurrentLoop(do_loop_head head, stmt* body) | DoLoop(identifier? name, do_loop_head head, stmt* body, stmt* orelse) | ErrorStop(expr? code) | Exit(identifier? stmt_name) | ForAllSingle(do_loop_head head, stmt assign_stmt) - -- GoTo points to a GoToTarget with the corresponding target_id within - -- the same procedure. We currently use `int` IDs to link GoTo with - -- GoToTarget to avoid issues with serialization. | GoTo(int target_id, identifier name) - -- An empty statement, a target of zero or more GoTo statements - -- the `id` is only unique within a procedure | GoToTarget(int id, identifier name) | If(expr test, stmt* body, stmt* orelse) | IfArithmetic(expr test, int lt_label, int eq_label, int gt_label) | Print(expr* values, expr? separator, expr? end) | FileOpen(int label, expr? newunit, expr? filename, expr? status, expr? form) | FileClose(int label, expr? unit, expr? iostat, expr? iomsg, expr? err, expr? status) - | FileRead(int label, expr? unit, expr? fmt, expr? iomsg, expr? iostat, expr? id, expr* values) + | FileRead(int label, expr? unit, expr? fmt, expr? iomsg, expr? iostat, expr? size, expr? id, expr* values, stmt? overloaded) | FileBackspace(int label, expr? unit, expr? iostat, expr? err) | FileRewind(int label, expr? unit, expr? iostat, expr? err) - | FileInquire(int label, expr? unit, expr? file, expr? iostat, expr? err, - expr? exist, expr? opened, expr? number, expr? named, - expr? name, expr? access, expr? sequential, expr? direct, - expr? form, expr? formatted, expr? unformatted, expr? recl, - expr? nextrec, expr? blank, expr? position, expr? action, - expr? read, expr? write, expr? readwrite, expr? delim, - expr? pad, expr? flen, expr? blocksize, expr? convert, - expr? carriagecontrol, expr? iolength) - | FileWrite(int label, expr? unit, expr? iomsg, expr? iostat, expr? id, expr* values, expr? separator, expr? end) + | FileInquire(int label, expr? unit, expr? file, expr? iostat, expr? err, expr? exist, expr? opened, expr? number, expr? named, expr? name, expr? access, expr? sequential, expr? direct, expr? form, expr? formatted, expr? unformatted, expr? recl, expr? nextrec, expr? blank, expr? position, expr? action, expr? read, expr? write, expr? readwrite, expr? delim, expr? pad, expr? flen, expr? blocksize, expr? convert, expr? carriagecontrol, expr? iolength) + | FileWrite(int label, expr? unit, expr? iomsg, expr? iostat, expr? id, expr* values, expr? separator, expr? end, stmt? overloaded) | Return() - | Select(expr test, case_stmt* body, stmt* default) + | Select(expr test, case_stmt* body, stmt* default, bool enable_fall_through) | Stop(expr? code) | Assert(expr test, expr? msg) | SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt) + | IntrinsicImpureSubroutine(int intrinsic_id, expr* args, int overload_id) | Where(expr test, stmt* body, stmt* orelse) | WhileLoop(identifier? name, expr test, stmt* body, stmt* orelse) | Nullify(symbol* vars) @@ -235,25 +75,19 @@ stmt | DictInsert(expr a, expr key, expr value) | Expr(expr expression) - expr = IfExp(expr test, expr body, expr orelse, ttype type, expr? value) - -- Such as: (x, y+z), (3.0, 2.0) generally not known at compile time | ComplexConstructor(expr re, expr im, ttype type, expr? value) | NamedExpr(expr target, expr value, ttype type) - | FunctionCall(symbol name, symbol? original_name, call_arg* args, - ttype type, expr? value, expr? dt) - | IntrinsicScalarFunction(int intrinsic_id, expr* args, int overload_id, - ttype? type, expr? value) - | IntrinsicArrayFunction(int arr_intrinsic_id, expr* args, int overload_id, - ttype? type, expr? value) - | IntrinsicImpureFunction(int impure_intrinsic_id, expr* args, int overload_id, - ttype? type, expr? value) + | FunctionCall(symbol name, symbol? original_name, call_arg* args, ttype type, expr? value, expr? dt) + | IntrinsicElementalFunction(int intrinsic_id, expr* args, int overload_id, ttype? type, expr? value) + | IntrinsicArrayFunction(int arr_intrinsic_id, expr* args, int overload_id, ttype? type, expr? value) + | IntrinsicImpureFunction(int impure_intrinsic_id, expr* args, int overload_id, ttype? type, expr? value) + | TypeInquiry(int inquiry_id, ttype arg_type, expr? arg, ttype type, expr value) | StructTypeConstructor(symbol dt_sym, call_arg* args, ttype type, expr? value) | EnumTypeConstructor(symbol dt_sym, expr* args, ttype type, expr? value) | UnionTypeConstructor(symbol dt_sym, expr* args, ttype type, expr? value) - | ImpliedDoLoop(expr* values, expr var, expr start, expr end, - expr? increment, ttype type, expr? value) + | ImpliedDoLoop(expr* values, expr var, expr start, expr end, expr? increment, ttype type, expr? value) | IntegerConstant(int n, ttype type) | IntegerBOZ(int v, integerboz intboz_type, ttype? type) | IntegerBitNot(expr arg, ttype type, expr? value) @@ -278,21 +112,17 @@ expr | LogicalNot(expr arg, ttype type, expr? value) | LogicalCompare(expr left, cmpop op, expr right, ttype type, expr? value) | LogicalBinOp(expr left, logicalbinop op, expr right, ttype type, expr? value) - | ListConstant(expr* args, ttype type) | ListLen(expr arg, ttype type, expr? value) | ListConcat(expr left, expr right, ttype type, expr? value) | ListCompare(expr left, cmpop op, expr right, ttype type, expr? value) | ListCount(expr arg, expr ele, ttype type, expr? value) - | SetConstant(expr* elements, ttype type) | SetLen(expr arg, ttype type, expr? value) - | TupleConstant(expr* elements, ttype type) | TupleLen(expr arg, ttype type, expr value) | TupleCompare(expr left, cmpop op, expr right, ttype type, expr? value) | TupleConcat(expr left, expr right, ttype type, expr? value) - | StringConstant(string s, ttype type) | StringConcat(expr left, expr right, ttype type, expr? value) | StringRepeat(expr left, expr right, ttype type, expr? value) @@ -303,28 +133,23 @@ expr | StringOrd(expr arg, ttype type, expr? value) | StringChr(expr arg, ttype type, expr? value) | StringFormat(expr fmt, expr* args, string_format_kind kind, ttype type, expr? value) - | CPtrCompare(expr left, cmpop op, expr right, ttype type, expr? value) | SymbolicCompare(expr left, cmpop op, expr right, ttype type, expr? value) - | DictConstant(expr* keys, expr* values, ttype type) | DictLen(expr arg, ttype type, expr? value) - | Var(symbol v) - | FunctionParam(int param_number, ttype type, expr? value) --- used in types - + | FunctionParam(int param_number, ttype type, expr? value) + | ArrayConstructor(expr* args, ttype type, expr? value, arraystorage storage_format) | ArrayConstant(expr* args, ttype type, arraystorage storage_format) | ArrayItem(expr v, array_index* args, ttype type, arraystorage storage_format, expr? value) | ArraySection(expr v, array_index* args, ttype type, expr? value) | ArraySize(expr v, expr? dim, ttype type, expr? value) - | ArrayBound(expr v, expr? dim, ttype type, arraybound bound, - expr? value) + | ArrayBound(expr v, expr? dim, ttype type, arraybound bound, expr? value) | ArrayTranspose(expr matrix, ttype type, expr? value) | ArrayPack(expr array, expr mask, expr? vector, ttype type, expr? value) | ArrayReshape(expr array, expr shape, ttype type, expr? value) | ArrayAll(expr mask, expr? dim, ttype type, expr? value) | ArrayBroadcast(expr array, expr shape, ttype type, expr? value) - | BitCast(expr source, expr mold, expr? size, ttype type, expr? value) | StructInstanceMember(expr v, symbol m, ttype type, expr? value) | StructStaticMember(expr v, symbol m, ttype type, expr? value) @@ -335,21 +160,8 @@ expr | OverloadedCompare(expr left, cmpop op, expr right, ttype type, expr? value, expr overloaded) | OverloadedBinOp(expr left, binop op, expr right, ttype type, expr? value, expr overloaded) | OverloadedUnaryMinus(expr arg, ttype type, expr? value, expr overloaded) - -- This Cast changes the value (the bits) of the `arg`: + | OverloadedStringConcat(expr left, expr right, ttype type, expr? value, expr overloaded) | Cast(expr arg, cast_kind kind, ttype type, expr? value) - -- This ArrayPhysicalCast we only change the physical type, the logical type does not change - -- Note: the "new" physical type here will also be part of the "type" member - -- This allow to represent any combination, but we'll only support a few, at least we need: - -- Maybe it's easier to add an enumeration here: - -- Descriptor -> Pointer - -- Pointer -> Descriptor - - -- CompileTimeFixedSizeArray -> Pointer - -- CompileTimeFixedSizeArray -> Descriptor - -- Descriptor -> NumPy - -- NumPy -> Descriptor - -- ISODescriptor -> Descriptor - -- Descriptor -> ISODescriptor | ArrayPhysicalCast(expr arg, array_physical_type old, array_physical_type new, ttype type, expr? value) | ComplexRe(expr arg, ttype type, expr? value) | ComplexIm(expr arg, ttype type, expr? value) @@ -366,33 +178,10 @@ expr | IntegerBitLen(expr a, ttype type, expr? value) | Ichar(expr arg, ttype type, expr? value) | Iachar(expr arg, ttype type, expr? value) - | SizeOfType(ttype arg, ttype type, expr? value) - | PointerNullConstant(ttype type) | PointerAssociated(expr ptr, expr? tgt, ttype type, expr? value) - - | IntrinsicFunctionSqrt(expr arg, ttype type, expr? value) - - --- `len` in Character: --- >=0 ... the length of the string, known at compile time --- -1 ... character(*), i.e., inferred at runtime --- -2 ... character(:), allocatable (possibly we might use -1 for that also) --- -3 ... character(n+3), i.e., a runtime expression stored in `len_expr` - --- kind: The `kind` member selects the kind of a given type. We currently --- support the following: --- Integer kinds: 1 (i8), 2 (i16), 4 (i32), 8 (i64) --- Real kinds: 4 (f32), 8 (f64) --- Complex kinds: 4 (c32), 8 (c64) --- Character kinds: 1 (utf8 string) --- Logical kinds: 1, 2, 4: (boolean represented by 1, 2, 4 bytes; the default --- kind is 4, just like the default integer kind, consistent with Python --- and Fortran: in Python "Booleans in Python are implemented as a subclass --- of integers", in Fortran the "default logical kind has the same storage --- size as the default integer"; we currently use kind=4 as default --- integer, so we also use kind=4 for the default logical.) + | RealSqrt(expr arg, ttype type, expr? value) ttype = Integer(int kind) @@ -416,96 +205,34 @@ ttype | SymbolicExpression() | TypeParameter(identifier param) | Array(ttype type, dimension* dims, array_physical_type physical_type) - | FunctionType(ttype* arg_types, ttype? return_var_type, - abi abi, deftype deftype, string? bindc_name, bool elemental, - bool pure, bool module, bool inline, bool static, - symbol* restrictions, bool is_restriction) - --- TODO: prefix the enumerators here, improve the names -array_physical_type - = DescriptorArray - | PointerToDataArray - | UnboundedPointerToDataArray - | FixedSizeArray - | NumPyArray - | ISODescriptorArray - | SIMDArray - -binop = Add | Sub | Mul | Div | Pow | BitAnd | BitOr | BitXor | BitLShift | BitRShift - -logicalbinop = And | Or | Xor | NEqv | Eqv - -cmpop = Eq | NotEq | Lt | LtE | Gt | GtE - -integerboz = Binary | Hex | Octal - -arraybound = LBound | UBound - -arraystorage = RowMajor | ColMajor - -cast_kind - = RealToInteger - | IntegerToReal - | LogicalToReal - | RealToReal - | IntegerToInteger - | RealToComplex - | IntegerToComplex - | IntegerToLogical - | RealToLogical - | CharacterToLogical - | CharacterToInteger - | CharacterToList - | ComplexToLogical - | ComplexToComplex - | ComplexToReal - | ComplexToInteger - | LogicalToInteger - | RealToCharacter - | IntegerToCharacter - | LogicalToCharacter - | UnsignedIntegerToInteger - | UnsignedIntegerToUnsignedInteger - | UnsignedIntegerToReal - | UnsignedIntegerToLogical - | IntegerToUnsignedInteger - | RealToUnsignedInteger - | CPtrToUnsignedInteger - | UnsignedIntegerToCPtr - | IntegerToSymbolicExpression + | FunctionType(ttype* arg_types, ttype? return_var_type, abi abi, deftype deftype, string? bindc_name, bool elemental, bool pure, bool module, bool inline, bool static, symbol* restrictions, bool is_restriction) +cast_kind = RealToInteger | IntegerToReal | LogicalToReal | RealToReal | IntegerToInteger | RealToComplex | IntegerToComplex | IntegerToLogical | RealToLogical | CharacterToLogical | CharacterToInteger | CharacterToList | ComplexToLogical | ComplexToComplex | ComplexToReal | ComplexToInteger | LogicalToInteger | RealToCharacter | IntegerToCharacter | LogicalToCharacter | UnsignedIntegerToInteger | UnsignedIntegerToUnsignedInteger | UnsignedIntegerToReal | UnsignedIntegerToLogical | IntegerToUnsignedInteger | RealToUnsignedInteger | CPtrToUnsignedInteger | UnsignedIntegerToCPtr | IntegerToSymbolicExpression | ListToArray +storage_type = Default | Save | Parameter +access = Public | Private +intent = Local | In | Out | InOut | ReturnVar | Unspecified +deftype = Implementation | Interface +presence = Required | Optional +abi = Source | LFortranModule | GFortranModule | BindC | BindPython | BindJS | Interactive | Intrinsic dimension = (expr? start, expr? length) - alloc_arg = (expr a, dimension* dims, expr? len_expr, ttype? type) - attribute = Attribute(identifier name, attribute_arg *args) - attribute_arg = (identifier arg) - call_arg = (expr? value) - tbind = Bind(string lang, string name) - array_index = (expr? left, expr? right, expr? step) - do_loop_head = (expr? v, expr? start, expr? end, expr? increment) - -case_stmt = CaseStmt(expr* test, stmt* body) | CaseStmt_Range(expr? start, expr? end, stmt* body) - -type_stmt - = TypeStmtName(symbol sym, stmt* body) - | ClassStmt(symbol sym, stmt* body) - | TypeStmtType(ttype type, stmt* body) - +case_stmt = CaseStmt(expr* test, stmt* body, bool fall_through) | CaseStmt_Range(expr? start, expr? end, stmt* body) +type_stmt = TypeStmtName(symbol sym, stmt* body) | ClassStmt(symbol sym, stmt* body) | TypeStmtType(ttype type, stmt* body) enumtype = IntegerConsecutiveFromZero | IntegerUnique | IntegerNotUnique | NonInteger - require_instantiation = Require(identifier name, identifier* args) - -string_format_kind - = FormatFortran -- "(f8.3,i4.2)", a, b - | FormatC -- "%f: %d", a, b - | FormatPythonPercent -- "%f: %d" % (a, b) - | FormatPythonFString -- f"{a}: {b}" - | FormatPythonFormat -- "{}: {}".format(a, b) +array_physical_type = DescriptorArray | PointerToDataArray | UnboundedPointerToDataArray | FixedSizeArray | CharacterArraySinglePointer | NumPyArray | ISODescriptorArray | SIMDArray +binop = Add | Sub | Mul | Div | Pow | BitAnd | BitOr | BitXor | BitLShift | BitRShift +logicalbinop = And | Or | Xor | NEqv | Eqv +cmpop = Eq | NotEq | Lt | LtE | Gt | GtE +integerboz = Binary | Hex | Octal +arraybound = LBound | UBound +arraystorage = RowMajor | ColMajor +string_format_kind = FormatFortran | FormatC | FormatPythonPercent | FormatPythonFString | FormatPythonFormat } diff --git a/src/libasr/CMakeLists.txt b/src/libasr/CMakeLists.txt index d7c9b89adc..aaf9db92c8 100644 --- a/src/libasr/CMakeLists.txt +++ b/src/libasr/CMakeLists.txt @@ -31,6 +31,7 @@ set(SRC pass/nested_vars.cpp pass/where.cpp + pass/function_call_in_declaration.cpp pass/param_to_const.cpp pass/do_loops.cpp pass/for_all.cpp @@ -53,6 +54,7 @@ set(SRC pass/div_to_mul.cpp pass/replace_symbolic.cpp pass/intrinsic_function.cpp + pass/intrinsic_subroutine.cpp pass/fma.cpp pass/loop_vectorise.cpp pass/sign_from_value.cpp @@ -66,6 +68,7 @@ set(SRC pass/pass_compare.cpp pass/unique_symbols.cpp pass/insert_deallocate.cpp + pass/promote_allocatable_to_nonallocatable.cpp asr_verify.cpp asr_utils.cpp @@ -113,3 +116,10 @@ endif() if (WITH_LLVM) target_link_libraries(asr p::llvm) endif() + +# Install the dwarf_convert.py and dat_convert.py +install( + FILES dwarf_convert.py dat_convert.py + PERMISSIONS OWNER_EXECUTE OWNER_READ + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/lfortran +) diff --git a/src/libasr/asdl_cpp.py b/src/libasr/asdl_cpp.py index 0efdcaaf05..9463cb9d1f 100644 --- a/src/libasr/asdl_cpp.py +++ b/src/libasr/asdl_cpp.py @@ -450,7 +450,7 @@ def make_visitor(self, name, fields): symtab_field_name = field.name if is_stmt_present and is_symtab_present: break - if is_stmt_present and name not in ("Assignment", "ForAllSingle"): + if is_stmt_present and name not in ("Assignment", "ForAllSingle", "FileRead", "FileWrite"): self.emit(" %s_t& xx = const_cast<%s_t&>(x);" % (name, name), 1) self.used = False @@ -562,7 +562,7 @@ def make_visitor(self, name, fields): symtab_field_name = field.name if is_stmt_present and is_symtab_present: break - if is_stmt_present and name not in ("Assignment", "ForAllSingle"): + if is_stmt_present and name not in ("Assignment", "ForAllSingle", "FileRead", "FileWrite"): self.emit(" %s_t& xx = const_cast<%s_t&>(x);" % (name, name), 1) self.used = False @@ -1029,17 +1029,13 @@ def visitConstructor(self, cons, _): def make_visitor(self, name, fields): self.emit("") self.emit("ASR::asr_t* duplicate_%s(%s_t* x) {" % (name, name), 1) - self.used = False - arguments = [] + arguments = ["al", "x->base.base.loc"] for field in fields: ret_value = self.visitField(field) for node_arg in ret_value: arguments.append(node_arg) - if not self.used: - self.emit("return (asr_t*)x;", 2) - else: - node_arg_str = ', '.join(arguments) - self.emit("return make_%s_t(al, x->base.base.loc, %s);" %(name, node_arg_str), 2) + node_arg_str = ', '.join(arguments) + self.emit("return make_%s_t(%s);" %(name, node_arg_str), 2) if self.is_stmt: self.duplicate_stmt.append((" case ASR::stmtType::%s: {" % name, 2)) if name == "SubroutineCall": @@ -1088,7 +1084,6 @@ def visitField(self, field): field.type == "dimension"): level = 2 if field.seq: - self.used = True pointer_char = '' if (field.type != "call_arg" and field.type != "array_index" and @@ -1141,7 +1136,6 @@ def visitField(self, field): self.emit("}", level) arguments = ("m_" + field.name + ".p", "x->n_" + field.name) else: - self.used = True if field.type == "symbol": self.emit("%s_t* m_%s = x->m_%s;" % (field.type, field.name, field.name), level) elif field.type == "do_loop_head": @@ -1461,12 +1455,6 @@ def visitConstructor(self, cons, _): def make_visitor(self, name, fields, cons): self.emit("void visit_%s(const %s_t &x) {" % (name, name), 1) self.emit( 's.append("(");', 2) - subs = { - "Assignment": "=", - "Associate": "=>", - } - if name in subs: - name = subs[name] # For ASR symbol = [ @@ -1680,7 +1668,7 @@ def visitField(self, field, cons): self.emit( 's.append("()");', 3) self.emit("}", 2) else: - if field.name == "intrinsic_id": + if field.name == "intrinsic_id" or field.name == "inquiry_id": self.emit('s.append(self().convert_intrinsic_id(x.m_%s));' % field.name, 2) elif field.name == "impure_intrinsic_id": self.emit('s.append(self().convert_impure_intrinsic_id(x.m_%s));' % field.name, 2) @@ -2593,7 +2581,8 @@ def make_visitor(self, name, fields): LCOMPILERS_ASSERT(!ASR::is_a(*e->m_external)); s = e->m_external; } - if( ASR::down_cast(s)->m_storage != + if( ASR::is_a(*s) || + ASR::down_cast(s)->m_storage != ASR::storage_typeType::Parameter ) { return nullptr; } @@ -2749,6 +2738,10 @@ def main(argv): elif subs["MOD"] == "AST": subs["MOD"] = "LFortran::AST" subs["lcompiler"] = "lfortran" + elif subs["MOD"] == "LC": + subs["MOD"] = "LC::AST" + subs["mod"] = "ast" + subs["lcompiler"] = "lc" else: subs["lcompiler"] = "lfortran" is_asr = (mod.name.upper() == "ASR") diff --git a/src/libasr/asr_builder.h b/src/libasr/asr_builder.h new file mode 100644 index 0000000000..0e4073381b --- /dev/null +++ b/src/libasr/asr_builder.h @@ -0,0 +1,1047 @@ +#ifndef LIBASR_BUILDER_H +#define LIBASR_BUILDER_H + +#include +#include +#include +#include + +namespace LCompilers::ASRUtils { + +class ASRBuilder { + private: + + Allocator& al; + // TODO: use the location to point C++ code in `intrinsic_function_registry` + const Location &loc; + + public: + + ASRBuilder(Allocator& al_, const Location& loc_): al(al_), loc(loc_) {} + + #define make_ConstantWithKind(Constructor, TypeConstructor, value, kind, loc) ASRUtils::EXPR( \ + ASR::Constructor( al, loc, value, \ + ASRUtils::TYPE(ASR::TypeConstructor(al, loc, kind)))) \ + + #define make_ConstantWithType(Constructor, value, type, loc) ASRUtils::EXPR( \ + ASR::Constructor(al, loc, value, type)) \ + + #define declare_basic_variables(name) \ + std::string fn_name = scope->get_unique_name(name, false); \ + SymbolTable *fn_symtab = al.make_new(scope); \ + ASRBuilder b(al, loc); \ + Vec args; args.reserve(al, 1); \ + Vec body; body.reserve(al, 1); \ + SetChar dep; dep.reserve(al, 1); + + // Symbols ----------------------------------------------------------------- + ASR::expr_t *Variable(SymbolTable *symtab, std::string var_name, + ASR::ttype_t *type, ASR::intentType intent, + ASR::abiType abi=ASR::abiType::Source, bool a_value_attr=false) { + ASR::symbol_t* sym = ASR::down_cast( + ASR::make_Variable_t(al, loc, symtab, s2c(al, var_name), nullptr, 0, + intent, nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, abi, + ASR::Public, ASR::presenceType::Required, a_value_attr)); + symtab->add_symbol(s2c(al, var_name), sym); + return ASRUtils::EXPR(ASR::make_Var_t(al, loc, sym)); + } + + #define declare(var_name, type, intent) \ + b.Variable(fn_symtab, var_name, type, ASR::intentType::intent) + + #define fill_func_arg(arg_name, type) { \ + auto arg = declare(arg_name, type, In); \ + args.push_back(al, arg); } + + #define fill_func_arg_sub(arg_name, type, intent) { \ + auto arg = declare(arg_name, type, intent); \ + args.push_back(al, arg); } + + #define make_ASR_Function_t(name, symtab, dep, args, body, return_var, abi, \ + deftype, bindc_name) \ + ASR::down_cast( ASRUtils::make_Function_t_util(al, loc, \ + symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, \ + return_var, abi, ASR::accessType::Public, \ + deftype, bindc_name, false, false, false, false, \ + false, nullptr, 0, false, false, false)); + + #define make_Function_Without_ReturnVar_t(name, symtab, dep, args, body, \ + abi, deftype, bindc_name) \ + ASR::down_cast( ASRUtils::make_Function_t_util(al, loc, \ + symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, \ + nullptr, abi, ASR::accessType::Public, \ + deftype, bindc_name, false, false, false, false, \ + false, nullptr, 0, false, false, false)); + + // Types ------------------------------------------------------------------- + #define int8 TYPE(ASR::make_Integer_t(al, loc, 1)) + #define int16 TYPE(ASR::make_Integer_t(al, loc, 2)) + #define int32 TYPE(ASR::make_Integer_t(al, loc, 4)) + #define int64 TYPE(ASR::make_Integer_t(al, loc, 8)) + #define real32 TYPE(ASR::make_Real_t(al, loc, 4)) + #define real64 TYPE(ASR::make_Real_t(al, loc, 8)) + #define complex32 TYPE(ASR::make_Complex_t(al, loc, 4)) + #define logical TYPE(ASR::make_Logical_t(al, loc, 4)) + #define character(x) TYPE(ASR::make_Character_t(al, loc, 1, x, nullptr)) + #define List(x) TYPE(ASR::make_List_t(al, loc, x)) + + ASR::ttype_t *Tuple(std::vector tuple_type) { + Vec m_tuple_type; m_tuple_type.reserve(al, 3); + for (auto &x: tuple_type) { + m_tuple_type.push_back(al, x); + } + return TYPE(ASR::make_Tuple_t(al, loc, m_tuple_type.p, m_tuple_type.n)); + } + ASR::ttype_t *Array(std::vector dims, ASR::ttype_t *type) { + Vec m_dims; m_dims.reserve(al, 1); + for (auto &x: dims) { + ASR::dimension_t dim; + dim.loc = loc; + if (x == -1) { + dim.m_start = nullptr; + dim.m_length = nullptr; + } else { + dim.m_start = EXPR(ASR::make_IntegerConstant_t(al, loc, 1, int32)); + dim.m_length = EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)); + } + m_dims.push_back(al, dim); + } + return make_Array_t_util(al, loc, type, m_dims.p, m_dims.n); + } + + // Expressions ------------------------------------------------------------- + inline ASR::expr_t* i(int64_t x, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerConstant_t(al, loc, x, t)); + } + + inline ASR::expr_t* i32(int64_t x) { + return EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)); + } + + inline ASR::expr_t* i64(int64_t x) { + return EXPR(ASR::make_IntegerConstant_t(al, loc, x, int64)); + } + + inline ASR::expr_t* i32_n(int64_t x) { + return EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, i32(abs(x)), int32, i32(x))); + } + + inline ASR::expr_t* i32_neg(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, x, t, nullptr)); + } + + inline ASR::expr_t* f(double x, ASR::ttype_t* t) { + return EXPR(ASR::make_RealConstant_t(al, loc, x, t)); + } + + inline ASR::expr_t* f32(double x) { + return EXPR(ASR::make_RealConstant_t(al, loc, x, real32)); + } + + inline ASR::expr_t* f32_neg(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_RealUnaryMinus_t(al, loc, x, t, nullptr)); + } + + inline ASR::expr_t* bool32(bool x) { + return EXPR(ASR::make_LogicalConstant_t(al, loc, x, logical)); + } + + inline ASR::expr_t* bool_t(bool x, ASR::ttype_t* t) { + return EXPR(ASR::make_LogicalConstant_t(al, loc, x, t)); + } + + inline ASR::expr_t* complex(double x, double y, ASR::ttype_t* t) { + return EXPR(ASR::make_ComplexConstant_t(al, loc, x, y, t)); + } + + inline ASR::expr_t* c32(double x, double y) { + return EXPR(ASR::make_ComplexConstant_t(al, loc, x, y, complex32)); + } + + inline ASR::expr_t* ListItem(ASR::expr_t* x, ASR::expr_t* pos, ASR::ttype_t* type) { + return EXPR(ASR::make_ListItem_t(al, loc, x, pos, type, nullptr)); + } + + inline ASR::stmt_t* ListAppend(ASR::expr_t* x, ASR::expr_t* val) { + return STMT(ASR::make_ListAppend_t(al, loc, x, val)); + } + + inline ASR::expr_t* StringSection(ASR::expr_t* s, ASR::expr_t* start, ASR::expr_t* end) { + return EXPR(ASR::make_StringSection_t(al, loc, s, start, end, i32(1), character(-2), nullptr)); + } + + inline ASR::expr_t* StringItem(ASR::expr_t* x, ASR::expr_t* idx) { + return EXPR(ASR::make_StringItem_t(al, loc, x, idx, character(-2), nullptr)); + } + + inline ASR::expr_t* StringConstant(std::string s, ASR::ttype_t* type) { + return EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s), type)); + } + + inline ASR::expr_t* StringLen(ASR::expr_t* s) { + return EXPR(ASR::make_StringLen_t(al, loc, s, int32, nullptr)); + } + + inline ASR::expr_t* StringConcat(ASR::expr_t* s1, ASR::expr_t* s2, ASR::ttype_t* type) { + return EXPR(ASR::make_StringConcat_t(al, loc, s1, s2, type, nullptr)); + } + + inline ASR::expr_t* ArraySize(ASR::expr_t* x, ASR::expr_t* dim, ASR::ttype_t* t) { + return EXPR(ASR::make_ArraySize_t(al, loc, x, dim, t, nullptr)); + } + + inline ASR::expr_t* Ichar(std::string s, ASR::ttype_t* type, ASR::ttype_t* t) { + return EXPR(ASR::make_Ichar_t(al, loc, + EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s), type)), t, nullptr)); + } + + // Cast -------------------------------------------------------------------- + + inline ASR::expr_t* r2i8(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToInteger, int8, nullptr)); + } + + inline ASR::expr_t* r2i16(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToInteger, int16, nullptr)); + } + + inline ASR::expr_t* r2i32(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToInteger, int32, nullptr)); + } + + inline ASR::expr_t* r2i64(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToInteger, int64, nullptr)); + } + + inline ASR::expr_t* i2r32(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToReal, real32, nullptr)); + } + + inline ASR::expr_t* i2r64(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToReal, real64, nullptr)); + } + + inline ASR::expr_t* i2i(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToInteger, t, nullptr)); + } + + inline ASR::expr_t* i2i64(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToInteger, int64, nullptr)); + } + + inline ASR::expr_t* i2i32(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToInteger, int32, nullptr)); + } + + inline ASR::expr_t* r2r32(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToReal, real32, nullptr)); + } + + inline ASR::expr_t* r2r64(ASR::expr_t* x) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToReal, real64, nullptr)); + } + + inline ASR::expr_t* r2r(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToReal, t, nullptr)); + } + + inline ASR::expr_t* r2i(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::RealToInteger, t, nullptr)); + } + + inline ASR::expr_t* i2r(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_Cast_t(al, loc, x, ASR::cast_kindType::IntegerToReal, t, nullptr)); + } + + // Binop ------------------------------------------------------------------- + + inline ASR::expr_t* iAdd(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::int32, nullptr)); + } + + inline ASR::expr_t* i8Add(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::int8, nullptr)); + } + + inline ASR::expr_t* i16Add(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::int16, nullptr)); + } + + inline ASR::expr_t* i64Add(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::int64, nullptr)); + } + + inline ASR::expr_t* rAdd(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, t, nullptr)); + } + + inline ASR::expr_t* r32Add(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::real32, nullptr)); + } + + inline ASR::expr_t* r64Add(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, ASRUtils::real64, nullptr)); + } + + inline ASR::expr_t* i_tAdd(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Add, right, t, nullptr)); + } + + inline ASR::expr_t* r_tAdd(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Add, right, t, nullptr)); + } + + inline ASR::expr_t* iSub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, ASRUtils::int32, nullptr)); + } + + inline ASR::expr_t* i_vSub(ASR::expr_t* left, ASR::expr_t* right, ASR::expr_t* value) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, ASRUtils::int32, value)); + } + + inline ASR::expr_t* i8Sub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, int8, nullptr)); + } + + inline ASR::expr_t* i16Sub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, int16, nullptr)); + } + + inline ASR::expr_t* i64Sub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, int64, nullptr)); + } + + inline ASR::expr_t* rSub(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Sub, right, t, nullptr)); + } + + inline ASR::expr_t* r32Sub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Sub, right, ASRUtils::real32, nullptr)); + } + + inline ASR::expr_t* r64Sub(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Sub, right, ASRUtils::real64, nullptr)); + } + + inline ASR::expr_t* i_tSub(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Sub, right, t, nullptr)); + } + + inline ASR::expr_t* r_tSub(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Sub, right, t, nullptr)); + } + + inline ASR::expr_t* iDiv(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::int32, nullptr)); + } + + inline ASR::expr_t* i8Div(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::int8, nullptr)); + } + + inline ASR::expr_t* i16Div(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::int16, nullptr)); + } + + inline ASR::expr_t* i64Div(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::int64, nullptr)); + } + + inline ASR::expr_t* rDiv(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Div, right, t, nullptr)); + } + + inline ASR::expr_t* r32Div(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::real32, nullptr)); + } + + inline ASR::expr_t* r64Div(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Div, right, ASRUtils::real64, nullptr)); + } + + inline ASR::expr_t* i_tDiv(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Div, right, t, nullptr)); + } + + inline ASR::expr_t* iMul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::int32, nullptr)); + } + + inline ASR::expr_t* i8Mul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::int8, nullptr)); + } + + inline ASR::expr_t* i16Mul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::int16, nullptr)); + } + + inline ASR::expr_t* i64Mul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::int64, nullptr)); + } + + inline ASR::expr_t* rMul(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Mul, right, t, nullptr)); + } + + inline ASR::expr_t* r32Mul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::real32, nullptr)); + } + + inline ASR::expr_t* r64Mul(ASR::expr_t* left, ASR::expr_t* right) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Mul, right, ASRUtils::real64, nullptr)); + } + + inline ASR::expr_t* i_tMul(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Mul, right, t, nullptr)); + } + + inline ASR::expr_t* i_tAnd(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::BitAnd, right, t, nullptr)); + } + + inline ASR::expr_t* r_tMul(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Mul, right, t, nullptr)); + } + + inline ASR::expr_t* iPow(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, ASR::binopType::Pow, right, t, nullptr)); + } + + inline ASR::expr_t* rPow(ASR::expr_t* left, ASR::expr_t* right, ASR::ttype_t* t) { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, ASR::binopType::Pow, right, t, nullptr)); + } + + inline ASR::expr_t* And(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_LogicalBinOp_t(al, loc, x, ASR::logicalbinopType::And, y, logical, nullptr)); + } + + inline ASR::expr_t* Or(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_LogicalBinOp_t(al, loc, x, ASR::logicalbinopType::Or, y, logical, nullptr)); + } + + inline ASR::expr_t* Not(ASR::expr_t* x) { + return EXPR(ASR::make_LogicalNot_t(al, loc, x, logical, nullptr)); + } + + inline ASR::expr_t* i_BitRshift(ASR::expr_t* n, ASR::expr_t* bits, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, n, ASR::binopType::BitRShift, bits, t, nullptr)); + } + + inline ASR::expr_t* i_BitLshift(ASR::expr_t* n, ASR::expr_t* bits, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, n, ASR::binopType::BitLShift, bits, t, nullptr)); + } + + inline ASR::expr_t* i_BitNot(ASR::expr_t* x, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBitNot_t(al, loc, x, t, nullptr)); + } + + inline ASR::expr_t* i_BitAnd(ASR::expr_t* i, ASR::expr_t* j, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, i, ASR::binopType::BitAnd, j, t, nullptr)); + } + + inline ASR::expr_t* i_BitOr(ASR::expr_t* i, ASR::expr_t* j, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, i, ASR::binopType::BitOr, j, t, nullptr)); + } + + inline ASR::expr_t* i_BitXor(ASR::expr_t* i, ASR::expr_t* j, ASR::ttype_t* t) { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, i, ASR::binopType::BitXor, j, t, nullptr)); + } + + inline ASR::expr_t* sConstant(std::string s, ASR::ttype_t* type) { + return EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s), type)); + } + + ASR::expr_t *Add(ASR::expr_t *left, ASR::expr_t *right) { + LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); + ASR::ttype_t *type = expr_type(left); + ASRUtils::make_ArrayBroadcast_t_util(al, loc, left, right); + switch (type->type) { + case ASR::ttypeType::Integer : { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, + ASR::binopType::Add, right, type, nullptr)); + break; + } + case ASR::ttypeType::Real : { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, + ASR::binopType::Add, right, type, nullptr)); + break; + } + case ASR::ttypeType::Character : { + return EXPR(ASR::make_StringConcat_t(al, loc, left, + right, type, nullptr)); + break; + } + case ASR::ttypeType::Complex : { + return EXPR(ASR::make_ComplexBinOp_t(al, loc, left, + ASR::binopType::Add, right, type, nullptr)); + } + default: { + LCOMPILERS_ASSERT(false); + return nullptr; + } + } + } + + ASR::expr_t *Mul(ASR::expr_t *left, ASR::expr_t *right) { + LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); + ASR::ttype_t *type = expr_type(left); + ASRUtils::make_ArrayBroadcast_t_util(al, loc, left, right); + switch (type->type) { + case ASR::ttypeType::Integer : { + return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, + ASR::binopType::Mul, right, type, nullptr)); + break; + } + case ASR::ttypeType::Real : { + return EXPR(ASR::make_RealBinOp_t(al, loc, left, + ASR::binopType::Mul, right, type, nullptr)); + break; + } + case ASR::ttypeType::Complex : { + return EXPR(ASR::make_ComplexBinOp_t(al, loc, left, + ASR::binopType::Mul, right, type, nullptr)); + } + default: { + LCOMPILERS_ASSERT(false); + return nullptr; + } + } + } + + ASR::stmt_t* CallIntrinsicSubroutine(SymbolTable* scope, std::vector types, + std::vector args, int64_t overload_id, + ASR::stmt_t* (*intrinsic_subroutine)(Allocator &, const Location &, SymbolTable *, + Vec&, Vec&, int64_t)) { + Vec arg_types; arg_types.reserve(al, types.size()); + for (auto &x: types) arg_types.push_back(al, x); + + Vec new_args; new_args.reserve(al, args.size()); + for (auto &x: args) { + ASR::call_arg_t call_arg; call_arg.loc = loc; call_arg.m_value = x; + new_args.push_back(al, call_arg); + } + + return intrinsic_subroutine(al, loc, scope, arg_types, new_args, overload_id); + } + + ASR::expr_t* CallIntrinsic(SymbolTable* scope, std::vector types, + std::vector args, ASR::ttype_t* return_type, int64_t overload_id, + ASR::expr_t* (*intrinsic_func)(Allocator &, const Location &, SymbolTable *, + Vec&, ASR::ttype_t *, Vec&, int64_t)) { + Vec arg_types; arg_types.reserve(al, types.size()); + for (auto &x: types) arg_types.push_back(al, x); + + Vec new_args; new_args.reserve(al, args.size()); + for (auto &x: args) { + ASR::call_arg_t call_arg; call_arg.loc = loc; call_arg.m_value = x; + new_args.push_back(al, call_arg); + } + + return intrinsic_func(al, loc, scope, arg_types, return_type, new_args, overload_id); + } + + // Compare ----------------------------------------------------------------- + inline ASR::expr_t* iEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::Eq, y, logical, nullptr)); + } + inline ASR::expr_t* iNotEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::NotEq, y, logical, nullptr)); + } + inline ASR::expr_t* iLt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::Lt, y, logical, nullptr)); + } + inline ASR::expr_t* iLtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::LtE, y, logical, nullptr)); + } + inline ASR::expr_t* iGtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::GtE, y, logical, nullptr)); + } + inline ASR::expr_t* iGt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_IntegerCompare_t(al, loc, x, ASR::cmpopType::Gt, y, logical, nullptr)); + } + inline ASR::expr_t* ArraySize_1(ASR::expr_t* x, ASR::expr_t* dim) { + return EXPR(make_ArraySize_t_util(al, loc, x, dim, int32, nullptr)); + } + inline ASR::expr_t* ArraySize_2(ASR::expr_t* x, ASR::expr_t* dim, ASR::ttype_t* t) { + return EXPR(make_ArraySize_t_util(al, loc, x, dim, t, nullptr)); + } + inline ASR::expr_t* fEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::Eq, y, logical, nullptr)); + } + inline ASR::expr_t* fGtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::GtE, y, logical, nullptr)); + } + inline ASR::expr_t* fLtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::LtE, y, logical, nullptr)); + } + inline ASR::expr_t* fLt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::Lt, y, logical, nullptr)); + } + inline ASR::expr_t* fGt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::Gt, y, logical, nullptr)); + } + inline ASR::expr_t* fNotEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_RealCompare_t(al, loc, x, ASR::cmpopType::NotEq, y, logical, nullptr)); + } + inline ASR::expr_t* boolEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_LogicalCompare_t(al, loc, x, ASR::cmpopType::Eq, y, logical, nullptr)); + } + inline ASR::expr_t* sEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::Eq, y, logical, nullptr)); + } + inline ASR::expr_t* sNotEq(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::NotEq, y, logical, nullptr)); + } + inline ASR::expr_t* sLt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::Lt, y, logical, nullptr)); + } + inline ASR::expr_t* sLtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::LtE, y, logical, nullptr)); + } + inline ASR::expr_t* sGt(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::Gt, y, logical, nullptr)); + } + inline ASR::expr_t* sGtE(ASR::expr_t* x, ASR::expr_t* y) { + return EXPR(ASR::make_StringCompare_t(al, loc, x, ASR::cmpopType::GtE, y, logical, nullptr)); + } + + ASR::expr_t *Gt(ASR::expr_t *left, ASR::expr_t *right) { + LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); + if (is_real(*expr_type(left))) { + return fGt(left, right); + } else if (is_integer(*expr_type(left))) { + return iGt(left, right); + } else { + LCOMPILERS_ASSERT(false); + return nullptr; + } + } + + ASR::expr_t *Lt(ASR::expr_t *left, ASR::expr_t *right) { + LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); + if (is_real(*expr_type(left))) { + return fLt(left, right); + } else if (is_integer(*expr_type(left))) { + return iLt(left, right); + } else { + LCOMPILERS_ASSERT(false); + return nullptr; + } + } + + ASR::stmt_t *If(ASR::expr_t *a_test, std::vector if_body, + std::vector else_body) { + Vec m_if_body; m_if_body.reserve(al, 1); + for (auto &x: if_body) m_if_body.push_back(al, x); + + Vec m_else_body; m_else_body.reserve(al, 1); + for (auto &x: else_body) m_else_body.push_back(al, x); + + return STMT(ASR::make_If_t(al, loc, a_test, m_if_body.p, m_if_body.n, + m_else_body.p, m_else_body.n)); + } + + ASR::stmt_t *While(ASR::expr_t *a_test, std::vector body) { + Vec m_body; m_body.reserve(al, 1); + for (auto &x: body) m_body.push_back(al, x); + + return STMT(ASR::make_WhileLoop_t(al, loc, nullptr, a_test, + m_body.p, m_body.n, nullptr, 0)); + } + + ASR::stmt_t *Exit(char* loop_name) { + return STMT(ASR::make_Exit_t(al, loc, loop_name)); + } + + ASR::expr_t *TupleConstant(std::vector ele, ASR::ttype_t *type) { + Vec m_ele; m_ele.reserve(al, 3); + for (auto &x: ele) m_ele.push_back(al, x); + return EXPR(ASR::make_TupleConstant_t(al, loc, m_ele.p, m_ele.n, type)); + } + + #define make_Compare(Constructor, left, op, right) ASRUtils::EXPR(ASR::Constructor( \ + al, loc, left, ASR::cmpopType::op, right, \ + ASRUtils::TYPE(ASR::make_Logical_t( \ + al, loc, 4)), nullptr)); \ + + #define create_ElementalBinOp(OpType, BinOpName, OpName, value) case ASR::ttypeType::OpType: { \ + return ASRUtils::EXPR(ASR::BinOpName(al, loc, \ + left, ASR::binopType::OpName, right, \ + ASRUtils::expr_type(left), value)); \ + } \ + + ASR::expr_t* ElementalAdd(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + ASR::ttype_t *left_type = ASRUtils::expr_type(left); + left_type = ASRUtils::type_get_past_pointer(left_type); + switch (left_type->type) { + create_ElementalBinOp(Real, make_RealBinOp_t, Add, value) + create_ElementalBinOp(Integer, make_IntegerBinOp_t, Add, value) + create_ElementalBinOp(Complex, make_ComplexBinOp_t, Add, value) + default: { + throw LCompilersException("Expression type, " + + std::to_string(left_type->type) + + " not yet supported"); + } + } + } + + ASR::expr_t* ElementalSub(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + switch (ASRUtils::expr_type(left)->type) { + create_ElementalBinOp(Real, make_RealBinOp_t, Sub, value) + create_ElementalBinOp(Integer, make_IntegerBinOp_t, Sub, value) + create_ElementalBinOp(Complex, make_ComplexBinOp_t, Sub, value) + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + + " not yet supported"); + } + } + } + + ASR::expr_t* ElementalDiv(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + switch (ASRUtils::expr_type(left)->type) { + create_ElementalBinOp(Real, make_RealBinOp_t, Div, value) + create_ElementalBinOp(Integer, make_IntegerBinOp_t, Div, value) + create_ElementalBinOp(Complex, make_ComplexBinOp_t, Div, value) + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + + " not yet supported"); + } + } + } + + ASR::expr_t* ElementalMul(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + switch (ASRUtils::expr_type(left)->type) { + create_ElementalBinOp(Real, make_RealBinOp_t, Mul, value) + create_ElementalBinOp(Integer, make_IntegerBinOp_t, Mul, value) + create_ElementalBinOp(Complex, make_ComplexBinOp_t, Mul, value) + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + + " not yet supported"); + } + } + } + + ASR::expr_t* ElementalPow(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + switch (ASRUtils::expr_type(left)->type) { + create_ElementalBinOp(Real, make_RealBinOp_t, Pow, value) + create_ElementalBinOp(Integer, make_IntegerBinOp_t, Pow, value) + create_ElementalBinOp(Complex, make_ComplexBinOp_t, Pow, value) + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + + " not yet supported"); + } + } + } + + ASR::expr_t* ElementalMax(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + ASR::expr_t* test_condition = nullptr; + switch (ASRUtils::expr_type(left)->type) { + case ASR::ttypeType::Integer: { + test_condition = make_Compare(make_IntegerCompare_t, left, Gt, right); + break; + } + case ASR::ttypeType::Real: { + test_condition = make_Compare(make_RealCompare_t, left, Gt, right); + break; + } + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + " not yet supported"); + } + } + return ASRUtils::EXPR(ASR::make_IfExp_t(al, loc, test_condition, left, right, ASRUtils::expr_type(left), value)); + } + + ASR::expr_t* ElementalMin(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc, ASR::expr_t* value=nullptr) { + ASR::expr_t* test_condition = nullptr; + switch (ASRUtils::expr_type(left)->type) { + case ASR::ttypeType::Integer: { + test_condition = make_Compare(make_IntegerCompare_t, left, Lt, right); + break; + } + case ASR::ttypeType::Real: { + test_condition = make_Compare(make_RealCompare_t, left, Lt, right); + break; + } + default: { + throw LCompilersException("Expression type, " + + std::to_string(expr_type(left)->type) + " not yet supported"); + } + } + return ASRUtils::EXPR(ASR::make_IfExp_t(al, loc, test_condition, left, right, ASRUtils::expr_type(left), value)); + } + + ASR::expr_t* ElementalOr(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc) { + return ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, + left, ASR::Or, right, + ASRUtils::TYPE(ASR::make_Logical_t( al, loc, 4)), nullptr)); + } + + ASR::expr_t* LogicalOr(ASR::expr_t* left, ASR::expr_t* right, + const Location& loc) { + return ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, + left, ASR::Or, right, ASRUtils::expr_type(left), + nullptr)); + } + + ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, + ASR::ttype_t* return_type) { + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + s, s, args.p, args.size(), return_type, nullptr, nullptr)); + } + + ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, + ASR::ttype_t* return_type) { + Vec args_; args_.reserve(al, 2); + visit_expr_list(al, args, args_); + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + s, s, args_.p, args_.size(), return_type, nullptr, nullptr)); + } + + ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, + ASR::ttype_t* return_type, ASR::expr_t* value) { + return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, + s, s, args.p, args.size(), return_type, value, nullptr)); + } + + ASR::stmt_t* SubroutineCall(ASR::symbol_t* s, Vec& args) { + return ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util(al, loc, + s, s, args.p, args.size(), nullptr, nullptr, false, false)); + } + + ASR::expr_t *ArrayItem_01(ASR::expr_t *arr, std::vector idx) { + Vec idx_vars; idx_vars.reserve(al, 1); + for (auto &x: idx) idx_vars.push_back(al, x); + return PassUtils::create_array_ref(arr, idx_vars, al); + } + + #define ArrayItem_02(arr, idx_vars) PassUtils::create_array_ref(arr, \ + idx_vars, al) + + ASR::expr_t *ArrayConstant(std::vector elements, + ASR::ttype_t *base_type, bool cast2descriptor=true) { + // This function only creates array with rank one + // TODO: Support other dimensions + Vec m_eles; m_eles.reserve(al, 1); + for (auto &x: elements) m_eles.push_back(al, x); + + ASR::ttype_t *fixed_size_type = Array({(int64_t) elements.size()}, base_type); + ASR::expr_t *arr_constant = EXPR(ASR::make_ArrayConstant_t(al, loc, + m_eles.p, m_eles.n, fixed_size_type, ASR::arraystorageType::ColMajor)); + + if (cast2descriptor) { + return cast_to_descriptor(al, arr_constant); + } else { + return arr_constant; + } + } + + ASR::dimension_t set_dim(ASR::expr_t *start, ASR::expr_t *length) { + ASR::dimension_t dim; + dim.loc = loc; + dim.m_start = start; + dim.m_length = length; + return dim; + } + + // Statements -------------------------------------------------------------- + #define Return() STMT(ASR::make_Return_t(al, loc)) + + ASR::stmt_t *Assignment(ASR::expr_t *lhs, ASR::expr_t *rhs) { + LCOMPILERS_ASSERT(check_equal_type(expr_type(lhs), expr_type(rhs))); + return STMT(ASR::make_Assignment_t(al, loc, lhs, rhs, nullptr)); + } + + template + ASR::stmt_t *Assign_Constant(ASR::expr_t *lhs, T init_value) { + ASR::ttype_t *type = expr_type(lhs); + switch(type->type) { + case ASR::ttypeType::Integer : { + return Assignment(lhs, i(init_value, type)); + } + case ASR::ttypeType::Real : { + return Assignment(lhs, f(init_value, type)); + } + case ASR::ttypeType::Complex : { + return Assignment(lhs, complex(init_value, init_value, type)); + } + default : { + LCOMPILERS_ASSERT(false); + return nullptr; + } + } + } + + ASR::stmt_t *Allocate(ASR::expr_t *m_a, Vec dims) { + Vec alloc_args; alloc_args.reserve(al, 1); + ASR::alloc_arg_t alloc_arg; + alloc_arg.loc = loc; + alloc_arg.m_a = m_a; + alloc_arg.m_dims = dims.p; + alloc_arg.n_dims = dims.n; + alloc_arg.m_type = nullptr; + alloc_arg.m_len_expr = nullptr; + alloc_args.push_back(al, alloc_arg); + return STMT(ASR::make_Allocate_t(al, loc, alloc_args.p, 1, + nullptr, nullptr, nullptr)); + } + + #define UBound(arr, dim) PassUtils::get_bound(arr, dim, "ubound", al) + #define LBound(arr, dim) PassUtils::get_bound(arr, dim, "lbound", al) + + ASR::stmt_t *DoLoop(ASR::expr_t *m_v, ASR::expr_t *start, ASR::expr_t *end, + std::vector loop_body, ASR::expr_t *step=nullptr) { + ASR::do_loop_head_t head; + head.loc = m_v->base.loc; + head.m_v = m_v; + head.m_start = start; + head.m_end = end; + head.m_increment = step; + Vec body; + body.from_pointer_n_copy(al, &loop_body[0], loop_body.size()); + return STMT(ASR::make_DoLoop_t(al, loc, nullptr, head, body.p, body.n, nullptr, 0)); + } + + template + ASR::stmt_t* create_do_loop( + const Location& loc, int rank, ASR::expr_t* array, + SymbolTable* scope, Vec& idx_vars, + Vec& doloop_body, LOOP_BODY loop_body) { + PassUtils::create_idx_vars(idx_vars, rank, loc, al, scope, "_i"); + + ASR::stmt_t* doloop = nullptr; + for( int i = (int) idx_vars.size() - 1; i >= 0; i-- ) { + ASR::do_loop_head_t head; + head.m_v = idx_vars[i]; + head.m_start = PassUtils::get_bound(array, i + 1, "lbound", al); + head.m_end = PassUtils::get_bound(array, i + 1, "ubound", al); + head.m_increment = nullptr; + + head.loc = head.m_v->base.loc; + doloop_body.reserve(al, 1); + if( doloop == nullptr ) { + loop_body(); + } else { + doloop_body.push_back(al, doloop); + } + doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, + head, doloop_body.p, doloop_body.size(), nullptr, 0)); + } + return doloop; + } + + template + ASR::stmt_t* create_do_loop( + const Location& loc, ASR::expr_t* array, + Vec& loop_vars, std::vector& loop_dims, + Vec& doloop_body, LOOP_BODY loop_body) { + + ASR::stmt_t* doloop = nullptr; + for( int i = (int) loop_vars.size() - 1; i >= 0; i-- ) { + ASR::do_loop_head_t head; + head.m_v = loop_vars[i]; + head.m_start = PassUtils::get_bound(array, loop_dims[i], "lbound", al); + head.m_end = PassUtils::get_bound(array, loop_dims[i], "ubound", al); + head.m_increment = nullptr; + + head.loc = head.m_v->base.loc; + doloop_body.reserve(al, 1); + if( doloop == nullptr ) { + loop_body(); + } else { + doloop_body.push_back(al, doloop); + } + doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, + head, doloop_body.p, doloop_body.size(), nullptr, 0)); + } + return doloop; + } + + template + void generate_reduction_intrinsic_stmts_for_scalar_output(const Location& loc, + ASR::expr_t* array, SymbolTable* fn_scope, + Vec& fn_body, Vec& idx_vars, + Vec& doloop_body, INIT init_stmts, LOOP_BODY loop_body) { + init_stmts(); + int rank = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(array)); + ASR::stmt_t* doloop = create_do_loop(loc, + rank, array, fn_scope, idx_vars, doloop_body, + loop_body); + fn_body.push_back(al, doloop); + } + + template + void generate_reduction_intrinsic_stmts_for_array_output(const Location& loc, + ASR::expr_t* array, ASR::expr_t* dim, SymbolTable* fn_scope, + Vec& fn_body, Vec& idx_vars, + Vec& target_idx_vars, Vec& doloop_body, + INIT init_stmts, LOOP_BODY loop_body) { + init_stmts(); + int n_dims = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(array)); + ASR::stmt_t** else_ = nullptr; + size_t else_n = 0; + idx_vars.reserve(al, n_dims); + PassUtils::create_idx_vars(idx_vars, n_dims, loc, al, fn_scope, "_j"); + for( int i = 1; i <= n_dims; i++ ) { + ASR::expr_t* current_dim = i32(i); + ASR::expr_t* test_expr = make_Compare(make_IntegerCompare_t, dim, + Eq, current_dim); + + Vec loop_vars; + std::vector loop_dims; + loop_dims.reserve(n_dims); + loop_vars.reserve(al, n_dims); + target_idx_vars.reserve(al, n_dims - 1); + for( int j = 1; j <= n_dims; j++ ) { + if( j == i ) { + continue ; + } + target_idx_vars.push_back(al, idx_vars[j - 1]); + loop_dims.push_back(j); + loop_vars.push_back(al, idx_vars[j - 1]); + } + loop_dims.push_back(i); + loop_vars.push_back(al, idx_vars[i - 1]); + + ASR::stmt_t* doloop = create_do_loop(loc, + array, loop_vars, loop_dims, doloop_body, + loop_body); + Vec if_body; + if_body.reserve(al, 1); + if_body.push_back(al, doloop); + ASR::stmt_t* if_ = ASRUtils::STMT(ASR::make_If_t(al, loc, test_expr, + if_body.p, if_body.size(), else_, else_n)); + Vec if_else_if; + if_else_if.reserve(al, 1); + if_else_if.push_back(al, if_); + else_ = if_else_if.p; + else_n = if_else_if.size(); + } + fn_body.push_back(al, else_[0]); + } + + ASR::stmt_t *Print(std::vector items) { + // Used for debugging + Vec x_exprs; + x_exprs.from_pointer_n_copy(al, &items[0], items.size()); + return STMT(ASR::make_Print_t(al, loc, x_exprs.p, x_exprs.n, + nullptr, nullptr)); + } + +}; + +} // namespace LCompilers::ASRUtils + +#endif // LIBASR_BUILDER_H diff --git a/src/libasr/asr_utils.cpp b/src/libasr/asr_utils.cpp index bfb718216d..009076b33b 100644 --- a/src/libasr/asr_utils.cpp +++ b/src/libasr/asr_utils.cpp @@ -483,7 +483,7 @@ ASR::asr_t* getStructInstanceMember_t(Allocator& al, const Location& loc, ASR::ttype_t* member_type = ASRUtils::TYPE(ASR::make_Struct_t(al, member_variable->base.base.loc, mem_es)); return ASR::make_StructInstanceMember_t(al, loc, ASRUtils::EXPR(v_var), - mem_es, member_type, nullptr); + mem_es, ASRUtils::fix_scoped_type(al, member_type, current_scope), nullptr); } else { LCOMPILERS_ASSERT(ASR::is_a(*member)); ASR::Variable_t* member_variable = ASR::down_cast(member); @@ -573,7 +573,7 @@ ASR::asr_t* getStructInstanceMember_t(Allocator& al, const Location& loc, } } return ASR::make_StructInstanceMember_t(al, loc, ASRUtils::EXPR(v_var), - member_ext, member_type, value); + member_ext, ASRUtils::fix_scoped_type(al, member_type, current_scope), value); } } @@ -650,9 +650,16 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right, } ASR::ttype_t *return_type = nullptr; if( ASRUtils::get_FunctionType(func)->m_elemental && - func->n_args == 1 && + func->n_args >= 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) { - return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value)); + ASR::dimension_t* array_dims; + size_t array_n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(a_args[0].m_value), array_dims); + Vec new_dims; + new_dims.from_pointer_n_copy(al, array_dims, array_n_dims); + return_type = ASRUtils::duplicate_type(al, + ASRUtils::get_FunctionType(func)->m_return_var_type, + &new_dims); } else { return_type = ASRUtils::expr_type(func->m_return_var); bool is_array = ASRUtils::is_array(return_type); @@ -734,9 +741,16 @@ void process_overloaded_unary_minus_function(ASR::symbol_t* proc, ASR::expr_t* o } ASR::ttype_t *return_type = nullptr; if( ASRUtils::get_FunctionType(func)->m_elemental && - func->n_args == 1 && + func->n_args >= 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) { - return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value)); + ASR::dimension_t* array_dims; + size_t array_n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(a_args[0].m_value), array_dims); + Vec new_dims; + new_dims.from_pointer_n_copy(al, array_dims, array_n_dims); + return_type = ASRUtils::duplicate_type(al, + ASRUtils::get_FunctionType(func)->m_return_var_type, + &new_dims); } else { return_type = ASRUtils::expr_type(func->m_return_var); bool is_array = ASRUtils::is_array(return_type); @@ -941,7 +955,7 @@ void process_overloaded_assignment_function(ASR::symbol_t* proc, ASR::expr_t* ta ASRUtils::insert_module_dependency(a_name, al, current_module_dependencies); ASRUtils::set_absent_optional_arguments_to_null(a_args, subrout, al); asr = ASRUtils::make_SubroutineCall_t_util(al, loc, a_name, sym, - a_args.p, 2, nullptr, nullptr, false); + a_args.p, 2, nullptr, nullptr, false, false); } } } @@ -974,7 +988,7 @@ bool use_overloaded_assignment(ASR::expr_t* target, ASR::expr_t* value, ASR::symbol_t* orig_sym = ASRUtils::symbol_get_past_external(sym); ASR::CustomOperator_t* gen_proc = ASR::down_cast(orig_sym); for( size_t i = 0; i < gen_proc->n_procs && !found; i++ ) { - ASR::symbol_t* proc = gen_proc->m_procs[i]; + ASR::symbol_t* proc = ASRUtils::symbol_get_past_external(gen_proc->m_procs[i]); switch( proc->type ) { case ASR::symbolType::Function: { process_overloaded_assignment_function(proc, target, value, target_type, @@ -993,7 +1007,103 @@ bool use_overloaded_assignment(ASR::expr_t* target, ASR::expr_t* value, break; } default: { - err("Only functions and class procedures can be used for generic assignment statement", loc); + err("Only functions and class procedures can be used for generic assignment statement, found " + std::to_string(proc->type), loc); + } + } + } + } + return found; +} + +void process_overloaded_read_write_function(std::string &read_write, ASR::symbol_t* proc, Vec &args, + ASR::ttype_t* arg_type, bool& found, Allocator& al, const Location& arg_loc, + SymbolTable* curr_scope, SetChar& current_function_dependencies, + SetChar& current_module_dependencies, ASR::asr_t*& asr, ASR::symbol_t* sym, const Location& loc, ASR::expr_t* expr_dt, + const std::function err, char* pass_arg=nullptr) { + ASR::Function_t* subrout = ASR::down_cast(proc); + std::string matched_subrout_name = ""; + ASR::ttype_t* func_arg_type = ASRUtils::expr_type(subrout->m_args[0]); + if( ASRUtils::types_equal(func_arg_type, arg_type) ) { + std::string arg0_name = ASRUtils::symbol_name(ASR::down_cast(subrout->m_args[0])->m_v); + if( pass_arg != nullptr ) { + std::string pass_arg_str = std::string(pass_arg); + if( (arg0_name == pass_arg_str && args[0] != expr_dt) ) { + err(std::string(subrout->m_name) + " is not a procedure of " + + ASRUtils::type_to_str(arg_type), + loc); + } + } + found = true; + Vec a_args; + a_args.reserve(al, args.size()); + for (size_t i = 0; i < args.size(); i++) { + ASR::call_arg_t arg; + arg.loc = arg_loc; + arg.m_value = args[i]; + a_args.push_back(al, arg); + } + std::string subrout_name = to_lower(subrout->m_name); + if( curr_scope->resolve_symbol(subrout_name) ) { + matched_subrout_name = subrout_name; + } else { + std::string mangled_name = subrout_name + "@" + read_write; + matched_subrout_name = mangled_name; + } + ASR::symbol_t *a_name = curr_scope->resolve_symbol(matched_subrout_name); + if( a_name == nullptr ) { + err("Unable to resolve matched subroutine for read/write overloading, " + matched_subrout_name, loc); + } + if (ASRUtils::symbol_parent_symtab(a_name)->get_counter() != curr_scope->get_counter()) { + ADD_ASR_DEPENDENCIES_WITH_NAME(curr_scope, a_name, current_function_dependencies, s2c(al, matched_subrout_name)); + } + ASRUtils::insert_module_dependency(a_name, al, current_module_dependencies); + ASRUtils::set_absent_optional_arguments_to_null(a_args, subrout, al); + asr = ASRUtils::make_SubroutineCall_t_util(al, loc, a_name, sym, + a_args.p, a_args.n, nullptr, nullptr, false, false); + } +} + +bool use_overloaded_file_read_write(std::string &read_write, Vec args, + SymbolTable* curr_scope, ASR::asr_t*& asr, + Allocator &al, const Location& loc, + SetChar& current_function_dependencies, + SetChar& current_module_dependencies, + const std::function err) { + ASR::ttype_t *arg_type = ASRUtils::type_get_past_allocatable(ASRUtils::expr_type(args[0])); + bool found = false; + ASR::symbol_t* sym = curr_scope->resolve_symbol(read_write); + ASR::expr_t* expr_dt = nullptr; + if( sym == nullptr ) { + if( ASR::is_a(*arg_type) ) { + ASR::StructType_t* arg_struct = ASR::down_cast( + ASRUtils::symbol_get_past_external(ASR::down_cast(arg_type)->m_derived_type)); + sym = arg_struct->m_symtab->resolve_symbol(read_write); + expr_dt = args[0]; + } + } else { + ASR::symbol_t* orig_sym = ASRUtils::symbol_get_past_external(sym); + ASR::CustomOperator_t* gen_proc = ASR::down_cast(orig_sym); + for( size_t i = 0; i < gen_proc->n_procs && !found; i++ ) { + ASR::symbol_t* proc = ASRUtils::symbol_get_past_external(gen_proc->m_procs[i]); + switch( proc->type ) { + case ASR::symbolType::Function: { + process_overloaded_read_write_function(read_write, proc, args, arg_type, + found, al, args[0]->base.loc, curr_scope, + current_function_dependencies, current_module_dependencies, asr, sym, + loc, expr_dt, err); + break; + } + case ASR::symbolType::ClassProcedure: { + ASR::ClassProcedure_t* class_proc = ASR::down_cast(proc); + ASR::symbol_t* proc_func = ASR::down_cast(proc)->m_proc; + process_overloaded_read_write_function(read_write, proc_func, args, arg_type, + found, al, args[0]->base.loc, curr_scope, + current_function_dependencies, current_module_dependencies, asr, proc_func, loc, + expr_dt, err, class_proc->m_self_argument); + break; + } + default: { + err("Only functions and class procedures can be used for generic read/write statement, found " + std::to_string(proc->type), loc); } } } @@ -1035,7 +1145,7 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right, ASR::down_cast( gen_proc->m_procs[i])->m_proc); } else { - proc = gen_proc->m_procs[i]; + proc = ASRUtils::symbol_get_past_external(gen_proc->m_procs[i]); } switch(proc->type) { case ASR::symbolType::Function: { @@ -1071,9 +1181,16 @@ bool use_overloaded(ASR::expr_t* left, ASR::expr_t* right, } ASR::ttype_t *return_type = nullptr; if( ASRUtils::get_FunctionType(func)->m_elemental && - func->n_args == 1 && + func->n_args >= 1 && ASRUtils::is_array(ASRUtils::expr_type(a_args[0].m_value)) ) { - return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(a_args[0].m_value)); + ASR::dimension_t* array_dims; + size_t array_n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(a_args[0].m_value), array_dims); + Vec new_dims; + new_dims.from_pointer_n_copy(al, array_dims, array_n_dims); + return_type = ASRUtils::duplicate_type(al, + ASRUtils::get_FunctionType(func)->m_return_var_type, + &new_dims); } else { return_type = ASRUtils::expr_type(func->m_return_var); } @@ -1169,7 +1286,7 @@ bool argument_types_match(const Vec& args, // Otherwise this should not be nullptr ASR::ttype_t *arg1 = ASRUtils::expr_type(args[i].m_value); ASR::ttype_t *arg2 = v->m_type; - if (!types_equal(arg1, arg2)) { + if (!types_equal(arg1, arg2, !ASRUtils::get_FunctionType(sub)->m_elemental)) { return false; } } @@ -1201,30 +1318,6 @@ bool select_func_subrout(const ASR::symbol_t* proc, const Vec& return result; } -int select_generic_procedure(const Vec& args, - const ASR::GenericProcedure_t &p, Location loc, - const std::function err, - bool raise_error) { - for (size_t i=0; i < p.n_procs; i++) { - if( ASR::is_a(*p.m_procs[i]) ) { - ASR::ClassProcedure_t *clss_fn - = ASR::down_cast(p.m_procs[i]); - const ASR::symbol_t *proc = ASRUtils::symbol_get_past_external(clss_fn->m_proc); - if( select_func_subrout(proc, args, loc, err) ) { - return i; - } - } else { - if( select_func_subrout(p.m_procs[i], args, loc, err) ) { - return i; - } - } - } - if( raise_error ) { - err("Arguments do not match for any generic procedure, " + std::string(p.m_name), loc); - } - return -1; -} - ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( const Location &loc, ASR::symbol_t *v, Vec& args, @@ -1244,9 +1337,16 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( func = ASR::down_cast(final_sym); if (func->m_return_var) { if( ASRUtils::get_FunctionType(func)->m_elemental && - func->n_args == 1 && + func->n_args >= 1 && ASRUtils::is_array(ASRUtils::expr_type(args[0].m_value)) ) { - return_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(args[0].m_value)); + ASR::dimension_t* array_dims; + size_t array_n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(args[0].m_value), array_dims); + Vec new_dims; + new_dims.from_pointer_n_copy(al, array_dims, array_n_dims); + return_type = ASRUtils::duplicate_type(al, + ASRUtils::get_FunctionType(func)->m_return_var_type, + &new_dims); } else { return_type = ASRUtils::EXPR2VAR(func->m_return_var)->m_type; } @@ -1283,7 +1383,7 @@ ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( } return ASRUtils::make_SubroutineCall_t_util(al, loc, final_sym, v, args.p, args.size(), - nullptr, nullptr, false); + nullptr, nullptr, false, false); } else { if( func ) { ASRUtils::set_absent_optional_arguments_to_null(args, func, al); @@ -1343,7 +1443,9 @@ ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, ASRUtils::expr_value(a_arg))->m_n; value = ASR::down_cast(ASR::make_UnsignedIntegerConstant_t(al, a_loc, int_value, a_type)); } else if (a_kind == ASR::cast_kindType::IntegerToLogical) { - // TODO: implement + int64_t int_value = ASR::down_cast( + ASRUtils::expr_value(a_arg))->m_n; + value = ASR::down_cast(ASR::make_LogicalConstant_t(al, a_loc, int_value, a_type)); } else if (a_kind == ASR::cast_kindType::ComplexToComplex) { ASR::ComplexConstant_t* value_complex = ASR::down_cast( ASRUtils::expr_value(a_arg)); @@ -1362,10 +1464,9 @@ ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, args.reserve(al, 1); args.push_back(al, a_arg); LCompilers::ASRUtils::create_intrinsic_function create_function = - LCompilers::ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicInteger"); - value = ASR::down_cast(create_function(al, a_loc, args, - [](const std::string&, const Location&) { - })); + LCompilers::ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicInteger"); + diag::Diagnostics diag; + value = ASR::down_cast(create_function(al, a_loc, args, diag)); } } @@ -1374,7 +1475,9 @@ ASR::asr_t* make_Cast_t_value(Allocator &al, const Location &a_loc, ASR::symbol_t* import_class_procedure(Allocator &al, const Location& loc, ASR::symbol_t* original_sym, SymbolTable *current_scope) { - if( original_sym && ASR::is_a(*original_sym) ) { + if( original_sym && (ASR::is_a(*original_sym) || + (ASR::is_a(*original_sym) && + ASR::is_a(*ASRUtils::symbol_type(original_sym)))) ) { std::string class_proc_name = ASRUtils::symbol_name(original_sym); if( original_sym != current_scope->resolve_symbol(class_proc_name) ) { std::string imported_proc_name = "1_" + class_proc_name; @@ -1463,6 +1566,7 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, Vec shape_args; shape_args.reserve(al, 1); shape_args.push_back(al, expr1); + bool is_value_character_array = ASRUtils::is_character(*ASRUtils::expr_type(expr2)); Vec dims; dims.reserve(al, 1); @@ -1475,7 +1579,7 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, dims.push_back(al, dim); ASR::ttype_t* dest_shape_type = ASRUtils::TYPE(ASR::make_Array_t(al, loc, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), dims.p, dims.size(), - ASR::array_physical_typeType::FixedSizeArray)); + is_value_character_array ? ASR::array_physical_typeType::CharacterArraySinglePointer: ASR::array_physical_typeType::FixedSizeArray)); ASR::expr_t* dest_shape = nullptr; ASR::expr_t* value = nullptr; @@ -1485,8 +1589,8 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, for( size_t i = 0; i < expr1_ndims; i++ ) { lengths.push_back(al, ASRUtils::expr_value(expr1_mdims[i].m_length)); } - dest_shape = ASRUtils::EXPR(ASR::make_ArrayConstant_t(al, loc, - lengths.p, lengths.size(), dest_shape_type, ASR::arraystorageType::ColMajor)); + dest_shape = EXPR(ASRUtils::make_ArrayConstructor_t_util(al, loc, lengths.p, + lengths.size(), dest_shape_type, ASR::arraystorageType::ColMajor)); Vec dims; dims.reserve(al, 1); ASR::dimension_t dim; @@ -1502,14 +1606,14 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, ASRUtils::get_fixed_size_of_array(expr1_mdims, expr1_ndims) <= 256 ) { ASR::ttype_t* value_type = ASRUtils::TYPE(ASR::make_Array_t(al, loc, ASRUtils::type_get_past_array(ASRUtils::expr_type(expr2)), dims.p, dims.size(), - ASR::array_physical_typeType::FixedSizeArray)); + is_value_character_array ? ASR::array_physical_typeType::CharacterArraySinglePointer: ASR::array_physical_typeType::FixedSizeArray)); Vec values; values.reserve(al, ASRUtils::get_fixed_size_of_array(expr1_mdims, expr1_ndims)); for( int64_t i = 0; i < ASRUtils::get_fixed_size_of_array(expr1_mdims, expr1_ndims); i++ ) { values.push_back(al, expr2); } - value = ASRUtils::EXPR(ASR::make_ArrayConstant_t(al, loc, - values.p, values.size(), value_type, ASR::arraystorageType::ColMajor)); + value = EXPR(ASRUtils::make_ArrayConstructor_t_util(al, loc, values.p, + values.size(), value_type, ASR::arraystorageType::ColMajor)); ret_type = value_type; } } else { @@ -1562,10 +1666,12 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, } } -int64_t compute_trailing_zeros(int64_t number) { +int64_t compute_trailing_zeros(int64_t number, int64_t kind) { int64_t trailing_zeros = 0; - if (number == 0) { + if (number == 0 && kind == 4) { return 32; + } else if (number == 0 && kind == 8) { + return 64; } while (number % 2 == 0) { number = number / 2; @@ -1574,6 +1680,30 @@ int64_t compute_trailing_zeros(int64_t number) { return trailing_zeros; } +int64_t compute_leading_zeros(int64_t number, int64_t kind) { + int64_t leading_zeros = 0; + int64_t total_bits = 32; + if (kind == 8) total_bits = 64; + if (number < 0) return 0; + while (total_bits > 0) { + if (number%2 == 0) { + leading_zeros++; + } else { + leading_zeros = 0; + } + number = number/2; + total_bits--; + } + return leading_zeros; +} + +void append_error(diag::Diagnostics& diag, const std::string& msg, + const Location& loc) { + diag.add(diag::Diagnostic(msg, diag::Level::Error, + diag::Stage::Semantic, {diag::Label("", { loc })})); +} + + //Initialize pointer to zero so that it can be initialized in first call to get_instance ASRUtils::LabelGenerator* ASRUtils::LabelGenerator::label_generator = nullptr; diff --git a/src/libasr/asr_utils.h b/src/libasr/asr_utils.h index 948a402a2b..4b43435fdd 100644 --- a/src/libasr/asr_utils.h +++ b/src/libasr/asr_utils.h @@ -8,9 +8,9 @@ #include #include -#include #include #include +#include #include @@ -112,6 +112,35 @@ static inline ASR::symbol_t *symbol_get_past_external(ASR::symbol_t *f) } } +template +Location get_vec_loc(const Vec& args) { + LCOMPILERS_ASSERT(args.size() > 0); + Location args_loc; + args_loc.first = args[0].loc.first; + args_loc.last = args[args.size() - 1].loc.last; + return args_loc; +} + +static inline ASR::FunctionType_t* get_FunctionType(ASR::symbol_t* x) { + ASR::symbol_t* a_name_ = ASRUtils::symbol_get_past_external(x); + ASR::FunctionType_t* func_type = nullptr; + if( ASR::is_a(*a_name_) ) { + func_type = ASR::down_cast( + ASR::down_cast(a_name_)->m_function_signature); + } else if( ASR::is_a(*a_name_) ) { + func_type = ASR::down_cast( + ASR::down_cast(a_name_)->m_type); + } else if( ASR::is_a(*a_name_) ) { + ASR::Function_t* func = ASR::down_cast( + ASRUtils::symbol_get_past_external( + ASR::down_cast(a_name_)->m_proc)); + func_type = ASR::down_cast(func->m_function_signature); + } else { + LCOMPILERS_ASSERT(false); + } + return func_type; +} + static inline const ASR::symbol_t *symbol_get_past_external(const ASR::symbol_t *f) { if (f->type == ASR::symbolType::ExternalSymbol) { @@ -149,8 +178,7 @@ static inline ASR::ttype_t *type_get_past_allocatable(ASR::ttype_t *f) { if (ASR::is_a(*f)) { ASR::Allocatable_t *e = ASR::down_cast(f); - LCOMPILERS_ASSERT(!ASR::is_a(*e->m_type)); - return e->m_type; + return type_get_past_allocatable(e->m_type); } else { return f; } @@ -208,6 +236,57 @@ static inline int extract_kind_from_ttype_t(const ASR::ttype_t* type) { } } +static inline void set_kind_to_ttype_t(ASR::ttype_t* type, int kind) { + if (type == nullptr) { + return; + } + switch (type->type) { + case ASR::ttypeType::Array: { + set_kind_to_ttype_t(ASR::down_cast(type)->m_type, kind); + break; + } + case ASR::ttypeType::Integer : { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::UnsignedInteger : { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::Real : { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::Complex: { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::Character: { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::Logical: { + ASR::down_cast(type)->m_kind = kind; + break; + } + case ASR::ttypeType::Pointer: { + set_kind_to_ttype_t(ASR::down_cast(type)->m_type, kind); + break; + } + case ASR::ttypeType::Allocatable: { + set_kind_to_ttype_t(ASR::down_cast(type)->m_type, kind); + break; + } + case ASR::ttypeType::Const: { + set_kind_to_ttype_t(ASR::down_cast(type)->m_type, kind); + break; + } + default : { + return; + } + } +} + static inline ASR::Variable_t* EXPR2VAR(const ASR::expr_t *f) { return ASR::down_cast(symbol_get_past_external( @@ -354,6 +433,15 @@ static inline ASR::abiType expr_abi(ASR::expr_t* e) { case ASR::exprType::GetPointer: { return ASRUtils::expr_abi(ASR::down_cast(e)->m_arg); } + case ASR::exprType::ComplexIm: { + return ASRUtils::expr_abi(ASR::down_cast(e)->m_arg); + } + case ASR::exprType::ComplexRe: { + return ASRUtils::expr_abi(ASR::down_cast(e)->m_arg); + } + case ASR::exprType::ArrayPhysicalCast: { + return ASRUtils::expr_abi(ASR::down_cast(e)->m_arg); + } default: throw LCompilersException("Cannot extract the ABI of " + std::to_string(e->type) + " expression."); @@ -412,6 +500,15 @@ static inline char *symbol_name(const ASR::symbol_t *f) } } +static inline bool get_class_proc_nopass_val(ASR::symbol_t* func_sym) { + func_sym = ASRUtils::symbol_get_past_external(func_sym); + bool nopass = false; + if (ASR::is_a(*func_sym)) { + nopass = ASR::down_cast(func_sym)->m_is_nopass; + } + return nopass; +} + static inline void encode_dimensions(size_t n_dims, std::string& res, bool use_underscore_sep=false) { if( n_dims == 0 ) { @@ -516,10 +613,76 @@ static inline std::string type_to_str(const ASR::ttype_t *t) case ASR::ttypeType::SymbolicExpression: { return "symbolic expression"; } + case ASR::ttypeType::FunctionType: { + ASR::FunctionType_t* ftp = ASR::down_cast(t); + std::string result = "("; + for( size_t i = 0; i < ftp->n_arg_types; i++ ) { + result += type_to_str(ftp->m_arg_types[i]) + ", "; + } + result += "return_type: "; + if( ftp->m_return_var_type ) { + result += type_to_str(ftp->m_return_var_type); + } else { + result += "void"; + } + result += ")"; + return result; + } default : throw LCompilersException("Not implemented " + std::to_string(t->type) + "."); } } +static inline std::string type_to_str_with_type(const ASR::ttype_t *t) { + std::string type = type_to_str(t); + std::string kind = std::to_string(extract_kind_from_ttype_t(t)); + return type + "(" + kind + ")"; +} + +static inline std::string type_to_str_with_substitution(const ASR::ttype_t *t, + std::map subs) +{ + if (ASR::is_a(*t)) { + ASR::TypeParameter_t* t_tp = ASR::down_cast(t); + t = subs[t_tp->m_param]; + } + switch (t->type) { + case ASR::ttypeType::Pointer: { + return type_to_str_with_substitution(ASRUtils::type_get_past_pointer( + const_cast(t)), subs) + " pointer"; + } + case ASR::ttypeType::Allocatable: { + return type_to_str_with_substitution(ASRUtils::type_get_past_allocatable( + const_cast(t)), subs) + " allocatable"; + } + case ASR::ttypeType::Array: { + ASR::Array_t* array_t = ASR::down_cast(t); + std::string res = type_to_str_with_substitution(array_t->m_type, subs); + encode_dimensions(array_t->n_dims, res, false); + return res; + } + case ASR::ttypeType::Const: { + return type_to_str_with_substitution(ASRUtils::get_contained_type( + const_cast(t)), subs) + " const"; + } + case ASR::ttypeType::FunctionType: { + ASR::FunctionType_t* ftp = ASR::down_cast(t); + std::string result = "("; + for( size_t i = 0; i < ftp->n_arg_types; i++ ) { + result += type_to_str_with_substitution(ftp->m_arg_types[i], subs) + ", "; + } + result += "return_type: "; + if( ftp->m_return_var_type ) { + result += type_to_str_with_substitution(ftp->m_return_var_type, subs); + } else { + result += "void"; + } + result += ")"; + return result; + } + default : return type_to_str(t); + } +} + static inline std::string binop_to_str(const ASR::binopType t) { switch (t) { case (ASR::binopType::Add): { return " + "; } @@ -847,97 +1010,113 @@ static inline bool is_value_constant(ASR::expr_t *a_value) { if( a_value == nullptr ) { return false; } - if (ASR::is_a(*a_value)) { - // OK - } else if (ASR::is_a(*a_value)) { - ASR::expr_t *val = ASR::down_cast( - a_value)->m_value; - return is_value_constant(val); - } else if (ASR::is_a(*a_value)) { - // OK - } else if (ASR::is_a(*a_value)) { - // OK - } else if (ASR::is_a(*a_value)) { - ASR::expr_t *val = ASR::down_cast( - a_value)->m_value; - return is_value_constant(val); - } else if (ASR::is_a(*a_value)) { - // OK - } else if (ASR::is_a(*a_value)) { - // OK - } else if (ASR::is_a(*a_value)) { - // OK - } else if(ASR::is_a(*a_value)) { - ASR::ArrayConstant_t* array_constant = ASR::down_cast(a_value); - for( size_t i = 0; i < array_constant->n_args; i++ ) { - if( !ASRUtils::is_value_constant(array_constant->m_args[i]) && - !ASRUtils::is_value_constant(ASRUtils::expr_value(array_constant->m_args[i])) ) { - return false; - } + switch ( a_value->type ) { + case ASR::exprType::IntegerConstant: + case ASR::exprType::IntegerBOZ: + case ASR::exprType::UnsignedIntegerConstant: + case ASR::exprType::RealConstant: + case ASR::exprType::ComplexConstant: + case ASR::exprType::LogicalConstant: + case ASR::exprType::ImpliedDoLoop: + case ASR::exprType::PointerNullConstant: + case ASR::exprType::ArrayConstant: + case ASR::exprType::StringConstant: { + return true; } - return true; - } else if(ASR::is_a(*a_value)) { - ASR::ListConstant_t* list_constant = ASR::down_cast(a_value); - for( size_t i = 0; i < list_constant->n_args; i++ ) { - if( !ASRUtils::is_value_constant(list_constant->m_args[i]) && - !ASRUtils::is_value_constant(ASRUtils::expr_value(list_constant->m_args[i])) ) { + case ASR::exprType::RealBinOp: + case ASR::exprType::IntegerUnaryMinus: + case ASR::exprType::RealUnaryMinus: + case ASR::exprType::IntegerBinOp: + case ASR::exprType::StringLen: { + return is_value_constant(expr_value(a_value)); + } case ASR::exprType::ListConstant: { + ASR::ListConstant_t* list_constant = ASR::down_cast(a_value); + for( size_t i = 0; i < list_constant->n_args; i++ ) { + if( !ASRUtils::is_value_constant(list_constant->m_args[i]) && + !ASRUtils::is_value_constant(ASRUtils::expr_value(list_constant->m_args[i])) ) { + return false; + } + } + return true; + } case ASR::exprType::IntrinsicElementalFunction: { + ASR::IntrinsicElementalFunction_t* intrinsic_elemental_function = + ASR::down_cast(a_value); + + if (ASRUtils::is_value_constant(intrinsic_elemental_function->m_value)) { + return true; + } + + for( size_t i = 0; i < intrinsic_elemental_function->n_args; i++ ) { + if( !ASRUtils::is_value_constant(intrinsic_elemental_function->m_args[i]) ) { + return false; + } + } + + return true; + } case ASR::exprType::FunctionCall: { + ASR::FunctionCall_t* func_call_t = ASR::down_cast(a_value); + if( !ASRUtils::is_intrinsic_symbol(ASRUtils::symbol_get_past_external(func_call_t->m_name)) ) { return false; } - } - return true; - } else if(ASR::is_a(*a_value)) { - ASR::FunctionCall_t* func_call_t = ASR::down_cast(a_value); - if( !ASRUtils::is_intrinsic_symbol(ASRUtils::symbol_get_past_external(func_call_t->m_name)) ) { - return false; - } - for( size_t i = 0; i < func_call_t->n_args; i++ ) { - if( !ASRUtils::is_value_constant(func_call_t->m_args[i].m_value) ) { + + ASR::Function_t* func = ASR::down_cast( + ASRUtils::symbol_get_past_external(func_call_t->m_name)); + for( size_t i = 0; i < func_call_t->n_args; i++ ) { + if (func_call_t->m_args[i].m_value == nullptr && + ASRUtils::EXPR2VAR(func->m_args[i])->m_presence == ASR::presenceType::Optional) { + continue; + } + if( !ASRUtils::is_value_constant(func_call_t->m_args[i].m_value) ) { + return false; + } + } + return true; + } case ASR::exprType::ArrayBroadcast: { + ASR::ArrayBroadcast_t* array_broadcast = ASR::down_cast(a_value); + return is_value_constant(array_broadcast->m_value); + } case ASR::exprType::StructInstanceMember: { + ASR::StructInstanceMember_t* + struct_member_t = ASR::down_cast(a_value); + return is_value_constant(struct_member_t->m_v); + } case ASR::exprType::Var: { + ASR::Var_t* var_t = ASR::down_cast(a_value); + if( ASR::is_a(*ASRUtils::symbol_get_past_external(var_t->m_v)) ) { + ASR::Variable_t* variable_t = ASR::down_cast( + ASRUtils::symbol_get_past_external(var_t->m_v)); + return variable_t->m_storage == ASR::storage_typeType::Parameter; + } else { return false; } + } case ASR::exprType::Cast: { + ASR::Cast_t* cast_t = ASR::down_cast(a_value); + return is_value_constant(cast_t->m_arg); + } case ASR::exprType::ArrayReshape: { + ASR::ArrayReshape_t* + array_reshape = ASR::down_cast(a_value); + return is_value_constant(array_reshape->m_array) && is_value_constant(array_reshape->m_shape); + } case ASR::exprType::ArrayPhysicalCast: { + ASR::ArrayPhysicalCast_t* + array_physical_t = ASR::down_cast(a_value); + return is_value_constant(array_physical_t->m_arg); + } case ASR::exprType::StructTypeConstructor: { + ASR::StructTypeConstructor_t* struct_type_constructor = + ASR::down_cast(a_value); + bool is_constant = true; + for( size_t i = 0; i < struct_type_constructor->n_args; i++ ) { + if( struct_type_constructor->m_args[i].m_value ) { + is_constant = is_constant && + (is_value_constant( + struct_type_constructor->m_args[i].m_value) || + is_value_constant( + ASRUtils::expr_value( + struct_type_constructor->m_args[i].m_value))); + } + } + return is_constant; + } default: { + return false; } - return true; - } else if( ASR::is_a(*a_value) ) { - ASR::StructInstanceMember_t* struct_member_t = ASR::down_cast(a_value); - return is_value_constant(struct_member_t->m_v); - } else if( ASR::is_a(*a_value) ) { - ASR::Var_t* var_t = ASR::down_cast(a_value); - LCOMPILERS_ASSERT(ASR::is_a(*ASRUtils::symbol_get_past_external(var_t->m_v))); - ASR::Variable_t* variable_t = ASR::down_cast( - ASRUtils::symbol_get_past_external(var_t->m_v)); - return variable_t->m_storage == ASR::storage_typeType::Parameter; - - } else if(ASR::is_a(*a_value)) { - // OK - } else if(ASR::is_a(*a_value)) { - ASR::Cast_t* cast_t = ASR::down_cast(a_value); - return is_value_constant(cast_t->m_arg); - } else if(ASR::is_a(*a_value)) { - // OK - } else if(ASR::is_a(*a_value)) { - ASR::ArrayReshape_t* array_reshape = ASR::down_cast(a_value); - return is_value_constant(array_reshape->m_array) && is_value_constant(array_reshape->m_shape); - } else if(ASR::is_a(*a_value)) { - ASR::ArrayPhysicalCast_t* array_physical_t = ASR::down_cast(a_value); - return is_value_constant(array_physical_t->m_arg); - } else if( ASR::is_a(*a_value) ) { - ASR::StructTypeConstructor_t* struct_type_constructor = - ASR::down_cast(a_value); - bool is_constant = true; - for( size_t i = 0; i < struct_type_constructor->n_args; i++ ) { - if( struct_type_constructor->m_args[i].m_value ) { - is_constant = is_constant && - (is_value_constant( - struct_type_constructor->m_args[i].m_value) || - is_value_constant( - ASRUtils::expr_value( - struct_type_constructor->m_args[i].m_value))); - } - } - return is_constant; - } else { - return false; } - return true; } static inline bool is_value_constant(ASR::expr_t *a_value, int64_t& const_value) { @@ -1045,8 +1224,9 @@ static inline bool is_value_in_range(ASR::expr_t* start, ASR::expr_t* end, ASR:: } // Returns true if all arguments are evaluated -static inline bool all_args_evaluated(const Vec &args) { +static inline bool all_args_evaluated(const Vec &args, bool ignore_null=false) { for (auto &a : args) { + if (ignore_null && !a) continue; ASR::expr_t* a_value = ASRUtils::expr_value(a); if( !is_value_constant(a_value) ) { return false; @@ -1112,6 +1292,39 @@ static inline bool extract_value(ASR::expr_t* value_expr, return true; } +static inline bool extract_string_value(ASR::expr_t* value_expr, + std::string& value) { + if( !is_value_constant(value_expr) ) { + return false; + } + switch (value_expr->type) + { + case ASR::exprType::StringConstant: { + ASR::StringConstant_t* const_string = ASR::down_cast(value_expr); + value = std::string(const_string->m_s); + break; + } + case ASR::exprType::Var: { + ASR::Variable_t* var = EXPR2VAR(value_expr); + if (var->m_storage == ASR::storage_typeType::Parameter + && !extract_string_value(var->m_value, value)) { + return false; + } + break; + } + case ASR::exprType::FunctionCall: { + ASR::FunctionCall_t* func_call = ASR::down_cast(value_expr); + if (!extract_string_value(func_call->m_value, value)) { + return false; + } + break; + } + default: + return false; + } + return true; +} + template >::value == false && @@ -1127,12 +1340,9 @@ static inline bool extract_value(ASR::expr_t* value_expr, T& value) { value = (T) const_int->m_n; break; } - case ASR::exprType::IntegerUnaryMinus: { - ASR::IntegerUnaryMinus_t* - const_int = ASR::down_cast(value_expr); - if (!extract_value(const_int->m_value, value)) { - return false; - } + case ASR::exprType::IntegerBOZ: { + ASR::IntegerBOZ_t* int_boz = ASR::down_cast(value_expr); + value = (T) int_boz->m_v; break; } case ASR::exprType::UnsignedIntegerConstant: { @@ -1145,14 +1355,6 @@ static inline bool extract_value(ASR::expr_t* value_expr, T& value) { value = (T) const_real->m_r; break; } - case ASR::exprType::RealUnaryMinus: { - ASR::RealUnaryMinus_t* - const_int = ASR::down_cast(value_expr); - if (!extract_value(const_int->m_value, value)) { - return false; - } - break; - } case ASR::exprType::LogicalConstant: { ASR::LogicalConstant_t* const_logical = ASR::down_cast(value_expr); value = (T) const_logical->m_value; @@ -1166,6 +1368,16 @@ static inline bool extract_value(ASR::expr_t* value_expr, T& value) { } break; } + case ASR::exprType::IntegerUnaryMinus: + case ASR::exprType::RealUnaryMinus: + case ASR::exprType::FunctionCall: + case ASR::exprType::IntegerBinOp: + case ASR::exprType::StringLen: { + if (!extract_value(expr_value(value_expr), value)) { + return false; + } + break; + } default: return false; } @@ -1620,10 +1832,10 @@ static inline ASR::expr_t* get_minimum_value_with_given_type(Allocator& al, ASR: case ASR::ttypeType::Integer: { int64_t val; switch (kind) { - case 1: val = std::numeric_limits::min(); break; - case 2: val = std::numeric_limits::min(); break; - case 4: val = std::numeric_limits::min(); break; - case 8: val = std::numeric_limits::min(); break; + case 1: val = std::numeric_limits::min()+1; break; + case 2: val = std::numeric_limits::min()+1; break; + case 4: val = std::numeric_limits::min()+1; break; + case 8: val = std::numeric_limits::min()+1; break; default: throw LCompilersException("get_minimum_value_with_given_type: Unsupported integer kind " + std::to_string(kind)); } @@ -1787,6 +1999,13 @@ bool use_overloaded_assignment(ASR::expr_t* target, ASR::expr_t* value, SetChar& /*current_module_dependencies*/, const std::function err); +bool use_overloaded_file_read_write(std::string &read_write, Vec args, + SymbolTable* curr_scope, ASR::asr_t*& asr, + Allocator &al, const Location& loc, + SetChar& current_function_dependencies, + SetChar& /*current_module_dependencies*/, + const std::function err); + void set_intrinsic(ASR::symbol_t* sym); static inline bool is_pointer(ASR::ttype_t *x) { @@ -1795,9 +2014,10 @@ static inline bool is_pointer(ASR::ttype_t *x) { static inline bool is_integer(ASR::ttype_t &x) { return ASR::is_a( - *type_get_past_array( + *type_get_past_const( + type_get_past_array( type_get_past_allocatable( - type_get_past_pointer(&x)))); + type_get_past_pointer(&x))))); } static inline bool is_unsigned_integer(ASR::ttype_t &x) { @@ -1925,9 +2145,9 @@ static inline int get_body_size(ASR::symbol_t* s) { return n_body; } -inline int extract_dimensions_from_ttype(ASR::ttype_t *x, +inline size_t extract_dimensions_from_ttype(ASR::ttype_t *x, ASR::dimension_t*& m_dims) { - int n_dims = 0; + size_t n_dims {}; switch (x->type) { case ASR::ttypeType::Array: { ASR::Array_t* array_t = ASR::down_cast(x); @@ -2102,6 +2322,9 @@ static inline ASR::asr_t* make_ArraySize_t_util( ASR::expr_t* start = array_section_t->m_args[i].m_left; ASR::expr_t* end = array_section_t->m_args[i].m_right; ASR::expr_t* d = array_section_t->m_args[i].m_step; + start = CastingUtil::perform_casting(start, a_type, al, a_loc); + end = CastingUtil::perform_casting(end, a_type, al, a_loc); + d = CastingUtil::perform_casting(d, a_type, al, a_loc); ASR::expr_t* endminusstart = ASRUtils::EXPR(ASR::make_IntegerBinOp_t( al, a_loc, end, ASR::binopType::Sub, start, a_type, nullptr)); ASR::expr_t* byd = ASRUtils::EXPR(ASR::make_IntegerBinOp_t( @@ -2117,6 +2340,9 @@ static inline ASR::asr_t* make_ArraySize_t_util( ASR::expr_t* start = array_section_t->m_args[dim - 1].m_left; ASR::expr_t* end = array_section_t->m_args[dim - 1].m_right; ASR::expr_t* d = array_section_t->m_args[dim - 1].m_step; + start = CastingUtil::perform_casting(start, a_type, al, a_loc); + end = CastingUtil::perform_casting(end, a_type, al, a_loc); + d = CastingUtil::perform_casting(d, a_type, al, a_loc); ASR::expr_t* endminusstart = ASRUtils::EXPR(ASR::make_IntegerBinOp_t( al, a_loc, end, ASR::binopType::Sub, start, a_type, nullptr)); ASR::expr_t* byd = ASRUtils::EXPR(ASR::make_IntegerBinOp_t( @@ -2317,7 +2543,9 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t, ASR::ttype_t* dup_type = duplicate_type(al, ptr->m_type, dims, physical_type, override_physical_type); if( override_physical_type && - physical_type == ASR::array_physical_typeType::FixedSizeArray ) { + (physical_type == ASR::array_physical_typeType::FixedSizeArray || + (physical_type == ASR::array_physical_typeType::CharacterArraySinglePointer && + dims != nullptr) ) ) { return dup_type; } return ASRUtils::TYPE(ASR::make_Pointer_t(al, ptr->base.base.loc, @@ -2378,6 +2606,9 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t, ft->m_static, ft->m_restrictions, ft->n_restrictions, ft->m_is_restriction)); } + case ASR::ttypeType::SymbolicExpression: { + return ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, t->base.loc)); + } default : throw LCompilersException("Not implemented " + std::to_string(t->type)); } LCOMPILERS_ASSERT(t_ != nullptr); @@ -2389,9 +2620,9 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t, static inline void set_absent_optional_arguments_to_null( Vec& args, ASR::Function_t* func, Allocator& al, - ASR::expr_t* dt=nullptr) { - int offset = (dt != nullptr); - for( size_t i = args.size(); i < func->n_args - offset; i++ ) { + ASR::expr_t* dt=nullptr, bool nopass = false) { + int offset = (dt != nullptr) && (!nopass); + for( size_t i = args.size(); i + offset < func->n_args; i++ ) { if( ASR::is_a( *ASR::down_cast(func->m_args[i + offset])->m_v) ) { LCOMPILERS_ASSERT(ASRUtils::EXPR2VAR(func->m_args[i + offset])->m_presence == @@ -2404,7 +2635,7 @@ static inline void set_absent_optional_arguments_to_null( args.push_back(al, empty_arg); } } - LCOMPILERS_ASSERT(args.size() == (func->n_args - offset)); + LCOMPILERS_ASSERT(args.size() + offset == (func->n_args)); } static inline ASR::ttype_t* duplicate_type_with_empty_dims(Allocator& al, ASR::ttype_t* t, @@ -2528,15 +2759,12 @@ inline int extract_kind_str(char* m_n, char *&kind_str) { return 4; } +// this function only extract's the 'kind' and raises an error when it's of +// inappropriate type (e.g. float), but doesn't ensure 'kind' is appropriate +// for whose kind it is template inline int extract_kind(ASR::expr_t* kind_expr, const Location& loc) { - int a_kind = 4; switch( kind_expr->type ) { - case ASR::exprType::IntegerConstant: { - a_kind = ASR::down_cast - (kind_expr)->m_n; - break; - } case ASR::exprType::Var: { ASR::Var_t* kind_var = ASR::down_cast(kind_expr); @@ -2550,29 +2778,64 @@ inline int extract_kind(ASR::expr_t* kind_expr, const Location& loc) { is_parent_enum = ASR::is_a(*s); } if( is_parent_enum ) { - a_kind = ASRUtils::extract_kind_from_ttype_t(kind_variable->m_type); + return ASRUtils::extract_kind_from_ttype_t(kind_variable->m_type); } else if( kind_variable->m_storage == ASR::storage_typeType::Parameter ) { if( kind_variable->m_type->type == ASR::ttypeType::Integer ) { LCOMPILERS_ASSERT( kind_variable->m_value != nullptr ); - a_kind = ASR::down_cast(kind_variable->m_value)->m_n; + return ASR::down_cast(kind_variable->m_value)->m_n; } else { std::string msg = "Integer variable required. " + std::string(kind_variable->m_name) + " is not an Integer variable."; throw SemanticError(msg, loc); } } else { - std::string msg = "Parameter " + std::string(kind_variable->m_name) + - " is a variable, which does not reduce to a constant expression"; + std::string msg = "Parameter '" + std::string(kind_variable->m_name) + + "' is a variable, which does not reduce to a constant expression"; throw SemanticError(msg, loc); } - break; } + case ASR::exprType::IntrinsicElementalFunction: { + ASR::IntrinsicElementalFunction_t* kind_isf = + ASR::down_cast(kind_expr); + if (kind_isf->m_intrinsic_id == 1 && kind_isf->m_value) { + // m_intrinsic_id: 1 -> kind intrinsic + LCOMPILERS_ASSERT( ASR::is_a(*kind_isf->m_value) ); + ASR::IntegerConstant_t* kind_ic = + ASR::down_cast(kind_isf->m_value); + return kind_ic->m_n; + } else { + throw SemanticError("Only Integer literals or expressions which " + "reduce to constant Integer are accepted as kind parameters.", + loc); + } + } + // allow integer binary operator kinds (e.g. '1 + 7') + case ASR::exprType::IntegerBinOp: + // allow integer kinds (e.g. 4, 8 etc.) + case ASR::exprType::IntegerConstant: { + int a_kind = -1; + if (!ASRUtils::extract_value(kind_expr, a_kind)) { + // we still need to ensure that values are constant + // e.g. "integer :: a = 4; real(1*a) :: x" is an invalid kind, + // as 'a' isn't a constant. + // ToDo: we should raise a better error, by "locating" just + // 'a' as well, instead of the whole '1*a' + throw SemanticError("Only Integer literals or expressions which " + "reduce to constant Integer are accepted as kind parameters.", + loc); + } + return a_kind; + } + // make sure not to allow kind having "RealConstant" (e.g. 4.0), + // and everything else default: { - throw SemanticError(R"""(Only Integer literals or expressions which reduce to constant Integer are accepted as kind parameters.)""", - loc); + throw SemanticError( + "Only Integer literals or expressions which " + "reduce to constant Integer are accepted as kind parameters.", + loc + ); } } - return a_kind; } template @@ -2600,7 +2863,7 @@ inline int extract_len(ASR::expr_t* len_expr, const Location& loc) { throw SemanticError(msg, loc); } } else { - // An expression is beind used for `len` that cannot be evaluated + // An expression is being used for `len` that cannot be evaluated a_len = -3; } break; @@ -2610,12 +2873,17 @@ inline int extract_len(ASR::expr_t* len_expr, const Location& loc) { a_len = -3; break; } + case ASR::exprType::ArraySize: case ASR::exprType::IntegerBinOp: { a_len = -3; break; } + case ASR::exprType::IntrinsicElementalFunction: { + a_len = -3; + break; + } default: { - throw SemanticError("Only Integers or variables implemented so far for `len` expressions", + throw SemanticError("Only Integers or variables implemented so far for `len` expressions, found: " + std::to_string(len_expr->type), loc); } } @@ -2714,25 +2982,37 @@ inline bool expr_equal(ASR::expr_t* x, ASR::expr_t* y) { return true; } -inline bool dimension_expr_equal(ASR::expr_t* dim_a, ASR::expr_t* dim_b) { - if( !(dim_a && dim_b) ) { +// Compares two dimension expressions for equality. +// Optionally allows skipping determination in certain cases. +inline bool dimension_expr_equal( + ASR::expr_t* dim_a, + ASR::expr_t* dim_b +) { + // If either dimension is null, consider them equal by default. + if (!(dim_a && dim_b)) { return true; } - int dim_a_int = -1, dim_b_int = -1; - if (ASRUtils::extract_value(ASRUtils::expr_value(dim_a), dim_a_int) - && ASRUtils::extract_value(ASRUtils::expr_value(dim_b), dim_b_int)) { + + int dim_a_int {-1}; + int dim_b_int {-1}; + + if (ASRUtils::extract_value(ASRUtils::expr_value(dim_a), dim_a_int) && + ASRUtils::extract_value(ASRUtils::expr_value(dim_b), dim_b_int)) { return dim_a_int == dim_b_int; } - if( !ASRUtils::expr_equal(dim_a, dim_b) ) { + if (!ASRUtils::expr_equal(dim_a, dim_b)) { return false; } + return true; } inline bool dimensions_equal(ASR::dimension_t* dims_a, size_t n_dims_a, - ASR::dimension_t* dims_b, size_t n_dims_b) { - if( n_dims_a != n_dims_b ) { + ASR::dimension_t* dims_b, size_t n_dims_b +) { + // unequal ranks means dimensions aren't equal + if (n_dims_a != n_dims_b) { return false; } @@ -2752,6 +3032,9 @@ inline bool types_equal(ASR::ttype_t *a, ASR::ttype_t *b, // TODO: If anyone of the input or argument is derived type then // add support for checking member wise types and do not compare // directly. From stdlib_string len(pattern) error + if( a == nullptr && b == nullptr ) { + return true; + } a = ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(a)); b = ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(b)); if( !check_for_dimensions ) { @@ -2862,6 +3145,207 @@ inline bool types_equal(ASR::ttype_t *a, ASR::ttype_t *b, b2->m_union_type)); return a2_type == b2_type; } + case ASR::ttypeType::FunctionType: { + ASR::FunctionType_t* a2 = ASR::down_cast(a); + ASR::FunctionType_t* b2 = ASR::down_cast(b); + if( a2->n_arg_types != b2->n_arg_types || + (a2->m_return_var_type != nullptr && b2->m_return_var_type == nullptr) || + (a2->m_return_var_type == nullptr && b2->m_return_var_type != nullptr) ) { + return false; + } + for( size_t i = 0; i < a2->n_arg_types; i++ ) { + if( !types_equal(a2->m_arg_types[i], b2->m_arg_types[i], true) ) { + return false; + } + } + if( !types_equal(a2->m_return_var_type, b2->m_return_var_type, true) ) { + return false; + } + return true; + } + default : return false; + } + } else if( a->type == ASR::ttypeType::Struct && + b->type == ASR::ttypeType::Class ) { + ASR::Struct_t *a2 = ASR::down_cast(a); + ASR::Class_t *b2 = ASR::down_cast(b); + ASR::symbol_t* a2_typesym = ASRUtils::symbol_get_past_external(a2->m_derived_type); + ASR::symbol_t* b2_typesym = ASRUtils::symbol_get_past_external(b2->m_class_type); + if( a2_typesym->type != b2_typesym->type ) { + return false; + } + if( a2_typesym->type == ASR::symbolType::ClassType ) { + ASR::ClassType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::ClassType_t *b2_type = ASR::down_cast(b2_typesym); + return a2_type == b2_type; + } else if( a2_typesym->type == ASR::symbolType::StructType ) { + ASR::StructType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::StructType_t *b2_type = ASR::down_cast(b2_typesym); + return is_derived_type_similar(a2_type, b2_type); + } + } else if( a->type == ASR::ttypeType::Class && + b->type == ASR::ttypeType::Struct ) { + ASR::Class_t *a2 = ASR::down_cast(a); + ASR::Struct_t *b2 = ASR::down_cast(b); + ASR::symbol_t* a2_typesym = ASRUtils::symbol_get_past_external(a2->m_class_type); + ASR::symbol_t* b2_typesym = ASRUtils::symbol_get_past_external(b2->m_derived_type); + if( a2_typesym->type != b2_typesym->type ) { + return false; + } + if( a2_typesym->type == ASR::symbolType::ClassType ) { + ASR::ClassType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::ClassType_t *b2_type = ASR::down_cast(b2_typesym); + return a2_type == b2_type; + } else if( a2_typesym->type == ASR::symbolType::StructType ) { + ASR::StructType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::StructType_t *b2_type = ASR::down_cast(b2_typesym); + return is_derived_type_similar(a2_type, b2_type); + } + } + return false; +} + +inline bool types_equal_with_substitution(ASR::ttype_t *a, ASR::ttype_t *b, + std::map subs, + bool check_for_dimensions=false) { + // TODO: If anyone of the input or argument is derived type then + // add support for checking member wise types and do not compare + // directly. From stdlib_string len(pattern) error + if( a == nullptr && b == nullptr ) { + return true; + } + a = ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(a)); + b = ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(b)); + if( !check_for_dimensions ) { + a = ASRUtils::type_get_past_array(a); + b = ASRUtils::type_get_past_array(b); + } + if (ASR::is_a(*a)) { + ASR::TypeParameter_t* a_tp = ASR::down_cast(a); + a = subs[a_tp->m_param]; + } + if (a->type == b->type) { + // TODO: check dims + // TODO: check all types + switch (a->type) { + case (ASR::ttypeType::Array): { + ASR::Array_t* a2 = ASR::down_cast(a); + ASR::Array_t* b2 = ASR::down_cast(b); + if( !types_equal_with_substitution(a2->m_type, b2->m_type, subs) ) { + return false; + } + + return ASRUtils::dimensions_equal( + a2->m_dims, a2->n_dims, + b2->m_dims, b2->n_dims); + } + case (ASR::ttypeType::TypeParameter) : { + ASR::TypeParameter_t* left_tp = ASR::down_cast(a); + ASR::TypeParameter_t* right_tp = ASR::down_cast(b); + std::string left_param = left_tp->m_param; + std::string right_param = right_tp->m_param; + return left_param == right_param; + } + case (ASR::ttypeType::Integer) : { + ASR::Integer_t *a2 = ASR::down_cast(a); + ASR::Integer_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case (ASR::ttypeType::UnsignedInteger) : { + ASR::UnsignedInteger_t *a2 = ASR::down_cast(a); + ASR::UnsignedInteger_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case ASR::ttypeType::CPtr: { + return true; + } + case ASR::ttypeType::SymbolicExpression: { + return true; + } + case (ASR::ttypeType::Real) : { + ASR::Real_t *a2 = ASR::down_cast(a); + ASR::Real_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case (ASR::ttypeType::Complex) : { + ASR::Complex_t *a2 = ASR::down_cast(a); + ASR::Complex_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case (ASR::ttypeType::Logical) : { + ASR::Logical_t *a2 = ASR::down_cast(a); + ASR::Logical_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case (ASR::ttypeType::Character) : { + ASR::Character_t *a2 = ASR::down_cast(a); + ASR::Character_t *b2 = ASR::down_cast(b); + return (a2->m_kind == b2->m_kind); + } + case (ASR::ttypeType::List) : { + ASR::List_t *a2 = ASR::down_cast(a); + ASR::List_t *b2 = ASR::down_cast(b); + return types_equal_with_substitution(a2->m_type, b2->m_type, subs); + } + case (ASR::ttypeType::Struct) : { + ASR::Struct_t *a2 = ASR::down_cast(a); + ASR::Struct_t *b2 = ASR::down_cast(b); + ASR::StructType_t *a2_type = ASR::down_cast( + ASRUtils::symbol_get_past_external( + a2->m_derived_type)); + ASR::StructType_t *b2_type = ASR::down_cast( + ASRUtils::symbol_get_past_external( + b2->m_derived_type)); + return a2_type == b2_type; + } + case (ASR::ttypeType::Class) : { + ASR::Class_t *a2 = ASR::down_cast(a); + ASR::Class_t *b2 = ASR::down_cast(b); + ASR::symbol_t* a2_typesym = ASRUtils::symbol_get_past_external(a2->m_class_type); + ASR::symbol_t* b2_typesym = ASRUtils::symbol_get_past_external(b2->m_class_type); + if( a2_typesym->type != b2_typesym->type ) { + return false; + } + if( a2_typesym->type == ASR::symbolType::ClassType ) { + ASR::ClassType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::ClassType_t *b2_type = ASR::down_cast(b2_typesym); + return a2_type == b2_type; + } else if( a2_typesym->type == ASR::symbolType::StructType ) { + ASR::StructType_t *a2_type = ASR::down_cast(a2_typesym); + ASR::StructType_t *b2_type = ASR::down_cast(b2_typesym); + return is_derived_type_similar(a2_type, b2_type); + } + return false; + } + case (ASR::ttypeType::Union) : { + ASR::Union_t *a2 = ASR::down_cast(a); + ASR::Union_t *b2 = ASR::down_cast(b); + ASR::UnionType_t *a2_type = ASR::down_cast( + ASRUtils::symbol_get_past_external( + a2->m_union_type)); + ASR::UnionType_t *b2_type = ASR::down_cast( + ASRUtils::symbol_get_past_external( + b2->m_union_type)); + return a2_type == b2_type; + } + case ASR::ttypeType::FunctionType: { + ASR::FunctionType_t* a2 = ASR::down_cast(a); + ASR::FunctionType_t* b2 = ASR::down_cast(b); + if( a2->n_arg_types != b2->n_arg_types || + (a2->m_return_var_type != nullptr && b2->m_return_var_type == nullptr) || + (a2->m_return_var_type == nullptr && b2->m_return_var_type != nullptr) ) { + return false; + } + for( size_t i = 0; i < a2->n_arg_types; i++ ) { + if( !types_equal_with_substitution(a2->m_arg_types[i], b2->m_arg_types[i], subs, true) ) { + return false; + } + } + if( !types_equal_with_substitution(a2->m_return_var_type, b2->m_return_var_type, subs, true) ) { + return false; + } + return true; + } default : return false; } } else if( a->type == ASR::ttypeType::Struct && @@ -3003,10 +3487,33 @@ inline bool check_equal_type(ASR::ttype_t* x, ASR::ttype_t* y, bool check_for_di return types_equal(x, y, check_for_dimensions); } +bool select_func_subrout(const ASR::symbol_t* proc, const Vec& args, + Location& loc, const std::function err); + +template int select_generic_procedure(const Vec &args, - const ASR::GenericProcedure_t &p, Location loc, - const std::function err, - bool raise_error=true); + const T &p, Location loc, + const std::function err, + bool raise_error=true) { + for (size_t i=0; i < p.n_procs; i++) { + if( ASR::is_a(*p.m_procs[i]) ) { + ASR::ClassProcedure_t *clss_fn + = ASR::down_cast(p.m_procs[i]); + const ASR::symbol_t *proc = ASRUtils::symbol_get_past_external(clss_fn->m_proc); + if( select_func_subrout(proc, args, loc, err) ) { + return i; + } + } else { + if( select_func_subrout(p.m_procs[i], args, loc, err) ) { + return i; + } + } + } + if( raise_error ) { + err("Arguments do not match for any generic procedure, " + std::string(p.m_name), loc); + } + return -1; +} ASR::asr_t* symbol_resolve_external_generic_procedure_without_eval( const Location &loc, @@ -3241,65 +3748,76 @@ class ReplaceArgVisitor: public ASR::BaseExprReplacer { f = ASR::down_cast(f_sym); } } - ASR::Module_t *m = ASR::down_cast2(f->m_symtab->parent->asr_owner); - char *modname = m->m_name; - ASR::symbol_t *maybe_f = current_scope->resolve_symbol(std::string(f->m_name)); - ASR::symbol_t* maybe_f_actual = nullptr; - std::string maybe_modname = ""; - if( maybe_f && ASR::is_a(*maybe_f) ) { - maybe_modname = ASR::down_cast(maybe_f)->m_module_name; - maybe_f_actual = ASRUtils::symbol_get_past_external(maybe_f); - } - // If the Function to be imported is already present - // then do not import. - if( maybe_modname == std::string(modname) && - f_sym == maybe_f_actual ) { - new_es = maybe_f; - } else { - // Import while assigning a new name to avoid conflicts - // For example, if someone is using `len` from a user - // define module then `get_unique_name` will avoid conflict - std::string unique_name = current_scope->get_unique_name(f->m_name, false); - Str s; s.from_str_view(unique_name); - char *unique_name_c = s.c_str(al); - LCOMPILERS_ASSERT(current_scope->get_symbol(unique_name) == nullptr); - new_es = ASR::down_cast(ASR::make_ExternalSymbol_t( - al, f->base.base.loc, - /* a_symtab */ current_scope, - /* a_name */ unique_name_c, - (ASR::symbol_t*)f, - modname, nullptr, 0, - f->m_name, - ASR::accessType::Private - )); - current_scope->add_symbol(unique_name, new_es); - } - // The following substitutes args from the current scope - for (size_t i = 0; i < x->n_args; i++) { - ASR::expr_t** current_expr_copy_ = current_expr; - current_expr = &(x->m_args[i].m_value); - replace_expr(x->m_args[i].m_value); - current_expr = current_expr_copy_; - } - switch( x->m_type->type ) { - case ASR::ttypeType::Character: { - ASR::Character_t* char_type = ASR::down_cast(x->m_type); - if( char_type->m_len_expr ) { + ASR::Module_t *m = nullptr; + if (ASR::is_a(*f->m_symtab->parent->asr_owner)) { + ASR::symbol_t* sym = ASR::down_cast(f->m_symtab->parent->asr_owner); + if (ASR::is_a(*sym)) { + m = ASR::down_cast(sym); + char *modname = m->m_name; + ASR::symbol_t *maybe_f = current_scope->resolve_symbol(std::string(f->m_name)); + ASR::symbol_t* maybe_f_actual = nullptr; + std::string maybe_modname = ""; + if( maybe_f && ASR::is_a(*maybe_f) ) { + maybe_modname = ASR::down_cast(maybe_f)->m_module_name; + maybe_f_actual = ASRUtils::symbol_get_past_external(maybe_f); + } + // If the Function to be imported is already present + // then do not import. + if( maybe_modname == std::string(modname) && + f_sym == maybe_f_actual ) { + new_es = maybe_f; + } else { + // Import while assigning a new name to avoid conflicts + // For example, if someone is using `len` from a user + // define module then `get_unique_name` will avoid conflict + std::string unique_name = current_scope->get_unique_name(f->m_name, false); + Str s; s.from_str_view(unique_name); + char *unique_name_c = s.c_str(al); + LCOMPILERS_ASSERT(current_scope->get_symbol(unique_name) == nullptr); + new_es = ASR::down_cast(ASR::make_ExternalSymbol_t( + al, f->base.base.loc, + /* a_symtab */ current_scope, + /* a_name */ unique_name_c, + (ASR::symbol_t*)f, + modname, nullptr, 0, + f->m_name, + ASR::accessType::Private + )); + current_scope->add_symbol(unique_name, new_es); + } + // The following substitutes args from the current scope + for (size_t i = 0; i < x->n_args; i++) { ASR::expr_t** current_expr_copy_ = current_expr; - current_expr = &(char_type->m_len_expr); - replace_expr(char_type->m_len_expr); + current_expr = &(x->m_args[i].m_value); + replace_expr(x->m_args[i].m_value); current_expr = current_expr_copy_; } - break; + replace_ttype(x->m_type); + if (ASRUtils::symbol_parent_symtab(new_es)->get_counter() != current_scope->get_counter()) { + ADD_ASR_DEPENDENCIES(current_scope, new_es, current_function_dependencies); + } + ASRUtils::insert_module_dependency(new_es, al, current_module_dependencies); + x->m_name = new_es; + if( x->m_original_name ) { + ASR::symbol_t* x_original_name = current_scope->resolve_symbol(ASRUtils::symbol_name(x->m_original_name)); + if( x_original_name ) { + x->m_original_name = x_original_name; + } + } + return; + } else { + return; } - default: - break; } - if (ASRUtils::symbol_parent_symtab(new_es)->get_counter() != current_scope->get_counter()) { - ADD_ASR_DEPENDENCIES(current_scope, new_es, current_function_dependencies); + // iterate over the arguments and replace them + for (size_t i = 0; i < x->n_args; i++) { + ASR::expr_t** current_expr_copy_ = current_expr; + current_expr = &(x->m_args[i].m_value); + if (x->m_args[i].m_value) { + replace_expr(x->m_args[i].m_value); + } + current_expr = current_expr_copy_; } - ASRUtils::insert_module_dependency(new_es, al, current_module_dependencies); - x->m_name = new_es; } void replace_Var(ASR::Var_t* x) { @@ -3352,6 +3870,49 @@ class ExprStmtDuplicator: public ASR::BaseExprStmtDuplicator }; +class FixScopedTypeVisitor: public ASR::BaseExprReplacer { + + private: + + Allocator& al; + SymbolTable* current_scope; + + public: + + FixScopedTypeVisitor(Allocator& al_, SymbolTable* current_scope_) : + al(al_), current_scope(current_scope_) {} + + void replace_Struct(ASR::Struct_t* x) { + ASR::symbol_t* m_derived_type = current_scope->resolve_symbol( + ASRUtils::symbol_name(x->m_derived_type)); + if (m_derived_type == nullptr) { + std::string imported_name = current_scope->get_unique_name( + ASRUtils::symbol_name(x->m_derived_type)); + m_derived_type = ASR::down_cast(ASR::make_ExternalSymbol_t( + al, x->base.base.loc, current_scope, s2c(al, imported_name), + x->m_derived_type, ASRUtils::get_sym_module( + ASRUtils::symbol_get_past_external(x->m_derived_type))->m_name, + nullptr, 0, ASRUtils::symbol_name( + ASRUtils::symbol_get_past_external(x->m_derived_type)), + ASR::accessType::Public)); + current_scope->add_symbol(imported_name, m_derived_type); + } + x->m_derived_type = m_derived_type; + } + +}; + +static inline ASR::ttype_t* fix_scoped_type(Allocator& al, + ASR::ttype_t* type, SymbolTable* scope) { + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(type); + ASRUtils::FixScopedTypeVisitor fixer(al, scope); + fixer.replace_ttype(type_); + return type_; + +} + class ReplaceWithFunctionParamVisitor: public ASR::BaseExprReplacer { private: @@ -4082,25 +4643,6 @@ static inline ASR::expr_t* get_size(ASR::expr_t* arr_expr, Allocator& al) { return ASRUtils::EXPR(ASRUtils::make_ArraySize_t_util(al, arr_expr->base.loc, arr_expr, nullptr, int32_type, nullptr)); } -static inline void get_dimensions(ASR::expr_t* array, Vec& dims, - Allocator& al) { - ASR::ttype_t* array_type = ASRUtils::expr_type(array); - ASR::dimension_t* compile_time_dims = nullptr; - int n_dims = extract_dimensions_from_ttype(array_type, compile_time_dims); - for( int i = 0; i < n_dims; i++ ) { - ASR::expr_t* start = compile_time_dims[i].m_start; - if( start == nullptr ) { - start = get_bound(array, i + 1, "lbound", al); - } - ASR::expr_t* length = compile_time_dims[i].m_length; - if( length == nullptr ) { - length = get_size(array, i + 1, al); - } - dims.push_back(al, start); - dims.push_back(al, length); - } -} - static inline ASR::EnumType_t* get_EnumType_from_symbol(ASR::symbol_t* s) { ASR::Variable_t* s_var = ASR::down_cast(s); if( ASR::is_a(*s_var->m_type) ) { @@ -4304,7 +4846,7 @@ class VerifyAbort {}; static inline void require_impl(bool cond, const std::string &error_msg, const Location &loc, diag::Diagnostics &diagnostics) { if (!cond) { - diagnostics.message_label("ASR verify: " + error_msg, + diagnostics.message_label(error_msg, {loc}, "failed here", diag::Level::Error, diag::Stage::ASRVerify); throw VerifyAbort(); @@ -4423,7 +4965,21 @@ static inline ASR::asr_t* make_ArrayPhysicalCast_t_util(Allocator &al, const Loc return ASR::make_ArrayPhysicalCast_t(al, a_loc, a_arg, a_old, a_new, a_type, a_value); } -inline ASR::asr_t* make_ArrayConstant_t_util(Allocator &al, const Location &a_loc, +inline void flatten_ArrayConstant(Allocator& al, ASR::expr_t** a_args, size_t n_args, Vec &new_args) { + for (size_t i = 0; i < n_args; i++) { + if (ASR::is_a(*a_args[i])) { + ASR::ArrayConstant_t* a_arg = ASR::down_cast(a_args[i]); + flatten_ArrayConstant(al, a_arg->m_args, a_arg->n_args, new_args); + } else if (ASR::is_a(*ASRUtils::expr_value(a_args[i]))) { + ASR::ArrayConstant_t* a_arg = ASR::down_cast(ASRUtils::expr_value(a_args[i])); + flatten_ArrayConstant(al, a_arg->m_args, a_arg->n_args, new_args); + } else { + new_args.push_back(al, ASRUtils::expr_value(a_args[i])); + } + } +} + +inline ASR::asr_t* make_ArrayConstructor_t_util(Allocator &al, const Location &a_loc, ASR::expr_t** a_args, size_t n_args, ASR::ttype_t* a_type, ASR::arraystorageType a_storage_format) { if( !ASRUtils::is_array(a_type) ) { Vec dims; @@ -4447,31 +5003,43 @@ inline ASR::asr_t* make_ArrayConstant_t_util(Allocator &al, const Location &a_lo } LCOMPILERS_ASSERT(ASRUtils::is_array(a_type)); - return ASR::make_ArrayConstant_t(al, a_loc, a_args, n_args, a_type, a_storage_format); + bool all_expr_evaluated = n_args > 0; + for (size_t i = 0; i < n_args; i++) { + ASR::expr_t* a_value = ASRUtils::expr_value(a_args[i]); + if (!is_value_constant(a_value)) { + all_expr_evaluated = false; + } + } + if (all_expr_evaluated) { + Vec a_args_values; a_args_values.reserve(al, n_args); + flatten_ArrayConstant(al, a_args, n_args, a_args_values); + ASR::Array_t* a_type_ = ASR::down_cast(a_type); + Vec dims; dims.reserve(al, 1); + ASR::dimension_t dim; dim.loc = a_type_->m_dims[0].loc; dim.m_start = a_type_->m_dims[0].m_start; + dim.m_length = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, a_type_->m_dims[0].m_length->base.loc, + a_args_values.n, + ASRUtils::TYPE(ASR::make_Integer_t(al, a_loc, 4)))); + dims.push_back(al, dim); + ASR::ttype_t* new_type = ASRUtils::TYPE(ASR::make_Array_t(al, a_type->base.loc, a_type_->m_type, + dims.p, dims.n, a_type_->m_physical_type)); + return ASR::make_ArrayConstant_t(al, a_loc, a_args_values.p, a_args_values.n, new_type, a_storage_format); + } else { + return ASR::make_ArrayConstructor_t(al, a_loc, a_args, n_args, a_type, nullptr, a_storage_format); + } } void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc, ASR::expr_t*& expr1, ASR::expr_t*& expr2); static inline void Call_t_body(Allocator& al, ASR::symbol_t* a_name, - ASR::call_arg_t* a_args, size_t n_args, ASR::expr_t* a_dt, ASR::stmt_t** cast_stmt, bool implicit_argument_casting) { - bool is_method = a_dt != nullptr; + ASR::call_arg_t* a_args, size_t n_args, ASR::expr_t* a_dt, ASR::stmt_t** cast_stmt, + bool implicit_argument_casting, bool nopass) { + bool is_method = (a_dt != nullptr) && (!nopass); ASR::symbol_t* a_name_ = ASRUtils::symbol_get_past_external(a_name); - ASR::FunctionType_t* func_type = nullptr; - if( ASR::is_a(*a_name_) ) { - func_type = ASR::down_cast( - ASR::down_cast(a_name_)->m_function_signature); - } else if( ASR::is_a(*a_name_) ) { - func_type = ASR::down_cast( - ASR::down_cast(a_name_)->m_type); - } else if( ASR::is_a(*a_name_) ) { - ASR::Function_t* func = ASR::down_cast( - ASRUtils::symbol_get_past_external( - ASR::down_cast(a_name_)->m_proc)); - func_type = ASR::down_cast(func->m_function_signature); - } else { - LCOMPILERS_ASSERT(false); + if( ASR::is_a(*a_name_) ) { + is_method = false; } + ASR::FunctionType_t* func_type = get_FunctionType(a_name); for( size_t i = 0; i < n_args; i++ ) { if( a_args[i].m_value == nullptr || @@ -4564,7 +5132,7 @@ static inline void Call_t_body(Allocator& al, ASR::symbol_t* a_name, dim.push_back(al, dim_); ASR::ttype_t* array_type = ASRUtils::TYPE(ASR::make_Array_t(al, arg->base.loc, int32_type, dim.p, dim.size(), ASR::array_physical_typeType::FixedSizeArray)); - ASR::asr_t* array_constant = ASRUtils::make_ArrayConstant_t_util(al, arg->base.loc, args_.p, args_.size(), array_type, ASR::arraystorageType::ColMajor); + ASR::asr_t* array_constant = ASRUtils::make_ArrayConstructor_t_util(al, arg->base.loc, args_.p, args_.size(), array_type, ASR::arraystorageType::ColMajor); ASR::asr_t* cptr_to_pointer = ASR::make_CPtrToPointer_t(al, arg->base.loc, ASRUtils::EXPR(pointer_to_cptr), cast_expr, ASRUtils::EXPR(array_constant), nullptr); *cast_stmt = ASRUtils::STMT(cptr_to_pointer); @@ -4632,7 +5200,7 @@ static inline ASR::asr_t* make_FunctionCall_t_util( ASR::symbol_t* a_original_name, ASR::call_arg_t* a_args, size_t n_args, ASR::ttype_t* a_type, ASR::expr_t* a_value, ASR::expr_t* a_dt) { - Call_t_body(al, a_name, a_args, n_args, a_dt, nullptr, false); + Call_t_body(al, a_name, a_args, n_args, a_dt, nullptr, false, false); return ASR::make_FunctionCall_t(al, a_loc, a_name, a_original_name, a_args, n_args, a_type, a_value, a_dt); @@ -4641,12 +5209,39 @@ static inline ASR::asr_t* make_FunctionCall_t_util( static inline ASR::asr_t* make_SubroutineCall_t_util( Allocator &al, const Location &a_loc, ASR::symbol_t* a_name, ASR::symbol_t* a_original_name, ASR::call_arg_t* a_args, size_t n_args, - ASR::expr_t* a_dt, ASR::stmt_t** cast_stmt, bool implicit_argument_casting) { + ASR::expr_t* a_dt, ASR::stmt_t** cast_stmt, bool implicit_argument_casting, bool nopass) { + + Call_t_body(al, a_name, a_args, n_args, a_dt, cast_stmt, implicit_argument_casting, nopass); + + if( a_dt && ASR::is_a( + *ASRUtils::symbol_get_past_external(a_name)) && + ASR::is_a(*ASRUtils::symbol_type(a_name)) ) { + a_dt = ASRUtils::EXPR(ASR::make_StructInstanceMember_t(al, a_loc, + a_dt, a_name, ASRUtils::symbol_type(a_name), nullptr)); + } + + return ASR::make_SubroutineCall_t(al, a_loc, a_name, a_original_name, a_args, n_args, a_dt); +} + +static inline void promote_ints_to_kind_8(ASR::expr_t** m_args, size_t n_args, + Allocator& al, const Location& loc) { + for (size_t i = 0; i < n_args; i++) { + if (ASRUtils::is_integer(*ASRUtils::expr_type(m_args[i]))) { + ASR::ttype_t* arg_type = ASRUtils::expr_type(m_args[i]); + ASR::ttype_t* dest_type = ASRUtils::duplicate_type(al, arg_type); + ASRUtils::set_kind_to_ttype_t(dest_type, 8); + m_args[i] = CastingUtil::perform_casting(m_args[i], dest_type, al, loc); + } + } +} + +static inline ASR::asr_t* make_StringFormat_t_util(Allocator &al, const Location &a_loc, + ASR::expr_t* a_fmt, ASR::expr_t** a_args, size_t n_args, ASR::string_format_kindType a_kind, + ASR::ttype_t* a_type, ASR::expr_t* a_value) { - Call_t_body(al, a_name, a_args, n_args, a_dt, cast_stmt, implicit_argument_casting); + promote_ints_to_kind_8(a_args, n_args, al, a_loc); - return ASR::make_SubroutineCall_t(al, a_loc, a_name, a_original_name, - a_args, n_args, a_dt); + return ASR::make_StringFormat_t(al, a_loc, a_fmt, a_args, n_args, a_kind, a_type, a_value); } static inline ASR::expr_t* cast_to_descriptor(Allocator& al, ASR::expr_t* arg) { @@ -4665,7 +5260,7 @@ static inline ASR::expr_t* cast_to_descriptor(Allocator& al, ASR::expr_t* arg) { return arg; } -static inline ASR::asr_t* make_IntrinsicScalarFunction_t_util( +static inline ASR::asr_t* make_IntrinsicElementalFunction_t_util( Allocator &al, const Location &a_loc, int64_t a_intrinsic_id, ASR::expr_t** a_args, size_t n_args, int64_t a_overload_id, ASR::ttype_t* a_type, ASR::expr_t* a_value) { @@ -4684,7 +5279,7 @@ static inline ASR::asr_t* make_IntrinsicScalarFunction_t_util( } } - return ASR::make_IntrinsicScalarFunction_t(al, a_loc, a_intrinsic_id, + return ASR::make_IntrinsicElementalFunction_t(al, a_loc, a_intrinsic_id, a_args, n_args, a_overload_id, a_type, a_value); } @@ -4767,7 +5362,10 @@ inline ASR::ttype_t* make_Pointer_t_util(Allocator& al, const Location& loc, ASR return ASRUtils::TYPE(ASR::make_Pointer_t(al, loc, type)); } -int64_t compute_trailing_zeros(int64_t number); +int64_t compute_trailing_zeros(int64_t number, int64_t kind); +int64_t compute_leading_zeros(int64_t number, int64_t kind); +void append_error(diag::Diagnostics& diag, const std::string& msg, + const Location& loc); static inline bool is_simd_array(ASR::expr_t *v) { return (ASR::is_a(*expr_type(v)) && diff --git a/src/libasr/asr_verify.cpp b/src/libasr/asr_verify.cpp index 7f6dc8484b..670d0a1f9e 100644 --- a/src/libasr/asr_verify.cpp +++ b/src/libasr/asr_verify.cpp @@ -51,6 +51,8 @@ class VerifyVisitor : public BaseWalkVisitor std::set> const_assigned; bool symbol_visited; + bool _return_var_or_intent_out = false; + bool _processing_dims = false; public: VerifyVisitor(bool check_external, diag::Diagnostics &diagnostics) : check_external{check_external}, @@ -122,6 +124,20 @@ class VerifyVisitor : public BaseWalkVisitor current_symtab = nullptr; } + void visit_Select(const Select_t& x) { + bool fall_through = false; + for( size_t i = 0; i < x.n_body; i++ ) { + if( ASR::is_a(*x.m_body[i]) ) { + ASR::CaseStmt_t* case_stmt_t = ASR::down_cast(x.m_body[i]); + fall_through = fall_through || case_stmt_t->m_fall_through; + } + } + require(fall_through == x.m_enable_fall_through, + "Select_t::m_enable_fall_through should be " + + std::to_string(x.m_enable_fall_through)); + BaseWalkVisitor::visit_Select(x); + } + // -------------------------------------------------------- // symbol instances: @@ -426,6 +442,7 @@ class VerifyVisitor : public BaseWalkVisitor LCOMPILERS_ASSERT(a.second); this->visit_symbol(*a.second); } + visit_ttype(*x.m_function_signature); for (size_t i=0; i visit_expr(*x.m_symbolic_value); if (x.m_value) visit_expr(*x.m_value); + _return_var_or_intent_out = x.m_intent == ASR::intentType::Out || + x.m_intent == ASR::intentType::InOut || + x.m_intent == ASR::intentType::ReturnVar; visit_ttype(*x.m_type); + _return_var_or_intent_out = false; verify_unique_dependencies(x.m_dependencies, x.n_dependencies, x.m_name, x.base.base.loc); @@ -691,6 +712,7 @@ class VerifyVisitor : public BaseWalkVisitor ASR::Module_t *m = ASRUtils::get_sym_module(x.m_external); ASR::StructType_t* sm = nullptr; ASR::EnumType_t* em = nullptr; + ASR::UnionType_t* um = nullptr; ASR::Function_t* fm = nullptr; bool is_valid_owner = false; is_valid_owner = m != nullptr && ((ASR::symbol_t*) m == ASRUtils::get_asr_owner(x.m_external)); @@ -699,13 +721,17 @@ class VerifyVisitor : public BaseWalkVisitor ASR::symbol_t* asr_owner_sym = ASRUtils::get_asr_owner(x.m_external); is_valid_owner = (ASR::is_a(*asr_owner_sym) || ASR::is_a(*asr_owner_sym) || - ASR::is_a(*asr_owner_sym)); + ASR::is_a(*asr_owner_sym) || + ASR::is_a(*asr_owner_sym)); if( ASR::is_a(*asr_owner_sym) ) { sm = ASR::down_cast(asr_owner_sym); asr_owner_name = sm->m_name; } else if( ASR::is_a(*asr_owner_sym) ) { em = ASR::down_cast(asr_owner_sym); asr_owner_name = em->m_name; + } else if( ASR::is_a(*asr_owner_sym) ) { + um = ASR::down_cast(asr_owner_sym); + asr_owner_name = um->m_name; } else if( ASR::is_a(*asr_owner_sym) ) { fm = ASR::down_cast(asr_owner_sym); asr_owner_name = fm->m_name; @@ -734,6 +760,8 @@ class VerifyVisitor : public BaseWalkVisitor s = em->m_symtab->resolve_symbol(std::string(x.m_original_name)); } else if( fm ) { s = fm->m_symtab->resolve_symbol(std::string(x.m_original_name)); + } else if( um ) { + s = um->m_symtab->resolve_symbol(std::string(x.m_original_name)); } require(s != nullptr, "ExternalSymbol::m_original_name ('" @@ -889,7 +917,7 @@ class VerifyVisitor : public BaseWalkVisitor } SymbolTable* temp_scope = current_symtab; - + if (asr_owner_sym && temp_scope->get_counter() != ASRUtils::symbol_parent_symtab(x.m_name)->get_counter() && !ASR::is_a(*x.m_name) && !ASR::is_a(*x.m_name)) { if (ASR::is_a(*asr_owner_sym) || ASR::is_a(*asr_owner_sym)) { @@ -899,7 +927,7 @@ class VerifyVisitor : public BaseWalkVisitor } } else { function_dependencies.push_back(std::string(ASRUtils::symbol_name(x.m_name))); - } + } } if( ASR::is_a(*x.m_name) ) { @@ -912,6 +940,12 @@ class VerifyVisitor : public BaseWalkVisitor verify_args(x); } + void visit_AssociateBlockCall(const AssociateBlockCall_t &x) { + require(symtab_in_scope(current_symtab, x.m_m), + "AssociateBlockCall::m_name '" + std::string(symbol_name(x.m_m)) + + "' cannot point outside of its symbol table"); + } + SymbolTable *get_dt_symtab(ASR::symbol_t *dt) { LCOMPILERS_ASSERT(dt) SymbolTable *symtab = ASRUtils::symbol_symtab(ASRUtils::symbol_get_past_external(dt)); @@ -1007,16 +1041,16 @@ class VerifyVisitor : public BaseWalkVisitor } } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t& x) { + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t& x) { if( !check_external ) { - BaseWalkVisitor::visit_IntrinsicScalarFunction(x); + BaseWalkVisitor::visit_IntrinsicElementalFunction(x); return ; } - ASRUtils::verify_function verify_ = ASRUtils::IntrinsicScalarFunctionRegistry + ASRUtils::verify_function verify_ = ASRUtils::IntrinsicElementalFunctionRegistry ::get_verify_function(x.m_intrinsic_id); LCOMPILERS_ASSERT(verify_ != nullptr); verify_(x, diagnostics); - BaseWalkVisitor::visit_IntrinsicScalarFunction(x); + BaseWalkVisitor::visit_IntrinsicElementalFunction(x); } void visit_IntrinsicArrayFunction(const ASR::IntrinsicArrayFunction_t& x) { @@ -1040,7 +1074,7 @@ class VerifyVisitor : public BaseWalkVisitor } SymbolTable* temp_scope = current_symtab; - + if (asr_owner_sym && temp_scope->get_counter() != ASRUtils::symbol_parent_symtab(x.m_name)->get_counter() && !ASR::is_a(*x.m_name) && !ASR::is_a(*x.m_name)) { if (ASR::is_a(*asr_owner_sym) || ASR::is_a(*asr_owner_sym)) { @@ -1050,7 +1084,12 @@ class VerifyVisitor : public BaseWalkVisitor } } else { function_dependencies.push_back(std::string(ASRUtils::symbol_name(x.m_name))); - } + } + } + if (_return_var_or_intent_out && _processing_dims && + temp_scope->get_counter() != ASRUtils::symbol_parent_symtab(x.m_name)->get_counter() && + !ASR::is_a(*x.m_name)) { + function_dependencies.push_back(std::string(ASRUtils::symbol_name(x.m_name))); } if( ASR::is_a(*x.m_name) ) { @@ -1097,10 +1136,26 @@ class VerifyVisitor : public BaseWalkVisitor symbol_owner); } + void visit_ArrayConstructor(const ArrayConstructor_t& x) { + require(ASRUtils::is_array(x.m_type), + "Type of ArrayConstructor must be an array"); + BaseWalkVisitor::visit_ArrayConstructor(x); + } + void visit_ArrayConstant(const ArrayConstant_t& x) { require(ASRUtils::is_array(x.m_type), "Type of ArrayConstant must be an array"); - BaseWalkVisitor::visit_ArrayConstant(x); + + for (size_t i = 0; i < x.n_args; i++) { + require(!ASR::is_a(*x.m_args[i]), + "ArrayConstant cannot have ArrayConstant as its elements"); + ASR::expr_t* arg_value = ASRUtils::expr_value(x.m_args[i]); + require( + ASRUtils::is_value_constant(arg_value), + "ArrayConstant must have constant values"); + } + + visit_ttype(*x.m_type); } void visit_dimension(const dimension_t &x) { @@ -1125,9 +1180,11 @@ class VerifyVisitor : public BaseWalkVisitor visit_ttype(*x.m_type); require(x.n_dims != 0, "Array type cannot have 0 dimensions.") require(!ASR::is_a(*x.m_type), "Array type cannot be nested.") + _processing_dims = true; for (size_t i = 0; i < x.n_dims; i++) { visit_dimension(x.m_dims[i]); } + _processing_dims = false; } void visit_Pointer(const Pointer_t &x) { diff --git a/src/libasr/casting_utils.cpp b/src/libasr/casting_utils.cpp index 0a8a1c1cd3..33537971e9 100644 --- a/src/libasr/casting_utils.cpp +++ b/src/libasr/casting_utils.cpp @@ -55,7 +55,7 @@ namespace LCompilers::CastingUtil { int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr, ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr, ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type, - bool is_assign) { + bool is_assign, bool allow_int_to_float) { ASR::ttype_t* left_type = ASRUtils::expr_type(left_expr); ASR::ttype_t* right_type = ASRUtils::expr_type(right_expr); if( ASR::is_a(*left_type) ) { @@ -71,13 +71,12 @@ namespace LCompilers::CastingUtil { return 2; } if( is_assign ) { - if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type)) { - throw SemanticError("Assigning integer to float is not supported", - right_expr->base.loc); + if( ASRUtils::is_real(*left_type) && ASRUtils::is_integer(*right_type) && + !allow_int_to_float) { + throw LCompilersException("Assigning integer to float is not supported"); } if ( ASRUtils::is_complex(*left_type) && !ASRUtils::is_complex(*right_type)) { - throw SemanticError("Assigning non-complex to complex is not supported", - right_expr->base.loc); + throw LCompilersException("Assigning non-complex to complex is not supported"); } dest_expr = left_expr, dest_type = left_type; src_expr = right_expr, src_type = right_type; @@ -115,9 +114,13 @@ namespace LCompilers::CastingUtil { return casted_expr_signal; } - ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* src, + ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* dest, Allocator& al, const Location& loc) { + ASR::ttype_t* src = ASRUtils::expr_type(expr); + if( ASR::is_a(*src) ) { + src = ASRUtils::get_contained_type(src); + } ASR::ttypeType src_type = src->type; ASR::ttypeType dest_type = dest->type; ASR::cast_kindType cast_kind; @@ -137,7 +140,13 @@ namespace LCompilers::CastingUtil { return expr; } // TODO: Fix loc - return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr, - cast_kind, dest)); + if( ASRUtils::is_array(src) ) { + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(src, m_dims); + dest = ASRUtils::make_Array_t_util(al, loc, ASRUtils::extract_type(dest), m_dims, n_dims); + } else { + dest = ASRUtils::extract_type(dest); + } + return ASRUtils::EXPR(ASRUtils::make_Cast_t_value(al, loc, expr, cast_kind, dest)); } } diff --git a/src/libasr/casting_utils.h b/src/libasr/casting_utils.h index 6c5a222ba9..695e2951fb 100644 --- a/src/libasr/casting_utils.h +++ b/src/libasr/casting_utils.h @@ -2,6 +2,8 @@ #define LFORTRAN_CASTING_UTILS_H +#include + #include namespace LCompilers::CastingUtil { @@ -11,11 +13,10 @@ namespace LCompilers::CastingUtil { int get_src_dest(ASR::expr_t* left_expr, ASR::expr_t* right_expr, ASR::expr_t*& src_expr, ASR::expr_t*& dest_expr, ASR::ttype_t*& src_type, ASR::ttype_t*& dest_type, - bool is_assign); + bool is_assign, bool allow_int_to_float=false); - ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* src, - ASR::ttype_t* dest, Allocator& al, - const Location& loc); + ASR::expr_t* perform_casting(ASR::expr_t* expr, ASR::ttype_t* dest, + Allocator& al, const Location& loc); } #endif // LFORTRAN_CASTING_UTILS_H diff --git a/src/libasr/codegen/asr_to_c.cpp b/src/libasr/codegen/asr_to_c.cpp index acf1ae5977..8df1f9d314 100644 --- a/src/libasr/codegen/asr_to_c.cpp +++ b/src/libasr/codegen/asr_to_c.cpp @@ -1217,7 +1217,6 @@ R"( // Initialise Numpy We need to generate: a = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0}; */ - CHECK_FAST_C(compiler_options, x) size_t size = ASRUtils::get_fixed_size_of_array(x.m_type); std::string array_const_str = "{"; for( size_t i = 0; i < size; i++ ) { @@ -1279,12 +1278,21 @@ R"( // Initialise Numpy visit_expr(*x.m_dim); std::string idx = src; if( x.m_bound == ASR::arrayboundType::LBound ) { - src = "((" + result_type + ")" + var_name + "->dims[" + idx + "-1].lower_bound)"; + if (ASRUtils::is_simd_array(x.m_v)) { + src = "0"; + } else { + src = "((" + result_type + ")" + var_name + "->dims[" + idx + "-1].lower_bound)"; + } } else if( x.m_bound == ASR::arrayboundType::UBound ) { - std::string lower_bound = var_name + "->dims[" + idx + "-1].lower_bound"; - std::string length = var_name + "->dims[" + idx + "-1].length"; - std::string upper_bound = length + " + " + lower_bound + " - 1"; - src = "((" + result_type + ") " + upper_bound + ")"; + if (ASRUtils::is_simd_array(x.m_v)) { + int64_t size = ASRUtils::get_fixed_size_of_array(ASRUtils::expr_type(x.m_v)); + src = std::to_string(size - 1); + } else { + std::string lower_bound = var_name + "->dims[" + idx + "-1].lower_bound"; + std::string length = var_name + "->dims[" + idx + "-1].length"; + std::string upper_bound = length + " + " + lower_bound + " - 1"; + src = "((" + result_type + ") " + upper_bound + ")"; + } } } @@ -1317,26 +1325,30 @@ R"( // Initialise Numpy int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims); bool is_data_only_array = ASRUtils::is_fixed_size_array(m_dims, n_dims) && ASR::is_a(*ASRUtils::get_asr_owner(x.m_v)); - if( is_data_only_array ) { + if( is_data_only_array || ASRUtils::is_simd_array(x.m_v)) { std::string index = ""; std::string out = array; out += "["; for (size_t i=0; ivisit_expr(*x.m_args[i].m_right); } else { src = "/* FIXME right index */"; } - current_index += src; - for( size_t j = 0; j < i; j++ ) { - int64_t dim_size = 0; - ASRUtils::extract_value(m_dims[j].m_length, dim_size); - std::string length = std::to_string(dim_size); - current_index += " * " + length; + if (ASRUtils::is_simd_array(x.m_v)) { + index += src; + } else { + std::string current_index = ""; + current_index += src; + for( size_t j = 0; j < i; j++ ) { + int64_t dim_size = 0; + ASRUtils::extract_value(m_dims[j].m_length, dim_size); + std::string length = std::to_string(dim_size); + current_index += " * " + length; + } + index += current_index; } - index += current_index; if (i < x.n_args - 1) { index += " + "; } diff --git a/src/libasr/codegen/asr_to_c_cpp.h b/src/libasr/codegen/asr_to_c_cpp.h index 8bb44f4e7a..f4dbdd48ce 100644 --- a/src/libasr/codegen/asr_to_c_cpp.h +++ b/src/libasr/codegen/asr_to_c_cpp.h @@ -24,6 +24,8 @@ #include #include #include +#include + #include #include @@ -93,6 +95,11 @@ class BaseCCPPVisitor : public ASR::BaseVisitor public: diag::Diagnostics &diag; Platform platform; + // `src` acts as a buffer that accumulates the generated C/C++ source code + // as the visitor traverses all the ASR nodes of a program. Each visitor method + // uses `src` to return the result, and the caller visitor uses `src` as the + // value of the callee visitors it calls. The C/C++ complete source code + // is then recursively constructed using `src`. std::string src; std::string current_body; CompilerOptions &compiler_options; @@ -2544,14 +2551,8 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { src += ASRUtils::binop_to_str_python(x.m_op); if (right_precedence == 3) { src += "(" + right + ")"; - } else if (x.m_op == ASR::binopType::Sub || x.m_op == ASR::binopType::Div) { - if (right_precedence < last_expr_precedence) { - src += right; - } else { - src += "(" + right + ")"; - } } else { - if (right_precedence <= last_expr_precedence) { + if (right_precedence < last_expr_precedence) { src += right; } else { src += "(" + right + ")"; @@ -3031,16 +3032,20 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { } #define SET_INTRINSIC_NAME(X, func_name) \ - case (static_cast(ASRUtils::IntrinsicScalarFunctions::X)) : { \ + case (static_cast(ASRUtils::IntrinsicElementalFunctions::X)) : { \ out += func_name; break; \ } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { + #define SET_INTRINSIC_SUBROUTINE_NAME(X, func_name) \ + case (static_cast(ASRUtils::IntrinsicImpureSubroutines::X)) : { \ + out += func_name; break; \ + } + + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t &x) { CHECK_FAST_C_CPP(compiler_options, x); std::string out; std::string indent(4, ' '); switch (x.m_intrinsic_id) { - SET_INTRINSIC_NAME(ObjectType, "type"); SET_INTRINSIC_NAME(Sin, "sin"); SET_INTRINSIC_NAME(Cos, "cos"); SET_INTRINSIC_NAME(Tan, "tan"); @@ -3057,8 +3062,22 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { SET_INTRINSIC_NAME(Trunc, "trunc"); SET_INTRINSIC_NAME(Fix, "fix"); SET_INTRINSIC_NAME(FloorDiv, "floordiv"); + SET_INTRINSIC_NAME(Char, "char"); + SET_INTRINSIC_NAME(StringContainsSet, "verify"); + SET_INTRINSIC_NAME(StringFindSet, "scan"); + SET_INTRINSIC_NAME(SubstrIndex, "index"); + case (static_cast(ASRUtils::IntrinsicElementalFunctions::FMA)) : { + this->visit_expr(*x.m_args[0]); + std::string a = src; + this->visit_expr(*x.m_args[1]); + std::string b = src; + this->visit_expr(*x.m_args[2]); + std::string c = src; + src = a +" + "+ b +"*"+ c; + return; + } default : { - throw LCompilersException("IntrinsicScalarFunction: `" + throw LCompilersException("IntrinsicElementalFunction: `" + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) + "` is not implemented"); } @@ -3069,7 +3088,11 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) { src = out; } - void visit_IntrinsicFunctionSqrt(const ASR::IntrinsicFunctionSqrt_t &x) { + void visit_TypeInquiry(const ASR::TypeInquiry_t &x) { + this->visit_expr(*x.m_value); + } + + void visit_RealSqrt(const ASR::RealSqrt_t &x) { std::string out = "sqrt"; headers.insert("math.h"); this->visit_expr(*x.m_arg); diff --git a/src/libasr/codegen/asr_to_fortran.cpp b/src/libasr/codegen/asr_to_fortran.cpp index dae695c1dc..04a0942ca5 100644 --- a/src/libasr/codegen/asr_to_fortran.cpp +++ b/src/libasr/codegen/asr_to_fortran.cpp @@ -28,7 +28,12 @@ enum Precedence { class ASRToFortranVisitor : public ASR::BaseVisitor { public: - std::string s; + // `src` acts as a buffer that accumulates the generated Fortran source code + // as the visitor traverses all the ASR nodes of a program. Each visitor method + // uses `src` to return the result, and the caller visitor uses `src` as the + // value of the callee visitors it calls. The Fortran complete source code + // is then recursively constructed using `src`. + std::string src; bool use_colors; int indent_level; std::string indent; @@ -37,6 +42,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // in the Fortran 2018 standard int last_expr_precedence; std::string format_string; + std::string tu_functions; // Used for importing struct type inside interface bool is_interface = false; @@ -63,7 +69,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor visit_expr(x); if (last_expr_precedence == 9 || last_expr_precedence < current_precedence) { - s = "(" + s + ")"; + src = "(" + src + ")"; } } @@ -130,13 +136,22 @@ class ASRToFortranVisitor : public ASR::BaseVisitor } for (size_t i = 0; i < x.n_body; i++) { visit_stmt(*x.m_body[i]); - r += s; + r += src; } if (apply_indent) { dec_indent(); } } + void handle_line_truncation(std::string &r, int i_level, int line_length=80) { + int line_segments_count = r.size()/line_length; + for (int i = 1; i <= line_segments_count; i ++) { + int index = r.find_last_of(',', line_length*i); + r.insert(index + 2, "&\n" + indent + + std::string(i_level*indent_spaces, ' ')); + } + } + std::string get_type(const ASR::ttype_t *t) { std::string r = ""; switch (t->type) { @@ -167,7 +182,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += ":"; } else if (c->m_len == -3) { visit_expr(*c->m_len_expr); - r += s; + r += src; } } r += ", kind="; @@ -187,11 +202,11 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string start = "", len = ""; if (arr_type->m_dims[i].m_start) { visit_expr(*arr_type->m_dims[i].m_start); - start = s; + start = src; } if (arr_type->m_dims[i].m_length) { visit_expr(*arr_type->m_dims[i].m_length); - len = s; + len = src; } if (len.length() == 0) { @@ -237,12 +252,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string r = "", m_op = cmpop2str(x.m_op); int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); - r += s; + r += src; r += m_op; visit_expr_with_precedence(*x.m_right, current_precedence); - r += s; + r += src; last_expr_precedence = current_precedence; - s = r; + src = r; } /********************************** Unit **********************************/ @@ -251,24 +266,28 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + r += src; + r += "\n"; } } + tu_functions = ""; for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + tu_functions += src; + tu_functions += "\n"; } } + // Main program for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + r += src; } } - s = r; + src = r; } /********************************* Symbol *********************************/ @@ -281,7 +300,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + r += src; } } r += indent + "implicit none"; @@ -304,14 +323,14 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : struct_deps) { ASR::symbol_t* struct_sym = x.m_symtab->get_symbol(item); visit_symbol(*struct_sym); - r += s; + r += src; } std::vector var_order = ASRUtils::determine_variable_declaration_order(x.m_symtab); for (auto &item : var_order) { ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); if (is_a(*var_sym)) { visit_symbol(*var_sym); - r += s; + r += src; } } @@ -327,14 +346,23 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "\n\n"; } visit_symbol(*item.second); - r += s; + r += src; + r += "\n"; + } + } + if (tu_functions.size() > 0) { + if (prepend_contains_keyword) { + r += "\n"; + r += "contains"; + r += "\n\n"; } + r += tu_functions; } r += "end program"; r += " "; r.append(x.m_name); r += "\n"; - s = r; + src = r; } void visit_Module(const ASR::Module_t &x) { @@ -346,7 +374,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + r += src; } } r += indent + "implicit none"; @@ -354,7 +382,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : x.m_symtab->get_scope()) { if (is_a(*item.second)) { visit_symbol(*item.second); - r += s; + r += src; } } @@ -376,14 +404,14 @@ class ASRToFortranVisitor : public ASR::BaseVisitor for (auto &item : struct_deps) { ASR::symbol_t* struct_sym = x.m_symtab->get_symbol(item); visit_symbol(*struct_sym); - r += s; + r += src; } std::vector var_order = ASRUtils::determine_variable_declaration_order(x.m_symtab); for (auto &item : var_order) { ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); if (is_a(*var_sym)) { visit_symbol(*var_sym); - r += s; + r += src; } } std::vector func_name; @@ -405,7 +433,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor inc_indent(); } visit_symbol(*x.m_symtab->get_symbol(interface_func_name[i])); - r += s; + r += src; if (i < interface_func_name.size() - 1) { r += "\n"; } else { @@ -421,14 +449,14 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "\n\n"; } visit_symbol(*x.m_symtab->get_symbol(func_name[i])); - r += s; + r += src; if (i < func_name.size()) r += "\n"; } r += "end module"; r += " "; r.append(x.m_name); r += "\n"; - s = r; + src = r; } void visit_Function(const ASR::Function_t &x) { @@ -456,10 +484,11 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; for (size_t i = 0; i < x.n_args; i ++) { visit_expr(*x.m_args[i]); - r += s; + r += src; if (i < x.n_args-1) r += ", "; } r += ")"; + handle_line_truncation(r, 2); if (type->m_abi == ASR::abiType::BindC) { r += " bind(c"; if (type->m_bindc_name) { @@ -473,7 +502,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor if (x.m_return_var) { LCOMPILERS_ASSERT(is_a(*x.m_return_var)); visit_expr(*x.m_return_var); - return_var = s; + return_var = src; if (strcmp(x.m_name, return_var.c_str())) { r += " result(" + return_var + ")"; } @@ -489,7 +518,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); if (is_a(*var_sym)) { visit_symbol(*var_sym); - variable_declaration += s; + variable_declaration += src; } } for (size_t i = 0; i < import_struct_type.size(); i ++) { @@ -518,7 +547,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "interface\n"; inc_indent(); visit_symbol(*item.second); - r += s; + r += src; r += "\n"; dec_indent(); r += indent; @@ -542,7 +571,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " "; r.append(x.m_name); r += "\n"; - s = r; + src = r; } void visit_GenericProcedure(const ASR::GenericProcedure_t &x) { @@ -562,7 +591,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "end interface "; r.append(x.m_name); r += "\n"; - s = r; + src = r; } // void visit_CustomOperator(const ASR::CustomOperator_t &x) {} @@ -571,12 +600,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor ASR::symbol_t *sym = down_cast( ASRUtils::symbol_parent_symtab(x.m_external)->asr_owner); if (!is_a(*sym)) { - s = indent; - s += "use "; - s.append(x.m_module_name); - s += ", only: "; - s.append(x.m_original_name); - s += "\n"; + src = indent; + src += "use "; + src.append(x.m_module_name); + src += ", only: "; + src.append(x.m_original_name); + src += "\n"; } } @@ -591,14 +620,14 @@ class ASRToFortranVisitor : public ASR::BaseVisitor ASR::symbol_t* var_sym = x.m_symtab->get_symbol(item); if (is_a(*var_sym)) { visit_symbol(*var_sym); - r += s; + r += src; } } dec_indent(); r += "end type "; r.append(x.m_name); r += "\n"; - s = r; + src = r; } // void visit_EnumType(const ASR::EnumType_t &x) {} @@ -645,17 +674,21 @@ class ASRToFortranVisitor : public ASR::BaseVisitor } r += " :: "; r.append(x.m_name); - if (x.m_value) { + if (x.m_symbolic_value && x.m_value && ASR::is_a(*x.m_symbolic_value) && ASR::is_a(*x.m_value)) { + r += " = "; + visit_expr(*x.m_symbolic_value); + r += src; + } else if (x.m_value) { r += " = "; visit_expr(*x.m_value); - r += s; + r += src; } else if (x.m_symbolic_value) { r += " = "; visit_expr(*x.m_symbolic_value); - r += s; + r += src; } r += "\n"; - s = r; + src = r; } // void visit_ClassType(const ASR::ClassType_t &x) {} @@ -676,19 +709,20 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "allocate("; for (size_t i = 0; i < x.n_args; i ++) { visit_expr(*x.m_args[i].m_a); - r += s; + r += src; if (x.m_args[i].n_dims > 0) { r += "("; for (size_t j = 0; j < x.m_args[i].n_dims; j ++) { visit_expr(*x.m_args[i].m_dims[j].m_length); - r += s; + r += src; if (j < x.m_args[i].n_dims-1) r += ", "; } r += ")"; } + if (i < x.n_args-1) r += ", "; } r += ")\n"; - s = r; + src = r; } // void visit_ReAlloc(const ASR::ReAlloc_t &x) {} @@ -703,49 +737,60 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " "; r += x.m_variable; r += "\n"; - s = r; + src = r; } void visit_Assignment(const ASR::Assignment_t &x) { std::string r = indent; visit_expr(*x.m_target); - r += s; + r += src; r += " = "; visit_expr(*x.m_value); - r += s; + r += src; r += "\n"; - s = r; + src = r; } void visit_Associate(const ASR::Associate_t &x) { visit_expr(*x.m_target); - std::string t = std::move(s); + std::string t = std::move(src); visit_expr(*x.m_value); - std::string v = std::move(s); - s = t + " => " + v + "\n"; + std::string v = std::move(src); + src = t + " => " + v + "\n"; } void visit_Cycle(const ASR::Cycle_t &x) { - s = indent + "cycle"; + src = indent + "cycle"; if (x.m_stmt_name) { - s += " " + std::string(x.m_stmt_name); + src += " " + std::string(x.m_stmt_name); } - s += "\n"; + src += "\n"; } - // void visit_ExplicitDeallocate(const ASR::ExplicitDeallocate_t &x) {} + void visit_ExplicitDeallocate(const ASR::ExplicitDeallocate_t &x) { + std::string r = indent; + r += "deallocate("; + for (size_t i = 0; i < x.n_vars; i ++) { + visit_expr(*x.m_vars[i]); + r += src; + if (i < x.n_vars-1) r += ", "; + } + r += ")"; + r += "\n"; + src = r; + } void visit_ImplicitDeallocate(const ASR::ImplicitDeallocate_t &x) { std::string r = indent; r += "deallocate("; for (size_t i = 0; i < x.n_vars; i ++) { visit_expr(*x.m_vars[i]); - r += s; + r += src; if (i < x.n_vars-1) r += ", "; } r += ") "; r += "! Implicit deallocate\n"; - s = r; + src = r; } // void visit_DoConcurrentLoop(const ASR::DoConcurrentLoop_t &x) {} @@ -759,17 +804,17 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "do "; visit_expr(*x.m_head.m_v); - r += s; + r += src; r += " = "; visit_expr(*x.m_head.m_start); - r += s; + r += src; r += ", "; visit_expr(*x.m_head.m_end); - r += s; + r += src; if (x.m_head.m_increment) { r += ", "; visit_expr(*x.m_head.m_increment); - r += s; + r += src; } r += "\n"; visit_body(x, r); @@ -779,21 +824,21 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " " + std::string(x.m_name); } r += "\n"; - s = r; + src = r; } void visit_ErrorStop(const ASR::ErrorStop_t &/*x*/) { - s = indent; - s += "error stop"; - s += "\n"; + src = indent; + src += "error stop"; + src += "\n"; } void visit_Exit(const ASR::Exit_t &x) { - s = indent + "exit"; + src = indent + "exit"; if (x.m_stmt_name) { - s += " " + std::string(x.m_stmt_name); + src += " " + std::string(x.m_stmt_name); } - s += "\n"; + src += "\n"; } // void visit_ForAllSingle(const ASR::ForAllSingle_t &x) {} @@ -804,7 +849,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " "; r += std::to_string(x.m_target_id); r += "\n"; - s = r; + src = r; } void visit_GoToTarget(const ASR::GoToTarget_t &x) { @@ -813,7 +858,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " "; r += "continue"; r += "\n"; - s = r; + src = r; } void visit_If(const ASR::If_t &x) { @@ -821,7 +866,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "if"; r += " ("; visit_expr(*x.m_test); - r += s; + r += src; r += ") "; r += "then"; r += "\n"; @@ -832,13 +877,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "\n"; inc_indent(); visit_stmt(*x.m_orelse[i]); - r += s; + r += src; dec_indent(); } r += indent; r += "end if"; r += "\n"; - s = r; + src = r; } // void visit_IfArithmetic(const ASR::IfArithmetic_t &x) {} @@ -851,20 +896,20 @@ class ASRToFortranVisitor : public ASR::BaseVisitor ASR::StringFormat_t *sf = down_cast(x.m_values[0]); visit_expr(*sf->m_fmt); if (is_a(*sf->m_fmt) - && (!startswith(s, "\"(") || !endswith(s, ")\""))) { - s = "\"(" + s.substr(1, s.size()-2) + ")\""; + && (!startswith(src, "\"(") || !endswith(src, ")\""))) { + src = "\"(" + src.substr(1, src.size()-2) + ")\""; } - r += s; + r += src; } else { r += "*"; } for (size_t i = 0; i < x.n_values; i++) { r += ", "; visit_expr(*x.m_values[i]); - r += s; + r += src; } r += "\n"; - s = r; + src = r; } void visit_FileOpen(const ASR::FileOpen_t &x) { @@ -874,7 +919,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; if (x.m_newunit) { visit_expr(*x.m_newunit); - r += s; + r += src; } else { throw CodeGenError("open() function must be called with a file unit number"); } @@ -882,23 +927,23 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += ", "; r += "file="; visit_expr(*x.m_filename); - r += s; + r += src; } if (x.m_status) { r += ", "; r += "status="; visit_expr(*x.m_status); - r += s; + r += src; } if (x.m_form) { r += ", "; r += "form="; visit_expr(*x.m_form); - r += s; + r += src; } r += ")"; r += "\n"; - s = r; + src = r; } void visit_FileClose(const ASR::FileClose_t &x) { @@ -908,13 +953,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; if (x.m_unit) { visit_expr(*x.m_unit); - r += s; + r += src; } else { throw CodeGenError("close() function must be called with a file unit number"); } r += ")"; r += "\n"; - s = r; + src = r; } void visit_FileRead(const ASR::FileRead_t &x) { @@ -924,7 +969,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; if (x.m_unit) { visit_expr(*x.m_unit); - r += s; + r += src; } else { r += "*"; } @@ -932,7 +977,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += ", "; r += "fmt="; visit_expr(*x.m_fmt); - r += s; + r += src; } else { r += ", *"; } @@ -940,28 +985,28 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += ", "; r += "iomsg="; visit_expr(*x.m_iomsg); - r += s; + r += src; } if (x.m_iostat) { r += ", "; r += "iostat="; visit_expr(*x.m_iostat); - r += s; + r += src; } if (x.m_id) { r += ", "; r += "id="; visit_expr(*x.m_id); - r += s; + r += src; } r += ") "; for (size_t i = 0; i < x.n_values; i++) { visit_expr(*x.m_values[i]); - r += s; + r += src; if (i < x.n_values - 1) r += ", "; } r += "\n"; - s = r; + src = r; } // void visit_FileBackspace(const ASR::FileBackspace_t &x) {} @@ -981,28 +1026,28 @@ class ASRToFortranVisitor : public ASR::BaseVisitor ASR::StringFormat_t *sf = down_cast(x.m_values[0]); visit_expr(*sf->m_fmt); if (is_a(*sf->m_fmt) - && (!startswith(s, "\"(") || !endswith(s, ")\""))) { - s = "\"(" + s.substr(1, s.size()-2) + ")\""; + && (!startswith(src, "\"(") || !endswith(src, ")\""))) { + src = "\"(" + src.substr(1, src.size()-2) + ")\""; } - r += s; + r += src; } else { r += "*"; } r += ") "; for (size_t i = 0; i < x.n_values; i++) { visit_expr(*x.m_values[i]); - r += s; + r += src; if (i < x.n_values-1) r += ", "; } r += "\n"; - s = r; + src = r; } void visit_Return(const ASR::Return_t &/*x*/) { std::string r = indent; r += "return"; r += "\n"; - s = r; + src = r; } void visit_Select(const ASR::Select_t &x) { @@ -1010,13 +1055,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "select case"; r += " ("; visit_expr(*x.m_test); - r += s; + r += src; r += ")\n"; inc_indent(); if (x.n_body > 0) { for(size_t i = 0; i < x.n_body; i ++) { visit_case_stmt(*x.m_body[i]); - r += s; + r += src; } } @@ -1026,20 +1071,20 @@ class ASRToFortranVisitor : public ASR::BaseVisitor inc_indent(); for(size_t i = 0; i < x.n_default; i ++) { visit_stmt(*x.m_default[i]); - r += s; + r += src; } dec_indent(); } dec_indent(); r += indent; r += "end select\n"; - s = r; + src = r; } void visit_Stop(const ASR::Stop_t /*x*/) { - s = indent; - s += "stop"; - s += "\n"; + src = indent; + src += "stop"; + src += "\n"; } // void visit_Assert(const ASR::Assert_t &x) {} @@ -1051,11 +1096,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; for (size_t i = 0; i < x.n_args; i ++) { visit_expr(*x.m_args[i].m_value); - r += s; + r += src; if (i < x.n_args-1) r += ", "; } r += ")\n"; - s = r; + handle_line_truncation(r, 1); + src = r; } void visit_Where(const ASR::Where_t &x) { @@ -1065,7 +1111,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " "; r += "("; visit_expr(*x.m_test); - r += s; + r += src; r += ")\n"; visit_body(x, r); for (size_t i = 0; i < x.n_orelse; i++) { @@ -1074,13 +1120,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "\n"; inc_indent(); visit_stmt(*x.m_orelse[i]); - r += s; + r += src; dec_indent(); } r += indent; r += "end where"; r += "\n"; - s = r; + src = r; } void visit_WhileLoop(const ASR::WhileLoop_t &x) { @@ -1092,7 +1138,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "do while"; r += " ("; visit_expr(*x.m_test); - r += s; + r += src; r += ")\n"; visit_body(x, r); r += indent; @@ -1101,7 +1147,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += " " + std::string(x.m_name); } r += "\n"; - s = r; + src = r; } // void visit_Nullify(const ASR::Nullify_t &x) {} @@ -1119,14 +1165,25 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // void visit_Expr(const ASR::Expr_t &x) {} /********************************** Expr **********************************/ - // void visit_IfExp(const ASR::IfExp_t &x) {} + void visit_IfExp(const ASR::IfExp_t &x) { + std::string r = ""; + visit_expr(*x.m_test); + r += src; + r += " ? "; + visit_expr(*x.m_body); + r += src; + r += " : "; + visit_expr(*x.m_orelse); + r += src; + src = r; + } void visit_ComplexConstructor(const ASR::ComplexConstructor_t &x) { visit_expr(*x.m_re); - std::string re = s; + std::string re = src; visit_expr(*x.m_im); - std::string im = s; - s = "(" + re + ", " + im + ")"; + std::string im = src; + src = "(" + re + ", " + im + ")"; } // void visit_NamedExpr(const ASR::NamedExpr_t &x) {} @@ -1139,7 +1196,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += ASRUtils::symbol_name(x.m_name); } if (r == "bit_size") { - // TODO: Remove this once bit_size is implemented in IntrinsicScalarFunction + // TODO: Remove this once bit_size is implemented in IntrinsicElementalFunction visit_expr(*x.m_value); return; } @@ -1147,14 +1204,56 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; for (size_t i = 0; i < x.n_args; i ++) { visit_expr(*x.m_args[i].m_value); - r += s; + r += src; if (i < x.n_args-1) r += ", "; } r += ")"; - s = r; + src = r; + } + + void visit_TypeInquiry(const ASR::TypeInquiry_t &x) { + std::string out = ""; + switch (x.m_inquiry_id) { + SET_INTRINSIC_NAME(Epsilon, "epsilon" ); + SET_INTRINSIC_NAME(Huge, "huge" ); + SET_INTRINSIC_NAME(Precision, "precision"); + SET_INTRINSIC_NAME(Radix, "radix" ); + SET_INTRINSIC_NAME(Range, "range" ); + SET_INTRINSIC_NAME(Rank, "rank" ); + SET_INTRINSIC_NAME(Tiny, "tiny" ); + default : { + throw LCompilersException("TypeInquiry: `" + + ASRUtils::get_intrinsic_name(x.m_inquiry_id) + + "` is not implemented"); + } + } + this->visit_expr(*x.m_arg); + out += "(" + src + ")"; + src = out; } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { + void visit_IntrinsicImpureSubroutine( const ASR::IntrinsicImpureSubroutine_t &x ) { + std::string out; + out = "call "; + switch ( x.m_intrinsic_id ) { + SET_INTRINSIC_SUBROUTINE_NAME(RandomNumber, "random_number"); + default : { + throw LCompilersException("IntrinsicImpureSubroutine: `" + + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) + + "` is not implemented"); + } + } + out += "("; + for (size_t i = 0; i < x.n_args; i ++) { + visit_expr(*x.m_args[i]); + out += src; + if (i < x.n_args-1) out += ", "; + } + out += ")\n"; + src = out; + } + + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t &x) { std::string out; switch (x.m_intrinsic_id) { SET_INTRINSIC_NAME(Abs, "abs"); @@ -1162,16 +1261,26 @@ class ASRToFortranVisitor : public ASR::BaseVisitor SET_INTRINSIC_NAME(Max, "max"); SET_INTRINSIC_NAME(Min, "min"); SET_INTRINSIC_NAME(Sqrt, "sqrt"); + SET_INTRINSIC_NAME(Mod, "mod"); + SET_INTRINSIC_NAME(Sin, "sin"); + SET_INTRINSIC_NAME(Char, "char"); + SET_INTRINSIC_NAME(StringContainsSet, "verify"); + SET_INTRINSIC_NAME(StringFindSet, "scan"); + SET_INTRINSIC_NAME(SubstrIndex, "index"); default : { - throw LCompilersException("IntrinsicScalarFunction: `" + throw LCompilersException("IntrinsicElementalFunction: `" + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) + "` is not implemented"); } } - LCOMPILERS_ASSERT(x.n_args == 1); - visit_expr(*x.m_args[0]); - out += "(" + s + ")"; - s = out; + out += "("; + for (size_t i = 0; i < x.n_args; i ++) { + visit_expr(*x.m_args[i]); + out += src; + if (i < x.n_args-1) out += ", "; + } + out += ")"; + src = out; } #define SET_ARR_INTRINSIC_NAME(X, func_name) \ @@ -1186,14 +1295,32 @@ class ASRToFortranVisitor : public ASR::BaseVisitor SET_ARR_INTRINSIC_NAME(Any, "any"); SET_ARR_INTRINSIC_NAME(Sum, "sum"); SET_ARR_INTRINSIC_NAME(Shape, "shape"); + SET_ARR_INTRINSIC_NAME(MaxVal, "maxval"); + SET_ARR_INTRINSIC_NAME(MinVal, "minval"); + case (static_cast(ASRUtils::IntrinsicArrayFunctions::Pack)) : { + out += "pack"; + visit_expr(*x.m_args[0]); + out += "(" + src + ", "; + visit_expr(*x.m_args[1]); + out += src; + if (x.n_args == 3) { + out += ", "; + visit_expr(*x.m_args[2]); + out += src; + } + out += ")"; + src = out; + out = ""; + break; + } default : { - throw LCompilersException("IntrinsicFunction: `" + throw LCompilersException("IntrinsicArrayFunction: `" + ASRUtils::get_array_intrinsic_name(x.m_arr_intrinsic_id) + "` is not implemented"); } } - out += "(" + s + ")"; - s = out; + out += "(" + src + ")"; + src = out; } // void visit_IntrinsicImpureFunction(const ASR::IntrinsicImpureFunction_t &x) {} @@ -1204,11 +1331,11 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "("; for(size_t i = 0; i < x.n_args; i++) { visit_expr(*x.m_args[i].m_value); - r += s; + r += src; if (i < x.n_args - 1) r += ", "; } r += ")"; - s = r; + src = r; } // void visit_EnumTypeConstructor(const ASR::EnumTypeConstructor_t &x) {} @@ -1218,7 +1345,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // void visit_ImpliedDoLoop(const ASR::ImpliedDoLoop_t &x) {} void visit_IntegerConstant(const ASR::IntegerConstant_t &x) { - s = std::to_string(x.m_n); + src = std::to_string(x.m_n); + int kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); + if (kind != 4) { + // We skip this for default kind + src += "_"; + src += std::to_string(kind); + } last_expr_precedence = Precedence::Ext; } @@ -1228,7 +1361,7 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_IntegerUnaryMinus(const ASR::IntegerUnaryMinus_t &x) { visit_expr_with_precedence(*x.m_arg, 9); - s = "-" + s; + src = "-" + src; last_expr_precedence = Precedence::UnaryMinus; } @@ -1240,16 +1373,16 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string r = "", m_op = binop2str(x.m_op); int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); - r += s; + r += src; r += m_op; visit_expr_with_precedence(*x.m_right, current_precedence); if ((x.m_op == ASR::binopType::Sub && last_expr_precedence <= 8) || (x.m_op == ASR::binopType::Div && last_expr_precedence <= 10)) { - s = "(" + s + ")"; + src = "(" + src + ")"; } - r += s; + r += src; last_expr_precedence = current_precedence; - s = r; + src = r; } // void visit_UnsignedIntegerConstant(const ASR::UnsignedIntegerConstant_t &x) {} @@ -1265,16 +1398,16 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_RealConstant(const ASR::RealConstant_t &x) { int kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); if (kind >= 8) { - s = std::to_string(x.m_r) + "d0"; + src = std::to_string(x.m_r) + "d0"; } else { - s = std::to_string(x.m_r); + src = std::to_string(x.m_r); } last_expr_precedence = Precedence::Ext; } void visit_RealUnaryMinus(const ASR::RealUnaryMinus_t &x) { visit_expr_with_precedence(*x.m_arg, 9); - s = "-" + s; + src = "-" + src; last_expr_precedence = Precedence::UnaryMinus; } @@ -1286,12 +1419,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string r = "", m_op = binop2str(x.m_op); int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); - r += s; + r += src; r += m_op; visit_expr_with_precedence(*x.m_right, current_precedence); - r += s; + r += src; last_expr_precedence = current_precedence; - s = r; + src = r; } // void visit_RealCopySign(const ASR::RealCopySign_t &x) {} @@ -1299,12 +1432,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_ComplexConstant(const ASR::ComplexConstant_t &x) { std::string re = std::to_string(x.m_re); std::string im = std::to_string(x.m_im); - s = "(" + re + ", " + im + ")"; + src = "(" + re + ", " + im + ")"; } void visit_ComplexUnaryMinus(const ASR::ComplexUnaryMinus_t &x) { visit_expr_with_precedence(*x.m_arg, 9); - s = "-" + s; + src = "-" + src; last_expr_precedence = Precedence::UnaryMinus; } @@ -1316,28 +1449,28 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string r = "", m_op = binop2str(x.m_op); int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); - r += s; + r += src; r += m_op; visit_expr_with_precedence(*x.m_right, current_precedence); - r += s; + r += src; last_expr_precedence = current_precedence; - s = r; + src = r; } void visit_LogicalConstant(const ASR::LogicalConstant_t &x) { - s = "."; + src = "."; if (x.m_value) { - s += "true"; + src += "true"; } else { - s += "false"; + src += "false"; } - s += "."; + src += "."; last_expr_precedence = Precedence::Ext; } void visit_LogicalNot(const ASR::LogicalNot_t &x) { visit_expr_with_precedence(*x.m_arg, 5); - s = ".not. " + s; + src = ".not. " + src; last_expr_precedence = Precedence::Not; } @@ -1349,53 +1482,53 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string r = "", m_op = logicalbinop2str(x.m_op); int current_precedence = last_expr_precedence; visit_expr_with_precedence(*x.m_left, current_precedence); - r += s; + r += src; r += m_op; visit_expr_with_precedence(*x.m_right, current_precedence); - r += s; + r += src; last_expr_precedence = current_precedence; - s = r; + src = r; } void visit_StringConstant(const ASR::StringConstant_t &x) { - s = "\""; - s.append(x.m_s); - s += "\""; + src = "\""; + src.append(x.m_s); + src += "\""; last_expr_precedence = Precedence::Ext; } void visit_StringConcat(const ASR::StringConcat_t &x) { this->visit_expr(*x.m_left); - std::string left = std::move(s); + std::string left = std::move(src); this->visit_expr(*x.m_right); - std::string right = std::move(s); - s = left + "//" + right; + std::string right = std::move(src); + src = left + "//" + right; } void visit_StringRepeat(const ASR::StringRepeat_t &x) { this->visit_expr(*x.m_left); - std::string str = s; + std::string str = src; this->visit_expr(*x.m_right); - std::string n = s; - s = "repeat(" + str + ", " + n + ")"; + std::string n = src; + src = "repeat(" + str + ", " + n + ")"; } void visit_StringLen(const ASR::StringLen_t &x) { visit_expr(*x.m_arg); - s = "len(" + s + ")"; + src = "len(" + src + ")"; } void visit_StringItem(const ASR::StringItem_t &x) { std::string r = ""; this->visit_expr(*x.m_arg); - r += s; + r += src; r += "("; this->visit_expr(*x.m_idx); - r += s; + r += src; r += ":"; - r += s; + r += src; r += ")"; - s = r; + src = r; } // void visit_StringSection(const ASR::StringSection_t &x) {} @@ -1408,21 +1541,21 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_StringChr(const ASR::StringChr_t &x) { visit_expr(*x.m_arg); - s = "char(" + s + ")"; + src = "char(" + src + ")"; } void visit_StringFormat(const ASR::StringFormat_t &x) { std::string r = ""; if (format_string.size() > 0) { visit_expr(*x.m_fmt); - format_string = s; + format_string = src; } for (size_t i = 0; i < x.n_args; i++) { visit_expr(*x.m_args[i]); - r += s; + r += src; if (i < x.n_args-1) r += ", "; } - s = r; + src = r; } // void visit_CPtrCompare(const ASR::CPtrCompare_t &x) {} @@ -1430,45 +1563,57 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // void visit_SymbolicCompare(const ASR::SymbolicCompare_t &x) {} void visit_Var(const ASR::Var_t &x) { - s = ASRUtils::symbol_name(x.m_v); + src = ASRUtils::symbol_name(x.m_v); last_expr_precedence = Precedence::Ext; } // void visit_FunctionParam(const ASR::FunctionParam_t &x) {} + void visit_ArrayConstructor(const ASR::ArrayConstructor_t &x) { + std::string r = "["; + for(size_t i = 0; i < x.n_args; i++) { + visit_expr(*x.m_args[i]); + r += src; + if (i < x.n_args-1) r += ", "; + } + r += "]"; + src = r; + last_expr_precedence = Precedence::Ext; + } + void visit_ArrayConstant(const ASR::ArrayConstant_t &x) { std::string r = "["; for(size_t i = 0; i < x.n_args; i++) { visit_expr(*x.m_args[i]); - r += s; + r += src; if (i < x.n_args-1) r += ", "; } r += "]"; - s = r; + src = r; last_expr_precedence = Precedence::Ext; } void visit_ArrayItem(const ASR::ArrayItem_t &x) { std::string r = ""; visit_expr(*x.m_v); - r += s; + r += src; r += "("; for(size_t i = 0; i < x.n_args; i++) { if (x.m_args[i].m_right) { visit_expr(*x.m_args[i].m_right); - r += s; + r += src; } if (i < x.n_args-1) r += ", "; } r += ")"; - s = r; + src = r; last_expr_precedence = Precedence::Ext; } void visit_ArraySection(const ASR::ArraySection_t &x) { std::string r = ""; visit_expr(*x.m_v); - r += s; + r += src; r += "("; for (size_t i = 0; i < x.n_args; i++) { if (i > 0) { @@ -1477,37 +1622,37 @@ class ASRToFortranVisitor : public ASR::BaseVisitor std::string left, right, step; if (x.m_args[i].m_left) { visit_expr(*x.m_args[i].m_left); - left = std::move(s); + left = std::move(src); r += left + ":"; } if (x.m_args[i].m_right) { visit_expr(*x.m_args[i].m_right); - right = std::move(s); + right = std::move(src); r += right; } if (x.m_args[i].m_step ) { visit_expr(*x.m_args[i].m_step); - step = std::move(s); + step = std::move(src); if (step != "1") { r += ":" + step; } } } r += ")"; - s = r; + src = r; last_expr_precedence = Precedence::Ext; } void visit_ArraySize(const ASR::ArraySize_t &x) { visit_expr(*x.m_v); - std::string r = "size(" + s; + std::string r = "size(" + src; if (x.m_dim) { r += ", "; visit_expr(*x.m_dim); - r += s; + r += src; } r += ")"; - s = r; + src = r; } void visit_ArrayBound(const ASR::ArrayBound_t &x) { @@ -1518,47 +1663,28 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "lbound("; } visit_expr(*x.m_v); - r += s; + r += src; r += ", "; visit_expr(*x.m_dim); - r += s; + r += src; r += ")"; - s = r; + src = r; } void visit_ArrayTranspose(const ASR::ArrayTranspose_t &x) { visit_expr(*x.m_matrix); - s = "transpose(" + s + ")"; - } - - void visit_ArrayPack(const ASR::ArrayPack_t &x) { - std::string r; - r += "pack"; - r += "("; - visit_expr(*x.m_array); - r += s; - r += ", "; - visit_expr(*x.m_mask); - r += s; - if (x.m_vector) { - r += ", "; - visit_expr(*x.m_vector); - r += s; - } - r += ")"; - s = r; + src = "transpose(" + src + ")"; } void visit_ArrayReshape(const ASR::ArrayReshape_t &x) { - std::string r; - r += "reshape("; + std::string r = "reshape("; visit_expr(*x.m_array); - r += s; + r += src; r += ", "; visit_expr(*x.m_shape); - r += s; + r += src; r += ")"; - s = r; + src = r; } void visit_ArrayAll(const ASR::ArrayAll_t &x) { @@ -1566,13 +1692,13 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "all"; r += "("; visit_expr(*x.m_mask); - r += s; + r += src; if (x.m_dim) { visit_expr(*x.m_dim); - r += s; + r += src; } r += ")"; - s = r; + src = r; } // void visit_BitCast(const ASR::BitCast_t &x) {} @@ -1580,10 +1706,10 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_StructInstanceMember(const ASR::StructInstanceMember_t &x) { std::string r; visit_expr(*x.m_v); - r += s; + r += src; r += "%"; r += ASRUtils::symbol_name(ASRUtils::symbol_get_past_external(x.m_m)); - s = r; + src = r; } // void visit_StructStaticMember(const ASR::StructStaticMember_t &x) {} @@ -1603,167 +1729,46 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // void visit_OverloadedUnaryMinus(const ASR::OverloadedUnaryMinus_t &x) {} void visit_Cast(const ASR::Cast_t &x) { - std::string r; visit_expr(*x.m_arg); - switch (x.m_kind) { - case (ASR::cast_kindType::IntegerToReal) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast IntegerToReal: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::RealToInteger) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast RealToInteger: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::RealToReal) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast RealToReal: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::IntegerToInteger) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "int(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast IntegerToInteger: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::ComplexToComplex) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 4: r = "cmplx(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "cmplx(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast ComplexToComplex: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::IntegerToComplex) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 4: r = "cmplx(" + s + ", " + "0.0" + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "cmplx(" + s + ", " + "0.0" + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast IntegerToComplex: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::ComplexToReal) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 4: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast ComplexToReal: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::RealToComplex) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 4: r = "cmplx(" + s + ", " + "0.0" + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "cmplx(" + s + ", " + "0.0" + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast IntegerToComplex: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::LogicalToInteger) : { - s = "int(" + s + ")"; - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::LogicalToCharacter) : { - s = "char(" + s + ")"; - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::IntegerToLogical) : { - // Implicit conversion between integer -> logical - break; - } - case (ASR::cast_kindType::LogicalToReal) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 4: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: r = "real(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast LogicalToReal: Unsupported Kind " + std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::RealToLogical) : { - s = "(bool)(" + s + ")"; - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::CharacterToLogical) : { - s = "(bool)(len(" + s + ") > 0)"; - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::ComplexToLogical) : { - s = "(bool)(" + s + ")"; - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::IntegerToCharacter) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: s = "char(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: s = "char(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: s = "char(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: s = "char(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast IntegerToCharacter: Unsupported Kind " + \ - std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - case (ASR::cast_kindType::CharacterToInteger) : { - int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); - switch (dest_kind) { - case 1: s = "ichar(" + s + ", " + "kind=dest_kind" + ")"; break; - case 2: s = "ichar(" + s + ", " + "kind=dest_kind" + ")"; break; - case 4: s = "ichar(" + s + ", " + "kind=dest_kind" + ")"; break; - case 8: s = "ichar(" + s + ", " + "kind=dest_kind" + ")"; break; - default: throw CodeGenError("Cast CharacterToInteger: Unsupported Kind " + \ - std::to_string(dest_kind)); - } - last_expr_precedence = 2; - break; - } - default : { - throw CodeGenError("Cast kind " + std::to_string(x.m_kind) + " not implemented", - x.base.base.loc); + int dest_kind = ASRUtils::extract_kind_from_ttype_t(x.m_type); + std::string type_str; + + // If the cast is from Integer to Logical, do nothing + if (x.m_kind == ASR::cast_kindType::IntegerToLogical) { + // Implicit conversion between integer -> logical + return; + } + + // Mapping cast kinds to their corresponding Fortran type names and valid kinds + std::map>> cast_map = { + {ASR::cast_kindType::IntegerToReal, {"real", {1, 2, 4, 8}}}, + {ASR::cast_kindType::RealToInteger, {"int", {1, 2, 4, 8}}}, + {ASR::cast_kindType::RealToReal, {"real", {1, 2, 4, 8}}}, + {ASR::cast_kindType::IntegerToInteger, {"int", {1, 2, 4, 8}}}, + {ASR::cast_kindType::ComplexToComplex, {"cmplx", {4, 8}}}, + {ASR::cast_kindType::IntegerToComplex, {"cmplx", {4, 8}}}, + {ASR::cast_kindType::ComplexToReal, {"real", {4, 8}}}, + {ASR::cast_kindType::RealToComplex, {"cmplx", {4, 8}}}, + {ASR::cast_kindType::LogicalToInteger, {"int", {1, 2, 4, 8}}}, + }; + + if (cast_map.find(x.m_kind) != cast_map.end()) { + type_str = cast_map[x.m_kind].first; + auto &valid_kinds = cast_map[x.m_kind].second; + if (std::find(valid_kinds.begin(), valid_kinds.end(), dest_kind) == valid_kinds.end()) { + throw CodeGenError("Cast " + type_str + ": Unsupported Kind " + std::to_string(dest_kind)); } + } else { + throw CodeGenError("Cast kind " + std::to_string(x.m_kind) + " not implemented", x.base.base.loc); } + + // Construct the string based on the type, with special handling for ComplexToComplex + if (x.m_kind == ASR::cast_kindType::ComplexToComplex) { + src = "cmplx(" + src + ", kind=" + std::to_string(dest_kind) + ")"; + } else { + src = type_str + "(" + src + ((type_str == "cmplx") ? ", 0.0" : "") + ", kind=" + std::to_string(dest_kind) + ")"; + } + last_expr_precedence = Precedence::Ext; } void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t &x) { @@ -1777,12 +1782,12 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_ComplexRe(const ASR::ComplexRe_t &x) { visit_expr(*x.m_arg); - s = "real(" + s + ")"; + src = "real(" + src + ")"; } void visit_ComplexIm(const ASR::ComplexIm_t &x) { visit_expr(*x.m_arg); - s = "aimag(" + s + ")"; + src = "aimag(" + src + ")"; } // void visit_CLoc(const ASR::CLoc_t &x) {} @@ -1793,17 +1798,17 @@ class ASRToFortranVisitor : public ASR::BaseVisitor void visit_IntegerBitLen(const ASR::IntegerBitLen_t &x) { visit_expr(*x.m_a); - s = "bit_size(" + s + ")"; + src = "bit_size(" + src + ")"; } void visit_Ichar(const ASR::Ichar_t &x) { visit_expr(*x.m_arg); - s = "ichar(" + s + ")"; + src = "ichar(" + src + ")"; } void visit_Iachar(const ASR::Iachar_t &x) { visit_expr(*x.m_arg); - s = "iachar(" + s + ")"; + src = "iachar(" + src + ")"; } // void visit_SizeOfType(const ASR::SizeOfType_t &x) {} @@ -1812,9 +1817,9 @@ class ASRToFortranVisitor : public ASR::BaseVisitor // void visit_PointerAssociated(const ASR::PointerAssociated_t &x) {} - void visit_IntrinsicFunctionSqrt(const ASR::IntrinsicFunctionSqrt_t &x) { + void visit_RealSqrt(const ASR::RealSqrt_t &x) { visit_expr(*x.m_arg); - s = "sqrt(" + s + ")"; + src = "sqrt(" + src + ")"; } /******************************* Case Stmt ********************************/ @@ -1823,17 +1828,17 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "case ("; for(size_t i = 0; i < x.n_test; i ++) { visit_expr(*x.m_test[i]); - r += s; + r += src; if (i < x.n_test-1) r += ", "; } r += ")\n"; inc_indent(); for(size_t i = 0; i < x.n_body; i ++) { visit_stmt(*x.m_body[i]); - r += s; + r += src; } dec_indent(); - s = r; + src = r; } void visit_CaseStmt_Range(const ASR::CaseStmt_Range_t &x) { @@ -1841,21 +1846,21 @@ class ASRToFortranVisitor : public ASR::BaseVisitor r += "case ("; if (x.m_start) { visit_expr(*x.m_start); - r += s; + r += src; } r += ":"; if (x.m_end) { visit_expr(*x.m_end); - r += s; + r += src; } r += ")\n"; inc_indent(); for(size_t i = 0; i < x.n_body; i ++) { visit_stmt(*x.m_body[i]); - r += s; + r += src; } dec_indent(); - s = r; + src = r; } }; @@ -1869,7 +1874,7 @@ Result asr_to_fortran(ASR::TranslationUnit_t &asr, diagnostics.diagnostics.push_back(e.d); return Error(); } - return v.s; + return v.src; } } // namespace LCompilers diff --git a/src/libasr/codegen/asr_to_julia.cpp b/src/libasr/codegen/asr_to_julia.cpp index a1b05247a5..588d4b5e1e 100644 --- a/src/libasr/codegen/asr_to_julia.cpp +++ b/src/libasr/codegen/asr_to_julia.cpp @@ -1173,7 +1173,7 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor src += indent + "exit(1)\n"; } - void visit_IntrinsicFunctionSqrt(const ASR::IntrinsicFunctionSqrt_t &x) { + void visit_RealSqrt(const ASR::RealSqrt_t &x) { /* if (x.m_value) { this->visit_expr(*x.m_value); @@ -1237,7 +1237,7 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor void visit_DoConcurrentLoop(const ASR::DoConcurrentLoop_t& x) { - const ASR::DoLoop_t do_loop = ASR::DoLoop_t{ x.base, nullptr, x.m_head, x.m_body, x.n_body , nullptr, 0}; + const ASR::DoLoop_t do_loop = ASR::DoLoop_t{ x.base, nullptr, x.m_head, x.m_body, x.n_body, nullptr, 0 }; visit_DoLoop(do_loop, true); } @@ -1881,7 +1881,7 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor src = out; } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t &x) { std::string out; LCOMPILERS_ASSERT(x.n_args == 1); visit_expr(*x.m_args[0]); @@ -1901,6 +1901,10 @@ class ASRToJuliaVisitor : public ASR::BaseVisitor SET_INTRINSIC_NAME(Expm1, "expm1"); SET_INTRINSIC_NAME(Trunc, "trunc"); SET_INTRINSIC_NAME(Fix, "fix"); + SET_INTRINSIC_NAME(Kind, "kind"); + SET_INTRINSIC_NAME(StringContainsSet, "verify"); + SET_INTRINSIC_NAME(StringFindSet, "scan"); + SET_INTRINSIC_NAME(SubstrIndex, "index"); default : { throw LCompilersException("IntrinsicFunction: `" + ASRUtils::get_intrinsic_name(x.m_intrinsic_id) diff --git a/src/libasr/codegen/asr_to_llvm.cpp b/src/libasr/codegen/asr_to_llvm.cpp index 668b2f2cb2..4e8de1d9d4 100644 --- a/src/libasr/codegen/asr_to_llvm.cpp +++ b/src/libasr/codegen/asr_to_llvm.cpp @@ -1249,9 +1249,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor for( size_t i = 0; i < x.n_args; i++ ) { if (is_argument_of_type_CPtr(x.m_args[i])) { ptr_loads = 0; - } else { + } else { ptr_loads = 1; - } + } this->visit_expr(*x.m_args[i]); llvm::Value* item = tmp; llvm::Value* pos = llvm::ConstantInt::get(context, llvm::APInt(32, i)); @@ -1368,7 +1368,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor this->visit_expr_wrapper(x.m_value, true); return; } - this->visit_expr(*x.m_arg); + this->visit_expr_wrapper(x.m_arg, true); llvm::Value *c = tmp; std::string runtime_func_name = "_lfortran_ichar"; llvm::Function *fn = module->getFunction(runtime_func_name); @@ -1455,7 +1455,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = builder->CreateCall(fn, {mask, size}); } - void visit_IntrinsicFunctionSqrt(const ASR::IntrinsicFunctionSqrt_t &x) { + void visit_RealSqrt(const ASR::RealSqrt_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; @@ -1829,7 +1829,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = list_api->pop_position(plist, pos, asr_el_type, module.get(), name2memidx); } - void generate_Reserve(ASR::expr_t* m_arg, ASR::expr_t* m_ele) { + void generate_ListReserve(ASR::expr_t* m_arg, ASR::expr_t* m_ele) { // For now, this only handles lists ASR::ttype_t* asr_el_type = ASRUtils::get_contained_type(ASRUtils::expr_type(m_arg)); int64_t ptr_loads_copy = ptr_loads; @@ -1921,13 +1921,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_utils->set_api->remove_item(pset, el, *module, asr_el_type); } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t& x) { + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t& x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; } - switch (static_cast(x.m_intrinsic_id)) { - case ASRUtils::IntrinsicScalarFunctions::ListIndex: { + switch (static_cast(x.m_intrinsic_id)) { + case ASRUtils::IntrinsicElementalFunctions::ListIndex: { ASR::expr_t* m_arg = x.m_args[0]; ASR::expr_t* m_ele = x.m_args[1]; ASR::expr_t* m_start = nullptr; @@ -1953,11 +1953,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor generate_ListIndex(m_arg, m_ele, m_start, m_end); break ; } - case ASRUtils::IntrinsicScalarFunctions::ListReverse: { + case ASRUtils::IntrinsicElementalFunctions::ListReverse: { generate_ListReverse(x.m_args[0]); break; } - case ASRUtils::IntrinsicScalarFunctions::ListPop: { + case ASRUtils::IntrinsicElementalFunctions::ListPop: { switch(x.m_overload_id) { case 0: generate_ListPop_0(x.m_args[0]); @@ -1968,27 +1968,27 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break; } - case ASRUtils::IntrinsicScalarFunctions::Reserve: { - generate_Reserve(x.m_args[0], x.m_args[1]); + case ASRUtils::IntrinsicElementalFunctions::ListReserve: { + generate_ListReserve(x.m_args[0], x.m_args[1]); break; } - case ASRUtils::IntrinsicScalarFunctions::DictKeys: { + case ASRUtils::IntrinsicElementalFunctions::DictKeys: { generate_DictElems(x.m_args[0], 0); break; } - case ASRUtils::IntrinsicScalarFunctions::DictValues: { + case ASRUtils::IntrinsicElementalFunctions::DictValues: { generate_DictElems(x.m_args[0], 1); break; } - case ASRUtils::IntrinsicScalarFunctions::SetAdd: { + case ASRUtils::IntrinsicElementalFunctions::SetAdd: { generate_SetAdd(x.m_args[0], x.m_args[1]); break; } - case ASRUtils::IntrinsicScalarFunctions::SetRemove: { + case ASRUtils::IntrinsicElementalFunctions::SetRemove: { generate_SetRemove(x.m_args[0], x.m_args[1]); break; } - case ASRUtils::IntrinsicScalarFunctions::Exp: { + case ASRUtils::IntrinsicElementalFunctions::Exp: { switch (x.m_overload_id) { case 0: { ASR::expr_t* m_arg = x.m_args[0]; @@ -2002,7 +2002,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break ; } - case ASRUtils::IntrinsicScalarFunctions::Exp2: { + case ASRUtils::IntrinsicElementalFunctions::Exp2: { switch (x.m_overload_id) { case 0: { ASR::expr_t* m_arg = x.m_args[0]; @@ -2016,7 +2016,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break ; } - case ASRUtils::IntrinsicScalarFunctions::Expm1: { + case ASRUtils::IntrinsicElementalFunctions::Expm1: { switch (x.m_overload_id) { case 0: { ASR::expr_t* m_arg = x.m_args[0]; @@ -2030,7 +2030,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break ; } - case ASRUtils::IntrinsicScalarFunctions::FlipSign: { + case ASRUtils::IntrinsicElementalFunctions::FlipSign: { Vec args; args.reserve(al, 2); ASR::call_arg_t arg0_, arg1_; @@ -2041,7 +2041,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor generate_flip_sign(args.p); break; } - case ASRUtils::IntrinsicScalarFunctions::FMA: { + case ASRUtils::IntrinsicElementalFunctions::FMA: { Vec args; args.reserve(al, 3); ASR::call_arg_t arg0_, arg1_, arg2_; @@ -2054,7 +2054,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor generate_fma(args.p); break; } - case ASRUtils::IntrinsicScalarFunctions::SignFromValue: { + case ASRUtils::IntrinsicElementalFunctions::SignFromValue: { Vec args; args.reserve(al, 2); ASR::call_arg_t arg0_, arg1_; @@ -2066,7 +2066,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor break; } default: { - throw CodeGenError("Either the '" + ASRUtils::IntrinsicScalarFunctionRegistry:: + throw CodeGenError("Either the '" + ASRUtils::IntrinsicElementalFunctionRegistry:: get_intrinsic_function_name(x.m_intrinsic_id) + "' intrinsic is not implemented by LLVM backend or " "the compile-time value is not available", x.base.base.loc); @@ -2086,6 +2086,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // until then, this returns `False` tmp = llvm::ConstantInt::get(context, llvm::APInt(1, 0)); break ; + } case ASRUtils::IntrinsicImpureFunctions::Allocated : { + handle_allocated(x.m_args[0]); + break ; } default: { throw CodeGenError( ASRUtils::get_impure_intrinsic_name(x.m_impure_intrinsic_id) + " is not implemented by LLVM backend.", x.base.base.loc); @@ -2093,6 +2096,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + void visit_TypeInquiry(const ASR::TypeInquiry_t &x) { + this->visit_expr(*x.m_value); + } + void visit_ListClear(const ASR::ListClear_t& x) { int64_t ptr_loads_copy = ptr_loads; ptr_loads = 0; @@ -2326,7 +2333,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_diminfo.reserve(al, 2 * x.n_args + 1); if( array_t->m_physical_type == ASR::array_physical_typeType::PointerToDataArray || array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray || - array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray ) { + array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray || + (array_t->m_physical_type == ASR::array_physical_typeType::CharacterArraySinglePointer && ASRUtils::is_fixed_size_array(x_mv_type)) ) { int ptr_loads_copy = ptr_loads; for( size_t idim = 0; idim < x.n_args; idim++ ) { ptr_loads = 2 - !LLVM::is_llvm_pointer(*ASRUtils::expr_type(m_dims[idim].m_start)); @@ -2360,7 +2368,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } else { tmp = arr_descr->get_single_element(array, indices, x.n_args, array_t->m_physical_type == ASR::array_physical_typeType::PointerToDataArray, - array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray || array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray, + array_t->m_physical_type == ASR::array_physical_typeType::FixedSizeArray || array_t->m_physical_type == ASR::array_physical_typeType::SIMDArray + || (array_t->m_physical_type == ASR::array_physical_typeType::CharacterArraySinglePointer && ASRUtils::is_fixed_size_array(x_mv_type)), llvm_diminfo.p, is_polymorphic, current_select_type_block_type); } } @@ -2419,7 +2428,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor switch( array_physical_type ) { case ASR::array_physical_typeType::DescriptorArray: { ASR::ttype_t* asr_data_type = ASRUtils::duplicate_type_without_dims(al, - x_m_array_type, x_m_array_type->base.loc); + ASRUtils::get_contained_type(x_m_array_type), x_m_array_type->base.loc); ASR::ttype_t* asr_shape_type = ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_shape)); llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util(asr_data_type, module.get()); tmp = arr_descr->reshape(array, llvm_data_type, shape, asr_shape_type, module.get()); @@ -2674,6 +2683,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } llvm_symtab[h] = ptr; + } else if (x.m_type->type == ASR::ttypeType::Array) { + // Using approach same as ASR::ttypeType::List + llvm::StructType* array_type = static_cast( + llvm_utils->get_type_from_ttype_t_util(x.m_type, module.get())); + llvm::Constant *ptr = module->getOrInsertGlobal(x.m_name, array_type); + module->getNamedGlobal(x.m_name)->setInitializer( + llvm::ConstantStruct::get(array_type, + llvm::Constant::getNullValue(array_type))); + llvm_symtab[h] = ptr; } else if (x.m_type->type == ASR::ttypeType::Logical) { llvm::Constant *ptr = module->getOrInsertGlobal(x.m_name, llvm::Type::getInt1Ty(context)); @@ -3181,8 +3199,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor size_t n_dims = ASRUtils::extract_dimensions_from_ttype(symbol_type, m_dims); ASR::array_physical_typeType phy_type = ASRUtils::extract_physical_type(symbol_type); bool is_data_only = (phy_type == ASR::array_physical_typeType::PointerToDataArray || - phy_type == ASR::array_physical_typeType::FixedSizeArray); - if (phy_type == ASR::array_physical_typeType::DescriptorArray) { + phy_type == ASR::array_physical_typeType::FixedSizeArray || + (phy_type == ASR::array_physical_typeType::CharacterArraySinglePointer && + ASRUtils::is_fixed_size_array(symbol_type))); + if (phy_type == ASR::array_physical_typeType::DescriptorArray || + (phy_type == ASR::array_physical_typeType::CharacterArraySinglePointer && + ASRUtils::is_dimension_empty(m_dims, n_dims))) { int n_dims = 0, a_kind=4; ASR::dimension_t* m_dims = nullptr; bool is_array_type = false; @@ -3223,8 +3245,22 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor LLVM::CreateStore(*builder, array_size_value, array_size); break; } + case ASR::array_physical_typeType::PointerToDataArray: { + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(v_m_type, m_dims); + llvm::Value* llvm_size = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 1)); + int ptr_loads_copy = ptr_loads; + ptr_loads = 2; + for( size_t i = 0; i < n_dims; i++ ) { + visit_expr_wrapper(m_dims[i].m_length, true); + llvm_size = builder->CreateMul(tmp, llvm_size); + } + ptr_loads = ptr_loads_copy; + LLVM::CreateStore(*builder, llvm_size, array_size); + break; + } default: { - LCOMPILERS_ASSERT(false); + LCOMPILERS_ASSERT_MSG(false, std::to_string(phy_type)); } } llvm::Value* llvmi = CreateAlloca(llvm::Type::getInt32Ty(context), nullptr, "i"); @@ -3249,6 +3285,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor LLVM::CreateLoad(*builder, llvmi)); break; } + case ASR::array_physical_typeType::PointerToDataArray: { + ptr_i = llvm_utils->create_ptr_gep(ptr, LLVM::CreateLoad(*builder, llvmi)); + break; + } default: { LCOMPILERS_ASSERT(false); } @@ -3497,9 +3537,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } llvm_symtab[h] = ptr; - if( ASRUtils::is_array(v->m_type) && - ASRUtils::extract_physical_type(v->m_type) == - ASR::array_physical_typeType::DescriptorArray ) { + if( (ASRUtils::is_array(v->m_type) && + ((ASRUtils::extract_physical_type(v->m_type) == ASR::array_physical_typeType::DescriptorArray) || + (ASRUtils::extract_physical_type(v->m_type) == ASR::array_physical_typeType::CharacterArraySinglePointer && + ASRUtils::is_dimension_empty(m_dims,n_dims)))) + ) { fill_array_details_(ptr, type_, m_dims, n_dims, is_malloc_array_type, is_array_type, is_list, v->m_type); } @@ -3577,8 +3619,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor if (strlen == -3) { LCOMPILERS_ASSERT(t->m_len_expr) this->visit_expr(*t->m_len_expr); - arg_size = builder->CreateAdd(tmp, - llvm::ConstantInt::get(context, llvm::APInt(32, 1))); + arg_size = builder->CreateAdd(builder->CreateSExtOrTrunc(tmp, + llvm::Type::getInt32Ty(context)), + llvm::ConstantInt::get(context, llvm::APInt(32, 1)) ); } else { // Compile time length arg_size = llvm::ConstantInt::get(context, @@ -3595,11 +3638,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *init_value = llvm::Constant::getNullValue(type); builder->CreateStore(init_value, target_var); } else { - throw CodeGenError("Unsupported len value in ASR"); + throw CodeGenError("Unsupported len value in ASR " + std::to_string(strlen)); } } else if (is_list) { - ASR::List_t* asr_list = ASR::down_cast( - ASRUtils::type_get_past_const(v->m_type)); + ASR::List_t* asr_list = ASR::down_cast(ASRUtils::type_get_past_const(v->m_type)); std::string type_code = ASRUtils::get_type_code(asr_list->m_type); list_api->list_init(type_code, ptr, *module); } @@ -3617,6 +3659,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + bool is_function_variable(const ASR::symbol_t *v) { + if( !ASR::is_a(*v) ) { + return false; + } + return is_function_variable(*ASR::down_cast(v)); + } + // F is the function that we are generating and we go over all arguments // (F.args()) and handle three cases: // * Variable (`integer :: x`) @@ -3627,6 +3676,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor for (llvm::Argument &llvm_arg : F.args()) { ASR::symbol_t *s = symbol_get_past_external( ASR::down_cast(x.m_args[i])->m_v); + ASR::symbol_t* arg_sym = s; if (is_a(*s)) { ASR::Variable_t *v = ASR::down_cast(s); if (is_function_variable(*v)) { @@ -3646,10 +3696,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // * Function (`fn`) // Deal with case where procedure passed in as argument ASR::Function_t *arg = ASR::down_cast(s); - uint32_t h = get_hash((ASR::asr_t*)arg); - std::string arg_s = arg->m_name; + uint32_t h = get_hash((ASR::asr_t*)arg_sym); + std::string arg_s = ASRUtils::symbol_name(arg_sym); llvm_arg.setName(arg_s); llvm_symtab_fn_arg[h] = &llvm_arg; + if( is_function_variable(arg_sym) ) { + llvm_symtab[h] = &llvm_arg; + } if (llvm_symtab_fn.find(h) == llvm_symtab_fn.end()) { llvm::FunctionType* fntype = llvm_utils->get_function_type(*arg, module.get()); llvm::Function* fn = llvm::Function::Create(fntype, llvm::Function::ExternalLinkage, arg->m_name, module.get()); @@ -4472,6 +4525,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor strings_to_be_deallocated.push_back(al, tmp); } + void visit_OverloadedStringConcat(const ASR::OverloadedStringConcat_t &x) { + LCOMPILERS_ASSERT(x.m_overloaded != nullptr) + this->visit_expr(*x.m_overloaded); + } + void visit_Assignment(const ASR::Assignment_t &x) { if (compiler_options.emit_debug_info) debug_emit_loc(x); if( x.m_overloaded ) { @@ -4750,8 +4808,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor (ASR::is_a(*x.m_target) && ASRUtils::is_character(*target_type))) && !ASR::is_a(*x.m_target) ) { - builder->CreateStore(value, target); - strings_to_be_deallocated.erase(strings_to_be_deallocated.back()); + if( ASRUtils::is_allocatable(x.m_target) ) { + tmp = lfortran_str_copy(target, value, true); + } else { + builder->CreateStore(value, target); + strings_to_be_deallocated.erase(strings_to_be_deallocated.back()); + } return; } else if (ASR::is_a(*x.m_target)) { ASR::Variable_t *asr_target = EXPR2VAR(x.m_target); @@ -4772,7 +4834,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor bool is_target_fixed_sized_array = (target_ptype == ASR::array_physical_typeType::FixedSizeArray); bool is_value_fixed_sized_array = (value_ptype == ASR::array_physical_typeType::FixedSizeArray); bool is_target_simd_array = (target_ptype == ASR::array_physical_typeType::SIMDArray); - // bool is_target_descriptor_based_array = (target_ptype == ASR::array_physical_typeType::DescriptorArray); + bool is_target_descriptor_based_array = (target_ptype == ASR::array_physical_typeType::DescriptorArray); bool is_value_descriptor_based_array = (value_ptype == ASR::array_physical_typeType::DescriptorArray); if( is_value_fixed_sized_array && is_target_fixed_sized_array ) { value = llvm_utils->create_gep(value, 0); @@ -4802,6 +4864,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm_size = builder->CreateMul(llvm_size, llvm::ConstantInt::get(context, llvm::APInt(32, data_size))); builder->CreateMemCpy(target, llvm::MaybeAlign(), value, llvm::MaybeAlign(), llvm_size); + } else if( is_target_descriptor_based_array && is_value_fixed_sized_array ) { + if( ASRUtils::is_allocatable(target_type) ) { + target = LLVM::CreateLoad(*builder, target); + } + llvm::Value* llvm_size = arr_descr->get_array_size(target, nullptr, 4); + target = LLVM::CreateLoad(*builder, arr_descr->get_pointer_to_data(target)); + value = llvm_utils->create_gep(value, 0); + llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util(ASRUtils::type_get_past_array( + ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(value_type))), module.get()); + llvm::DataLayout data_layout(module.get()); + uint64_t data_size = data_layout.getTypeAllocSize(llvm_data_type); + llvm_size = builder->CreateMul(llvm_size, + llvm::ConstantInt::get(context, llvm::APInt(32, data_size))); + builder->CreateMemCpy(target, llvm::MaybeAlign(), value, llvm::MaybeAlign(), llvm_size); } else if( is_target_data_only_array || is_value_data_only_array ) { if( is_value_fixed_sized_array ) { value = llvm_utils->create_gep(value, 0); @@ -4812,24 +4888,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor is_target_data_only_array = true; } llvm::Value *target_data = nullptr, *value_data = nullptr, *llvm_size = nullptr; + llvm_size = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 1)); if( is_target_data_only_array ) { target_data = target; ASR::dimension_t* target_dims = nullptr; int target_ndims = ASRUtils::extract_dimensions_from_ttype(target_type, target_dims); - size_t target_size = 1; data_only_copy = true; for( int i = 0; i < target_ndims; i++ ) { - int dim_length = -1; - if( !ASRUtils::extract_value(ASRUtils::expr_value(target_dims[i].m_length), dim_length) ) { + if( target_dims[i].m_length == nullptr ) { data_only_copy = false; break; } - target_size *= dim_length; - } - if( data_only_copy ) { - llvm_size = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), - llvm::APInt(32, target_size)); - data_only_copy = false; + this->visit_expr_wrapper(target_dims[i].m_length, true); + llvm_size = builder->CreateMul(llvm_size, tmp); } } else { target_data = LLVM::CreateLoad(*builder, arr_descr->get_pointer_to_data(target)); @@ -4838,32 +4909,28 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor value_data = value; ASR::dimension_t* value_dims = nullptr; int value_ndims = ASRUtils::extract_dimensions_from_ttype(value_type, value_dims); - size_t value_size = 1; - data_only_copy = true; - for( int i = 0; i < value_ndims; i++ ) { - int dim_length = -1; - if( !ASRUtils::extract_value(ASRUtils::expr_value(value_dims[i].m_length), dim_length) ) { - data_only_copy = false; - break; + if( !data_only_copy ) { + llvm_size = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 1)); + data_only_copy = true; + for( int i = 0; i < value_ndims; i++ ) { + if( value_dims[i].m_length == nullptr ) { + data_only_copy = false; + break; + } + this->visit_expr_wrapper(value_dims[i].m_length, true); + llvm_size = builder->CreateMul(llvm_size, tmp); } - value_size *= dim_length; - } - if( data_only_copy ) { - llvm_size = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), - llvm::APInt(32, value_size)); - data_only_copy = false; } } else { value_data = LLVM::CreateLoad(*builder, arr_descr->get_pointer_to_data(value)); } - if( llvm_size ) { - llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util( - ASRUtils::type_get_past_allocatable( - ASRUtils::type_get_past_pointer( - ASRUtils::type_get_past_array(target_type))), module.get()); - arr_descr->copy_array_data_only(value_data, target_data, module.get(), - llvm_data_type, llvm_size); - } + LCOMPILERS_ASSERT(data_only_copy); + llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util( + ASRUtils::type_get_past_allocatable( + ASRUtils::type_get_past_pointer( + ASRUtils::type_get_past_array(target_type))), module.get()); + arr_descr->copy_array_data_only(value_data, target_data, module.get(), + llvm_data_type, llvm_size); } else if ( is_target_simd_array ) { if (ASR::is_a(*x.m_value)) { int idx = 1; @@ -4886,8 +4953,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor builder->CreateStore(value, target); } } else { + bool create_dim_des_array = false; + if( LLVM::is_llvm_pointer(*target_type) ) { + target = LLVM::CreateLoad(*builder, target); + create_dim_des_array = true; + } arr_descr->copy_array(value, target, module.get(), - target_type, false, false); + target_type, create_dim_des_array, false); } } else if( ASR::is_a(*x.m_target) ) { ASR::DictItem_t* dict_item_t = ASR::down_cast(x.m_target); @@ -4915,6 +4987,30 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } + void PointerToData_to_Descriptor(ASR::ttype_t* m_type, ASR::ttype_t* m_type_for_dimensions) { + llvm::BasicBlock &entry_block = builder->GetInsertBlock()->getParent()->getEntryBlock(); + llvm::IRBuilder<> builder0(context); + builder0.SetInsertPoint(&entry_block, entry_block.getFirstInsertionPt()); + llvm::Type* target_type = llvm_utils->get_type_from_ttype_t_util( + ASRUtils::type_get_past_allocatable( + ASRUtils::type_get_past_pointer(m_type)), module.get()); + llvm::AllocaInst *target = builder0.CreateAlloca( + target_type, nullptr, "array_descriptor"); + builder->CreateStore(tmp, arr_descr->get_pointer_to_data(target)); + ASR::dimension_t* m_dims = nullptr; + int n_dims = ASRUtils::extract_dimensions_from_ttype(m_type_for_dimensions, m_dims); + llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util( + ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(m_type)), module.get()); + fill_array_details(target, llvm_data_type, m_dims, n_dims, false, false); + if( LLVM::is_llvm_pointer(*m_type) ) { + llvm::AllocaInst* target_ptr = builder0.CreateAlloca( + target_type->getPointerTo(), nullptr, "array_descriptor_ptr"); + builder->CreateStore(target, target_ptr); + target = target_ptr; + } + tmp = target; + } + void visit_ArrayPhysicalCastUtil(llvm::Value* arg, ASR::expr_t* m_arg, ASR::ttype_t* m_type, ASR::ttype_t* m_type_for_dimensions, ASR::array_physical_typeType m_old, ASR::array_physical_typeType m_new) { @@ -4924,29 +5020,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor return ; } - #define PointerToData_to_Descriptor() llvm::BasicBlock &entry_block = builder->GetInsertBlock()->getParent()->getEntryBlock(); \ - llvm::IRBuilder<> builder0(context); \ - builder0.SetInsertPoint(&entry_block, entry_block.getFirstInsertionPt()); \ - llvm::Type* target_type = llvm_utils->get_type_from_ttype_t_util( \ - ASRUtils::type_get_past_allocatable( \ - ASRUtils::type_get_past_pointer(m_type)), module.get()); \ - llvm::AllocaInst *target = builder0.CreateAlloca( \ - target_type, nullptr, "array_descriptor"); \ - builder->CreateStore(tmp, arr_descr->get_pointer_to_data(target)); \ - ASR::dimension_t* m_dims = nullptr; \ - int n_dims = ASRUtils::extract_dimensions_from_ttype(m_type_for_dimensions, m_dims); \ - llvm::Type* llvm_data_type = llvm_utils->get_type_from_ttype_t_util( \ - ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(m_type)), module.get()); \ - fill_array_details(target, llvm_data_type, m_dims, n_dims, false, false); \ - if( LLVM::is_llvm_pointer(*m_type) ) { \ - llvm::AllocaInst* target_ptr = builder0.CreateAlloca( \ - target_type->getPointerTo(), nullptr, "array_descriptor_ptr"); \ - builder->CreateStore(target, target_ptr); \ - target = target_ptr; \ - } \ - tmp = target; \ - - if( m_new == ASR::array_physical_typeType::PointerToDataArray && m_old == ASR::array_physical_typeType::DescriptorArray ) { if( ASR::is_a(*m_arg) ) { @@ -4974,6 +5047,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor m_new == ASR::array_physical_typeType::SIMDArray && m_old == ASR::array_physical_typeType::FixedSizeArray) { // pass + } else if ( + m_new == ASR::array_physical_typeType::DescriptorArray && + m_old == ASR::array_physical_typeType::SIMDArray) { + tmp = CreateLoad(arg); } else if( m_new == ASR::array_physical_typeType::DescriptorArray && m_old == ASR::array_physical_typeType::FixedSizeArray) { @@ -4982,11 +5059,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASRUtils::expr_value(m_arg) == nullptr ) { tmp = llvm_utils->create_gep(tmp, 0); } - PointerToData_to_Descriptor() + PointerToData_to_Descriptor(m_type, m_type_for_dimensions); } else if( m_new == ASR::array_physical_typeType::DescriptorArray && m_old == ASR::array_physical_typeType::PointerToDataArray) { - PointerToData_to_Descriptor() + PointerToData_to_Descriptor(m_type, m_type_for_dimensions); } else if( m_new == ASR::array_physical_typeType::FixedSizeArray && m_old == ASR::array_physical_typeType::DescriptorArray) { @@ -5012,6 +5089,29 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor int n_dims = ASRUtils::extract_n_dims_from_ttype(m_type_for_dimensions); arr_descr->reset_array_details(target, tmp, n_dims); tmp = target; + } else if ( + m_new == ASR::array_physical_typeType::PointerToDataArray && + m_old == ASR::array_physical_typeType::CharacterArraySinglePointer) { + // + if (ASRUtils::is_fixed_size_array(m_type)) { + if( (ASRUtils::expr_value(m_arg) && + !ASR::is_a(*ASRUtils::expr_value(m_arg))) || + ASRUtils::expr_value(m_arg) == nullptr ) { + tmp = llvm_utils->create_gep(tmp, 0); + } + } else { + tmp = LLVM::CreateLoad(*builder, arr_descr->get_pointer_to_data(tmp)); + } + } else if ( + m_new == ASR::array_physical_typeType::CharacterArraySinglePointer && + m_old == ASR::array_physical_typeType::DescriptorArray) { + if (ASRUtils::is_fixed_size_array(m_type)) { + tmp = LLVM::CreateLoad(*builder, arr_descr->get_pointer_to_data(tmp)); + llvm::Type* target_type = llvm_utils->get_type_from_ttype_t_util(m_type, module.get())->getPointerTo(); + tmp = builder->CreateBitCast(tmp, target_type); // [1 x i8*]* + // we need [1 x i8*] + tmp = LLVM::CreateLoad(*builder, tmp); + } } else { LCOMPILERS_ASSERT(false); } @@ -5038,6 +5138,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } void visit_BlockCall(const ASR::BlockCall_t& x) { + std::vector heap_arrays_copy; + heap_arrays_copy = heap_arrays; + heap_arrays.clear(); if( x.m_label != -1 ) { if( llvm_goto_targets.find(x.m_label) == llvm_goto_targets.end() ) { llvm::BasicBlock *new_target = llvm::BasicBlock::Create(context, "goto_target"); @@ -5047,7 +5150,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } LCOMPILERS_ASSERT(ASR::is_a(*x.m_m)); ASR::Block_t* block = ASR::down_cast(x.m_m); - declare_vars(*block); std::string block_name; if (block->m_name) { block_name = std::string(block->m_name); @@ -5066,6 +5168,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor fn->getBasicBlockList().push_back(blockend); #endif builder->SetInsertPoint(blockstart); + declare_vars(*block); loop_or_block_end.push_back(blockend); loop_or_block_end_names.push_back(blockend_name); for (size_t i = 0; i < block->n_body; i++) { @@ -5075,6 +5178,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor loop_or_block_end_names.pop_back(); llvm::BasicBlock *last_bb = builder->GetInsertBlock(); llvm::Instruction *block_terminator = last_bb->getTerminator(); + for( auto& value: heap_arrays ) { + LLVM::lfortran_free(context, *module, *builder, value); + } + heap_arrays = heap_arrays_copy; if (block_terminator == nullptr) { // The previous block is not terminated --- terminate it by jumping // to blockend @@ -5423,13 +5530,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *real_res, *img_res; switch (x.m_op) { case (ASR::cmpopType::Eq) : { - real_res = builder->CreateFCmpUEQ(real_left, real_right); - img_res = builder->CreateFCmpUEQ(img_left, img_right); + real_res = builder->CreateFCmpOEQ(real_left, real_right); + img_res = builder->CreateFCmpOEQ(img_left, img_right); + tmp = builder->CreateAnd(real_res, img_res); break; } case (ASR::cmpopType::NotEq) : { - real_res = builder->CreateFCmpUNE(real_left, real_right); - img_res = builder->CreateFCmpUNE(img_left, img_right); + real_res = builder->CreateFCmpONE(real_left, real_right); + img_res = builder->CreateFCmpONE(img_left, img_right); + tmp = builder->CreateOr(real_res, img_res); break; } default : { @@ -5437,7 +5546,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor x.base.base.loc); } } - tmp = builder->CreateAnd(real_res, img_res); } void visit_StringCompare(const ASR::StringCompare_t &x) { @@ -5814,7 +5922,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::AllocaInst *parg = builder->CreateAlloca(character_type, nullptr); builder->CreateStore(tmp, parg); ASR::ttype_t* arg_type = ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_arg)); - tmp = lfortran_str_len(parg, ASRUtils::is_array(arg_type)); + tmp = builder->CreateSExtOrTrunc( + lfortran_str_len(parg, ASRUtils::is_array(arg_type)), + llvm_utils->get_type_from_ttype_t_util(x.m_type, module.get())); } void visit_StringOrd(const ASR::StringOrd_t &x) { @@ -5850,7 +5960,8 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ptr_loads = ptr_loads_copy; llvm::Value *str = tmp; if( is_assignment_target ) { - idx = builder->CreateSub(idx, llvm::ConstantInt::get(context, llvm::APInt(32, 1))); + idx = builder->CreateSub(builder->CreateSExtOrTrunc(idx, llvm::Type::getInt32Ty(context)), + llvm::ConstantInt::get(context, llvm::APInt(32, 1))); std::vector idx_vec = {idx}; tmp = CreateGEP(str, idx_vec); } else { @@ -5939,7 +6050,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } template - void handle_SU_IntegerBinOp(const T &x) { + void handle_SU_IntegerBinOp(const T &x, bool signed_int) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; @@ -5964,19 +6075,27 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor break; }; case ASR::binopType::Div: { - tmp = builder->CreateUDiv(left_val, right_val); + if (signed_int) { + tmp = builder->CreateSDiv(left_val, right_val); + } else { + tmp = builder->CreateUDiv(left_val, right_val); + } break; }; case ASR::binopType::Pow: { llvm::Type *type; int a_kind; a_kind = down_cast(ASRUtils::extract_type(x.m_type))->m_kind; - type = llvm_utils->getFPType(a_kind); + if( a_kind <= 4 ) { + type = llvm_utils->getFPType(4); + } else { + type = llvm_utils->getFPType(8); + } llvm::Value *fleft = builder->CreateSIToFP(left_val, type); llvm::Value *fright = builder->CreateSIToFP(right_val, type); - std::string func_name = a_kind == 4 ? "llvm.pow.f32" : "llvm.pow.f64"; + std::string func_name = a_kind <= 4 ? "llvm.pow.f32" : "llvm.pow.f64"; llvm::Function *fn_pow = module->getFunction(func_name); if (!fn_pow) { llvm::FunctionType *function_type = llvm::FunctionType::get( @@ -6014,11 +6133,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } void visit_IntegerBinOp(const ASR::IntegerBinOp_t &x) { - handle_SU_IntegerBinOp(x); + handle_SU_IntegerBinOp(x, true); } void visit_UnsignedIntegerBinOp(const ASR::UnsignedIntegerBinOp_t &x) { - handle_SU_IntegerBinOp(x); + handle_SU_IntegerBinOp(x, false); } void visit_RealBinOp(const ASR::RealBinOp_t &x) { @@ -6277,8 +6396,56 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } + void visit_ArrayConstructor(const ASR::ArrayConstructor_t &x) { + llvm::Type* el_type = nullptr; + ASR::ttype_t* x_m_type = ASRUtils::type_get_past_array(x.m_type); + if (ASR::is_a(*x_m_type)) { + el_type = llvm_utils->getIntType(ASR::down_cast(x_m_type)->m_kind); + } else if (ASR::is_a(*x_m_type)) { + switch (ASR::down_cast(x_m_type)->m_kind) { + case (4) : + el_type = llvm::Type::getFloatTy(context); break; + case (8) : + el_type = llvm::Type::getDoubleTy(context); break; + default : + throw CodeGenError("ConstArray real kind not supported yet"); + } + } else if (ASR::is_a(*x_m_type)) { + el_type = llvm::Type::getInt1Ty(context); + } else if (ASR::is_a(*x_m_type)) { + el_type = character_type; + } else if (ASR::is_a(*x_m_type)) { + int complex_kind = ASR::down_cast(x_m_type)->m_kind; + if( complex_kind == 4 ) { + el_type = llvm_utils->complex_type_4; + } else if( complex_kind == 8 ) { + el_type = llvm_utils->complex_type_8; + } else { + LCOMPILERS_ASSERT(false); + } + } else { + throw CodeGenError("ConstArray type not supported yet"); + } + // Create type, where `n` is the length of the `x` constant array + llvm::Type* type_fxn = FIXED_VECTOR_TYPE::get(el_type, x.n_args); + // Create a pointer * to a stack allocated + llvm::AllocaInst *p_fxn = builder->CreateAlloca(type_fxn, nullptr); + // Assign the array elements to `p_fxn`. + for (size_t i=0; i < x.n_args; i++) { + llvm::Value *llvm_el = llvm_utils->create_gep(p_fxn, i); + ASR::expr_t *el = x.m_args[i]; + int64_t ptr_loads_copy = ptr_loads; + ptr_loads = 2; + this->visit_expr_wrapper(el, true); + ptr_loads = ptr_loads_copy; + builder->CreateStore(tmp, llvm_el); + } + // Return the vector as float* type: + tmp = llvm_utils->create_gep(p_fxn, 0); + } + void visit_ArrayConstant(const ASR::ArrayConstant_t &x) { - llvm::Type* el_type; + llvm::Type* el_type = nullptr; ASR::ttype_t* x_m_type = ASRUtils::type_get_past_array(x.m_type); if (ASR::is_a(*x_m_type)) { el_type = llvm_utils->getIntType(ASR::down_cast(x_m_type)->m_kind); @@ -6295,6 +6462,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor el_type = llvm::Type::getInt1Ty(context); } else if (ASR::is_a(*x_m_type)) { el_type = character_type; + } else if (ASR::is_a(*x_m_type)) { + int complex_kind = ASR::down_cast(x_m_type)->m_kind; + if( complex_kind == 4 ) { + el_type = llvm_utils->complex_type_4; + } else if( complex_kind == 8 ) { + el_type = llvm_utils->complex_type_8; + } else { + LCOMPILERS_ASSERT(false); + } } else { throw CodeGenError("ConstArray type not supported yet"); } @@ -6553,9 +6729,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } void visit_Var(const ASR::Var_t &x) { - ASR::Variable_t *v = ASR::down_cast( - symbol_get_past_external(x.m_v)); - fetch_var(v); + ASR::symbol_t* x_m_v = ASRUtils::symbol_get_past_external(x.m_v); + switch( x_m_v->type ) { + case ASR::symbolType::Variable: { + ASR::Variable_t *v = ASR::down_cast(x_m_v); + fetch_var(v); + return ; + } + case ASR::symbolType::Function: { + uint32_t h = get_hash((ASR::asr_t*)x_m_v); + if( llvm_symtab_fn.find(h) != llvm_symtab_fn.end() ) { + tmp = llvm_symtab_fn[h]; + } + return; + } + default: { + throw CodeGenError("Only function and variables supported so far"); + } + } } inline ASR::ttype_t* extract_ttype_t_from_expr(ASR::expr_t* expr) { @@ -6571,11 +6762,55 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor arg_kind = ASRUtils::extract_kind_from_ttype_t(curr_type); } + template + void handle_arr_for_complex_im_re(const T& t) { + int64_t ptr_loads_copy = ptr_loads; + ptr_loads = 2 - LLVM::is_llvm_pointer(*ASRUtils::expr_type(t.m_arg)); + this->visit_expr_wrapper(t.m_arg, false); + ptr_loads = ptr_loads_copy; + llvm::Value* des_complex_arr = tmp; + tmp = CreateLoad(arr_descr->get_pointer_to_data(des_complex_arr)); + int kind = ASRUtils::extract_kind_from_ttype_t(t.m_type); + llvm::Type* pointer_cast_type = nullptr; + if (kind == 4) { + pointer_cast_type = llvm::Type::getFloatPtrTy(context); + } else { + pointer_cast_type = llvm::Type::getDoublePtrTy(context); + } + tmp = builder->CreateBitCast(tmp, pointer_cast_type); + PointerToData_to_Descriptor(t.m_type, t.m_type); + llvm::Value* des_real_arr = tmp; + llvm::Value* arr_data = CreateLoad(arr_descr->get_pointer_to_data(des_complex_arr)); + tmp = builder->CreateBitCast(arr_data, pointer_cast_type); + builder->CreateStore(tmp, arr_descr->get_pointer_to_data(des_real_arr)); + if (std::is_same::value) { + llvm::Value* incremented_offset = builder->CreateAdd( + arr_descr->get_offset(des_real_arr, true), + llvm::ConstantInt::get(context, llvm::APInt(32, 1))); + builder->CreateStore(incremented_offset, arr_descr->get_offset(des_real_arr, false)); + } + int n_dims = ASRUtils::extract_n_dims_from_ttype(t.m_type); + llvm::Value* dim_des_real_arr = arr_descr->get_pointer_to_dimension_descriptor_array(des_real_arr, true); + for (int i = 0; i < n_dims; i++) { + llvm::Value* dim_idx = llvm::ConstantInt::get(context, llvm::APInt(32, i)); + llvm::Value* dim_des_real_arr_idx = arr_descr->get_pointer_to_dimension_descriptor(dim_des_real_arr, dim_idx); + llvm::Value* doubled_stride = builder->CreateMul( + arr_descr->get_stride(dim_des_real_arr_idx, true), + llvm::ConstantInt::get(context, llvm::APInt(32, 2))); + builder->CreateStore(doubled_stride, arr_descr->get_stride(dim_des_real_arr_idx, false)); + } + tmp = des_real_arr; + } + void visit_ComplexRe(const ASR::ComplexRe_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); return; } + if (ASRUtils::is_array(x.m_type)) { + handle_arr_for_complex_im_re(x); + return; + } this->visit_expr_wrapper(x.m_arg, true); ASR::ttype_t* curr_type = extract_ttype_t_from_expr(x.m_arg); int arg_kind = ASRUtils::extract_kind_from_ttype_t(curr_type); @@ -6609,6 +6844,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor this->visit_expr_wrapper(x.m_value, true); return; } + if (ASRUtils::is_array(x.m_type)) { + handle_arr_for_complex_im_re(x); + return; + } ASR::ttype_t* curr_type = extract_ttype_t_from_expr(x.m_arg); int arg_kind = ASRUtils::extract_kind_from_ttype_t(curr_type); llvm::Function *fn = nullptr; @@ -6646,6 +6885,21 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = CreateLoad(result); } + void visit_BitCast(const ASR::BitCast_t& x) { + if (x.m_value) { + this->visit_expr_wrapper(x.m_value, true); + return; + } + + this->visit_expr_wrapper(x.m_source, true); + llvm::Value* source = tmp; + llvm::Type* source_type = llvm_utils->get_type_from_ttype_t_util(ASRUtils::expr_type(x.m_source), module.get()); + llvm::Value* source_ptr = CreateAlloca(source_type, nullptr, "bitcast_source"); + builder->CreateStore(source, source_ptr); + llvm::Type* target_llvm_type = llvm_utils->get_type_from_ttype_t_util(x.m_type, module.get())->getPointerTo(); + tmp = LLVM::CreateLoad(*builder, builder->CreateBitCast(source_ptr, target_llvm_type)); + } + void visit_Cast(const ASR::Cast_t &x) { if (x.m_value) { this->visit_expr_wrapper(x.m_value, true); @@ -7125,12 +7379,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } void visit_FileRead(const ASR::FileRead_t &x) { - llvm::Value *unit_val, *iostat; + if( x.m_overloaded ) { + this->visit_stmt(*x.m_overloaded); + return ; + } + + llvm::Value *unit_val, *iostat, *read_size; + bool is_string = false; if (x.m_unit == nullptr) { // Read from stdin unit_val = llvm::ConstantInt::get( llvm::Type::getInt32Ty(context), llvm::APInt(32, -1)); } else { + is_string = ASRUtils::is_character(*expr_type(x.m_unit)); this->visit_expr_wrapper(x.m_unit, true); unit_val = tmp; } @@ -7146,10 +7407,22 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Type::getInt32Ty(context), nullptr); } + if (x.m_size) { + int ptr_copy = ptr_loads; + ptr_loads = 0; + this->visit_expr_wrapper(x.m_size, false); + ptr_loads = ptr_copy; + read_size = tmp; + } else { + read_size = builder->CreateAlloca( + llvm::Type::getInt32Ty(context), nullptr); + } + if (x.m_fmt) { std::vector args; args.push_back(unit_val); args.push_back(iostat); + args.push_back(read_size); this->visit_expr_wrapper(x.m_fmt, true); args.push_back(tmp); args.push_back(llvm::ConstantInt::get(context, llvm::APInt(32, x.n_values))); @@ -7167,6 +7440,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Type::getVoidTy(context), { llvm::Type::getInt32Ty(context), llvm::Type::getInt32Ty(context)->getPointerTo(), + llvm::Type::getInt32Ty(context)->getPointerTo(), character_type, llvm::Type::getInt32Ty(context) }, true); @@ -7181,7 +7455,26 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor this->visit_expr(*x.m_values[i]); ptr_loads = ptr_copy; ASR::ttype_t* type = ASRUtils::expr_type(x.m_values[i]); - llvm::Function *fn = get_read_function(type); + llvm::Function *fn; + if (is_string) { + // TODO: Support multiple arguments and fmt + std::string runtime_func_name = "_lfortran_string_read"; + llvm::Function *fn = module->getFunction(runtime_func_name); + if (!fn) { + llvm::FunctionType *function_type = llvm::FunctionType::get( + llvm::Type::getVoidTy(context), { + character_type, character_type, + llvm::Type::getInt32Ty(context)->getPointerTo() + }, false); + fn = llvm::Function::Create(function_type, + llvm::Function::ExternalLinkage, runtime_func_name, *module); + } + llvm::Value *fmt = builder->CreateGlobalStringPtr("%d"); + builder->CreateCall(fn, {unit_val, fmt, tmp}); + return; + } else { + fn = get_read_function(type); + } if (ASRUtils::is_array(type)) { if (ASR::is_a(*type) || ASR::is_a(*type)) { @@ -7222,7 +7515,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Function::ExternalLinkage, runtime_func_name, *module); } - this->visit_expr_wrapper(x.m_unit, true); builder->CreateCall(fn, {unit_val, iostat}); } } @@ -7232,24 +7524,29 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *status = nullptr, *form = nullptr; this->visit_expr_wrapper(x.m_newunit, true); unit_val = tmp; + int ptr_copy = ptr_loads; if (x.m_filename) { - this->visit_expr_wrapper(x.m_filename, true); + ptr_loads = 1; + this->visit_expr_wrapper(x.m_filename); f_name = tmp; } else { f_name = llvm::Constant::getNullValue(character_type); } if (x.m_status) { - this->visit_expr_wrapper(x.m_status, true); + ptr_loads = 1; + this->visit_expr_wrapper(x.m_status); status = tmp; } else { status = llvm::Constant::getNullValue(character_type); } if (x.m_form) { - this->visit_expr_wrapper(x.m_form, true); + ptr_loads = 1; + this->visit_expr_wrapper(x.m_form); form = tmp; } else { form = llvm::Constant::getNullValue(character_type); } + ptr_loads = ptr_copy; std::string runtime_func_name = "_lfortran_open"; llvm::Function *fn = module->getFunction(runtime_func_name); if (!fn) { @@ -7387,6 +7684,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } void visit_FileWrite(const ASR::FileWrite_t &x) { + if( x.m_overloaded ) { + this->visit_stmt(*x.m_overloaded); + return ; + } + if (x.m_unit == nullptr) { handle_print(x); return; @@ -7397,6 +7699,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor llvm::Value *sep = nullptr; llvm::Value *end = nullptr; llvm::Value *unit = nullptr; + llvm::Value *iostat = nullptr; std::string runtime_func_name; bool is_string = ASRUtils::is_character(*expr_type(x.m_unit)); @@ -7416,6 +7719,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ptr_loads = ptr_loads_copy; unit = tmp; + if (x.m_iostat) { + int ptr_copy = ptr_loads; + ptr_loads = 0; + this->visit_expr_wrapper(x.m_iostat, false); + ptr_loads = ptr_copy; + iostat = tmp; + } else { + iostat = builder->CreateAlloca( + llvm::Type::getInt32Ty(context), nullptr); + } + if (x.m_separator) { this->visit_expr_wrapper(x.m_separator, true); sep = tmp; @@ -7429,16 +7743,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor end = builder->CreateGlobalStringPtr("\n"); } size_t n_values = x.n_values; ASR::expr_t **m_values = x.m_values; - // TODO: Handle String Formatting - if (n_values > 0 && is_a(*m_values[0]) && is_string) { - n_values = down_cast(m_values[0])->n_args; - m_values = down_cast(m_values[0])->m_args; - } for (size_t i=0; i std::vector printf_args; printf_args.push_back(unit); + printf_args.push_back(iostat); printf_args.push_back(fmt_ptr); printf_args.insert(printf_args.end(), args.begin(), args.end()); llvm::Function *fn = module->getFunction(runtime_func_name); if (!fn) { + args_type.push_back(llvm::Type::getInt32PtrTy(context)); args_type.push_back(llvm::Type::getInt8PtrTy(context)); llvm::FunctionType *function_type = llvm::FunctionType::get( llvm::Type::getVoidTy(context), args_type, true); @@ -7640,13 +7947,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor template void handle_print(const T &x) { std::vector args; + args.push_back(nullptr); // reserve space for fmt_str std::vector fmt; llvm::Value *sep = nullptr; + llvm::Value *sep_no_space = nullptr; llvm::Value *end = nullptr; + bool global_sep_space = false; if (x.m_separator) { this->visit_expr_wrapper(x.m_separator, true); sep = tmp; } else { + global_sep_space = true; sep = builder->CreateGlobalStringPtr(" "); } if (x.m_end) { @@ -7658,7 +7969,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor for (size_t i=0; iCreateGlobalStringPtr(""); + args.push_back(sep_no_space); + } } compute_fmt_specifier_and_arg(fmt, args, x.m_values[i], x.base.base.loc); } @@ -7669,36 +7987,67 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor fmt_str += fmt[i]; } llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr(fmt_str); - std::vector printf_args; - printf_args.push_back(fmt_ptr); - printf_args.insert(printf_args.end(), args.begin(), args.end()); - printf(context, *module, *builder, printf_args); + args[0] = fmt_ptr; + printf(context, *module, *builder, args); } - void visit_Stop(const ASR::Stop_t &x) { - if (compiler_options.emit_debug_info) debug_emit_loc(x); - llvm::Value *exit_code; - if (x.m_code && is_a(*ASRUtils::expr_type(x.m_code))) { - this->visit_expr(*x.m_code); + void construct_stop(llvm::Value* exit_code, std::string stop_msg, ASR::expr_t* stop_code, Location loc) { + std::string fmt_str; + std::vector fmt; + std::vector args; + args.push_back(nullptr); // reserve space for fmt_str + ASR::ttype_t *str_type_len_msg = ASRUtils::TYPE(ASR::make_Character_t( + al, loc, 1, stop_msg.size(), nullptr)); + ASR::expr_t* STOP_MSG = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, + s2c(al, stop_msg), str_type_len_msg)); + ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t( + al, loc, 1, 1, nullptr)); + ASR::expr_t* NEWLINE = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, + s2c(al, "\n"), str_type_len_1)); + compute_fmt_specifier_and_arg(fmt, args, STOP_MSG, loc); + if (stop_code) { + ASR::expr_t* SPACE = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, + s2c(al, " "), str_type_len_1)); + compute_fmt_specifier_and_arg(fmt, args, SPACE, loc); + compute_fmt_specifier_and_arg(fmt, args, stop_code, loc); + } + compute_fmt_specifier_and_arg(fmt, args, NEWLINE, loc); + + for (auto ch:fmt) { + fmt_str += ch; + } + + llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr(fmt_str); + args[0] = fmt_ptr; + print_error(context, *module, *builder, args); + + if (stop_code && is_a(*ASRUtils::expr_type(stop_code))) { + this->visit_expr(*stop_code); exit_code = tmp; - if (compiler_options.emit_debug_info) { + } + exit(context, *module, *builder, exit_code); + } + + void visit_Stop(const ASR::Stop_t &x) { + if (compiler_options.emit_debug_info) { + debug_emit_loc(x); + if (x.m_code && is_a(*ASRUtils::expr_type(x.m_code))) { llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr(infile); llvm::Value *fmt_ptr1 = llvm::ConstantInt::get(context, llvm::APInt( 1, compiler_options.use_colors)); - llvm::Value *test = builder->CreateICmpNE(exit_code, builder->getInt32(0)); + this->visit_expr(*x.m_code); + llvm::Value *test = builder->CreateICmpNE(tmp, builder->getInt32(0)); llvm_utils->create_if_else(test, [=]() { call_print_stacktrace_addresses(context, *module, *builder, {fmt_ptr, fmt_ptr1}); }, [](){}); } - } else { - int exit_code_int = 0; - exit_code = llvm::ConstantInt::get(context, - llvm::APInt(32, exit_code_int)); } - llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("STOP\n"); - print_error(context, *module, *builder, {fmt_ptr}); - exit(context, *module, *builder, exit_code); + + int exit_code_int = 0; + llvm::Value *exit_code = llvm::ConstantInt::get(context, + llvm::APInt(32, exit_code_int)); + construct_stop(exit_code, "STOP", x.m_code, x.base.base.loc); } void visit_ErrorStop(const ASR::ErrorStop_t &x) { @@ -7710,12 +8059,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor call_print_stacktrace_addresses(context, *module, *builder, {fmt_ptr, fmt_ptr1}); } - llvm::Value *fmt_ptr = builder->CreateGlobalStringPtr("ERROR STOP\n"); - print_error(context, *module, *builder, {fmt_ptr}); + int exit_code_int = 1; llvm::Value *exit_code = llvm::ConstantInt::get(context, llvm::APInt(32, exit_code_int)); - exit(context, *module, *builder, exit_code); + construct_stop(exit_code, "ERROR STOP", x.m_code, x.base.base.loc); } template @@ -7780,6 +8128,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor if (llvm_symtab.find(h) != llvm_symtab.end()) { tmp = llvm_symtab[h]; if( !ASRUtils::is_array(arg->m_type) ) { + if (x_abi == ASR::abiType::Source && ASR::is_a(*arg->m_type)) { if ( orig_arg_intent != ASRUtils::intent_out && arg->m_intent == intent_local ) { @@ -7861,6 +8210,20 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor builder->CreateStore(tmp, target); tmp = target; } + } else { + if( orig_arg && + !LLVM::is_llvm_pointer(*orig_arg->m_type) && + LLVM::is_llvm_pointer(*arg->m_type) && + ASRUtils::check_equal_type( + ASRUtils::type_get_past_allocatable( + ASRUtils::type_get_past_pointer(orig_arg->m_type)), + ASRUtils::type_get_past_allocatable( + ASRUtils::type_get_past_pointer(arg->m_type))) && + !ASRUtils::is_character(*arg->m_type) ) { + // TODO: Remove call to ASRUtils::check_equal_type + // pass(rhs) is not respected in integration_tests/class_08.f90 + tmp = LLVM::CreateLoad(*builder, tmp); + } } } else { if( orig_arg && @@ -7921,6 +8284,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } } else if (ASR::is_a(*x.m_args[i].m_value)) { this->visit_expr_wrapper(x.m_args[i].m_value); + } else if( ASR::is_a( + *ASRUtils::type_get_past_pointer( + ASRUtils::type_get_past_allocatable( + ASRUtils::expr_type(x.m_args[i].m_value)))) ) { + this->visit_expr_wrapper(x.m_args[i].m_value, true); } else { ASR::ttype_t* arg_type = expr_type(x.m_args[i].m_value); int64_t ptr_loads_copy = ptr_loads; @@ -7955,7 +8323,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // there might be a bug below. llvm::Type *target_type = nullptr; bool character_bindc = false; - ASR::ttype_t* arg_type_ = ASRUtils::type_get_past_const(ASRUtils::type_get_past_array(arg_type)); + ASR::ttype_t* arg_type_ = ASRUtils::type_get_past_array(arg_type); switch (arg_type_->type) { case (ASR::ttypeType::Integer) : { int a_kind = down_cast(arg_type_)->m_kind; @@ -8020,6 +8388,14 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor target_type = llvm_utils->get_type_from_ttype_t_util(arg_type_, module.get()); break ; } + case (ASR::ttypeType::FunctionType): { + target_type = llvm_utils->get_type_from_ttype_t_util(arg_type_, module.get()); + break; + } + case (ASR::ttypeType::Const): { + target_type = llvm_utils->get_type_from_ttype_t_util(ASRUtils::get_contained_type(arg_type), module.get()); + break; + } default : throw CodeGenError("Type " + ASRUtils::type_to_str(arg_type) + " not implemented yet."); } @@ -8251,21 +8627,41 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor return ; } } + + std::vector args; + if( x.m_dt && ASR::is_a(*x.m_dt) && + ASR::is_a(*ASRUtils::symbol_get_past_external(x.m_name)) && + ASR::is_a(*ASRUtils::symbol_type(x.m_name)) ) { + uint64_t ptr_loads_copy = ptr_loads; + ptr_loads = 1; + this->visit_expr(*x.m_dt); + ptr_loads = ptr_loads_copy; + llvm::Value* callee = LLVM::CreateLoad(*builder, tmp); + + args = convert_call_args(x, false); + llvm::FunctionType* fntype = llvm_utils->get_function_type( + ASR::down_cast(ASRUtils::expr_type(x.m_dt)), + module.get()); + tmp = builder->CreateCall(fntype, callee, args); + return ; + } + const ASR::symbol_t *proc_sym = symbol_get_past_external(x.m_name); std::string proc_sym_name = ""; bool is_deferred = false; + bool is_nopass = false; if( ASR::is_a(*proc_sym) ) { ASR::ClassProcedure_t* class_proc = ASR::down_cast(proc_sym); is_deferred = class_proc->m_is_deferred; proc_sym_name = class_proc->m_name; + is_nopass = class_proc->m_is_nopass; } if( is_deferred ) { visit_RuntimePolymorphicSubroutineCall(x, proc_sym_name); return ; } ASR::Function_t *s; - std::vector args; char* self_argument = nullptr; llvm::Value* pass_arg = nullptr; if (ASR::is_a(*proc_sym)) { @@ -8275,6 +8671,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASR::ClassProcedure_t>(proc_sym); s = ASR::down_cast(clss_proc->m_proc); self_argument = clss_proc->m_self_argument; + proc_sym = clss_proc->m_proc; } else if (ASR::is_a(*proc_sym)) { ASR::symbol_t *type_decl = ASR::down_cast(proc_sym)->m_type_declaration; LCOMPILERS_ASSERT(type_decl); @@ -8286,7 +8683,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor s = ASR::down_cast(symbol_get_past_external(x.m_name)); } bool is_method = false; - if (x.m_dt) { + if (x.m_dt && (!is_nopass)) { is_method = true; if (ASR::is_a(*x.m_dt)) { ASR::Variable_t *caller = EXPR2VAR(x.m_dt); @@ -8363,11 +8760,11 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor if (s_func_type->m_abi == ASR::abiType::LFortranModule) { throw CodeGenError("Subroutine LCompilers interfaces not implemented yet"); } else if (s_func_type->m_abi == ASR::abiType::Interactive) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::Source) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::BindC) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::Intrinsic) { if (sub_name == "get_command_argument") { llvm::Function *fn = module->getFunction("_lpython_get_argv"); @@ -8416,7 +8813,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor tmp = builder->CreateCall(fn, {CreateLoad(args[0])}); return; } - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else { throw CodeGenError("ABI type not implemented yet in SubroutineCall."); } @@ -8727,14 +9124,34 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor return ; } + std::vector args; + if( x.m_dt && ASR::is_a(*x.m_dt) && + ASR::is_a(*ASRUtils::symbol_get_past_external(x.m_name)) && + ASR::is_a(*ASRUtils::symbol_type(x.m_name)) ) { + uint64_t ptr_loads_copy = ptr_loads; + ptr_loads = 1; + this->visit_expr(*x.m_dt); + ptr_loads = ptr_loads_copy; + llvm::Value* callee = LLVM::CreateLoad(*builder, tmp); + + args = convert_call_args(x, false); + llvm::FunctionType* fntype = llvm_utils->get_function_type( + ASR::down_cast(ASRUtils::expr_type(x.m_dt)), + module.get()); + tmp = builder->CreateCall(fntype, callee, args); + return ; + } + const ASR::symbol_t *proc_sym = symbol_get_past_external(x.m_name); std::string proc_sym_name = ""; bool is_deferred = false; + bool is_nopass = false; if( ASR::is_a(*proc_sym) ) { ASR::ClassProcedure_t* class_proc = ASR::down_cast(proc_sym); is_deferred = class_proc->m_is_deferred; proc_sym_name = class_proc->m_name; + is_nopass = class_proc->m_is_nopass; } if( is_deferred ) { visit_RuntimePolymorphicFunctionCall(x, proc_sym_name); @@ -8742,7 +9159,6 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } ASR::Function_t *s = nullptr; - std::vector args; std::string self_argument = ""; if (ASR::is_a(*proc_sym)) { s = ASR::down_cast(proc_sym); @@ -8752,6 +9168,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor s = ASR::down_cast(clss_proc->m_proc); if (clss_proc->m_self_argument) self_argument = std::string(clss_proc->m_self_argument); + proc_sym = clss_proc->m_proc; } else if (ASR::is_a(*proc_sym)) { ASR::symbol_t *type_decl = ASR::down_cast(proc_sym)->m_type_declaration; LCOMPILERS_ASSERT(type_decl); @@ -8764,7 +9181,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } bool is_method = false; llvm::Value* pass_arg = nullptr; - if (x.m_dt) { + if (x.m_dt && (!is_nopass)) { is_method = true; if (ASR::is_a(*x.m_dt)) { ASR::Variable_t *caller = EXPR2VAR(x.m_dt); @@ -8864,28 +9281,23 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor handle_bitwise_or(x); return ; } - if( startswith(symbol_name, "allocated") ){ - LCOMPILERS_ASSERT(x.n_args == 1); - handle_allocated(x.m_args[0].m_value); - return ; - } } bool intrinsic_function = ASRUtils::is_intrinsic_function2(s); uint32_t h; ASR::FunctionType_t* s_func_type = ASR::down_cast(s->m_function_signature); if (s_func_type->m_abi == ASR::abiType::Source && !intrinsic_function) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::LFortranModule) { throw CodeGenError("Function LCompilers interfaces not implemented yet"); } else if (s_func_type->m_abi == ASR::abiType::Interactive) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::BindC) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else if (s_func_type->m_abi == ASR::abiType::Intrinsic || intrinsic_function) { std::string func_name = s->m_name; if( fname2arg_type.find(func_name) != fname2arg_type.end() ) { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } else { if (func_name == "len") { args = convert_call_args(x, is_method); @@ -8917,7 +9329,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor if( ASRUtils::get_FunctionType(s)->m_deftype == ASR::deftypeType::Interface ) { throw CodeGenError("Intrinsic '" + func_name + "' not implemented yet and compile time value is not available."); } else { - h = get_hash((ASR::asr_t*)s); + h = get_hash((ASR::asr_t*)proc_sym); } } } else { @@ -9037,6 +9449,13 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor ASR::ttype_t* x_mv_type = ASRUtils::expr_type(m_v); ASR::array_physical_typeType physical_type = ASRUtils::extract_physical_type(x_mv_type); + if (physical_type == ASR::array_physical_typeType::CharacterArraySinglePointer) { + if (ASRUtils::is_fixed_size_array(x_mv_type)) { + physical_type = ASR::array_physical_typeType::FixedSizeArray; + } else { + physical_type = ASR::array_physical_typeType::DescriptorArray; + } + } switch( physical_type ) { case ASR::array_physical_typeType::DescriptorArray: { tmp = arr_descr->get_array_size(llvm_arg, llvm_dim, output_kind, dim_kind); @@ -9180,6 +9599,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor { if( x.m_bound == ASR::arrayboundType::LBound ) { this->visit_expr_wrapper(m_dims[i].m_start, true); + tmp = builder->CreateSExtOrTrunc(tmp, target_type); builder->CreateStore(tmp, target); } else if( x.m_bound == ASR::arrayboundType::UBound ) { llvm::Value *lbound = nullptr, *length = nullptr; @@ -9210,6 +9630,73 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor } break; } + case ASR::array_physical_typeType::CharacterArraySinglePointer: { + ASR::dimension_t* m_dims = nullptr; + int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims); + if (ASRUtils::is_dimension_empty(m_dims, n_dims)) { + // treat it as DescriptorArray + llvm::Value* dim_des_val = arr_descr->get_pointer_to_dimension_descriptor_array(llvm_arg1); + llvm::Value* const_1 = llvm::ConstantInt::get(context, llvm::APInt(32, 1)); + dim_val = builder->CreateSub(dim_val, const_1); + llvm::Value* dim_struct = arr_descr->get_pointer_to_dimension_descriptor(dim_des_val, dim_val); + llvm::Value* res = nullptr; + if( x.m_bound == ASR::arrayboundType::LBound ) { + res = arr_descr->get_lower_bound(dim_struct); + } else if( x.m_bound == ASR::arrayboundType::UBound ) { + res = arr_descr->get_upper_bound(dim_struct); + } + tmp = res; + break; + } else if (ASRUtils::is_fixed_size_array(x_mv_type)) { + llvm::BasicBlock &entry_block = builder->GetInsertBlock()->getParent()->getEntryBlock(); + llvm::IRBuilder<> builder0(context); + builder0.SetInsertPoint(&entry_block, entry_block.getFirstInsertionPt()); + llvm::Type* target_type = llvm_utils->get_type_from_ttype_t_util( + ASRUtils::type_get_past_allocatable( + ASRUtils::type_get_past_pointer(x.m_type)), module.get()); + llvm::AllocaInst *target = builder0.CreateAlloca( + target_type, nullptr, "array_bound"); + llvm::BasicBlock *mergeBB = llvm::BasicBlock::Create(context, "ifcont"); + ASR::dimension_t* m_dims = nullptr; + int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims); + for( int i = 0; i < n_dims; i++ ) { + llvm::Function *fn = builder->GetInsertBlock()->getParent(); + + llvm::BasicBlock *thenBB = llvm::BasicBlock::Create(context, "then", fn); + llvm::BasicBlock *elseBB = llvm::BasicBlock::Create(context, "else"); + + llvm::Value* cond = builder->CreateICmpEQ(dim_val, + llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, i + 1))); + builder->CreateCondBr(cond, thenBB, elseBB); + builder->SetInsertPoint(thenBB); + { + if( x.m_bound == ASR::arrayboundType::LBound ) { + this->visit_expr_wrapper(m_dims[i].m_start, true); + builder->CreateStore(tmp, target); + } else if( x.m_bound == ASR::arrayboundType::UBound ) { + llvm::Value *lbound = nullptr, *length = nullptr; + this->visit_expr_wrapper(m_dims[i].m_start, true); + lbound = tmp; + this->visit_expr_wrapper(m_dims[i].m_length, true); + length = tmp; + builder->CreateStore( + builder->CreateSub(builder->CreateAdd(length, lbound), + llvm::ConstantInt::get(context, llvm::APInt(32, 1))), + target); + } + } + builder->CreateBr(mergeBB); + + start_new_block(elseBB); + } + start_new_block(mergeBB); + tmp = LLVM::CreateLoad(*builder, target); + break; + } else { + LCOMPILERS_ASSERT(false); + break; + } + } default: { LCOMPILERS_ASSERT(false); } @@ -9222,17 +9709,17 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor // if (fmt_value) ... if (x.m_kind == ASR::string_format_kindType::FormatFortran) { std::vector args; - int size = x.n_args; - llvm::Value *count = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), size); - args.push_back(count); visit_expr(*x.m_fmt); args.push_back(tmp); for (size_t i=0; ifmt; + std::vector fmt; // Use the function to compute the args, but ignore the format compute_fmt_specifier_and_arg(fmt, args, x.m_args[i], x.base.base.loc); } + llvm::Value *args_cnt = llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), + args.size() - 1); + args.insert(args.begin(), args_cnt); tmp = string_format_fortran(context, *module, *builder, args); } else { throw CodeGenError("Only FormatFortran string formatting implemented so far."); @@ -9268,15 +9755,14 @@ Result> asr_to_llvm(ASR::TranslationUnit_t &asr, context.setOpaquePointers(false); #endif ASRToLLVMVisitor v(al, context, infile, co, diagnostics); - LCompilers::PassOptions pass_options; std::vector skip_optimization_func_instantiation; skip_optimization_func_instantiation.push_back(static_cast( - ASRUtils::IntrinsicScalarFunctions::FlipSign)); + ASRUtils::IntrinsicElementalFunctions::FlipSign)); skip_optimization_func_instantiation.push_back(static_cast( - ASRUtils::IntrinsicScalarFunctions::FMA)); + ASRUtils::IntrinsicElementalFunctions::FMA)); skip_optimization_func_instantiation.push_back(static_cast( - ASRUtils::IntrinsicScalarFunctions::SignFromValue)); + ASRUtils::IntrinsicElementalFunctions::SignFromValue)); co.po.run_fun = run_fn; co.po.always_run = false; diff --git a/src/libasr/codegen/asr_to_python.cpp b/src/libasr/codegen/asr_to_python.cpp index fa9a06adc4..204880be21 100644 --- a/src/libasr/codegen/asr_to_python.cpp +++ b/src/libasr/codegen/asr_to_python.cpp @@ -379,7 +379,7 @@ class ASRToLpythonVisitor : public ASR::BaseVisitor s = r; } - void visit_IntrinsicScalarFunction(const ASR::IntrinsicScalarFunction_t &x) { + void visit_IntrinsicElementalFunction(const ASR::IntrinsicElementalFunction_t &x) { std::string out; switch (x.m_intrinsic_id) { SET_INTRINSIC_NAME(Abs, "abs"); diff --git a/src/libasr/codegen/asr_to_wasm.cpp b/src/libasr/codegen/asr_to_wasm.cpp index d83a351171..8ca62ff172 100644 --- a/src/libasr/codegen/asr_to_wasm.cpp +++ b/src/libasr/codegen/asr_to_wasm.cpp @@ -2434,12 +2434,12 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { if (m_func_name_idx_map.find(hash) != m_func_name_idx_map.end()) { m_wa.emit_call(m_func_name_idx_map[hash].index); } else { - if (strcmp(fn->m_name, "c_caimag") == 0) { + if (strcmp(fn->m_name, "_lfortran_caimag") == 0) { LCOMPILERS_ASSERT(x.n_args == 1); m_wa.emit_global_set(m_compiler_globals[tmp_reg_f32]); m_wa.emit_drop(); m_wa.emit_global_get(m_compiler_globals[tmp_reg_f32]); - } else if (strcmp(fn->m_name, "c_zaimag") == 0) { + } else if (strcmp(fn->m_name, "_lfortran_zaimag") == 0) { m_wa.emit_global_set(m_compiler_globals[tmp_reg_f64]); m_wa.emit_drop(); m_wa.emit_global_get(m_compiler_globals[tmp_reg_f64]); @@ -3196,6 +3196,10 @@ class ASRToWASMVisitor : public ASR::BaseVisitor { wasm_exit(); }); } + + void visit_TypeInquiry(const ASR::TypeInquiry_t &x) { + this->visit_expr(*x.m_value); + } }; Result> asr_to_wasm_bytes_stream(ASR::TranslationUnit_t &asr, diff --git a/src/libasr/codegen/c_utils.h b/src/libasr/codegen/c_utils.h index 0a72817868..b21d7b2f85 100644 --- a/src/libasr/codegen/c_utils.h +++ b/src/libasr/codegen/c_utils.h @@ -290,6 +290,11 @@ namespace CUtils { type_src = get_c_type_from_ttype_t(ptr_type->m_type) + "*"; break; } + case ASR::ttypeType::Const: { + ASR::Const_t* ptr_type = ASR::down_cast(t); + type_src = "const " + get_c_type_from_ttype_t(ptr_type->m_type); + break; + } case ASR::ttypeType::CPtr: { type_src = "void*"; break; diff --git a/src/libasr/codegen/llvm_array_utils.cpp b/src/libasr/codegen/llvm_array_utils.cpp index 3f884952e7..a38415e125 100644 --- a/src/libasr/codegen/llvm_array_utils.cpp +++ b/src/libasr/codegen/llvm_array_utils.cpp @@ -261,12 +261,10 @@ namespace LCompilers { llvm::Value* offset_val = llvm_utils->create_gep(arr, 1); builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, 0)), offset_val); llvm::Value* dim_des_val = llvm_utils->create_gep(arr, 2); - llvm::Value* llvm_ndims = builder->CreateAlloca(llvm::Type::getInt32Ty(context), nullptr); - builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, n_dims)), llvm_ndims); - llvm::Value* dim_des_first = builder->CreateAlloca(dim_des, - LLVM::CreateLoad(*builder, llvm_ndims)); - builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, n_dims)), get_rank(arr, true)); + llvm::Value* arr_rank = llvm::ConstantInt::get(context, llvm::APInt(32, n_dims)); + llvm::Value* dim_des_first = builder->CreateAlloca(dim_des, arr_rank); builder->CreateStore(dim_des_first, dim_des_val); + builder->CreateStore(arr_rank, get_rank(arr, true)); dim_des_val = LLVM::CreateLoad(*builder, dim_des_val); llvm::Value* prod = llvm::ConstantInt::get(context, llvm::APInt(32, 1)); for( int r = 0; r < n_dims; r++ ) { @@ -346,9 +344,10 @@ namespace LCompilers { llvm::Value* s_val = llvm_utils->create_gep(dim_val, 0); llvm::Value* l_val = llvm_utils->create_gep(dim_val, 1); llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 2); + llvm::Value* first = builder->CreateSExtOrTrunc(llvm_dims[r].first, llvm::Type::getInt32Ty(context)); + llvm::Value* dim_size = builder->CreateSExtOrTrunc(llvm_dims[r].second, llvm::Type::getInt32Ty(context)); builder->CreateStore(prod, s_val); - builder->CreateStore(llvm_dims[r].first, l_val); - llvm::Value* dim_size = llvm_dims[r].second; + builder->CreateStore(first, l_val); builder->CreateStore(dim_size, dim_size_ptr); prod = builder->CreateMul(prod, dim_size); } @@ -444,18 +443,20 @@ namespace LCompilers { int j = 0; for( int i = 0; i < value_rank; i++ ) { if( ds[i] != nullptr ) { + llvm::Value* ubsi = builder->CreateSExtOrTrunc(ubs[i], llvm::Type::getInt32Ty(context)); + llvm::Value* lbsi = builder->CreateSExtOrTrunc(lbs[i], llvm::Type::getInt32Ty(context)); + llvm::Value* dsi = builder->CreateSExtOrTrunc(ds[i], llvm::Type::getInt32Ty(context)); llvm::Value* dim_length = builder->CreateAdd( - builder->CreateSDiv( - builder->CreateSub(ubs[i], lbs[i]), - ds[i]), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), - llvm::APInt(32, 1)) - ); + builder->CreateSDiv(builder->CreateSub(ubsi, lbsi), dsi), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), + llvm::APInt(32, 1)) + ); llvm::Value* value_dim_des = llvm_utils->create_ptr_gep(value_dim_des_array, i); llvm::Value* target_dim_des = llvm_utils->create_ptr_gep(target_dim_des_array, j); llvm::Value* value_stride = get_stride(value_dim_des, true); llvm::Value* target_stride = get_stride(target_dim_des, false); - builder->CreateStore(value_stride, target_stride); + builder->CreateStore(builder->CreateMul(value_stride, builder->CreateZExtOrTrunc( + ds[i], llvm::Type::getInt32Ty(context))), target_stride); // Diverges from LPython, 0 should be stored there. builder->CreateStore(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 1)), get_lower_bound(target_dim_des, false)); @@ -500,16 +501,17 @@ namespace LCompilers { llvm::Value* stride = llvm::ConstantInt::get(context, llvm::APInt(32, 1)); for( int i = 0; i < value_rank; i++ ) { if( ds[i] != nullptr ) { + llvm::Value* ubsi = builder->CreateSExtOrTrunc(ubs[i], llvm::Type::getInt32Ty(context)); + llvm::Value* lbsi = builder->CreateSExtOrTrunc(lbs[i], llvm::Type::getInt32Ty(context)); + llvm::Value* dsi = builder->CreateSExtOrTrunc(ds[i], llvm::Type::getInt32Ty(context)); llvm::Value* dim_length = builder->CreateAdd( - builder->CreateSDiv( - builder->CreateSub(ubs[i], lbs[i]), - ds[i]), - llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), - llvm::APInt(32, 1)) - ); + builder->CreateSDiv(builder->CreateSub(ubsi, lbsi), dsi), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), + llvm::APInt(32, 1)) + ); llvm::Value* target_dim_des = llvm_utils->create_ptr_gep(target_dim_des_array, j); - builder->CreateStore(stride, - get_stride(target_dim_des, false)); + builder->CreateStore(builder->CreateMul(stride, builder->CreateZExtOrTrunc( + ds[i], llvm::Type::getInt32Ty(context))), get_stride(target_dim_des, false)); builder->CreateStore(llvm::ConstantInt::get(llvm::Type::getInt32Ty(context), llvm::APInt(32, 1)), get_lower_bound(target_dim_des, false)); builder->CreateStore(dim_length, @@ -579,6 +581,8 @@ namespace LCompilers { llvm::Value* curr_llvm_idx = m_args[r]; llvm::Value* dim_des_ptr = llvm_utils->create_ptr_gep(dim_des_arr_ptr, r); llvm::Value* lval = LLVM::CreateLoad(*builder, llvm_utils->create_gep(dim_des_ptr, 1)); + // first cast curr_llvm_idx to 32 bit + curr_llvm_idx = builder->CreateSExtOrTrunc(curr_llvm_idx, llvm::Type::getInt32Ty(context)); curr_llvm_idx = builder->CreateSub(curr_llvm_idx, lval); if( check_for_bounds ) { // check_single_element(curr_llvm_idx, arr); TODO: To be implemented @@ -598,6 +602,8 @@ namespace LCompilers { for( int r = 0, r1 = 0; r < n_args; r++ ) { llvm::Value* curr_llvm_idx = m_args[r]; llvm::Value* lval = llvm_diminfo[r1]; + // first cast curr_llvm_idx to 32 bit + curr_llvm_idx = builder->CreateSExtOrTrunc(curr_llvm_idx, llvm::Type::getInt32Ty(context)); curr_llvm_idx = builder->CreateSub(curr_llvm_idx, lval); if( check_for_bounds ) { // check_single_element(curr_llvm_idx, arr); TODO: To be implemented @@ -669,7 +675,7 @@ namespace LCompilers { if( dim ) { tmp = builder->CreateSub(dim, llvm::ConstantInt::get(context, llvm::APInt(dim_kind * 8, 1))); tmp = this->get_dimension_size(dim_des_val, tmp); - tmp = builder->CreateSExt(tmp, llvm_utils->getIntType(kind)); + tmp = builder->CreateSExtOrTrunc(tmp, llvm_utils->getIntType(kind)); return tmp; } llvm::BasicBlock &entry_block = builder->GetInsertBlock()->getParent()->getEntryBlock(); @@ -695,7 +701,7 @@ namespace LCompilers { llvm::Value* r_val = LLVM::CreateLoad(*builder, r); llvm::Value* ret_val = LLVM::CreateLoad(*builder, llvm_size); llvm::Value* dim_size = this->get_dimension_size(dim_des_val, r_val); - dim_size = builder->CreateSExt(dim_size, llvm_utils->getIntType(kind)); + dim_size = builder->CreateSExtOrTrunc(dim_size, llvm_utils->getIntType(kind)); ret_val = builder->CreateMul(ret_val, dim_size); builder->CreateStore(ret_val, llvm_size); r_val = builder->CreateAdd(r_val, llvm::ConstantInt::get(context, llvm::APInt(32, 1))); @@ -730,6 +736,10 @@ namespace LCompilers { LLVM::CreateLoad(*builder, ptr2firstptr), llvm::MaybeAlign(), num_elements); + builder->CreateStore( + llvm::ConstantInt::get(context, llvm::APInt(32, 0)), + this->get_offset(reshaped, false)); + if( this->is_array(asr_shape_type) ) { builder->CreateStore(LLVM::CreateLoad(*builder, llvm_utils->create_gep(array, 1)), llvm_utils->create_gep(reshaped, 1)); @@ -739,7 +749,8 @@ namespace LCompilers { llvm::Value* dim_des_first = builder->CreateAlloca(dim_des, n_dims); builder->CreateStore(n_dims, this->get_rank(reshaped, true)); builder->CreateStore(dim_des_first, dim_des_val); - llvm::Value* prod = llvm::ConstantInt::get(context, llvm::APInt(32, 1)); + llvm::Value* prod = builder->CreateAlloca(llvm_utils->getIntType(4)); + builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, 1)), prod); dim_des_val = LLVM::CreateLoad(*builder, dim_des_val); llvm::BasicBlock *loophead = llvm::BasicBlock::Create(context, "loop.head"); llvm::BasicBlock *loopbody = llvm::BasicBlock::Create(context, "loop.body"); @@ -757,10 +768,12 @@ namespace LCompilers { llvm::Value* r_val = LLVM::CreateLoad(*builder, r); llvm::Value* dim_val = llvm_utils->create_ptr_gep(dim_des_val, r_val); llvm::Value* s_val = llvm_utils->create_gep(dim_val, 0); + llvm::Value* l_val = llvm_utils->create_gep(dim_val, 1); llvm::Value* dim_size_ptr = llvm_utils->create_gep(dim_val, 2); - builder->CreateStore(prod, s_val); + builder->CreateStore(llvm::ConstantInt::get(context, llvm::APInt(32, 1)), l_val); + builder->CreateStore(LLVM::CreateLoad(*builder, prod), s_val); llvm::Value* dim_size = LLVM::CreateLoad(*builder, llvm_utils->create_ptr_gep(shape_data, r_val)); - prod = builder->CreateMul(prod, dim_size); + builder->CreateStore(builder->CreateMul(LLVM::CreateLoad(*builder, prod), dim_size), prod); builder->CreateStore(dim_size, dim_size_ptr); r_val = builder->CreateAdd(r_val, llvm::ConstantInt::get(context, llvm::APInt(32, 1))); builder->CreateStore(r_val, r); diff --git a/src/libasr/codegen/llvm_utils.cpp b/src/libasr/codegen/llvm_utils.cpp index e19f309b1f..61e19a6286 100644 --- a/src/libasr/codegen/llvm_utils.cpp +++ b/src/libasr/codegen/llvm_utils.cpp @@ -627,6 +627,33 @@ namespace LCompilers { v_type->m_dims, v_type->n_dims))->getPointerTo(); break; } + case ASR::array_physical_typeType::CharacterArraySinglePointer: { + // type = character_type->getPointerTo(); + // is_array_type = true; + // llvm::Type* el_type = get_el_type(v_type->m_type, module); + // type = arr_api->get_array_type(asr_type, el_type, get_pointer); + // break; + if (ASRUtils::is_fixed_size_array(v_type->m_dims, v_type->n_dims)) { + // llvm_type = character_type; -- @character_01.c = internal global i8* null + // llvm_type = character_type->getPointerTo(); -- @character_01.c = internal global i8** null + // llvm_type = llvm::ArrayType::get(character_type, + // ASRUtils::get_fixed_size_of_array(v_type->m_dims, v_type->n_dims))->getPointerTo(); + // -- @character_01 = internal global [2 x i8*]* zeroinitializer + + type = llvm::ArrayType::get(character_type, + ASRUtils::get_fixed_size_of_array(v_type->m_dims, v_type->n_dims)); + break; + } else if (ASRUtils::is_dimension_empty(v_type->m_dims, v_type->n_dims)) { + // Treat it as a DescriptorArray + is_array_type = true; + llvm::Type* el_type = character_type; + type = arr_api->get_array_type(asr_type, el_type); + break; + } else { + LCOMPILERS_ASSERT(false); + break; + } + } default: { LCOMPILERS_ASSERT(false); } @@ -1104,6 +1131,208 @@ namespace LCompilers { return function_type; } + std::vector LLVMUtils::convert_args(ASR::FunctionType_t* x, llvm::Module* module) { + std::vector args; + for (size_t i=0; i < x->n_arg_types; i++) { + llvm::Type *type = nullptr, *type_original = nullptr; + int n_dims = 0, a_kind = 4; + bool is_array_type = false; + type_original = get_arg_type_from_ttype_t(x->m_arg_types[i], + nullptr, x->m_abi, x->m_abi, ASR::storage_typeType::Default, + false, n_dims, a_kind, is_array_type, ASR::intentType::Unspecified, + module, false); + if( is_array_type ) { + type = type_original->getPointerTo(); + } else { + type = type_original; + } + args.push_back(type); + } + return args; + } + + llvm::FunctionType* LLVMUtils::get_function_type(ASR::FunctionType_t* x, llvm::Module* module) { + llvm::Type *return_type; + if (x->m_return_var_type) { + ASR::ttype_t* return_var_type0 = x->m_return_var_type; + ASR::ttypeType return_var_type = return_var_type0->type; + switch (return_var_type) { + case (ASR::ttypeType::Integer) : { + int a_kind = ASR::down_cast(return_var_type0)->m_kind; + return_type = getIntType(a_kind); + break; + } + case (ASR::ttypeType::UnsignedInteger) : { + int a_kind = ASR::down_cast(return_var_type0)->m_kind; + return_type = getIntType(a_kind); + break; + } + case (ASR::ttypeType::Real) : { + int a_kind = ASR::down_cast(return_var_type0)->m_kind; + return_type = getFPType(a_kind); + break; + } + case (ASR::ttypeType::Complex) : { + int a_kind = ASR::down_cast(return_var_type0)->m_kind; + if (a_kind == 4) { + if (x->m_abi == ASR::abiType::BindC) { + if (compiler_options.platform == Platform::Windows) { + // i64 + return_type = llvm::Type::getInt64Ty(context); + } else if (compiler_options.platform == Platform::macOS_ARM) { + // {float, float} + return_type = getComplexType(a_kind); + } else { + // <2 x float> + return_type = FIXED_VECTOR_TYPE::get(llvm::Type::getFloatTy(context), 2); + } + } else { + return_type = getComplexType(a_kind); + } + } else { + LCOMPILERS_ASSERT(a_kind == 8) + if (x->m_abi == ASR::abiType::BindC) { + if (compiler_options.platform == Platform::Windows) { + // pass as subroutine + return_type = getComplexType(a_kind, true); + std::vector args = convert_args(x, module); + args.insert(args.begin(), return_type); + llvm::FunctionType *function_type = llvm::FunctionType::get( + llvm::Type::getVoidTy(context), args, false); + return function_type; + } else { + return_type = getComplexType(a_kind); + } + } else { + return_type = getComplexType(a_kind); + } + } + break; + } + case (ASR::ttypeType::Character) : + return_type = character_type; + break; + case (ASR::ttypeType::Logical) : + return_type = llvm::Type::getInt1Ty(context); + break; + case (ASR::ttypeType::CPtr) : + return_type = llvm::Type::getVoidTy(context)->getPointerTo(); + break; + case (ASR::ttypeType::Const) : { + return_type = get_type_from_ttype_t_util(ASRUtils::get_contained_type(return_var_type0), module); + break; + } + case (ASR::ttypeType::Pointer) : { + return_type = get_type_from_ttype_t_util(ASRUtils::get_contained_type(return_var_type0), module)->getPointerTo(); + break; + } + case (ASR::ttypeType::Allocatable) : { + // TODO: Do getPointerTo as well. + return_type = get_type_from_ttype_t_util(ASRUtils::get_contained_type(return_var_type0), module); + break; + } + case (ASR::ttypeType::Struct) : + throw CodeGenError("Struct return type not implemented yet"); + break; + case (ASR::ttypeType::Tuple) : { + ASR::Tuple_t* asr_tuple = ASR::down_cast(return_var_type0); + std::string type_code = ASRUtils::get_type_code(asr_tuple->m_type, + asr_tuple->n_type); + std::vector llvm_el_types; + for( size_t i = 0; i < asr_tuple->n_type; i++ ) { + bool is_local_array_type = false, is_local_malloc_array_type = false; + bool is_local_list = false; + ASR::dimension_t* local_m_dims = nullptr; + int local_n_dims = 0; + int local_a_kind = -1; + ASR::storage_typeType local_m_storage = ASR::storage_typeType::Default; + llvm_el_types.push_back(get_type_from_ttype_t( + asr_tuple->m_type[i], nullptr, local_m_storage, + is_local_array_type, is_local_malloc_array_type, + is_local_list, local_m_dims, local_n_dims, local_a_kind, module)); + } + return_type = tuple_api->get_tuple_type(type_code, llvm_el_types); + break; + } + case (ASR::ttypeType::List) : { + bool is_array_type = false, is_malloc_array_type = false; + bool is_list = true; + ASR::dimension_t *m_dims = nullptr; + ASR::storage_typeType m_storage = ASR::storage_typeType::Default; + int n_dims = 0, a_kind = -1; + ASR::List_t* asr_list = ASR::down_cast(return_var_type0); + llvm::Type* el_llvm_type = get_type_from_ttype_t(asr_list->m_type, nullptr, m_storage, + is_array_type, is_malloc_array_type, is_list, m_dims, n_dims, a_kind, module); + int32_t type_size = -1; + if( LLVM::is_llvm_struct(asr_list->m_type) || + ASR::is_a(*asr_list->m_type) || + ASR::is_a(*asr_list->m_type) ) { + llvm::DataLayout data_layout(module); + type_size = data_layout.getTypeAllocSize(el_llvm_type); + } else { + type_size = a_kind; + } + std::string el_type_code = ASRUtils::get_type_code(asr_list->m_type); + return_type = list_api->get_list_type(el_llvm_type, el_type_code, type_size); + break; + } + case (ASR::ttypeType::Dict) : { + ASR::Dict_t* asr_dict = ASR::down_cast(return_var_type0); + std::string key_type_code = ASRUtils::get_type_code(asr_dict->m_key_type); + std::string value_type_code = ASRUtils::get_type_code(asr_dict->m_value_type); + + bool is_local_array_type = false, is_local_malloc_array_type = false; + bool is_local_list = false; + ASR::dimension_t* local_m_dims = nullptr; + ASR::storage_typeType local_m_storage = ASR::storage_typeType::Default; + int local_n_dims = 0, local_a_kind = -1; + + llvm::Type* key_llvm_type = get_type_from_ttype_t(asr_dict->m_key_type, + nullptr, local_m_storage, is_local_array_type, is_local_malloc_array_type, + is_local_list, local_m_dims, local_n_dims, local_a_kind, module); + llvm::Type* value_llvm_type = get_type_from_ttype_t(asr_dict->m_value_type, + nullptr, local_m_storage,is_local_array_type, is_local_malloc_array_type, + is_local_list, local_m_dims, local_n_dims, local_a_kind, module); + int32_t key_type_size = get_type_size(asr_dict->m_key_type, key_llvm_type, local_a_kind, module); + int32_t value_type_size = get_type_size(asr_dict->m_value_type, value_llvm_type, local_a_kind, module); + + set_dict_api(asr_dict); + + return_type = dict_api->get_dict_type(key_type_code, value_type_code, key_type_size,value_type_size, key_llvm_type, value_llvm_type); + break; + } + case (ASR::ttypeType::Set) : { + ASR::Set_t* asr_set = ASR::down_cast(return_var_type0); + std::string el_type_code = ASRUtils::get_type_code(asr_set->m_type); + + bool is_local_array_type = false, is_local_malloc_array_type = false; + bool is_local_list = false; + ASR::dimension_t* local_m_dims = nullptr; + ASR::storage_typeType local_m_storage = ASR::storage_typeType::Default; + int local_n_dims = 0, local_a_kind = -1; + + llvm::Type* el_llvm_type = get_type_from_ttype_t(asr_set->m_type, + nullptr, local_m_storage, is_local_array_type, is_local_malloc_array_type, + is_local_list, local_m_dims, local_n_dims, local_a_kind, module); + int32_t el_type_size = get_type_size(asr_set->m_type, el_llvm_type, local_a_kind, module); + + set_set_api(asr_set); + + return_type = set_api->get_set_type(el_type_code, el_type_size, el_llvm_type); + break; + } + default : + throw CodeGenError("Type not implemented " + std::to_string(return_var_type)); + } + } else { + return_type = llvm::Type::getVoidTy(context); + } + std::vector args = convert_args(x, module); + llvm::FunctionType *function_type = llvm::FunctionType::get( + return_type, args, false); + return function_type; + } + llvm::Type* LLVMUtils::get_type_from_ttype_t(ASR::ttype_t* asr_type, ASR::symbol_t *type_declaration, ASR::storage_typeType m_storage, bool& is_array_type, bool& is_malloc_array_type, bool& is_list, @@ -1147,6 +1376,27 @@ namespace LCompilers { v_type->m_dims, v_type->n_dims)); break; } + case ASR::array_physical_typeType::SIMDArray: { + llvm_type = llvm::VectorType::get(get_el_type(v_type->m_type, module), + ASRUtils::get_fixed_size_of_array(v_type->m_dims, v_type->n_dims), false); + break; + } + case ASR::array_physical_typeType::CharacterArraySinglePointer: { + if (ASRUtils::is_fixed_size_array(v_type->m_dims, v_type->n_dims)) { + llvm_type = llvm::ArrayType::get(character_type, + ASRUtils::get_fixed_size_of_array(v_type->m_dims, v_type->n_dims)); + break; + } else if (ASRUtils::is_dimension_empty(v_type->m_dims, v_type->n_dims)) { + // Treat it as a DescriptorArray + is_array_type = true; + llvm::Type* el_type = character_type; + llvm_type = arr_api->get_array_type(asr_type, el_type); + break; + } else { + LCOMPILERS_ASSERT(false); + break; + } + } default: { LCOMPILERS_ASSERT(false); } @@ -1282,9 +1532,14 @@ namespace LCompilers { break; } case (ASR::ttypeType::FunctionType) : { - ASR::Function_t* fn = ASR::down_cast( - ASRUtils::symbol_get_past_external(type_declaration)); - llvm_type = get_function_type(*fn, module)->getPointerTo(); + if( type_declaration ) { + ASR::Function_t* fn = ASR::down_cast( + ASRUtils::symbol_get_past_external(type_declaration)); + llvm_type = get_function_type(*fn, module)->getPointerTo(); + } else { + ASR::FunctionType_t* func_type = ASR::down_cast(asr_type); + llvm_type = get_function_type(func_type, module)->getPointerTo(); + } break; } default : @@ -1680,12 +1935,21 @@ namespace LCompilers { } break ; }; - case ASR::ttypeType::Allocatable: case ASR::ttypeType::Character: + case ASR::ttypeType::FunctionType: case ASR::ttypeType::CPtr: { LLVM::CreateStore(*builder, src, dest); break ; } + case ASR::ttypeType::Allocatable: { + ASR::Allocatable_t* alloc_type = ASR::down_cast(asr_type); + if( ASR::is_a(*alloc_type->m_type) ) { + lfortran_str_copy(dest, src, true, *module, *builder, context); + } else { + LLVM::CreateStore(*builder, src, dest); + } + break; + } case ASR::ttypeType::Tuple: { ASR::Tuple_t* tuple_type = ASR::down_cast(asr_type); tuple_api->tuple_deepcopy(src, dest, tuple_type, module, name2memidx); @@ -1737,7 +2001,7 @@ namespace LCompilers { } default: { throw LCompilersException("LLVMUtils::deepcopy isn't implemented for " + - ASRUtils::type_to_str_python(asr_type)); + ASRUtils::type_to_str(asr_type)); } } } diff --git a/src/libasr/codegen/llvm_utils.h b/src/libasr/codegen/llvm_utils.h index 904cbea903..a4fdedff84 100644 --- a/src/libasr/codegen/llvm_utils.h +++ b/src/libasr/codegen/llvm_utils.h @@ -96,6 +96,25 @@ namespace LCompilers { return builder.CreateCall(fn_printf, args); } + static inline llvm::Value* lfortran_str_copy(llvm::Value* dest, llvm::Value *src, bool is_allocatable, + llvm::Module &module, llvm::IRBuilder<> &builder, llvm::LLVMContext &context) { + std::string runtime_func_name = "_lfortran_strcpy"; + llvm::Function *fn = module.getFunction(runtime_func_name); + if (!fn) { + llvm::FunctionType *function_type = llvm::FunctionType::get( + llvm::Type::getVoidTy(context), { + llvm::Type::getInt8PtrTy(context)->getPointerTo(), + llvm::Type::getInt8PtrTy(context), + llvm::Type::getInt8Ty(context) + }, false); + fn = llvm::Function::Create(function_type, + llvm::Function::ExternalLinkage, runtime_func_name, module); + } + llvm::Value* free_string = llvm::ConstantInt::get( + llvm::Type::getInt8Ty(context), llvm::APInt(8, is_allocatable)); + return builder.CreateCall(fn, {dest, src, free_string}); + } + static inline void print_error(llvm::LLVMContext &context, llvm::Module &module, llvm::IRBuilder<> &builder, const std::vector &args) { @@ -282,6 +301,10 @@ namespace LCompilers { std::vector convert_args(const ASR::Function_t &x, llvm::Module* module); + llvm::FunctionType* get_function_type(ASR::FunctionType_t* x, llvm::Module* module); + + std::vector convert_args(ASR::FunctionType_t* x, llvm::Module* module); + llvm::Type* get_type_from_ttype_t(ASR::ttype_t* asr_type, ASR::symbol_t *type_declaration, ASR::storage_typeType m_storage, bool& is_array_type, bool& is_malloc_array_type, bool& is_list, diff --git a/src/libasr/compiler_tester/tester.py b/src/libasr/compiler_tester/tester.py index e6c492602c..bd6d7e62e5 100644 --- a/src/libasr/compiler_tester/tester.py +++ b/src/libasr/compiler_tester/tester.py @@ -255,9 +255,27 @@ def do_update_reference(jo, jr, do): f_r = os.path.join(os.path.dirname(jr), do[f]) shutil.copyfile(f_o, f_r) +def do_verify_reference_hash(jr, dr, s): + for f in ["outfile", "stdout", "stderr"]: + if dr[f]: + f_r = os.path.join(os.path.dirname(jr), dr[f]) + temp = unl_loop_del(open(f_r, "rb").read()) + f_r_hash = hashlib.sha224(temp).hexdigest() + if (f_r_hash != dr[f + "_hash"]): + # This string builds up the error message. + # Print test name in red in the beginning. + # More information is added afterwards. + full_err_str = f"\n{(color(fg.red)+color(style.bold))}{s}{color(fg.reset)+color(style.reset)}\n" + full_err_str += "The generated hash for the reference file and its committed hash are different\n" + full_err_str += "Reference File: " + f_r + "\n" + full_err_str += "Reference Json File: " + jr + "\n" + full_err_str += "Reference File Hash Expected: " + f_r_hash + "\n" + full_err_str += "Reference File Hash Found: " + dr[f + "_hash"] + "\n" + raise RunException("Verifying reference hash failed." + + full_err_str) def run_test(testname, basename, cmd, infile, update_reference=False, - extra_args=None): + verify_hash=False, extra_args=None): """ Runs the test `cmd` and compare against reference results. @@ -274,6 +292,9 @@ def run_test(testname, basename, cmd, infile, update_reference=False, it exists and hash it. update_reference ... if True, it will copy the output into the reference directory as reference results, overwriting old ones + verify_hash ...... if True, it will check the hash in the committed + json file and the hash for the committed references + directory as reference results, overwriting old ones extra_args ......... Extra arguments to append to the command that are not part of the hash @@ -303,6 +324,11 @@ def run_test(testname, basename, cmd, infile, update_reference=False, f"The reference json file '{jr}' for {testname} does not exist") dr = json.load(open(jr)) + + if verify_hash: + do_verify_reference_hash(jr, dr, s) + return + if do != dr: # This string builds up the error message. Print test name in red in the beginning. # More information is added afterwards. @@ -336,10 +362,12 @@ def run_test(testname, basename, cmd, infile, update_reference=False, log.debug(s + " " + check()) -def tester_main(compiler, single_test): +def tester_main(compiler, single_test, is_lcompilers_executable_installed=False): parser = argparse.ArgumentParser(description=f"{compiler} Test Suite") parser.add_argument("-u", "--update", action="store_true", help="update all reference results") + parser.add_argument("-vh", "--verify-hash", action="store_true", + help="Verify all reference hashes") parser.add_argument("-l", "--list", action="store_true", help="list all tests") parser.add_argument("-t", "--test", @@ -368,6 +396,7 @@ def tester_main(compiler, single_test): help="Turn off colored tests output") args = parser.parse_args() update_reference = args.update + verify_hash = args.verify_hash list_tests = args.list specific_tests = list( itertools.chain.from_iterable( @@ -387,8 +416,9 @@ def tester_main(compiler, single_test): no_color = args.no_color # So that the tests find the `lcompiler` executable - os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \ - + os.pathsep + os.environ["PATH"] + if not is_lcompilers_executable_installed: + os.environ["PATH"] = os.path.join(SRC_DIR, "bin") \ + + os.pathsep + os.environ["PATH"] test_data = toml.load(open(os.path.join(ROOT_DIR, "tests", "tests.toml"))) filtered_tests = test_data["test"] if specific_tests: @@ -409,6 +439,7 @@ def tester_main(compiler, single_test): if 'extrafiles' in test: single_test(test, update_reference=update_reference, + verify_hash=verify_hash, specific_backends=specific_backends, excluded_backends=excluded_backends, verbose=verbose, @@ -422,6 +453,7 @@ def tester_main(compiler, single_test): for test in filtered_tests: single_test(test, update_reference=update_reference, + verify_hash=verify_hash, specific_backends=specific_backends, excluded_backends=excluded_backends, verbose=verbose, @@ -434,6 +466,7 @@ def tester_main(compiler, single_test): single_tester_partial_args = partial( single_test, update_reference=update_reference, + verify_hash=verify_hash, specific_backends=specific_backends, excluded_backends=excluded_backends, verbose=verbose, @@ -451,6 +484,13 @@ def tester_main(compiler, single_test): if update_reference: log.info("Test references updated.") + elif verify_hash: + if no_color: + log.info("Test references hash verfied.") + else: + log.info( + f"{(color(fg.green) + color(style.bold))}Test references hash verfied." + f"{color(fg.reset) + color(style.reset)}") else: if no_color: log.info("TESTS PASSED") diff --git a/src/libasr/config.h.in b/src/libasr/config.h.in index 292b593bb4..f2e453edc4 100644 --- a/src/libasr/config.h.in +++ b/src/libasr/config.h.in @@ -6,6 +6,9 @@ /* LFortran version */ #cmakedefine LFORTRAN_VERSION "@LFORTRAN_VERSION@" +#define LFORTRAN_MAJOR @CMAKE_PROJECT_VERSION_MAJOR@ +#define LFORTRAN_MINOR @CMAKE_PROJECT_VERSION_MINOR@ +#define LFORTRAN_PATCHLEVEL @CMAKE_PROJECT_VERSION_PATCH@ /* Define if LLVM is enabled */ #cmakedefine HAVE_LFORTRAN_LLVM diff --git a/src/libasr/gen_pass.py b/src/libasr/gen_pass.py index e7f7f03132..abccd1ccbd 100644 --- a/src/libasr/gen_pass.py +++ b/src/libasr/gen_pass.py @@ -1,5 +1,6 @@ passes = [ "replace_arr_slice", + "replace_function_call_in_declaration", "replace_array_op", "replace_class_constructor", "dead_code_removal", @@ -33,7 +34,8 @@ "update_array_dim_intrinsic_calls", "replace_where", "unique_symbols", - "insert_deallocate" + "insert_deallocate", + "promote_allocatable_to_nonallocatable" ] diff --git a/src/libasr/intrinsic_func_registry_util_gen.py b/src/libasr/intrinsic_func_registry_util_gen.py new file mode 100644 index 0000000000..32a9f494e3 --- /dev/null +++ b/src/libasr/intrinsic_func_registry_util_gen.py @@ -0,0 +1,749 @@ +import sys +import os + +intrinsic_funcs_args = { + "Kind": [ + { + "args": [("int",), ("real",), ("bool",), ("char",), (("complex",))], + "return": "int32" + }, + ], + "FMA": [ + { + "args": [("real", "real", "real")], + "ret_type_arg_idx": 0 + } + ], + "FlipSign": [ + { + "args": [("int", "real")], + "ret_type_arg_idx": 1 + } + ], + "FloorDiv": [ + { + "args": [("int", "int"), ("uint", "uint"), ("real", "real"), ("bool", "bool")], + "ret_type_arg_idx": 0 + }, + ], + "Mod": [ + { + "args": [("int", "int"), ("real", "real")], + "ret_type_arg_idx": 0 + }, + ], + "Trailz": [ + { + "args": [("int",)], + "ret_type_arg_idx": 0 + }, + ], + "BesselJ0": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + }, + ], + "BesselJ1": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + }, + ], + "BesselY0": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + }, + ], + "Mvbits": [ + { + "args": [("int", "int", "int", "int", "int")], + "ret_type_arg_idx": 3 + }, + ], + "Leadz": [ + { + "args": [("int",)], + "ret_type_arg_idx": 0 + }, + ], + "ToLowerCase": [ + { + "args": [("char",)], + "ret_type_arg_idx": 0 + }, + ], + "Hypot": [ + { + "args": [("real", "real")], + "ret_type_arg_idx": 0 + } + ], + "SelectedIntKind": [ + { + "args": [("int",)], + "return": "int32" + } + ], + "SelectedRealKind": [ + { + "args": [("int", "int", "int")], + "return": "int32" + } + ], + "SelectedCharKind": [ + { + "args": [("char",)], + "return": "int32" + } + ], + "Digits": [ + { + "args": [("int",), ("real",)], + "return": "int32" + }, + ], + "Repeat": [ + { + "args": [("char", "int")], + "ret_type_arg_idx": 0 + } + ], + "StringContainsSet": [ + { + "args": [("char", "char", "bool", "int")], + "ret_type_arg_idx": 3 + } + ], + "StringFindSet": [ + { + "args": [("char", "char", "bool", "int")], + "ret_type_arg_idx": 3 + } + ], + "SubstrIndex": [ + { + "args": [("char", "char", "bool", "int")], + "ret_type_arg_idx": 3 + } + ], + "MinExponent": [ + { + "args": [("real",)], + "return": "int32" + } + ], + "MaxExponent": [ + { + "args": [("real",)], + "return": "int32" + } + ], + "Partition": [ + { + "args": [("char", "char")], + "ret_type_arg_idx": 0 + } + ], + "ListReverse": [ + { + "args": [("list",)], + "return": "nullptr" + } + ], + "ListReserve": [ + { + "args": [("list", "int")], + "return": "nullptr" + } + ], + "Sign": [ + { + "args": [("int", "int"), ("real", "real")], + "ret_type_arg_idx": 0 + }, + ], + "Radix": [ + { + "args": [("int",), ("real",)], + "return": "int32" + }, + ], + "Adjustl": [ + { + "args": [("char",)], + "return": "character(-1)" + } + ], + "Adjustr": [ + { + "args": [("char",)], + "return": "character(-1)" + } + ], + "Aint": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0, + "kind_arg": True + } + ], + "Nint": [ + { + "args": [("real",)], + "return": "int32", + "kind_arg": True + } + ], + "Anint": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0, + "kind_arg": True + } + ], + "Floor": [ + { + "args": [("real",)], + "return": "int32", + "kind_arg": True + } + ], + "Ceiling": [ + { + "args": [("real",)], + "return": "int32", + "kind_arg": True + } + ], + "Sqrt": [ + { + "args": [("real",), ("complex",)], + "ret_type_arg_idx": 0 + }, + ], + "Sngl": [ + { + "args": [("real",)], + "return": "real32" + } + ], + "SignFromValue": [ + { + "args": [("int", "int"), ("real", "real")], + "ret_type_arg_idx": 0 + }, + ], + "Ifix": [ + { + "args": [("real",)], + "return": "int32" + } + ], + "Idint": [ + { + "args": [("real",)], + "return": "int32" + } + ], + "Ishft": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Bgt": [ + { + "args": [("int", "int")], + "return": "logical" + }, + ], + "Blt": [ + { + "args": [("int", "int")], + "return": "logical" + }, + ], + "Bge": [ + { + "args": [("int", "int")], + "return": "logical" + }, + ], + "Ble": [ + { + "args": [("int", "int")], + "return": "logical" + }, + ], + "Lgt": [ + { + "args": [("char", "char")], + "return": "logical" + }, + ], + "Llt": [ + { + "args": [("char", "char")], + "return": "logical" + }, + ], + "Lge": [ + { + "args": [("char", "char")], + "return": "logical" + }, + ], + "Lle": [ + { + "args": [("char", "char")], + "return": "logical" + }, + ], + "Not": [ + { + "args": [("int",)], + "ret_type_arg_idx": 0 + }, + ], + "Iand": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Ior": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Ieor": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Ibclr": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Ibset": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Btest": [ + { + "args": [("int", "int")], + "return": "logical" + }, + ], + "Ibits": [ + { + "args": [("int", "int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Shiftr": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + } + ], + "Rshift": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + } + ], + "Shiftl": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + } + ], + "Aimag": [ + { + "args": [("complex",)], + "return": "real32", + "kind_arg": True + }, + ], + "Rank": [ + { + "args": [("any",)], + "return": "int32" + } + ], + "Range": [ + { + "args": [("int",), ("real",), ("complex",)], + "return": "int32" + }, + ], + "Epsilon": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + } + ], + "Precision": [ + { + "args": [("real",), ("complex",)], + "return": "int32" + } + ], + "Tiny": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + } + ], + "Conjg": [ + { + "args": [("complex",)], + "ret_type_arg_idx": 0 + }, + ], + "Scale": [ + { + "args": [("real", "int")], + "ret_type_arg_idx": 0 + } + ], + "Huge": [ + { + "args": [("int",), ("real",)], + "ret_type_arg_idx": 0 + } + ], + "Dprod": [ + { + "args": [("real", "real")], + "return": "real64" + } + ], + "Dim": [ + { + "args": [("int", "int"), ("real", "real")], + "ret_type_arg_idx": 0 + }, + ], + "Maskl": [ + { + "args": [("int",)], + "return": "int32", + "kind_arg": True + } + ], + "Maskr": [ + { + "args": [("int",)], + "return": "int32", + "kind_arg": True + } + ], + "Ishftc": [ + { + "args": [("int", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Ichar": [ + { + "args": [("char",)], + "return": "int32", + "kind_arg": True + }, + ], + "Char": [ + { + "args": [("int",)], + "return": "character(1)", + "kind_arg": True + } + ], + "Exponent": [ + { + "args": [("real",)], + "return": "int32", + }, + ], + "Fraction": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + }, + ], + "SetExponent": [ + { + "args": [("real", "int")], + "ret_type_arg_idx": 0 + }, + ], + "Rrspacing": [ + { + "args": [("real",)], + "ret_type_arg_idx": 0 + }, + ], + "Dshiftl": [ + { + "args": [("int", "int", "int",)], + "ret_type_arg_idx": 0 + }, + ], + "Popcnt": [ + { + "args": [("int",)], + "return": "int32", + }, + ], + "Poppar": [ + { + "args": [("int",)], + "return": "int32", + }, + ], + +} + +skip_create_func = ["Partition"] +compile_time_only_fn = [ + "Epsilon", + "Radix", + "Range", + "Precision", + "Rank", + "Tiny", + "Huge", +] + +type_to_asr_type_check = { + "any": "!ASR::is_a", + "int": "is_integer", + "uint": "is_unsigned_integer", + "real": "is_real", + "bool": "is_logical", + "char": "is_character", + "complex": "is_complex", + "dict": "ASR::is_a", + "list": "ASR::is_a", + "tuple": "ASR::is_a" +} + +intrinsic_funcs_ret_type = { + "Kind": ["int"], + "Partition": ["tuple"], + "ListReverse": ["null"], + "ListReserve": [ "null"], + "Radix": ["int"], +} + +src = "" +indent = " " + +def compute_arg_types(indent, no_of_args, args_arr): + global src + for i in range(no_of_args): + src += indent + f"ASR::ttype_t *arg_type{i} = ASRUtils::type_get_past_const(ASRUtils::expr_type({args_arr}[{i}]));\n" + +def compute_arg_condition(no_of_args, args_lists): + condition = [] + cond_in_msg = [] + for arg_list in args_lists: + subcond = [] + subcond_in_msg = [] + for i in range(no_of_args): + arg = arg_list[i] + subcond.append(f"{type_to_asr_type_check[arg]}(*arg_type{i})") + subcond_in_msg.append(arg) + condition.append(" && ".join(subcond)) + cond_in_msg.append(", ".join(subcond_in_msg)) + return (f"({') || ('.join(condition)})", f"({') or ('.join(cond_in_msg)})") + +def add_verify_arg_type_src(func_name): + global src + arg_infos = intrinsic_funcs_args[func_name] + no_of_args_msg = "" + for i, arg_info in enumerate(arg_infos): + args_lists = arg_info["args"] + no_of_args = len(args_lists[0]) + no_of_args_msg += " or " if i > 0 else "" + no_of_args_msg += f"{no_of_args}" + else_if = "else if" if i > 0 else "if" + src += 2 * indent + f"{else_if} (x.n_args == {no_of_args}) " + " {\n" + src += 3 * indent + f'ASRUtils::require_impl(x.m_overload_id == {i}, "Overload Id for {func_name} expected to be {i}, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics);\n' + compute_arg_types(3 * indent, no_of_args, "x.m_args") + condition, cond_in_msg = compute_arg_condition(no_of_args, args_lists) + src += 3 * indent + f'ASRUtils::require_impl({condition}, "Unexpected args, {func_name} expects {cond_in_msg} as arguments", x.base.base.loc, diagnostics);\n' + src += 2 * indent + "}\n" + src += 2 * indent + "else {\n" + src += 3 * indent + f'ASRUtils::require_impl(false, "Unexpected number of args, {func_name} takes {no_of_args_msg} arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics);\n' + src += 2 * indent + "}\n" + +def add_verify_return_type_src(func_name): + if func_name not in intrinsic_funcs_ret_type.keys(): + return "" + global src + ret_type_cond = "" + ret_type_cond_in_msg = "" + for i, ret_type in enumerate(intrinsic_funcs_ret_type[func_name]): + if ret_type == "null": + ret_type_cond += f"x.m_type == nullptr" + else: + ret_type_cond += f"{type_to_asr_type_check[ret_type]}(*x.m_type)" + ret_type_cond_in_msg += f"{ret_type}" + if i < len(intrinsic_funcs_ret_type[func_name]) - 1: + ret_type_cond += " || " + ret_type_cond_in_msg += " or " + src += 2 * indent + f'ASRUtils::require_impl({ret_type_cond}, "Unexpected return type, {func_name} expects `{ret_type_cond_in_msg}` as return type", x.base.base.loc, diagnostics);\n' + +def add_create_func_arg_type_src(func_name): + global src + arg_infos = intrinsic_funcs_args[func_name] + no_of_args_msg = "" + for i, arg_info in enumerate(arg_infos): + args_lists = arg_info["args"] + kind_arg = arg_info.get("kind_arg", False) + no_of_args = len(args_lists[0]) + no_of_args_msg += " or " if i > 0 else "" + no_of_args_msg += f"{no_of_args + int(kind_arg)}" + else_if = "else if" if i > 0 else "if" + src += 2 * indent + f"{else_if} (args.size() == {no_of_args + int(kind_arg)}) " + " {\n" + compute_arg_types(3 * indent, no_of_args, "args") + condition, cond_in_msg = compute_arg_condition(no_of_args, args_lists) + src += 3 * indent + f'if(!({condition}))' + ' {\n' + src += 4 * indent + f'append_error(diag, "Unexpected args, {func_name} expects {cond_in_msg} as arguments", loc);\n' + src += 4 * indent + f'return nullptr;\n' + src += 3 * indent + '}\n' + src += 2 * indent + "}\n" + src += 2 * indent + "else {\n" + src += 3 * indent + f'append_error(diag, "Unexpected number of args, {func_name} takes {no_of_args_msg} arguments, found " + std::to_string(args.size()), loc);\n' + src += 3 * indent + f'return nullptr;\n' + src += 2 * indent + "}\n" + + +def add_create_func_return_src(func_name): + global src, indent + arg_infos = intrinsic_funcs_args[func_name] + args_lists = arg_infos[0]["args"] + no_of_args = len(args_lists[0]) + ret_type_val = arg_infos[0].get("return", None) + ret_type_arg_idx = arg_infos[0].get("ret_type_arg_idx", None) + if ret_type_val: + ret_type = ret_type_val + else: + src += indent * 2 + "ASRUtils::ExprStmtDuplicator expr_duplicator(al);\n" + src += indent * 2 + "expr_duplicator.allow_procedure_calls = true;\n" + src += indent * 2 + f"ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[{ret_type_arg_idx}]));\n" + ret_type = "type_" + kind_arg = arg_infos[0].get("kind_arg", False) + src += indent * 2 + f"ASR::ttype_t *return_type = {ret_type};\n" + if kind_arg: + src += indent * 2 + "if ( args[1] != nullptr ) {\n" + src += indent * 3 + "int kind = -1;\n" + src += indent * 3 + "if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) {\n" + src += indent * 4 + f'append_error(diag, "`kind` argument of the `{func_name}` function must be a scalar Integer constant", args[1]->base.loc);\n' + src += indent * 4 + "return nullptr;\n" + src += indent * 3 + "}\n" + src += indent * 3 + "set_kind_to_ttype_t(return_type, kind);\n" + src += indent * 2 + "}\n" + src += indent * 2 + "ASR::expr_t *m_value = nullptr;\n" + src += indent * 2 + f"Vec m_args; m_args.reserve(al, {no_of_args});\n" + for _i in range(no_of_args): + src += indent * 2 + f"m_args.push_back(al, args[{_i}]);\n" + if func_name in compile_time_only_fn: + src += indent * 2 + f"return_type = ASRUtils::extract_type(return_type);\n" + src += indent * 2 + f"m_value = eval_{func_name}(al, loc, return_type, args, diag);\n" + src += indent * 2 + "return ASR::make_TypeInquiry_t(al, loc, "\ + f"static_cast(IntrinsicElementalFunctions::{func_name}), "\ + "ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value);\n" + + else: + src += indent * 2 + "if (all_args_evaluated(m_args)) {\n" + src += indent * 3 + f"Vec args_values; args_values.reserve(al, {no_of_args});\n" + for _i in range(no_of_args): + src += indent * 3 + f"args_values.push_back(al, expr_value(m_args[{_i}]));\n" + src += indent * 3 + f"m_value = eval_{func_name}(al, loc, return_type, args_values, diag);\n" + src += indent * 2 + "}\n" + if "null" in intrinsic_funcs_ret_type.get(func_name, []): + src += indent * 2 + f"return ASR::make_Expr_t(al, loc, ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::{func_name}), m_args.p, m_args.n, 0, return_type, m_value)));\n" + else: + src += indent * 2 + f"return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::{func_name}), m_args.p, m_args.n, 0, return_type, m_value);\n" + +def gen_verify_args(func_name): + global src + src += indent + R"static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) {" + "\n" + add_verify_arg_type_src(func_name) + if func_name in compile_time_only_fn: + src += indent * 2 + 'ASRUtils::require_impl(x.m_value, '\ + f'"Missing compile time value, `{func_name}` intrinsic output must '\ + 'be computed during compile time", x.base.base.loc, diagnostics);\n' + add_verify_return_type_src(func_name) + src += indent + "}\n\n" + +def gen_create_function(func_name): + global src + src += indent + Rf"static inline ASR::asr_t* create_{func_name}(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) " + "{\n" + add_create_func_arg_type_src(func_name) + add_create_func_return_src(func_name) + src += indent + "}\n" + + +def get_registry_funcs_src(): + global src + for func_name in intrinsic_funcs_args.keys(): + src += f"namespace {func_name}" + " {\n\n" + gen_verify_args(func_name) + + if func_name not in skip_create_func: + gen_create_function(func_name) + src += "}\n\n" + return src + + +HEAD = """#ifndef LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H +#define LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H + +#include + +namespace LCompilers { + +namespace ASRUtils { + +""" + +FOOT = """ +} // namespace ASRUtil + +} // namespace LCompilers + +#endif // LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H +""" +def main(argv): + if len(argv) == 2: + out_file = argv[1] + elif len(argv) == 1: + print("Assuming default values of intrinsic_function_registry_util.h") + here = os.path.dirname(__file__) + pass_dir = os.path.join(here, "pass") + out_file = os.path.join(pass_dir, "intrinsic_function_registry_util.h") + else: + print("invalid arguments") + return 2 + fp = open(out_file, "w", encoding="utf-8") + try: + fp.write(HEAD) + fp.write(get_registry_funcs_src()) + fp.write(FOOT) + finally: + fp.close() + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/src/libasr/modfile.cpp b/src/libasr/modfile.cpp index d2c7501149..25864da1ca 100644 --- a/src/libasr/modfile.cpp +++ b/src/libasr/modfile.cpp @@ -7,7 +7,6 @@ #include #include - namespace LCompilers { const std::string lfortran_modfile_type_string = "LCompilers Modfile"; @@ -92,7 +91,6 @@ ASR::TranslationUnit_t* load_modfile(Allocator &al, const std::string &s, std::string asr_binary; load_serialised_asr(s, asr_binary); ASR::asr_t *asr = deserialize_asr(al, asr_binary, load_symtab_id, symtab); - ASR::TranslationUnit_t *tu = ASR::down_cast2(asr); return tu; } diff --git a/src/libasr/pass/array_op.cpp b/src/libasr/pass/array_op.cpp index eeca4dbd16..6a733211c1 100644 --- a/src/libasr/pass/array_op.cpp +++ b/src/libasr/pass/array_op.cpp @@ -132,8 +132,13 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { head.m_end = result_ubound[j]; head.m_increment = result_inc[j]; } else { - head.m_start = PassUtils::get_bound(result_var, i + 1, "lbound", al); - head.m_end = PassUtils::get_bound(result_var, i + 1, "ubound", al); + ASR::expr_t* var = result_var; + if (ASR::is_a(*result_var)) { + ASR::ComplexConstructor_t* cc = ASR::down_cast(result_var); + var = cc->m_re; + } + head.m_start = PassUtils::get_bound(var, i + 1, "lbound", al); + head.m_end = PassUtils::get_bound(var, i + 1, "ubound", al); head.m_increment = nullptr; } head.loc = head.m_v->base.loc; @@ -174,7 +179,12 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, head, doloop_body.p, doloop_body.size(), nullptr, 0)); } if( var_rank > 0 ) { - ASR::expr_t* idx_lb = PassUtils::get_bound(op_expr1, 1, "lbound", al); + ASR::expr_t* expr = op_expr1; + if (ASR::is_a(*op_expr1)) { + ASR::ComplexConstructor_t* cc = ASR::down_cast(op_expr1); + expr = cc->m_re; + } + ASR::expr_t* idx_lb = PassUtils::get_bound(expr, 1, "lbound", al); ASR::stmt_t* set_to_one = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, idx_vars_value1[0], idx_lb, nullptr)); pass_result.push_back(al, set_to_one); @@ -268,7 +278,15 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { [=, &idx_vars_value, &idx_vars, &doloop_body]() { ASR::expr_t* ref = nullptr; if( var_rank > 0 ) { - ref = PassUtils::create_array_ref(*current_expr, idx_vars_value, al, current_scope); + if (ASR::is_a(**current_expr)) { + ASR::ComplexConstructor_t* cc = ASR::down_cast(*current_expr); + ASR::expr_t* re = PassUtils::create_array_ref(cc->m_re, idx_vars_value, al, current_scope); + ASR::expr_t* im = PassUtils::create_array_ref(cc->m_im, idx_vars_value, al, current_scope); + ref = ASRUtils::EXPR(ASR::make_ComplexConstructor_t(al, loc, re, im, cc->m_type, cc->m_value)); + *current_expr = ref; + } else { + ref = PassUtils::create_array_ref(*current_expr, idx_vars_value, al, current_scope); + } } else { ref = *current_expr; } @@ -282,7 +300,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { use_custom_loop_params = false; } - #define allocate_result_var(op_arg, op_dims_arg, op_n_dims_arg, result_var_created) if( ASR::is_a(*ASRUtils::expr_type(result_var)) || \ + #define allocate_result_var(op_arg, op_dims_arg, op_n_dims_arg, result_var_created, reset_bounds) if( ASR::is_a(*ASRUtils::expr_type(result_var)) || \ ASR::is_a(*ASRUtils::expr_type(result_var)) ) { \ bool is_dimension_empty = false; \ for( int i = 0; i < op_n_dims_arg; i++ ) { \ @@ -291,6 +309,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { break; \ } \ } \ + ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)); \ Vec alloc_args; \ alloc_args.reserve(al, 1); \ if( !is_dimension_empty ) { \ @@ -310,9 +329,18 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { for( int i = 0; i < op_n_dims_arg; i++ ) { \ ASR::dimension_t alloc_dim; \ alloc_dim.loc = loc; \ - alloc_dim.m_start = PassUtils::get_bound(op_arg, i + 1, "lbound", al); \ - alloc_dim.m_length = ASRUtils::compute_length_from_start_end(al, alloc_dim.m_start, \ - PassUtils::get_bound(op_arg, i + 1, "ubound", al)); \ + if( reset_bounds && result_var_created ) { \ + alloc_dim.m_start = make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, 1, 4, loc); \ + } else { \ + alloc_dim.m_start = PassUtils::get_bound(op_arg, i + 1, "lbound", al); \ + alloc_dim.m_start = CastingUtil::perform_casting(alloc_dim.m_start, \ + int32_type, al, loc); \ + } \ + ASR::expr_t* lbound = PassUtils::get_bound(op_arg, i + 1, "lbound", al); \ + lbound = CastingUtil::perform_casting(lbound, int32_type, al, loc); \ + ASR::expr_t* ubound = PassUtils::get_bound(op_arg, i + 1, "ubound", al); \ + ubound = CastingUtil::perform_casting(ubound, int32_type, al, loc); \ + alloc_dim.m_length = ASRUtils::compute_length_from_start_end(al, lbound, ubound); \ alloc_dims.push_back(al, alloc_dim); \ } \ ASR::alloc_arg_t alloc_arg; \ @@ -360,7 +388,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var_type, al, current_scope); result_counter += 1; if( allocate ) { - allocate_result_var(arr_expr, arr_expr_dims, arr_expr_n_dims, true); + allocate_result_var(arr_expr, arr_expr_dims, arr_expr_n_dims, true, false); } } @@ -667,8 +695,9 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { x_dims.reserve(al, x->n_args); const Location& loc = x->base.base.loc; ASRUtils::ASRBuilder builder(al, loc); + ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)); ASR::expr_t* i32_one = ASRUtils::EXPR(ASR::make_IntegerConstant_t( - al, loc, 1, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))); + al, loc, 1, int32_type)); Vec empty_dims; empty_dims.reserve(al, x->n_args); for( size_t i = 0; i < x->n_args; i++ ) { @@ -705,9 +734,16 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { length_value = make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, ((const_end - const_start)/const_step) + 1, 4, loc); } + + ASR::expr_t* m_right = x->m_args[i].m_right; + ASR::expr_t* m_left = x->m_args[i].m_left; + ASR::expr_t* m_step = x->m_args[i].m_step; + m_right = CastingUtil::perform_casting(m_right, int32_type, al, loc); + m_left = CastingUtil::perform_casting(m_left, int32_type, al, loc); + m_step = CastingUtil::perform_casting(m_step, int32_type, al, loc); x_dim.m_length = builder.ElementalAdd(builder.ElementalDiv( - builder.ElementalSub(x->m_args[i].m_right, x->m_args[i].m_left, loc), - x->m_args[i].m_step, loc), i32_one, loc, length_value); + builder.ElementalSub(m_right, m_left, loc), + m_step, loc), i32_one, loc, length_value); x_dims.push_back(al, x_dim); } } @@ -864,7 +900,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var_type, al, current_scope); result_counter += 1; if( allocate ) { - allocate_result_var(left, left_dims, rank_left, true); + allocate_result_var(left, left_dims, rank_left, true, true); } new_result_var_created = true; } @@ -930,7 +966,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var_type, al, current_scope); result_counter += 1; if( allocate ) { - allocate_result_var(arr_expr, arr_expr_dims, arr_expr_n_dims, true); + allocate_result_var(arr_expr, arr_expr_dims, arr_expr_n_dims, true, true); } new_result_var_created = true; } @@ -981,11 +1017,31 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { void replace_Cast(ASR::Cast_t* x) { + const Location& loc = x->base.base.loc; + ASR::Cast_t* x_ = x; + if( ASR::is_a(*x->m_arg) ) { + *current_expr = x->m_arg; + ASR::ArrayReshape_t* array_reshape_t = ASR::down_cast(x->m_arg); + ASR::array_physical_typeType array_reshape_ptype = ASRUtils::extract_physical_type(array_reshape_t->m_type); + Vec m_dims_vec; + ASR::dimension_t* m_dims; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(ASRUtils::expr_type(array_reshape_t->m_array), m_dims); + m_dims_vec.from_pointer_n(m_dims, n_dims); + array_reshape_t->m_array = ASRUtils::EXPR(ASR::make_Cast_t(al, x->base.base.loc, + array_reshape_t->m_array, x->m_kind, ASRUtils::duplicate_type(al, x->m_type, &m_dims_vec, + array_reshape_ptype, true), nullptr)); + n_dims = ASRUtils::extract_dimensions_from_ttype(array_reshape_t->m_type, m_dims); + m_dims_vec.from_pointer_n(m_dims, n_dims); + array_reshape_t->m_type = ASRUtils::duplicate_type(al, x->m_type, &m_dims_vec, array_reshape_ptype, true); + x_ = ASR::down_cast(array_reshape_t->m_array); + current_expr = &array_reshape_t->m_array; + result_var = nullptr; + } ASR::expr_t* result_var_copy = result_var; result_var = nullptr; - BaseExprReplacer::replace_Cast(x); + BaseExprReplacer::replace_Cast(x_); result_var = result_var_copy; - ASR::expr_t* tmp_val = x->m_arg; + ASR::expr_t* tmp_val = x_->m_arg; bool is_arg_array = PassUtils::is_array(tmp_val); bool is_result_var_array = result_var && PassUtils::is_array(result_var); @@ -994,12 +1050,40 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { return ; } - const Location& loc = x->base.base.loc; if( result_var == nullptr ) { - PassUtils::fix_dimension(x, tmp_val); + PassUtils::fix_dimension(x_, tmp_val); result_var = PassUtils::create_var(result_counter, std::string("_implicit_cast_res"), loc, *current_expr, al, current_scope); + ASR::dimension_t* allocate_dims = nullptr; + int n_dims = ASRUtils::extract_dimensions_from_ttype(x_->m_type, allocate_dims); + allocate_result_var(x_->m_arg, allocate_dims, n_dims, true, true); result_counter += 1; + } else { + ASR::ttype_t* result_var_type = ASRUtils::expr_type(result_var); + if( realloc_lhs && is_arg_array && ASRUtils::is_allocatable(result_var_type)) { + Vec result_var_m_dims; + size_t result_var_n_dims = ASRUtils::extract_n_dims_from_ttype(result_var_type); + result_var_m_dims.reserve(al, result_var_n_dims); + ASR::alloc_arg_t result_alloc_arg; + result_alloc_arg.loc = loc; + result_alloc_arg.m_a = result_var; + for( size_t i = 0; i < result_var_n_dims; i++ ) { + ASR::dimension_t result_var_dim; + result_var_dim.loc = loc; + result_var_dim.m_start = make_ConstantWithKind( + make_IntegerConstant_t, make_Integer_t, 1, 4, loc); + result_var_dim.m_length = ASRUtils::get_size(tmp_val, i + 1, al); + result_var_m_dims.push_back(al, result_var_dim); + } + result_alloc_arg.m_dims = result_var_m_dims.p; + result_alloc_arg.n_dims = result_var_n_dims; + result_alloc_arg.m_len_expr = nullptr; + result_alloc_arg.m_type = nullptr; + Vec alloc_result_args; alloc_result_args.reserve(al, 1); + alloc_result_args.push_back(al, result_alloc_arg); + pass_result.push_back(al, ASRUtils::STMT(ASR::make_ReAlloc_t( + al, loc, alloc_result_args.p, 1))); + } } int n_dims = PassUtils::get_rank(result_var); @@ -1015,7 +1099,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { } ASR::expr_t* res = PassUtils::create_array_ref(result_var, idx_vars, al, current_scope); ASR::ttype_t* x_m_type = ASRUtils::duplicate_type_without_dims( - al, x->m_type, x->m_type->base.loc); + al, x_->m_type, x_->m_type->base.loc); ASR::expr_t* impl_cast_el_wise = ASRUtils::EXPR(ASR::make_Cast_t( al, loc, ref, x->m_kind, x_m_type, nullptr)); ASR::stmt_t* assign = ASRUtils::STMT(ASR::make_Assignment_t(al, loc, res, impl_cast_el_wise, nullptr)); @@ -1024,8 +1108,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { *current_expr = result_var; if( op_expr == &(x->base) ) { op_dims = nullptr; - op_n_dims = ASRUtils::extract_dimensions_from_ttype( - ASRUtils::expr_type(*current_expr), op_dims); + op_n_dims = ASRUtils::extract_dimensions_from_ttype(x->m_type, op_dims); } result_var = nullptr; use_custom_loop_params = false; @@ -1093,7 +1176,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { loc, result_var_type, al, current_scope); result_counter += 1; if( allocate ) { - allocate_result_var(operand, operand_dims, rank_operand, true); + allocate_result_var(operand, operand_dims, rank_operand, true, true); } result_var_created = true; } @@ -1270,14 +1353,28 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var = result_var_copy; bool result_var_created = false; if( result_var == nullptr ) { - result_var = PassUtils::create_var(result_counter, res_prefix, - loc, *current_expr, al, current_scope); + if (x->m_type && !ASRUtils::is_array(x->m_type)) { + ASR::ttype_t* sibling_type = ASRUtils::expr_type(operand); + ASR::dimension_t* m_dims; int ndims; + PassUtils::get_dim_rank(sibling_type, m_dims, ndims); + ASR::ttype_t* arr_type = ASRUtils::make_Array_t_util( + al, loc, x->m_type, m_dims, ndims); + if( ASRUtils::extract_physical_type(arr_type) == + ASR::array_physical_typeType::DescriptorArray ) { + arr_type = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, arr_type)); + } + result_var = PassUtils::create_var(result_counter, res_prefix, + loc, arr_type, al, current_scope); + } else { + result_var = PassUtils::create_var(result_counter, res_prefix, + loc, *current_expr, al, current_scope); + } result_counter += 1; operand = first_array_operand; ASR::dimension_t* m_dims; int n_dims = ASRUtils::extract_dimensions_from_ttype( ASRUtils::expr_type(first_array_operand), m_dims); - allocate_result_var(operand, m_dims, n_dims, true); + allocate_result_var(operand, m_dims, n_dims, true, false); result_var_created = true; } *current_expr = result_var; @@ -1320,15 +1417,18 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var = nullptr; } - void replace_IntrinsicScalarFunction(ASR::IntrinsicScalarFunction_t* x) { - if(!ASRUtils::IntrinsicScalarFunctionRegistry::is_elemental(x->m_intrinsic_id)) { - return ; - } + void replace_IntrinsicElementalFunction(ASR::IntrinsicElementalFunction_t* x) { replace_intrinsic_function(x); } void replace_IntrinsicArrayFunction(ASR::IntrinsicArrayFunction_t* x) { if(!ASRUtils::IntrinsicArrayFunctionRegistry::is_elemental(x->m_arr_intrinsic_id)) { + // ASR::BaseExprReplacer::replace_IntrinsicArrayFunction(x); + if( op_expr == &(x->base) ) { + op_dims = nullptr; + op_n_dims = ASRUtils::extract_dimensions_from_ttype( + ASRUtils::expr_type(*current_expr), op_dims); + } return ; } replace_intrinsic_function(x); @@ -1379,6 +1479,10 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { int common_rank = 0; bool are_all_rank_same = true; for( size_t iarg = 0; iarg < x->n_args; iarg++ ) { + if (x->m_args[iarg].m_value == nullptr) { + operands.push_back(nullptr); + continue; + } ASR::expr_t** current_expr_copy_9 = current_expr; current_expr = &(x->m_args[iarg].m_value); self().replace_expr(x->m_args[iarg].m_value); @@ -1409,8 +1513,24 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { result_var = result_var_copy; bool result_var_created = false; if( result_var == nullptr ) { - result_var = PassUtils::create_var(result_counter, res_prefix, - loc, operand, al, current_scope); + ASR::Function_t* func = ASR::down_cast(ASRUtils::symbol_get_past_external(x->m_name)); + if (func->m_return_var != nullptr && !ASRUtils::is_array(ASRUtils::expr_type(func->m_return_var))) { + ASR::ttype_t* sibling_type = ASRUtils::expr_type(first_array_operand); + ASR::dimension_t* m_dims = nullptr; int ndims = 0; + PassUtils::get_dim_rank(sibling_type, m_dims, ndims); + LCOMPILERS_ASSERT(m_dims != nullptr); + ASR::ttype_t* arr_type = ASRUtils::make_Array_t_util( + al, loc, ASRUtils::expr_type(func->m_return_var), m_dims, ndims); + if( ASRUtils::extract_physical_type(arr_type) == + ASR::array_physical_typeType::DescriptorArray ) { + arr_type = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, arr_type)); + } + result_var = PassUtils::create_var(result_counter, res_prefix, + loc, arr_type, al, current_scope); + } else { + result_var = PassUtils::create_var(result_counter, res_prefix, + loc, operand, al, current_scope); + } result_counter += 1; result_var_created = true; } @@ -1423,7 +1543,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { ASR::dimension_t* m_dims; int n_dims = ASRUtils::extract_dimensions_from_ttype( ASRUtils::expr_type(operand), m_dims); - allocate_result_var(operand, m_dims, n_dims, result_var_created); + allocate_result_var(operand, m_dims, n_dims, result_var_created, false); *current_expr = result_var; Vec idx_vars, loop_vars, idx_vars_value; @@ -1440,7 +1560,7 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer { ref = PassUtils::create_array_ref(operands[iarg], idx_vars_value, al, current_scope); } ASR::call_arg_t ref_arg; - ref_arg.loc = ref->base.loc; + ref_arg.loc = x->m_args[iarg].loc; ref_arg.m_value = ref; ref_args.push_back(al, ref_arg); } @@ -1614,6 +1734,10 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*x.m_value) ) { + remove_original_statement = false; + return ; + } this->visit_expr(*x.m_value); } if (x.m_overloaded) { @@ -1622,6 +1746,7 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*x.m_value)) { @@ -1638,7 +1763,8 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*ASRUtils::expr_type(x.m_target)) && ASR::is_a(*x.m_value)) || - (ASR::is_a(*x.m_value)) ) { + (ASR::is_a(*x.m_value) || + ASR::is_a(*x.m_value)) ) { if( realloc_lhs && ASRUtils::is_allocatable(x.m_target)) { // Add realloc-lhs later Vec vec_alloc; vec_alloc.reserve(al, 1); @@ -1654,11 +1780,14 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor vec_dims; vec_dims.reserve(al, n_dims); + ASR::ttype_t* int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)); for( size_t i = 0; i < n_dims; i++ ) { ASR::dimension_t dim; dim.loc = x.m_value->base.loc; dim.m_start = PassUtils::get_bound(x.m_value, i + 1, "lbound", al); dim.m_length = ASRUtils::get_size(x.m_value, i + 1, al); + dim.m_start = CastingUtil::perform_casting(dim.m_start, int32_type, al, loc); + dim.m_length = CastingUtil::perform_casting(dim.m_length, int32_type, al, loc); vec_dims.push_back(al, dim); } @@ -1688,11 +1817,9 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor(*x.m_target) ) { ASR::ArraySection_t* array_ref = ASR::down_cast(x.m_target); replacer.result_var = array_ref->m_v; - remove_original_statement = true; result_lbound.reserve(al, array_ref->n_args); result_ubound.reserve(al, array_ref->n_args); result_inc.reserve(al, array_ref->n_args); @@ -1721,6 +1848,7 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitorbase.loc; ref_arg.m_value = array_item; ref_args.push_back(al, ref_arg); ASR::stmt_t* subroutine_call = ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util(al, x.base.base.loc, - x.m_name, x.m_original_name, ref_args.p, ref_args.n, nullptr, nullptr, false)); + x.m_name, x.m_original_name, ref_args.p, ref_args.n, nullptr, nullptr, false, ASRUtils::get_class_proc_nopass_val(x.m_name))); doloop_body.push_back(al, subroutine_call); }); remove_original_statement = true; diff --git a/src/libasr/pass/do_loops.cpp b/src/libasr/pass/do_loops.cpp index 0772908150..cdc6cb8436 100644 --- a/src/libasr/pass/do_loops.cpp +++ b/src/libasr/pass/do_loops.cpp @@ -43,6 +43,12 @@ class DoLoopVisitor : public ASR::StatementWalkVisitor void visit_DoLoop(const ASR::DoLoop_t &x) { pass_result = PassUtils::replace_doloop(al, x, -1, use_loop_variable_after_loop); } + + void visit_DoConcurrentLoop(const ASR::DoConcurrentLoop_t &x) { + ASR::asr_t* do_loop = ASR::make_DoLoop_t(al, x.base.base.loc, s2c(al, ""), x.m_head, x.m_body, x.n_body, nullptr, 0); + const ASR::DoLoop_t &do_loop_ref = (const ASR::DoLoop_t&)(*do_loop); + pass_result = PassUtils::replace_doloop(al, do_loop_ref, -1, use_loop_variable_after_loop); + } }; void pass_replace_do_loops(Allocator &al, ASR::TranslationUnit_t &unit, diff --git a/src/libasr/pass/function_call_in_declaration.cpp b/src/libasr/pass/function_call_in_declaration.cpp new file mode 100644 index 0000000000..f94e2371c3 --- /dev/null +++ b/src/libasr/pass/function_call_in_declaration.cpp @@ -0,0 +1,354 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +namespace LCompilers { + +using ASR::down_cast; +using ASR::is_a; + +/* + +This ASR pass replaces function calls in declarations with a new function call. +The function `pass_replace_function_call_in_declaration` transforms the ASR tree inplace. + +Converts: + +pure function diag_rsp_mat(A) result(res) +real, intent(in) :: A(:,:) +real :: res(minval(shape(A))) + +res = 123.71_4 +end function diag_rsp_mat + +To: + +pure integer function __lcompilers_created_helper_function_(A) result(r) +real, intent(in) :: A(:,:) +r = minval(shape(A)) +end function __lcompilers_created_helper_function_ + +pure function diag_rsp_mat(A) result(res) +real, intent(in) :: A(:,:) +real :: res(__lcompilers_created_helper_function_(A)) + +res = 123.71_4 +end function diag_rsp_mat + +*/ + +class ReplaceFunctionCall : public ASR::BaseExprReplacer +{ +public: + Allocator& al; + SymbolTable* current_scope = nullptr; + ASR::expr_t* assignment_value = nullptr; + ASR::expr_t* call_for_return_var = nullptr; + ASR::Function_t* current_function = nullptr; + Vec* newargsp = nullptr; + + struct ArgInfo { + int arg_number; + ASR::ttype_t* arg_type; + ASR::expr_t* arg_expr; + ASR::expr_t* arg_param; + }; + + ReplaceFunctionCall(Allocator &al_) : al(al_) {} + + void replace_FunctionParam(ASR::FunctionParam_t* x) { + if( newargsp == nullptr ) { + return ; + } + *current_expr = newargsp->p[x->m_param_number]; + } + + void replace_FunctionParam_with_FunctionArgs(ASR::expr_t*& value, Vec& new_args) { + if( !value ) { + return ; + } + newargsp = &new_args; + ASR::expr_t** current_expr_copy = current_expr; + current_expr = &value; + replace_expr(value); + current_expr = current_expr_copy; + newargsp = nullptr; + } + + bool exists_in_arginfo(int arg_number, std::vector& indicies) { + for (auto info: indicies) { + if (info.arg_number == arg_number) return true; + } + return false; + } + + void helper_get_arg_indices_used(ASR::expr_t* arg, std::vector& indicies) { + if (is_a(*arg)) { + ASR::ArrayPhysicalCast_t* cast = ASR::down_cast(arg); + arg = cast->m_arg; + } + if (is_a(*arg)) { + get_arg_indices_used_functioncall(ASR::down_cast(arg), indicies); + } else if (is_a(*arg)) { + get_arg_indices_used(ASR::down_cast(arg), indicies); + } else if (is_a(*arg)) { + ASR::FunctionParam_t* param = ASR::down_cast(arg); + ArgInfo info = {static_cast(param->m_param_number), param->m_type, current_function->m_args[param->m_param_number], arg}; + if (!exists_in_arginfo(param->m_param_number, indicies)) { + indicies.push_back(info); + } + } else if (is_a(*arg)) { + ASR::ArraySize_t* size = ASR::down_cast(arg); + helper_get_arg_indices_used(size->m_v, indicies); + } else if (is_a(*arg)) { + ASR::IntegerCompare_t* comp = ASR::down_cast(arg); + helper_get_arg_indices_used(comp->m_left, indicies); + helper_get_arg_indices_used(comp->m_right, indicies); + } + } + + void get_arg_indices_used_functioncall(ASR::FunctionCall_t* x, std::vector& indicies) { + for (size_t i = 0; i < x->n_args; i++) { + ASR::expr_t* arg = x->m_args[i].m_value; + helper_get_arg_indices_used(arg, indicies); + } + return; + } + + template + void get_arg_indices_used(T* x, std::vector& indicies) { + for (size_t i = 0; i < x->n_args; i++) { + ASR::expr_t* arg = x->m_args[i]; + helper_get_arg_indices_used(arg, indicies); + } + return; + } + + void replace_IntrinsicArrayFunction(ASR::IntrinsicArrayFunction_t *x) { + if (!current_scope || !current_function || !assignment_value) return; + + if( newargsp != nullptr ) { + BaseExprReplacer::replace_IntrinsicArrayFunction(x); + return ; + } + + std::vector indicies; + get_arg_indices_used(x, indicies); + + SymbolTable* global_scope = current_scope; + while (global_scope->parent) { + global_scope = global_scope->parent; + } + SetChar current_function_dependencies; current_function_dependencies.clear(al); + SymbolTable* new_scope = al.make_new(global_scope); + + ASRUtils::SymbolDuplicator sd(al); + ASRUtils::ASRBuilder b(al, x->base.base.loc); + Vec new_args; new_args.reserve(al, indicies.size()); + Vec new_call_args; new_call_args.reserve(al, indicies.size()); + Vec args_for_return_var; args_for_return_var.reserve(al, indicies.size()); + + Vec new_body; new_body.reserve(al, 1); + std::string new_function_name = global_scope->get_unique_name("__lcompilers_created_helper_function_", false); + ASR::ttype_t* integer_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x->base.base.loc, 4)); + ASR::expr_t* return_var = b.Variable(new_scope, new_scope->get_unique_name("__lcompilers_return_var_", false), integer_type, ASR::intentType::ReturnVar); + + for (auto arg: indicies) { + ASR::expr_t* arg_expr = arg.arg_expr; + if (is_a(*arg_expr)) { + ASR::Var_t* var = ASR::down_cast(arg_expr); + sd.duplicate_symbol(var->m_v, new_scope); + ASR::expr_t* new_var_expr = ASRUtils::EXPR(ASR::make_Var_t(al, var->base.base.loc, new_scope->get_symbol(ASRUtils::symbol_name(var->m_v)))); + new_args.push_back(al, new_var_expr); + } + ASR::call_arg_t new_call_arg; new_call_arg.loc = arg_expr->base.loc; new_call_arg.m_value = arg.arg_param; + new_call_args.push_back(al, new_call_arg); + + ASR::call_arg_t arg_for_return_var; arg_for_return_var.loc = arg_expr->base.loc; arg_for_return_var.m_value = arg.arg_expr; + args_for_return_var.push_back(al, arg_for_return_var); + } + replace_FunctionParam_with_FunctionArgs(assignment_value, new_args); + new_body.push_back(al, b.Assignment(return_var, assignment_value)); + ASR::asr_t* new_function = ASRUtils::make_Function_t_util(al, current_function->base.base.loc, + new_scope, s2c(al, new_function_name), current_function_dependencies.p, current_function_dependencies.n, + new_args.p, new_args.n, + new_body.p, new_body.n, + return_var, + ASR::abiType::Source, ASR::accessType::Public, ASR::deftypeType::Implementation, + nullptr, false, false, false, false, false, nullptr, 0, + false, false, false); + + ASR::symbol_t* new_function_sym = ASR::down_cast(new_function); + global_scope->add_or_overwrite_symbol(new_function_name, new_function_sym); + + ASR::expr_t* new_function_call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x->base.base.loc, + new_function_sym, + new_function_sym, + new_call_args.p, new_call_args.n, + integer_type, + nullptr, + nullptr)); + *current_expr = new_function_call; + + ASR::expr_t* function_call_for_return_var = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, x->base.base.loc, + new_function_sym, + new_function_sym, + args_for_return_var.p, args_for_return_var.n, + integer_type, + nullptr, + nullptr)); + call_for_return_var = function_call_for_return_var; + } + +}; + +class FunctionTypeVisitor : public ASR::CallReplacerOnExpressionsVisitor +{ +public: + + Allocator &al; + ReplaceFunctionCall replacer; + SymbolTable* current_scope; + Vec pass_result; + + + FunctionTypeVisitor(Allocator &al_) : al(al_), replacer(al_) { + current_scope = nullptr; + pass_result.reserve(al, 1); + } + + void call_replacer_(ASR::expr_t* value) { + replacer.current_expr = current_expr; + replacer.current_scope = current_scope; + replacer.assignment_value = value; + ASR::asr_t* asr_owner = current_scope->asr_owner; + if (asr_owner) { + ASR::Function_t* func = ASR::down_cast2(asr_owner); + replacer.current_function = func; + } + replacer.replace_expr(*current_expr); + replacer.current_scope = nullptr; + replacer.current_function = nullptr; + replacer.assignment_value = nullptr; + } + + bool is_function_call_or_intrinsic_array_function(ASR::expr_t* expr) { + if (!expr) return false; + if (is_a(*expr)) { + return true; + } else if (is_a(*expr)) { + return true; + } + return false; + } + + void set_type_of_result_var(const ASR::FunctionType_t &x, ASR::Function_t* func) { + if( !ASR::is_a(*x.m_return_var_type) ) { + return ; + } + ASR::ttype_t* return_type_copy = ASRUtils::duplicate_type(al, x.m_return_var_type); + ASR::Array_t* array_t = ASR::down_cast(return_type_copy); + Vec new_args; new_args.reserve(al, func->n_args); + for (size_t j = 0; j < func->n_args; j++) { + new_args.push_back(al, func->m_args[j]); + } + for( size_t i = 0; i < array_t->n_dims; i++ ) { + replacer.replace_FunctionParam_with_FunctionArgs(array_t->m_dims[i].m_start, new_args); + replacer.replace_FunctionParam_with_FunctionArgs(array_t->m_dims[i].m_length, new_args); + } + ASRUtils::EXPR2VAR(func->m_return_var)->m_type = return_type_copy; + } + + void visit_FunctionType(const ASR::FunctionType_t &x) { + if (!current_scope) return; + + ASR::ttype_t* return_var_type = x.m_return_var_type; + + if (return_var_type && ASRUtils::is_array(return_var_type)) { + ASR::Function_t* func = nullptr; + ASR::asr_t* asr_owner = current_scope->asr_owner; + if (ASR::is_a(*asr_owner)) { + ASR::symbol_t* sym = ASR::down_cast(asr_owner); + if (ASR::is_a(*sym)) { + func = ASR::down_cast2(current_scope->asr_owner); + } + } + if (!func) return; + ASR::Array_t* arr = ASR::down_cast(ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_pointer(return_var_type))); + for (size_t i = 0; i < arr->n_dims; i++) { + ASR::dimension_t dim = arr->m_dims[i]; + ASR::expr_t* start = dim.m_start; + ASR::expr_t* end = dim.m_length; + if (start && is_a(*start)) { + ASR::IntegerBinOp_t* binop = ASR::down_cast(start); + if (is_function_call_or_intrinsic_array_function(binop->m_left)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(binop->m_left)); + this->call_replacer_(binop->m_left); + current_expr = current_expr_copy; + } + if (is_function_call_or_intrinsic_array_function(binop->m_right)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(binop->m_right)); + this->call_replacer_(binop->m_right); + current_expr = current_expr_copy; + } + + } + if (end && is_a(*end)) { + ASR::IntegerBinOp_t* binop = ASR::down_cast(end); + if (is_function_call_or_intrinsic_array_function(binop->m_left)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(binop->m_left)); + this->call_replacer_(binop->m_left); + current_expr = current_expr_copy; + } + if (is_function_call_or_intrinsic_array_function(binop->m_right)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(binop->m_right)); + this->call_replacer_(binop->m_right); + current_expr = current_expr_copy; + } + + } + if (is_function_call_or_intrinsic_array_function(start)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(ASR::down_cast(x.m_return_var_type)->m_dims[i].m_start)); + this->call_replacer_(start); + current_expr = current_expr_copy; + } + if (is_function_call_or_intrinsic_array_function(end)) { + ASR::expr_t** current_expr_copy = current_expr; + current_expr = const_cast(&(ASR::down_cast(x.m_return_var_type)->m_dims[i].m_length)); + this->call_replacer_(end); + current_expr = current_expr_copy; + } + } + + set_type_of_result_var(x, func); + } + } + + void visit_Function(const ASR::Function_t &x) { + current_scope = x.m_symtab; + this->visit_ttype(*x.m_function_signature); + current_scope = nullptr; + } + +}; + +void pass_replace_function_call_in_declaration(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { + FunctionTypeVisitor v(al); + v.visit_TranslationUnit(unit); + PassUtils::UpdateDependenciesVisitor x(al); + x.visit_TranslationUnit(unit); +} + + +} // namespace LCompilers diff --git a/src/libasr/pass/implied_do_loops.cpp b/src/libasr/pass/implied_do_loops.cpp index c4254dc55d..f490105bd8 100644 --- a/src/libasr/pass/implied_do_loops.cpp +++ b/src/libasr/pass/implied_do_loops.cpp @@ -46,14 +46,15 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { ASR::expr_t* end = implied_doloop->m_end; ASR::expr_t* d = implied_doloop->m_increment; ASR::expr_t* implied_doloop_size = nullptr; + int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(end)); if( d == nullptr ) { implied_doloop_size = builder.ElementalAdd( builder.ElementalSub(end, start, loc), - make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, 1, 4, loc), loc); + make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, 1, kind, loc), loc); } else { implied_doloop_size = builder.ElementalAdd(builder.ElementalDiv( builder.ElementalSub(end, start, loc), d, loc), - make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, 1, 4, loc), loc); + make_ConstantWithKind(make_IntegerConstant_t, make_Integer_t, 1, kind, loc), loc); } int const_elements = 0; ASR::expr_t* implied_doloop_size_ = nullptr; @@ -74,11 +75,11 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { if( const_elements > 1 ) { if( implied_doloop_size_ == nullptr ) { implied_doloop_size_ = make_ConstantWithKind(make_IntegerConstant_t, - make_Integer_t, const_elements, 4, loc); + make_Integer_t, const_elements, kind, loc); } else { implied_doloop_size_ = builder.ElementalAdd( make_ConstantWithKind(make_IntegerConstant_t, - make_Integer_t, const_elements, 4, loc), + make_Integer_t, const_elements, kind, loc), implied_doloop_size_, loc); } } @@ -89,19 +90,10 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { } size_t get_constant_ArrayConstant_size(ASR::ArrayConstant_t* x) { - size_t size = 0; - for( size_t i = 0; i < x->n_args; i++ ) { - if( ASR::is_a(*x->m_args[i]) ) { - size += get_constant_ArrayConstant_size( - ASR::down_cast(x->m_args[i])); - } else { - size += 1; - } - } - return size; + return x->n_args; } - ASR::expr_t* get_ArrayConstant_size(ASR::ArrayConstant_t* x, bool& is_allocatable) { + ASR::expr_t* get_ArrayConstructor_size(ASR::ArrayConstructor_t* x, bool& is_allocatable) { ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x->base.base.loc, 4)); ASR::expr_t* array_size = nullptr; int64_t constant_size = 0; @@ -115,7 +107,7 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { ASR::down_cast(element)); } else { ASR::expr_t* element_array_size = get_ArrayConstant_size( - ASR::down_cast(element), is_allocatable); + ASR::down_cast(element)); if( array_size == nullptr ) { array_size = element_array_size; } else { @@ -123,6 +115,15 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { element_array_size, x->base.base.loc); } } + } else if( ASR::is_a(*element) ) { + ASR::expr_t* element_array_size = get_ArrayConstructor_size( + ASR::down_cast(element), is_allocatable); + if( array_size == nullptr ) { + array_size = element_array_size; + } else { + array_size = builder.ElementalAdd(array_size, + element_array_size, x->base.base.loc); + } } else if( ASR::is_a(*element) ) { ASR::ttype_t* element_type = ASRUtils::type_get_past_allocatable( ASRUtils::expr_type(element)); @@ -201,6 +202,98 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { return array_size; } + ASR::expr_t* get_ArrayConstant_size(ASR::ArrayConstant_t* x) { + ASR::ttype_t* int_type = ASRUtils::TYPE(ASR::make_Integer_t(al, x->base.base.loc, 4)); + return make_ConstantWithType(make_IntegerConstant_t, + ASRUtils::get_fixed_size_of_array(x->m_type), int_type, x->base.base.loc); + } + + void replace_ArrayConstructor(ASR::ArrayConstructor_t* x) { + const Location& loc = x->base.base.loc; + ASR::expr_t* result_var_copy = result_var; + bool is_result_var_fixed_size = false; + if (result_var != nullptr && + resultvar2value.find(result_var) != resultvar2value.end() && + resultvar2value[result_var] == &(x->base)) { + is_result_var_fixed_size = ASRUtils::is_fixed_size_array(ASRUtils::expr_type(result_var)); + } + ASR::ttype_t* result_type_ = nullptr; + bool is_allocatable = false; + ASR::expr_t* array_constructor = get_ArrayConstructor_size(x, is_allocatable); + Vec dims; + dims.reserve(al, 1); + ASR::dimension_t dim; + dim.loc = loc; + dim.m_start = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, + ASRUtils::type_get_past_pointer( + ASRUtils::type_get_past_allocatable( + ASRUtils::expr_type(array_constructor))))); + dim.m_length = array_constructor; + dims.push_back(al, dim); + remove_original_statement = false; + if( is_result_var_fixed_size ) { + result_type_ = ASRUtils::expr_type(result_var); + is_allocatable = false; + } else { + if( is_allocatable ) { + result_type_ = ASRUtils::TYPE(ASR::make_Allocatable_t(al, x->m_type->base.loc, + ASRUtils::type_get_past_allocatable( + ASRUtils::duplicate_type_with_empty_dims(al, x->m_type)))); + } else { + result_type_ = ASRUtils::duplicate_type(al, + ASRUtils::type_get_past_allocatable(x->m_type), &dims); + } + } + result_var = PassUtils::create_var(result_counter, "_array_constructor_", + loc, result_type_, al, current_scope); + result_counter += 1; + *current_expr = result_var; + + Vec alloc_args; + alloc_args.reserve(al, 1); + ASR::alloc_arg_t arg; + arg.m_len_expr = nullptr; + arg.m_type = nullptr; + arg.m_dims = dims.p; + arg.n_dims = dims.size(); + if( is_allocatable ) { + arg.loc = result_var->base.loc; + arg.m_a = result_var; + alloc_args.push_back(al, arg); + Vec to_be_deallocated; + to_be_deallocated.reserve(al, alloc_args.size()); + for( size_t i = 0; i < alloc_args.size(); i++ ) { + to_be_deallocated.push_back(al, alloc_args.p[i].m_a); + } + pass_result.push_back(al, ASRUtils::STMT(ASR::make_ExplicitDeallocate_t( + al, loc, to_be_deallocated.p, to_be_deallocated.size()))); + ASR::stmt_t* allocate_stmt = ASRUtils::STMT(ASR::make_Allocate_t( + al, loc, alloc_args.p, alloc_args.size(), nullptr, nullptr, nullptr)); + pass_result.push_back(al, allocate_stmt); + } + if ( allocate_target && realloc_lhs ) { + allocate_target = false; + arg.loc = result_var_copy->base.loc; + arg.m_a = result_var_copy; + alloc_args.push_back(al, arg); + Vec to_be_deallocated; + to_be_deallocated.reserve(al, alloc_args.size()); + for( size_t i = 0; i < alloc_args.size(); i++ ) { + to_be_deallocated.push_back(al, alloc_args.p[i].m_a); + } + pass_result.push_back(al, ASRUtils::STMT(ASR::make_ExplicitDeallocate_t( + al, loc, to_be_deallocated.p, to_be_deallocated.size()))); + ASR::stmt_t* allocate_stmt = ASRUtils::STMT(ASR::make_Allocate_t( + al, loc, alloc_args.p, alloc_args.size(), nullptr, nullptr, nullptr)); + pass_result.push_back(al, allocate_stmt); + } + LCOMPILERS_ASSERT(result_var != nullptr); + Vec* result_vec = &pass_result; + PassUtils::ReplacerUtils::replace_ArrayConstructor(x, this, + remove_original_statement, result_vec); + result_var = result_var_copy; + } + void replace_ArrayConstant(ASR::ArrayConstant_t* x) { const Location& loc = x->base.base.loc; ASR::expr_t* result_var_copy = result_var; @@ -212,7 +305,7 @@ class ReplaceArrayConstant: public ASR::BaseExprReplacer { } ASR::ttype_t* result_type_ = nullptr; bool is_allocatable = false; - ASR::expr_t* array_constant_size = get_ArrayConstant_size(x, is_allocatable); + ASR::expr_t* array_constant_size = get_ArrayConstant_size(x); Vec dims; dims.reserve(al, 1); ASR::dimension_t dim; @@ -427,7 +520,7 @@ class ArrayConstantVisitor : public ASR::CallReplacerOnExpressionsVisitorbase.loc, ASRUtils::expr_type(value), dim.p, dim.size(), ASR::array_physical_typeType::FixedSizeArray)); - ASR::asr_t* array_constant = ASR::make_ArrayConstant_t(al, value->base.loc, + ASR::asr_t* array_constant = ASRUtils::make_ArrayConstructor_t_util(al, value->base.loc, args.p, args.n, array_type, ASR::arraystorageType::ColMajor); return array_constant; } @@ -508,7 +601,21 @@ class ArrayConstantVisitor : public ASR::CallReplacerOnExpressionsVisitorvisit_stmt(*x.m_overloaded); + remove_original_statement = false; + return; + } + } + void visit_FileWrite(const ASR::FileWrite_t &x) { + if (x.m_overloaded) { + this->visit_stmt(*x.m_overloaded); + remove_original_statement = false; + return; + } + /* integer :: i write(*,*) (i, i=1, 10) diff --git a/src/libasr/pass/init_expr.cpp b/src/libasr/pass/init_expr.cpp index bab7f2f2c7..0ee4c67a12 100644 --- a/src/libasr/pass/init_expr.cpp +++ b/src/libasr/pass/init_expr.cpp @@ -52,6 +52,23 @@ class ReplaceInitExpr: public ASR::BaseExprReplacer { *current_expr = nullptr; } + void replace_ArrayConstructor(ASR::ArrayConstructor_t* x) { + if( symtab2decls.find(current_scope) == symtab2decls.end() ) { + Vec result_vec_; + result_vec_.reserve(al, 0); + symtab2decls[current_scope] = result_vec_; + } + Vec* result_vec = &symtab2decls[current_scope]; + bool remove_original_statement = false; + if( casted_type != nullptr ) { + casted_type = ASRUtils::type_get_past_array(casted_type); + } + PassUtils::ReplacerUtils::replace_ArrayConstructor(x, this, + remove_original_statement, result_vec, + perform_cast, cast_kind, casted_type); + *current_expr = nullptr; + } + void replace_StructTypeConstructor(ASR::StructTypeConstructor_t* x) { if( symtab2decls.find(current_scope) == symtab2decls.end() ) { Vec result_vec_; @@ -165,9 +182,11 @@ class InitExprVisitor : public ASR::CallReplacerOnExpressionsVisitor(*symbolic_value) || - ASR::is_a(*symbolic_value))) || + ASR::is_a(*symbolic_value) || + ASR::is_a(*symbolic_value))) || (ASR::is_a(*asr_owner) && - ASR::is_a(*symbolic_value))) { + (ASR::is_a(*symbolic_value) || + ASR::is_a(*symbolic_value)))) { return ; } diff --git a/src/libasr/pass/instantiate_template.cpp b/src/libasr/pass/instantiate_template.cpp index c0756212bd..aa3576c5e2 100644 --- a/src/libasr/pass/instantiate_template.cpp +++ b/src/libasr/pass/instantiate_template.cpp @@ -7,6 +7,8 @@ namespace LCompilers { +namespace LPython { + class SymbolRenamer : public ASR::BaseExprStmtDuplicator { public: @@ -47,7 +49,7 @@ class SymbolRenamer : public ASR::BaseExprStmtDuplicator ASR::ttype_t *t = x->m_type; ASR::dimension_t* tp_m_dims = nullptr; int tp_n_dims = ASRUtils::extract_dimensions_from_ttype(t, tp_m_dims); - + if (ASR::is_a(*t)) { ASR::TypeParameter_t *tp = ASR::down_cast(t); if (type_subs.find(tp->m_param) != type_subs.end()) { @@ -98,7 +100,7 @@ class SymbolRenamer : public ASR::BaseExprStmtDuplicator ASR::symbol_t *new_f = ASR::down_cast(ASRUtils::make_Function_t_util( al, x->base.base.loc, current_scope, s2c(al, new_sym_name), x->m_dependencies, - x->n_dependencies, args.p, args.size(), nullptr, 0, new_return_var_ref, ftype->m_abi, + x->n_dependencies, args.p, args.size(), nullptr, 0, new_return_var_ref, ftype->m_abi, x->m_access, ftype->m_deftype, ftype->m_bindc_name, ftype->m_elemental, ftype->m_pure, ftype->m_module, ftype->m_inline, ftype->m_static, ftype->m_restrictions, ftype->n_restrictions, ftype->m_is_restriction, x->m_deterministic, x->m_side_effect_free)); @@ -434,7 +436,7 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicator(ASR::make_ClassProcedure_t( al, x->base.base.loc, current_scope, x->m_name, x->m_self_argument, - s2c(al, new_cp_name), new_cp_proc, x->m_abi, x->m_is_deferred)); + s2c(al, new_cp_name), new_cp_proc, x->m_abi, x->m_is_deferred, x->m_is_nopass)); current_scope->add_symbol(x->m_name, new_x); return new_x; @@ -473,6 +475,16 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicatorbase.base.loc, m_args.p, x->n_args, m_type, x->m_storage_format); } + ASR::asr_t* duplicate_ArrayConstructor(ASR::ArrayConstructor_t *x) { + Vec m_args; + m_args.reserve(al, x->n_args); + for (size_t i = 0; i < x->n_args; i++) { + m_args.push_back(al, self().duplicate_expr(x->m_args[i])); + } + ASR::ttype_t* m_type = substitute_type(x->m_type); + return make_ArrayConstructor_t(al, x->base.base.loc, m_args.p, x->n_args, m_type, x->m_value, x->m_storage_format); + } + ASR::asr_t* duplicate_ListItem(ASR::ListItem_t *x) { ASR::expr_t *m_a = duplicate_expr(x->m_a); ASR::expr_t *m_pos = duplicate_expr(x->m_pos); @@ -612,7 +624,7 @@ class SymbolInstantiator : public ASR::BaseExprStmtDuplicatorbase.base.loc, name /* change this */, - x->m_original_name, args.p, args.size(), dt, nullptr, false); + x->m_original_name, args.p, args.size(), dt, nullptr, false, false); } ASR::asr_t* duplicate_StructInstanceMember(ASR::StructInstanceMember_t *x) { @@ -887,4 +899,1057 @@ void report_check_restriction(std::map type_subs, symbol_subs[f_name] = sym_arg; } +} // namespace LPython + +namespace LFortran { + +class SymbolRenamer : public ASR::BaseExprStmtDuplicator +{ +public: + SymbolTable* current_scope; + std::map &type_subs; + std::string new_sym_name; + + SymbolRenamer(Allocator& al, std::map& type_subs, + SymbolTable* current_scope, std::string new_sym_name): + BaseExprStmtDuplicator(al), + current_scope{current_scope}, + type_subs{type_subs}, + new_sym_name{new_sym_name} + {} + + ASR::symbol_t* rename_symbol(ASR::symbol_t *x) { + switch (x->type) { + case (ASR::symbolType::Variable): { + ASR::Variable_t *v = ASR::down_cast(x); + return rename_Variable(v); + } + case (ASR::symbolType::Function): { + if (current_scope->get_symbol(new_sym_name)) { + return current_scope->get_symbol(new_sym_name); + } + ASR::Function_t *f = ASR::down_cast(x); + return rename_Function(f); + } + default: { + std::string sym_name = ASRUtils::symbol_name(x); + throw new LCompilersException("Symbol renaming not supported " + " for " + sym_name); + } + } + } + + ASR::symbol_t* rename_Variable(ASR::Variable_t *x) { + ASR::ttype_t *t = x->m_type; + ASR::dimension_t* tp_m_dims = nullptr; + int tp_n_dims = ASRUtils::extract_dimensions_from_ttype(t, tp_m_dims); + + if (ASR::is_a(*t)) { + ASR::TypeParameter_t *tp = ASR::down_cast(t); + if (type_subs.find(tp->m_param) != type_subs.end()) { + t = ASRUtils::make_Array_t_util(al, tp->base.base.loc, + ASRUtils::duplicate_type(al, type_subs[tp->m_param]), + tp_m_dims, tp_n_dims); + } else { + t = ASRUtils::make_Array_t_util(al, tp->base.base.loc, ASRUtils::TYPE( + ASR::make_TypeParameter_t(al, tp->base.base.loc, + s2c(al, new_sym_name))), tp_m_dims, tp_n_dims); + type_subs[tp->m_param] = t; + } + } + + if (current_scope->get_symbol(new_sym_name)) { + return current_scope->get_symbol(new_sym_name); + } + + ASR::symbol_t* new_v = ASR::down_cast(ASR::make_Variable_t( + al, x->base.base.loc, + current_scope, s2c(al, new_sym_name), x->m_dependencies, + x->n_dependencies, x->m_intent, x->m_symbolic_value, + x->m_value, x->m_storage, t, x->m_type_declaration, + x->m_abi, x->m_access, x->m_presence, x->m_value_attr)); + + current_scope->add_symbol(new_sym_name, new_v); + + return new_v; + } + + ASR::symbol_t* rename_Function(ASR::Function_t *x) { + ASR::FunctionType_t* ftype = ASR::down_cast(x->m_function_signature); + + SymbolTable* parent_scope = current_scope; + current_scope = al.make_new(parent_scope); + + Vec args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + ASR::expr_t *new_arg = duplicate_expr(x->m_args[i]); + args.push_back(al, new_arg); + } + + ASR::expr_t *new_return_var_ref = nullptr; + if (x->m_return_var != nullptr) { + new_return_var_ref = duplicate_expr(x->m_return_var); + } + + ASR::symbol_t *new_f = ASR::down_cast(ASRUtils::make_Function_t_util( + al, x->base.base.loc, current_scope, s2c(al, new_sym_name), x->m_dependencies, + x->n_dependencies, args.p, args.size(), nullptr, 0, new_return_var_ref, ftype->m_abi, + x->m_access, ftype->m_deftype, ftype->m_bindc_name, ftype->m_elemental, + ftype->m_pure, ftype->m_module, ftype->m_inline, ftype->m_static, ftype->m_restrictions, + ftype->n_restrictions, ftype->m_is_restriction, x->m_deterministic, x->m_side_effect_free)); + + parent_scope->add_symbol(new_sym_name, new_f); + current_scope = parent_scope; + + return new_f; + } + + ASR::asr_t* duplicate_Var(ASR::Var_t *x) { + std::string sym_name = ASRUtils::symbol_name(x->m_v); + ASR::symbol_t* sym = duplicate_symbol(x->m_v); + return ASR::make_Var_t(al, x->base.base.loc, sym); + } + + ASR::symbol_t* duplicate_symbol(ASR::symbol_t *x) { + ASR::symbol_t* new_symbol = nullptr; + switch (x->type) { + case ASR::symbolType::Variable: { + new_symbol = duplicate_Variable(ASR::down_cast(x)); + break; + } + default: { + throw LCompilersException("Unsupported symbol for symbol renaming"); + } + } + return new_symbol; + } + + ASR::symbol_t* duplicate_Variable(ASR::Variable_t *x) { + ASR::symbol_t *v = current_scope->get_symbol(x->m_name); + if (!v) { + ASR::ttype_t *t = substitute_type(x->m_type); + v = ASR::down_cast(ASR::make_Variable_t( + al, x->base.base.loc, current_scope, x->m_name, x->m_dependencies, + x->n_dependencies, x->m_intent, x->m_symbolic_value, + x->m_value, x->m_storage, t, x->m_type_declaration, + x->m_abi, x->m_access, x->m_presence, x->m_value_attr)); + current_scope->add_symbol(x->m_name, v); + } + return v; + } + + ASR::ttype_t* substitute_type(ASR::ttype_t *ttype) { + switch (ttype->type) { + case (ASR::ttypeType::TypeParameter) : { + ASR::TypeParameter_t *tp = ASR::down_cast(ttype); + LCOMPILERS_ASSERT(type_subs.find(tp->m_param) != type_subs.end()); + return ASRUtils::duplicate_type(al, type_subs[tp->m_param]); + } + case (ASR::ttypeType::Array) : { + ASR::Array_t *a = ASR::down_cast(ttype); + ASR::ttype_t *t = substitute_type(a->m_type); + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(ttype, m_dims); + Vec new_dims; + new_dims.reserve(al, n_dims); + for (size_t i = 0; i < n_dims; i++) { + ASR::dimension_t old_dim = m_dims[i]; + ASR::dimension_t new_dim; + new_dim.loc = old_dim.loc; + new_dim.m_start = duplicate_expr(old_dim.m_start); + new_dim.m_length = duplicate_expr(old_dim.m_length); + new_dims.push_back(al, new_dim); + } + return ASRUtils::make_Array_t_util(al, t->base.loc, + t, new_dims.p, new_dims.size()); + } + default : return ttype; + } + } + +}; + +class SymbolInstantiator : public ASR::BaseExprStmtDuplicator +{ +public: + SymbolTable* target_scope; // scope where the instantiation is + SymbolTable* new_scope; // scope of the new symbol + std::map type_subs; // type name -> ASR type map based on instantiation's args + std::map& symbol_subs; // symbol name -> ASR symbol map based on instantiation's args + std::string new_sym_name; // name for the new symbol + ASR::symbol_t* sym; + SetChar dependencies; + + SymbolInstantiator(Allocator &al, + SymbolTable* target_scope, + std::map type_subs, + std::map& symbol_subs, + std::string new_sym_name, ASR::symbol_t* sym): + BaseExprStmtDuplicator(al), + target_scope{target_scope}, + new_scope{target_scope}, + type_subs{type_subs}, + symbol_subs{symbol_subs}, + new_sym_name{new_sym_name}, sym{sym} + {} + + ASR::symbol_t* instantiate() { + std::string sym_name = ASRUtils::symbol_name(sym); + + // if passed as instantiation's argument + if (symbol_subs.find(sym_name) != symbol_subs.end()) { + ASR::symbol_t* added_sym = symbol_subs[sym_name]; + std::string added_sym_name = ASRUtils::symbol_name(added_sym); + if (new_scope->resolve_symbol(added_sym_name)) { + return new_scope->resolve_symbol(added_sym_name); + } + } + + // check current scope + if (target_scope->get_symbol(sym_name) != nullptr) { + return target_scope->get_symbol(sym_name); + } + + switch (sym->type) { + case (ASR::symbolType::Function) : { + ASR::Function_t* x = ASR::down_cast(sym); + return instantiate_Function(x); + } + case (ASR::symbolType::Variable) : { + ASR::Variable_t* x = ASR::down_cast(sym); + return instantiate_Variable(x); + } + case (ASR::symbolType::Template) : { + ASR::Template_t* x = ASR::down_cast(sym); + return instantiate_Template(x); + } + case (ASR::symbolType::StructType) : { + ASR::StructType_t* x = ASR::down_cast(sym); + return instantiate_StructType(x); + } + case (ASR::symbolType::ExternalSymbol) : { + ASR::ExternalSymbol_t* x = ASR::down_cast(sym); + return instantiate_ExternalSymbol(x); + } + case (ASR::symbolType::ClassProcedure) : { + ASR::ClassProcedure_t* x = ASR::down_cast(sym); + return instantiate_ClassProcedure(x); + } + case (ASR::symbolType::CustomOperator) : { + ASR::CustomOperator_t* x = ASR::down_cast(sym); + return instantiate_CustomOperator(x); + } + default: { + std::string sym_name = ASRUtils::symbol_name(sym); + throw LCompilersException("Instantiation of " + sym_name + + " symbol is not supported"); + }; + } + } + + ASR::symbol_t* instantiate_Function(ASR::Function_t* x) { + dependencies.clear(al); + new_scope = al.make_new(target_scope); + + // duplicate symbol table + for (auto const &sym_pair: x->m_symtab->get_scope()) { + SymbolInstantiator t(al, new_scope, type_subs, symbol_subs, + ASRUtils::symbol_name(sym_pair.second), sym_pair.second); + t.instantiate(); + } + + Vec args; + args.reserve(al, x->n_args); + ASR::expr_t *new_return_var_ref = nullptr; + SetChar deps_vec; + deps_vec.reserve(al, dependencies.size()); + + for (size_t i=0; in_args; i++) { + ASR::expr_t *new_arg = duplicate_expr(x->m_args[i]); + args.push_back(al, new_arg); + } + + if (x->m_return_var != nullptr) { + new_return_var_ref = duplicate_expr(x->m_return_var); + } + + for( size_t i = 0; i < dependencies.size(); i++ ) { + char* dep = dependencies[i]; + deps_vec.push_back(al, dep); + } + + ASR::asr_t *result = ASRUtils::make_Function_t_util( + al, x->base.base.loc, new_scope, s2c(al, new_sym_name), + deps_vec.p, deps_vec.size(), args.p, args.size(), + nullptr, 0, new_return_var_ref, + ASRUtils::get_FunctionType(x)->m_abi, x->m_access, + ASRUtils::get_FunctionType(x)->m_deftype, ASRUtils::get_FunctionType(x)->m_bindc_name, + ASRUtils::get_FunctionType(x)->m_elemental, ASRUtils::get_FunctionType(x)->m_pure, + ASRUtils::get_FunctionType(x)->m_module, ASRUtils::get_FunctionType(x)->m_inline, + ASRUtils::get_FunctionType(x)->m_static, ASRUtils::get_FunctionType(x)->m_restrictions, + ASRUtils::get_FunctionType(x)->n_restrictions, false, false, false); + + ASR::symbol_t *f = ASR::down_cast(result); + target_scope->add_symbol(new_sym_name, f); + symbol_subs[x->m_name] = f; + + return f; + } + + ASR::symbol_t* instantiate_Variable(ASR::Variable_t* x) { + ASR::ttype_t *new_type = substitute_type(x->m_type); + + SetChar variable_dependencies_vec; + variable_dependencies_vec.reserve(al, 1); + ASRUtils::collect_variable_dependencies(al, variable_dependencies_vec, new_type); + + ASR::symbol_t* s = ASR::down_cast(ASR::make_Variable_t(al, + x->base.base.loc, target_scope, s2c(al, x->m_name), variable_dependencies_vec.p, + variable_dependencies_vec.size(), x->m_intent, nullptr, nullptr, x->m_storage, + new_type, nullptr, x->m_abi, x->m_access, x->m_presence, x->m_value_attr)); + target_scope->add_symbol(x->m_name, s); + + return s; + } + + ASR::symbol_t* instantiate_Template(ASR::Template_t* x) { + new_scope = al.make_new(target_scope); + + // duplicate symbol table + for (auto const &sym_pair: x->m_symtab->get_scope()) { + SymbolInstantiator t(al, new_scope, type_subs, symbol_subs, + ASRUtils::symbol_name(sym_pair.second), sym_pair.second); + t.instantiate(); + } + + SetChar args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + char* arg_i = x->m_args[i]; + args.push_back(al, arg_i); + } + + // TODO: fill the requires + Vec m_requires; + m_requires.reserve(al, x->n_requires); + for (size_t i=0; in_requires; i++) { + m_requires.push_back(al, duplicate_Require(ASR::down_cast(x->m_requires[i]))); + } + + ASR::asr_t *result = ASR::make_Template_t(al, x->base.base.loc, new_scope, + s2c(al, new_sym_name), args.p, args.size(), m_requires.p, m_requires.size()); + + ASR::symbol_t *t = ASR::down_cast(result); + target_scope->add_symbol(new_sym_name, t); + + return t; + } + + ASR::symbol_t* instantiate_StructType(ASR::StructType_t* x) { + new_scope = al.make_new(target_scope); + + Vec data_member_names; + data_member_names.reserve(al, x->n_members); + for (size_t i=0; in_members; i++) { + data_member_names.push_back(al, x->m_members[i]); + } + + ASR::expr_t* m_alignment = duplicate_expr(x->m_alignment); + + ASR::asr_t* result = ASR::make_StructType_t(al, x->base.base.loc, + new_scope, s2c(al, new_sym_name), nullptr, 0, data_member_names.p, + data_member_names.size(), x->m_abi, x->m_access, x->m_is_packed, + x->m_is_abstract, nullptr, 0, m_alignment, nullptr); + + ASR::symbol_t* s = ASR::down_cast(result); + target_scope->add_symbol(new_sym_name, s); + symbol_subs[x->m_name] = s; + + for (auto const &sym_pair: x->m_symtab->get_scope()) { + SymbolInstantiator t(al, new_scope, type_subs, symbol_subs, + ASRUtils::symbol_name(sym_pair.second), sym_pair.second); + t.instantiate(); + } + + return s; + } + + ASR::symbol_t* instantiate_ExternalSymbol(ASR::ExternalSymbol_t* x) { + std::string m_name = x->m_module_name; + + if (symbol_subs.find(m_name) != symbol_subs.end()) { + std::string new_m_name = ASRUtils::symbol_name(symbol_subs[m_name]); + std::string member_name = x->m_original_name; + std::string new_e_name = "1_" + new_m_name + "_" + member_name; + + if (target_scope->get_symbol(new_e_name)) { + return target_scope->get_symbol(new_e_name); + } + + ASR::symbol_t* new_m_sym = target_scope->resolve_symbol(new_m_name); + ASR::symbol_t* member_sym = ASRUtils::symbol_symtab(new_m_sym)->resolve_symbol(member_name); + + ASR::symbol_t* e = ASR::down_cast(ASR::make_ExternalSymbol_t( + al, x->base.base.loc, target_scope, s2c(al, new_e_name), member_sym, + s2c(al, new_m_name), nullptr, 0, s2c(al, member_name), x->m_access)); + target_scope->add_symbol(new_e_name, e); + symbol_subs[x->m_name] = e; + + return e; + } + + ASRUtils::SymbolDuplicator d(al); + d.duplicate_symbol(x->m_parent_symtab->get_symbol(x->m_name), target_scope); + return target_scope->get_symbol(x->m_name); + } + + ASR::symbol_t* instantiate_ClassProcedure(ASR::ClassProcedure_t* x) { + std::string new_cp_name = target_scope->parent->get_unique_name("__asr_" + std::string(x->m_name), false); + ASR::symbol_t* cp_proc = x->m_proc; + + SymbolInstantiator t(al, target_scope->parent, type_subs, symbol_subs, new_cp_name, cp_proc); + ASR::symbol_t* new_cp_proc = t.instantiate(); + symbol_subs[ASRUtils::symbol_name(cp_proc)] = new_cp_proc; + + ASR::symbol_t *new_x = ASR::down_cast(ASR::make_ClassProcedure_t( + al, x->base.base.loc, target_scope, x->m_name, x->m_self_argument, + s2c(al, new_cp_name), new_cp_proc, x->m_abi, x->m_is_deferred, x->m_is_nopass)); + target_scope->add_symbol(x->m_name, new_x); + + return new_x; + } + + ASR::symbol_t* instantiate_CustomOperator(ASR::CustomOperator_t* x) { + return new_scope->resolve_symbol(x->m_name); + } + + ASR::asr_t* duplicate_Var(ASR::Var_t *x) { + std::string sym_name = ASRUtils::symbol_name(x->m_v); + + SymbolInstantiator t(al, new_scope, type_subs, symbol_subs, sym_name, x->m_v); + ASR::symbol_t* sym = t.instantiate(); + + return ASR::make_Var_t(al, x->base.base.loc, sym); + } + + /* require */ + + ASR::require_instantiation_t* duplicate_Require(ASR::Require_t* x) { + SetChar r_args; + r_args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + char* r_arg_i = x->m_args[i]; + r_args.push_back(al, r_arg_i); + } + + return ASR::down_cast( + ASR::make_Require_t(al, x->base.base.loc, s2c(al, x->m_name), r_args.p, r_args.size())); + } + + /* utility */ + + ASR::ttype_t* substitute_type(ASR::ttype_t *ttype) { + switch (ttype->type) { + case (ASR::ttypeType::TypeParameter) : { + ASR::TypeParameter_t *param = ASR::down_cast(ttype); + return ASRUtils::duplicate_type(al, type_subs[param->m_param]); + } + case (ASR::ttypeType::List) : { + ASR::List_t *tlist = ASR::down_cast(ttype); + return ASRUtils::TYPE(ASR::make_List_t(al, ttype->base.loc, + substitute_type(tlist->m_type))); + } + case (ASR::ttypeType::Struct) : { + ASR::Struct_t *s = ASR::down_cast(ttype); + std::string struct_name = ASRUtils::symbol_name(s->m_derived_type); + if (symbol_subs.find(struct_name) != symbol_subs.end()) { + ASR::symbol_t *sym = symbol_subs[struct_name]; + return ASRUtils::TYPE(ASR::make_Struct_t(al, ttype->base.loc, sym)); + } + return ttype; + } + case (ASR::ttypeType::Array) : { + ASR::Array_t *a = ASR::down_cast(ttype); + ASR::ttype_t *t = substitute_type(a->m_type); + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(ttype, m_dims); + Vec new_dims; + new_dims.reserve(al, n_dims); + for (size_t i = 0; i < n_dims; i++) { + ASR::dimension_t old_dim = m_dims[i]; + ASR::dimension_t new_dim; + new_dim.loc = old_dim.loc; + new_dim.m_start = duplicate_expr(old_dim.m_start); + new_dim.m_length = duplicate_expr(old_dim.m_length); + new_dims.push_back(al, new_dim); + } + return ASRUtils::make_Array_t_util(al, t->base.loc, + t, new_dims.p, new_dims.size()); + } + case (ASR::ttypeType::Allocatable) : { + ASR::Allocatable_t *a = ASR::down_cast(ttype); + return ASRUtils::TYPE(ASR::make_Allocatable_t(al, ttype->base.loc, + substitute_type(a->m_type))); + } + case (ASR::ttypeType::Class) : { + ASR::Class_t *c = ASR::down_cast(ttype); + std::string class_name = ASRUtils::symbol_name(c->m_class_type); + if (symbol_subs.find(class_name) != symbol_subs.end()) { + ASR::symbol_t *new_c = symbol_subs[class_name]; + return ASRUtils::TYPE(ASR::make_Class_t(al, ttype->base.loc, new_c)); + } + return ttype; + } + default : return ttype; + } + } + +}; + +class BodyInstantiator : public ASR::BaseExprStmtDuplicator +{ +public: + SymbolTable* new_scope; + std::map type_subs; + std::map& symbol_subs; + ASR::symbol_t* new_sym; + ASR::symbol_t* sym; + SetChar dependencies; + + BodyInstantiator(Allocator &al, + std::map type_subs, + std::map& symbol_subs, + ASR::symbol_t* new_sym, ASR::symbol_t* sym): + BaseExprStmtDuplicator(al), + type_subs{type_subs}, + symbol_subs{symbol_subs}, + new_sym{new_sym}, sym{sym} + {} + + void instantiate() { + switch (sym->type) { + case (ASR::symbolType::Function) : { + LCOMPILERS_ASSERT(ASR::is_a(*new_sym)); + ASR::Function_t* x = ASR::down_cast(sym); + instantiate_Function(x); + break; + } + case (ASR::symbolType::Template) : { + LCOMPILERS_ASSERT(ASR::is_a(*new_sym)); + ASR::Template_t* x = ASR::down_cast(sym); + instantiate_Template(x); + break; + } + case (ASR::symbolType::Variable) : { + break; + } + case (ASR::symbolType::StructType) : { + LCOMPILERS_ASSERT(ASR::is_a(*new_sym)); + ASR::StructType_t* x = ASR::down_cast(sym); + instantiate_StructType(x); + break; + } + case (ASR::symbolType::ClassProcedure) : { + LCOMPILERS_ASSERT(ASR::is_a(*new_sym)); + ASR::ClassProcedure_t* x = ASR::down_cast(sym); + instantiate_ClassProcedure(x); + break; + } + case (ASR::symbolType::ExternalSymbol) : { + break; + } + case (ASR::symbolType::CustomOperator) : { + break; + } + default: { + std::string sym_name = ASRUtils::symbol_name(sym); + throw LCompilersException("Instantiation body of " + sym_name + + " symbol is not supported"); + }; + } + } + + void instantiate_Function(ASR::Function_t* x) { + ASR::Function_t* new_f = ASR::down_cast(new_sym); + new_scope = new_f->m_symtab; + + for (auto const &sym_pair: x->m_symtab->get_scope()) { + ASR::symbol_t* sym_i = sym_pair.second; + + SymbolInstantiator t_i(al, new_scope, type_subs, symbol_subs, sym_pair.first, sym_i); + ASR::symbol_t* new_sym_i = t_i.instantiate(); + + BodyInstantiator t_b(al, type_subs, symbol_subs, new_sym_i, sym_i); + t_b.instantiate(); + } + + Vec body; + body.reserve(al, x->n_body); + for (size_t i=0; in_body; i++) { + ASR::stmt_t *new_body = this->duplicate_stmt(x->m_body[i]); + if (new_body != nullptr) { + body.push_back(al, new_body); + } + } + + SetChar deps_vec; + deps_vec.reserve(al, new_f->n_dependencies + dependencies.size()); + for (size_t i=0; in_dependencies; i++) { + char* dep = new_f->m_dependencies[i]; + deps_vec.push_back(al, dep); + } + for (size_t i=0; im_body = body.p; + new_f->n_body = body.size(); + new_f->m_dependencies = deps_vec.p; + new_f->n_dependencies = deps_vec.size(); + } + + void instantiate_Template(ASR::Template_t* x) { + ASR::Template_t* new_t = ASR::down_cast(new_sym); + + for (auto const &sym_pair: new_t->m_symtab->get_scope()) { + ASR::symbol_t* new_sym_i = sym_pair.second; + ASR::symbol_t* sym_i = x->m_symtab->get_symbol(sym_pair.first); + + BodyInstantiator t(al, type_subs, symbol_subs, new_sym_i, sym_i); + t.instantiate(); + } + } + + void instantiate_StructType(ASR::StructType_t* x) { + ASR::StructType_t* new_s = ASR::down_cast(new_sym); + + for (auto const &sym_pair: new_s->m_symtab->get_scope()) { + ASR::symbol_t* new_sym_i = sym_pair.second; + ASR::symbol_t* sym_i = x->m_symtab->get_symbol(sym_pair.first); + + BodyInstantiator t(al, type_subs, symbol_subs, new_sym_i, sym_i); + t.instantiate(); + } + } + + void instantiate_ClassProcedure(ASR::ClassProcedure_t* x) { + ASR::ClassProcedure_t* new_c = ASR::down_cast(new_sym); + + ASR::symbol_t* new_proc = new_c->m_proc; + ASR::symbol_t* proc = x->m_proc; + + BodyInstantiator t(al, type_subs, symbol_subs, new_proc, proc); + t.instantiate(); + } + + /* expr */ + + ASR::asr_t* duplicate_Var(ASR::Var_t* x) { + std::string sym_name = ASRUtils::symbol_name(x->m_v); + + SymbolInstantiator t_i(al, new_scope, type_subs, symbol_subs, sym_name, x->m_v); + ASR::symbol_t* sym = t_i.instantiate(); + + BodyInstantiator t_b(al, type_subs, symbol_subs, sym, x->m_v); + t_b.instantiate(); + + return ASR::make_Var_t(al, x->base.base.loc, sym); + } + + ASR::asr_t* duplicate_FunctionCall(ASR::FunctionCall_t* x) { + Vec args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + ASR::call_arg_t new_arg; + new_arg.loc = x->m_args[i].loc; + new_arg.m_value = duplicate_expr(x->m_args[i].m_value); + args.push_back(al, new_arg); + } + + ASR::ttype_t* type = substitute_type(x->m_type); + ASR::expr_t* value = duplicate_expr(x->m_value); + ASR::expr_t* dt = duplicate_expr(x->m_dt); + + std::string call_name = ASRUtils::symbol_name(x->m_name); + ASR::symbol_t* name = new_scope->resolve_symbol(call_name); + + // requirement function + if (symbol_subs.find(call_name) != symbol_subs.end()) { + name = symbol_subs[call_name]; + } + + // function call found in body that needs to be instantiated + if (name == nullptr) { + ASR::symbol_t* nested_sym = ASRUtils::symbol_symtab(sym)->resolve_symbol(call_name); + SymbolTable* target_scope = ASRUtils::symbol_parent_symtab(new_sym); + std::string nested_sym_name = target_scope->get_unique_name("__asr_" + call_name, false); + + SymbolInstantiator t_i(al, target_scope, type_subs, symbol_subs, nested_sym_name, nested_sym); + name = t_i.instantiate(); + symbol_subs[call_name] = name; + + BodyInstantiator t_b(al, type_subs, symbol_subs, name, nested_sym); + t_b.instantiate(); + } + + if (ASRUtils::symbol_parent_symtab(name)->get_counter() != new_scope->get_counter() + && !ASR::is_a(*name)) { + ADD_ASR_DEPENDENCIES(new_scope, name, dependencies); + } + + return ASRUtils::make_FunctionCall_t_util(al, x->base.base.loc, name, + x->m_original_name, args.p, args.size(), type, value, dt); + } + + ASR::asr_t* duplicate_SubroutineCall(ASR::SubroutineCall_t* x) { + Vec args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + ASR::call_arg_t new_arg; + new_arg.loc = x->m_args[i].loc; + new_arg.m_value = duplicate_expr(x->m_args[i].m_value); + args.push_back(al, new_arg); + } + + ASR::expr_t* dt = duplicate_expr(x->m_dt); + + std::string call_name = ASRUtils::symbol_name(x->m_name); + ASR::symbol_t* name = new_scope->resolve_symbol(call_name); + + // requirement function + if (symbol_subs.find(call_name) != symbol_subs.end()) { + name = symbol_subs[call_name]; + } + + // function call found in body that needs to be instantiated + if (name == nullptr) { + ASR::symbol_t* nested_sym = ASRUtils::symbol_symtab(sym)->resolve_symbol(call_name); + SymbolTable* target_scope = ASRUtils::symbol_parent_symtab(new_sym); + std::string nested_sym_name = target_scope->get_unique_name("__asr_" + call_name, false); + + SymbolInstantiator t_i(al, target_scope, type_subs, symbol_subs, nested_sym_name, nested_sym); + name = t_i.instantiate(); + symbol_subs[call_name] = name; + + BodyInstantiator t_b(al, type_subs, symbol_subs, name, nested_sym); + t_b.instantiate(); + } + + if (ASRUtils::symbol_parent_symtab(name)->get_counter() != new_scope->get_counter() + && !ASR::is_a(*name)) { + ADD_ASR_DEPENDENCIES(new_scope, name, dependencies); + } + + return ASRUtils::make_SubroutineCall_t_util(al, x->base.base.loc, name, + x->m_original_name, args.p, args.size(), dt, nullptr, false, + ASRUtils::get_class_proc_nopass_val(x->m_name)); + } + + ASR::asr_t* duplicate_DoLoop(ASR::DoLoop_t *x) { + Vec m_body; + m_body.reserve(al, x->n_body); + for (size_t i=0; in_body; i++) { + m_body.push_back(al, duplicate_stmt(x->m_body[i])); + } + ASR::do_loop_head_t head; + head.m_v = duplicate_expr(x->m_head.m_v); + head.m_start = duplicate_expr(x->m_head.m_start); + head.m_end = duplicate_expr(x->m_head.m_end); + head.m_increment = duplicate_expr(x->m_head.m_increment); + head.loc = x->m_head.m_v->base.loc; + return ASR::make_DoLoop_t(al, x->base.base.loc, x->m_name, head, m_body.p, x->n_body, x->m_orelse, x->n_orelse); + } + + ASR::asr_t* duplicate_ArrayItem(ASR::ArrayItem_t *x) { + ASR::expr_t *m_v = duplicate_expr(x->m_v); + ASR::expr_t *m_value = duplicate_expr(x->m_value); + + Vec args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + args.push_back(al, duplicate_array_index(x->m_args[i])); + } + + ASR::ttype_t *type = substitute_type(x->m_type); + + return ASRUtils::make_ArrayItem_t_util(al, x->base.base.loc, m_v, args.p, x->n_args, + ASRUtils::type_get_past_pointer( + ASRUtils::type_get_past_allocatable(type)), x->m_storage_format, m_value); + } + + ASR::asr_t* duplicate_ArrayConstant(ASR::ArrayConstant_t *x) { + Vec m_args; + m_args.reserve(al, x->n_args); + for (size_t i = 0; i < x->n_args; i++) { + m_args.push_back(al, self().duplicate_expr(x->m_args[i])); + } + ASR::ttype_t* m_type = substitute_type(x->m_type); + return make_ArrayConstant_t(al, x->base.base.loc, m_args.p, x->n_args, m_type, x->m_storage_format); + } + + ASR::asr_t* duplicate_ArrayPhysicalCast(ASR::ArrayPhysicalCast_t *x) { + ASR::expr_t *arg = duplicate_expr(x->m_arg); + ASR::ttype_t *ttype = substitute_type(x->m_type); + ASR::expr_t *value = duplicate_expr(x->m_value); + return ASR::make_ArrayPhysicalCast_t(al, x->base.base.loc, + arg, x->m_old, x->m_new, ttype, value); + } + + ASR::asr_t* duplicate_ArraySection(ASR::ArraySection_t *x) { + ASR::expr_t *v = duplicate_expr(x->m_v); + + Vec args; + args.reserve(al, x->n_args); + for (size_t i=0; in_args; i++) { + args.push_back(al, duplicate_array_index(x->m_args[i])); + } + + ASR::ttype_t *ttype = substitute_type(x->m_type); + ASR::expr_t *value = duplicate_expr(x->m_value); + + return ASR::make_ArraySection_t(al, x->base.base.loc, + v, args.p, args.size(), ttype, value); + } + + ASR::asr_t* duplicate_StructInstanceMember(ASR::StructInstanceMember_t *x) { + ASR::expr_t *v = duplicate_expr(x->m_v); + ASR::ttype_t *t = substitute_type(x->m_type); + ASR::expr_t *value = duplicate_expr(x->m_value); + + std::string s_name = ASRUtils::symbol_name(x->m_m); + SymbolInstantiator t_i(al, new_scope, type_subs, symbol_subs, s_name, x->m_m); + ASR::symbol_t *s = t_i.instantiate(); + + return ASR::make_StructInstanceMember_t(al, x->base.base.loc, v, s, t, value); + } + + ASR::asr_t* duplicate_ListItem(ASR::ListItem_t *x) { + ASR::expr_t *m_a = duplicate_expr(x->m_a); + ASR::expr_t *m_pos = duplicate_expr(x->m_pos); + ASR::ttype_t *type = substitute_type(x->m_type); + ASR::expr_t *m_value = duplicate_expr(x->m_value); + + return ASR::make_ListItem_t(al, x->base.base.loc, + m_a, m_pos, type, m_value); + } + + ASR::asr_t* duplicate_Cast(ASR::Cast_t *x) { + ASR::expr_t *arg = duplicate_expr(x->m_arg); + ASR::ttype_t *type = substitute_type(ASRUtils::expr_type(x->m_arg)); + if (ASRUtils::is_real(*type)) { + return (ASR::asr_t*) arg; + } + return ASRUtils::make_Cast_t_value(al, x->base.base.loc, arg, ASR::cast_kindType::IntegerToReal, x->m_type); + } + + /* stmt */ + + ASR::asr_t* duplicate_Assignment(ASR::Assignment_t *x) { + ASR::expr_t *target = duplicate_expr(x->m_target); + ASR::expr_t *value = duplicate_expr(x->m_value); + ASR::stmt_t *overloaded = duplicate_stmt(x->m_overloaded); + return ASR::make_Assignment_t(al, x->base.base.loc, target, value, overloaded); + } + + /* array_index */ + + ASR::array_index_t duplicate_array_index(ASR::array_index_t x) { + ASR::expr_t *left = duplicate_expr(x.m_left); + ASR::expr_t *right = duplicate_expr(x.m_right); + ASR::expr_t *step = duplicate_expr(x.m_step); + ASR::array_index_t result; + result.m_left = left; + result.m_right = right; + result.m_step = step; + return result; + } + + /* utility */ + + // TODO: join this with the other substitute_type + ASR::ttype_t* substitute_type(ASR::ttype_t *ttype) { + switch (ttype->type) { + case (ASR::ttypeType::TypeParameter) : { + ASR::TypeParameter_t *param = ASR::down_cast(ttype); + return ASRUtils::duplicate_type(al, type_subs[param->m_param]); + } + case (ASR::ttypeType::List) : { + ASR::List_t *tlist = ASR::down_cast(ttype); + return ASRUtils::TYPE(ASR::make_List_t(al, ttype->base.loc, + substitute_type(tlist->m_type))); + } + case (ASR::ttypeType::Struct) : { + ASR::Struct_t *s = ASR::down_cast(ttype); + std::string struct_name = ASRUtils::symbol_name(s->m_derived_type); + if (symbol_subs.find(struct_name) != symbol_subs.end()) { + ASR::symbol_t *sym = symbol_subs[struct_name]; + ttype = ASRUtils::TYPE(ASR::make_Struct_t(al, s->base.base.loc, sym)); + } + return ttype; + } + case (ASR::ttypeType::Array) : { + ASR::Array_t *a = ASR::down_cast(ttype); + ASR::ttype_t *t = substitute_type(a->m_type); + ASR::dimension_t* m_dims = nullptr; + size_t n_dims = ASRUtils::extract_dimensions_from_ttype(ttype, m_dims); + Vec new_dims; + new_dims.reserve(al, n_dims); + for (size_t i = 0; i < n_dims; i++) { + ASR::dimension_t old_dim = m_dims[i]; + ASR::dimension_t new_dim; + new_dim.loc = old_dim.loc; + new_dim.m_start = duplicate_expr(old_dim.m_start); + new_dim.m_length = duplicate_expr(old_dim.m_length); + new_dims.push_back(al, new_dim); + } + return ASRUtils::make_Array_t_util(al, t->base.loc, + t, new_dims.p, new_dims.size()); + } + case (ASR::ttypeType::Allocatable): { + ASR::Allocatable_t *a = ASR::down_cast(ttype); + return ASRUtils::TYPE(ASR::make_Allocatable_t(al, ttype->base.loc, + substitute_type(a->m_type))); + } + case (ASR::ttypeType::Class) : { + ASR::Class_t *c = ASR::down_cast(ttype); + std::string class_name = ASRUtils::symbol_name(c->m_class_type); + if (symbol_subs.find(class_name) != symbol_subs.end()) { + ASR::symbol_t *new_c = symbol_subs[class_name]; + return ASRUtils::TYPE(ASR::make_Class_t(al, ttype->base.loc, new_c)); + } + return ttype; + } + default : return ttype; + } + } +}; + +ASR::symbol_t* instantiate_symbol(Allocator &al, + SymbolTable *target_scope, + std::map type_subs, + std::map& symbol_subs, + std::string new_sym_name, ASR::symbol_t *sym) { + SymbolInstantiator t(al, target_scope, type_subs, symbol_subs, new_sym_name, sym); + return t.instantiate(); +} + +void instantiate_body(Allocator &al, + std::map type_subs, + std::map& symbol_subs, + ASR::symbol_t *new_sym, ASR::symbol_t *sym) { + BodyInstantiator t(al, type_subs, symbol_subs, new_sym, sym); + t.instantiate(); +} + +ASR::symbol_t* rename_symbol(Allocator &al, + std::map &type_subs, + SymbolTable *current_scope, + std::string new_sym_name, ASR::symbol_t *sym) { + SymbolRenamer t(al, type_subs, current_scope, new_sym_name); + return t.rename_symbol(sym); +} + +bool check_restriction(std::map type_subs, + std::map &symbol_subs, + ASR::Function_t *f, ASR::symbol_t *sym_arg, const Location &loc, + diag::Diagnostics &diagnostics, + const std::function semantic_abort, bool report=true) { + std::string f_name = f->m_name; + ASR::Function_t *arg = ASR::down_cast(ASRUtils::symbol_get_past_external(sym_arg)); + std::string arg_name = arg->m_name; + if (f->n_args != arg->n_args) { + if (report) { + std::string f_narg = std::to_string(f->n_args); + std::string arg_narg = std::to_string(arg->n_args); + diagnostics.add(diag::Diagnostic( + "Number of arguments mismatch, restriction expects a function with " + f_narg + + " parameters, but a function with " + arg_narg + " parameters is provided", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label(arg_name + " has " + arg_narg + " parameters", + {loc, arg->base.base.loc}), + diag::Label(f_name + " has " + f_narg + " parameters", + {f->base.base.loc}) + } + )); + semantic_abort(); + } + return false; + } + for (size_t i = 0; i < f->n_args; i++) { + ASR::ttype_t *f_param = ASRUtils::expr_type(f->m_args[i]); + ASR::ttype_t *arg_param = ASRUtils::expr_type(arg->m_args[i]); + if (!ASRUtils::types_equal_with_substitution(f_param, arg_param, type_subs)) { + if (report) { + std::string rtype = ASRUtils::type_to_str_with_substitution(f_param, type_subs); + std::string rvar = ASRUtils::symbol_name( + ASR::down_cast(f->m_args[i])->m_v); + std::string atype = ASRUtils::type_to_str(arg_param); + std::string avar = ASRUtils::symbol_name( + ASR::down_cast(arg->m_args[i])->m_v); + diagnostics.add(diag::Diagnostic( + "Restriction type mismatch with provided function argument", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label("", {loc}), + diag::Label("Restriction's parameter " + rvar + " of type " + rtype, + {f->m_args[i]->base.loc}), + diag::Label("Function's parameter " + avar + " of type " + atype, + {arg->m_args[i]->base.loc}) + } + )); + semantic_abort(); + } + return false; + } + } + if (f->m_return_var) { + if (!arg->m_return_var) { + if (report) { + std::string msg = "The restriction argument " + arg_name + + " should have a return value"; + diagnostics.add(diag::Diagnostic(msg, + diag::Level::Error, diag::Stage::Semantic, {diag::Label("", {loc})})); + semantic_abort(); + } + return false; + } + ASR::ttype_t *f_ret = ASRUtils::expr_type(f->m_return_var); + ASR::ttype_t *arg_ret = ASRUtils::expr_type(arg->m_return_var); + if (!ASRUtils::types_equal_with_substitution(f_ret, arg_ret, type_subs)) { + if (report) { + std::string rtype = ASRUtils::type_to_str_with_substitution(f_ret, type_subs); + std::string atype = ASRUtils::type_to_str(arg_ret); + diagnostics.add(diag::Diagnostic( + "Restriction type mismatch with provided function argument", + diag::Level::Error, diag::Stage::Semantic, { + diag::Label("", {loc}), + diag::Label("Requirement's return type " + rtype, + {f->m_return_var->base.loc}), + diag::Label("Function's return type " + atype, + {arg->m_return_var->base.loc}) + } + )); + semantic_abort(); + } + return false; + } + } else { + if (arg->m_return_var) { + if (report) { + std::string msg = "The restriction argument " + arg_name + + " should not have a return value"; + diagnostics.add(diag::Diagnostic(msg, + diag::Level::Error, diag::Stage::Semantic, {diag::Label("", {loc})})); + semantic_abort(); + } + return false; + } + } + symbol_subs[f_name] = sym_arg; + return true; +} + +} // namespace LFortran + } // namespace LCompilers diff --git a/src/libasr/pass/instantiate_template.h b/src/libasr/pass/instantiate_template.h index 253adc7de3..748f8a94e3 100644 --- a/src/libasr/pass/instantiate_template.h +++ b/src/libasr/pass/instantiate_template.h @@ -6,6 +6,8 @@ namespace LCompilers { +namespace LPython { + /** * @brief Instantiate a generic function into a function that does not * contain any type parameters and restrictions. No type checking @@ -39,6 +41,42 @@ namespace LCompilers { ASR::Function_t *f, ASR::symbol_t *sym_arg, const Location &loc, diag::Diagnostics &diagnostics); +} + +namespace LFortran { + + /** + * @brief Instantiate a generic function into a function that does not + * contain any type parameters and restrictions. No type checking + * is executed here + */ + ASR::symbol_t* instantiate_symbol(Allocator& al, + SymbolTable* target_scope, + std::map type_subs, + std::map& symbol_subs, + std::string new_sym_name, ASR::symbol_t* sym); + + + void instantiate_body(Allocator& al, + std::map type_subs, + std::map& symbol_subs, + ASR::symbol_t* new_sym, ASR::symbol_t* sym); + + + ASR::symbol_t* rename_symbol(Allocator &al, + std::map &type_subs, + SymbolTable *current_scope, + std::string new_sym_name, ASR::symbol_t *sym); + + + bool check_restriction(std::map type_subs, + std::map &symbol_subs, + ASR::Function_t *f, ASR::symbol_t *sym_arg, const Location &loc, + diag::Diagnostics &diagnostics, + const std::function semantic_abort, bool report=true); + +} + } // namespace LCompilers #endif // LIBASR_PASS_INSTANTIATE_TEMPLATE_H diff --git a/src/libasr/pass/intrinsic_array_function_registry.h b/src/libasr/pass/intrinsic_array_function_registry.h index 3c3bca0a6b..ca21031751 100644 --- a/src/libasr/pass/intrinsic_array_function_registry.h +++ b/src/libasr/pass/intrinsic_array_function_registry.h @@ -9,6 +9,7 @@ #include #include +#include #include namespace LCompilers { @@ -27,6 +28,11 @@ enum class IntrinsicArrayFunctions : int64_t { Product, Shape, Sum, + Transpose, + Pack, + Unpack, + Count, + DotProduct, // ... }; @@ -47,6 +53,11 @@ inline std::string get_array_intrinsic_name(int x) { ARRAY_INTRINSIC_NAME_CASE(Product) ARRAY_INTRINSIC_NAME_CASE(Shape) ARRAY_INTRINSIC_NAME_CASE(Sum) + ARRAY_INTRINSIC_NAME_CASE(Transpose) + ARRAY_INTRINSIC_NAME_CASE(Pack) + ARRAY_INTRINSIC_NAME_CASE(Unpack) + ARRAY_INTRINSIC_NAME_CASE(Count) + ARRAY_INTRINSIC_NAME_CASE(DotProduct) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); } @@ -64,6 +75,180 @@ typedef void (*verify_array_function)( const ASR::IntrinsicArrayFunction_t&, diag::Diagnostics&); +namespace Merge { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t& x, + diag::Diagnostics& diagnostics) { + const Location& loc = x.base.base.loc; + ASR::expr_t *tsource = x.m_args[0], *fsource = x.m_args[1], *mask = x.m_args[2]; + ASR::ttype_t *tsource_type = ASRUtils::expr_type(tsource); + ASR::ttype_t *fsource_type = ASRUtils::expr_type(fsource); + ASR::ttype_t *mask_type = ASRUtils::expr_type(mask); + int tsource_ndims, fsource_ndims; + ASR::dimension_t *tsource_mdims = nullptr, *fsource_mdims = nullptr; + tsource_ndims = ASRUtils::extract_dimensions_from_ttype(tsource_type, tsource_mdims); + fsource_ndims = ASRUtils::extract_dimensions_from_ttype(fsource_type, fsource_mdims); + if( tsource_ndims > 0 && fsource_ndims > 0 ) { + ASRUtils::require_impl(tsource_ndims == fsource_ndims, + "All arguments of `merge` should be of same rank and dimensions", loc, diagnostics); + + if( ASRUtils::extract_physical_type(tsource_type) == ASR::array_physical_typeType::FixedSizeArray && + ASRUtils::extract_physical_type(fsource_type) == ASR::array_physical_typeType::FixedSizeArray ) { + ASRUtils::require_impl(ASRUtils::get_fixed_size_of_array(tsource_mdims, tsource_ndims) == + ASRUtils::get_fixed_size_of_array(fsource_mdims, fsource_ndims), + "`tsource` and `fsource` arguments should have matching size", loc, diagnostics); + } + } + + ASRUtils::require_impl(ASRUtils::check_equal_type(tsource_type, fsource_type), + "`tsource` and `fsource` arguments to `merge` should be of same type, found " + + ASRUtils::get_type_code(tsource_type) + ", " + + ASRUtils::get_type_code(fsource_type), loc, diagnostics); + ASRUtils::require_impl(ASRUtils::is_logical(*mask_type), + "`mask` argument to `merge` should be of logical type, found " + + ASRUtils::get_type_code(mask_type), loc, diagnostics); + } + + static inline ASR::expr_t* eval_Merge( + Allocator &/*al*/, const Location &/*loc*/, ASR::ttype_t *, + Vec& args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(args.size() == 3); + ASR::expr_t *tsource = args[0], *fsource = args[1], *mask = args[2]; + if( ASRUtils::is_array(ASRUtils::expr_type(mask)) ) { + return nullptr; + } + + bool mask_value = false; + if( ASRUtils::is_value_constant(mask, mask_value) ) { + if( mask_value ) { + return tsource; + } else { + return fsource; + } + } + return nullptr; + } + + static inline ASR::asr_t* create_Merge(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if( args.size() != 3 ) { + append_error(diag, "`merge` intrinsic accepts 3 positional arguments, found " + + std::to_string(args.size()), loc); + return nullptr; + } + + ASR::expr_t *tsource = args[0], *fsource = args[1], *mask = args[2]; + ASR::ttype_t *tsource_type = ASRUtils::expr_type(tsource); + ASR::ttype_t *fsource_type = ASRUtils::expr_type(fsource); + ASR::ttype_t *mask_type = ASRUtils::expr_type(mask); + ASR::ttype_t* result_type = tsource_type; + int tsource_ndims, fsource_ndims, mask_ndims; + ASR::dimension_t *tsource_mdims = nullptr, *fsource_mdims = nullptr, *mask_mdims = nullptr; + tsource_ndims = ASRUtils::extract_dimensions_from_ttype(tsource_type, tsource_mdims); + fsource_ndims = ASRUtils::extract_dimensions_from_ttype(fsource_type, fsource_mdims); + mask_ndims = ASRUtils::extract_dimensions_from_ttype(mask_type, mask_mdims); + if( tsource_ndims > 0 && fsource_ndims > 0 ) { + if( tsource_ndims != fsource_ndims ) { + append_error(diag, "All arguments of `merge` should be of same rank and dimensions", loc); + return nullptr; + } + + if( ASRUtils::extract_physical_type(tsource_type) == ASR::array_physical_typeType::FixedSizeArray && + ASRUtils::extract_physical_type(fsource_type) == ASR::array_physical_typeType::FixedSizeArray && + ASRUtils::get_fixed_size_of_array(tsource_mdims, tsource_ndims) != + ASRUtils::get_fixed_size_of_array(fsource_mdims, fsource_ndims) ) { + append_error(diag, "`tsource` and `fsource` arguments should have matching size", loc); + return nullptr; + } + } else { + if( tsource_ndims > 0 && fsource_ndims == 0 ) { + result_type = tsource_type; + } else if( tsource_ndims == 0 && fsource_ndims > 0 ) { + result_type = fsource_type; + } else if( tsource_ndims == 0 && fsource_ndims == 0 && mask_ndims > 0 ) { + Vec mask_mdims_vec; + mask_mdims_vec.from_pointer_n(mask_mdims, mask_ndims); + result_type = ASRUtils::duplicate_type(al, tsource_type, &mask_mdims_vec, + ASRUtils::extract_physical_type(mask_type), true); + if( ASR::is_a(*mask_type) ) { + result_type = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, result_type)); + } + } + } + if( !ASRUtils::check_equal_type(tsource_type, fsource_type) ) { + append_error(diag, "`tsource` and `fsource` arguments to `merge` should be of same type, found " + + ASRUtils::get_type_code(tsource_type) + ", " + + ASRUtils::get_type_code(fsource_type), loc); + return nullptr; + } + if( !ASRUtils::is_logical(*mask_type) ) { + append_error(diag, "`mask` argument to `merge` should be of logical type, found " + + ASRUtils::get_type_code(mask_type), loc); + return nullptr; + } + + return ASR::make_IntrinsicArrayFunction_t(al, loc, + static_cast(ASRUtils::IntrinsicArrayFunctions::Merge), + args.p, args.size(), 0, result_type, nullptr); + } + + static inline ASR::expr_t* instantiate_Merge(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + LCOMPILERS_ASSERT(arg_types.size() == 3); + + // Array inputs should be elementalised in array_op pass already + LCOMPILERS_ASSERT( !ASRUtils::is_array(arg_types[2]) ); + ASR::ttype_t *tsource_type = ASRUtils::duplicate_type(al, arg_types[0]); + ASR::ttype_t *fsource_type = ASRUtils::duplicate_type(al, arg_types[1]); + ASR::ttype_t *mask_type = ASRUtils::duplicate_type(al, arg_types[2]); + if( ASR::is_a(*tsource_type) ) { + ASR::Character_t* tsource_char = ASR::down_cast(tsource_type); + ASR::Character_t* fsource_char = ASR::down_cast(fsource_type); + tsource_char->m_len_expr = nullptr; fsource_char->m_len_expr = nullptr; + tsource_char->m_len = -2; fsource_char->m_len = -2; + ASR::Character_t* return_char = ASR::down_cast( + ASRUtils::type_get_past_allocatable(return_type)); + return_char->m_len = -2; return_char->m_len_expr = nullptr; + + } + std::string new_name = "_lcompilers_merge_" + get_type_code(tsource_type); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); + } + + auto tsource_arg = declare("tsource", tsource_type, In); + args.push_back(al, tsource_arg); + auto fsource_arg = declare("fsource", fsource_type, In); + args.push_back(al, fsource_arg); + auto mask_arg = declare("mask", mask_type, In); + args.push_back(al, mask_arg); + // TODO: In case of Character type, set len of ReturnVar to len(tsource) expression + auto result = declare("merge", type_get_past_allocatable(return_type), ReturnVar); + + { + Vec if_body; if_body.reserve(al, 1); + if_body.push_back(al, b.Assignment(result, tsource_arg)); + Vec else_body; else_body.reserve(al, 1); + else_body.push_back(al, b.Assignment(result, fsource_arg)); + body.push_back(al, STMT(ASR::make_If_t(al, loc, mask_arg, + if_body.p, if_body.n, else_body.p, else_body.n))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type, nullptr); + } + +} // namespace Merge + namespace ArrIntrinsic { static inline void verify_array_int_real_cmplx(ASR::expr_t* array, ASR::ttype_t* return_type, @@ -189,13 +374,14 @@ static inline void verify_args(const ASR::IntrinsicArrayFunction_t& x, diag::Dia } static inline ASR::expr_t *eval_ArrIntrinsic(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/) { + const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { return nullptr; } static inline ASR::asr_t* create_ArrIntrinsic( Allocator& al, const Location& loc, Vec& args, - const std::function err, + diag::Diagnostics& diag, ASRUtils::IntrinsicArrayFunctions intrinsic_func_id) { std::string intrinsic_func_name = ASRUtils::get_array_intrinsic_name(static_cast(intrinsic_func_id)); int64_t id_array = 0, id_array_dim = 1, id_array_mask = 2; @@ -230,13 +416,15 @@ static inline ASR::asr_t* create_ArrIntrinsic( size_t arg3_rank = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(arg3)); if( arg2_rank != 0 ) { - err("dim argument to " + intrinsic_func_name + " must be a scalar and must not be an array", + append_error(diag, "dim argument to " + intrinsic_func_name + " must be a scalar and must not be an array", arg2->base.loc); + return nullptr; } if( arg3_rank == 0 ) { - err("mask argument to " + intrinsic_func_name + " must be an array and must not be a scalar", + append_error(diag, "mask argument to " + intrinsic_func_name + " must be an array and must not be a scalar", arg3->base.loc); + return nullptr; } overload_id = id_array_dim_mask; @@ -246,12 +434,14 @@ static inline ASR::asr_t* create_ArrIntrinsic( // if axis is available at compile time ASR::expr_t *value = nullptr; + bool runtime_dim = false; Vec arg_values; arg_values.reserve(al, 3); ASR::expr_t *array_value = ASRUtils::expr_value(array); arg_values.push_back(al, array_value); if( arg2 ) { ASR::expr_t *arg2_value = ASRUtils::expr_value(arg2); + runtime_dim = arg2_value == nullptr; arg_values.push_back(al, arg2_value); } if( arg3 ) { @@ -272,16 +462,22 @@ static inline ASR::asr_t* create_ArrIntrinsic( Vec dims; size_t n_dims = ASRUtils::extract_n_dims_from_ttype(array_type); dims.reserve(al, (int) n_dims - 1); - for( int i = 0; i < (int) n_dims - 1; i++ ) { + for( int it = 0; it < (int) n_dims - 1; it++ ) { + Vec args_merge; args_merge.reserve(al, 3); + ASRUtils::ASRBuilder b(al, loc); + args_merge.push_back(al, b.ArraySize(args[0], b.i32(it+1), int32)); + args_merge.push_back(al, b.ArraySize(args[0], b.i32(it+2), int32)); + args_merge.push_back(al, b.iLt(b.i32(it+1), args[1])); + ASR::expr_t* merge = EXPR(Merge::create_Merge(al, loc, args_merge, diag)); ASR::dimension_t dim; dim.loc = array->base.loc; - dim.m_length = nullptr; - dim.m_start = nullptr; + dim.m_start = b.i32(1); + dim.m_length = runtime_dim ? merge : nullptr; dims.push_back(al, dim); } - return_type = ASRUtils::duplicate_type(al, array_type, &dims); + return_type = ASRUtils::duplicate_type(al, array_type, &dims, ASR::array_physical_typeType::DescriptorArray, true); } - value = eval_ArrIntrinsic(al, loc, return_type, arg_values); + value = eval_ArrIntrinsic(al, loc, return_type, arg_values, diag); Vec arr_intrinsic_args; arr_intrinsic_args.reserve(al, 3); @@ -488,7 +684,26 @@ static inline ASR::expr_t* instantiate_ArrIntrinsic(Allocator &al, int result_dims = extract_n_dims_from_ttype(return_type); ASR::expr_t* return_var = nullptr; if( result_dims > 0 ) { - fill_func_arg("result", return_type) + ASR::ttype_t* return_type_ = return_type; + if( !ASRUtils::is_fixed_size_array(return_type) ) { + bool is_allocatable = ASRUtils::is_allocatable(return_type); + Vec empty_dims; + empty_dims.reserve(al, result_dims); + for( int idim = 0; idim < result_dims; idim++ ) { + ASR::dimension_t empty_dim; + empty_dim.loc = loc; + empty_dim.m_start = nullptr; + empty_dim.m_length = nullptr; + empty_dims.push_back(al, empty_dim); + } + return_type_ = ASRUtils::make_Array_t_util(al, loc, + ASRUtils::extract_type(return_type_), empty_dims.p, empty_dims.size()); + if( is_allocatable ) { + return_type_ = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, return_type_)); + } + } + ASR::expr_t *result = declare("result", return_type_, Out); + args.push_back(al, result); } else if( result_dims == 0 ) { return_var = declare("result", return_type, ReturnVar); } @@ -567,9 +782,9 @@ static inline ASR::expr_t *eval_MaxMinLoc(Allocator &al, const Location &loc, std::min_element(m_eles.begin(), m_eles.end())) + 1; } if (!is_array(type)) { - return i(index, type); + return b.i(index, type); } else { - return b.ArrayConstant({i32(index)}, extract_type(type), false); + return b.ArrayConstant({b.i32(index)}, extract_type(type), false); } } else { return nullptr; @@ -578,16 +793,20 @@ static inline ASR::expr_t *eval_MaxMinLoc(Allocator &al, const Location &loc, static inline ASR::asr_t* create_MaxMinLoc(Allocator& al, const Location& loc, Vec& args, int intrinsic_id, - const std::function err) { + diag::Diagnostics& diag) { std::string intrinsic_name = get_array_intrinsic_name(static_cast(intrinsic_id)); + ASRUtils::ASRBuilder b(al, loc); ASR::ttype_t *array_type = expr_type(args[0]); if ( !is_array(array_type) ) { - err("`array` argument of `"+ intrinsic_name +"` must be an array", loc); + append_error(diag, "`array` argument of `"+ intrinsic_name +"` must be an array", loc); + return nullptr; } else if ( !is_integer(*array_type) && !is_real(*array_type) ) { - err("`array` argument of `"+ intrinsic_name +"` must be integer or " + append_error(diag, "`array` argument of `"+ intrinsic_name +"` must be integer or " "real for now", loc); + return nullptr; } else if ( args[2] || args[4] ) { - err("`mask` and `back` keyword argument is not supported yet", loc); + append_error(diag, "`mask` and `back` keyword argument is not supported yet", loc); + return nullptr; } ASR::ttype_t *return_type = nullptr; Vec m_args; m_args.reserve(al, 1); @@ -598,18 +817,22 @@ static inline ASR::asr_t* create_MaxMinLoc(Allocator& al, const Location& loc, int dim = 0, kind = 4; // default kind if (args[3]) { if (!extract_value(expr_value(args[3]), kind)) { - err("Runtime value for `kind` argument is not supported yet", loc); + append_error(diag, "Runtime value for `kind` argument is not supported yet", loc); + return nullptr; } } if ( args[1] ) { if ( !ASR::is_a(*expr_type(args[1])) ) { - err("`dim` should be a scalar integer type", loc); + append_error(diag, "`dim` should be a scalar integer type", loc); + return nullptr; } else if (!extract_value(expr_value(args[1]), dim)) { - err("Runtime values for `dim` argument is not supported yet", loc); + append_error(diag, "Runtime values for `dim` argument is not supported yet", loc); + return nullptr; } if ( 1 > dim || dim > n_dims ) { - err("`dim` argument of `"+ intrinsic_name +"` is out of " + append_error(diag, "`dim` argument of `"+ intrinsic_name +"` is out of " "array index range", loc); + return nullptr; } if ( n_dims == 1 ) { return_type = TYPE(ASR::make_Integer_t(al, loc, kind)); // 1D @@ -629,8 +852,8 @@ static inline ASR::asr_t* create_MaxMinLoc(Allocator& al, const Location& loc, } else { ASR::dimension_t tmp_dim; tmp_dim.loc = args[0]->base.loc; - tmp_dim.m_start = i32(1); - tmp_dim.m_length = i32(n_dims); + tmp_dim.m_start = b.i32(1); + tmp_dim.m_length = b.i32(n_dims); result_dims.push_back(al, tmp_dim); } if ( !return_type ) { @@ -677,15 +900,15 @@ static inline ASR::expr_t *instantiate_MaxMinLoc(Allocator &al, b.generate_reduction_intrinsic_stmts_for_scalar_output( loc, args[0], fn_symtab, body, idx_vars, doloop_body, [=, &al, &body, &b] () { - body.push_back(al, b.Assignment(result, i(1, type))); + body.push_back(al, b.Assignment(result, b.i(1, type))); }, [=, &al, &b, &idx_vars, &doloop_body] () { std::vector if_body; if_body.reserve(n_dims); Vec result_idx; result_idx.reserve(al, n_dims); for (int i = 0; i < n_dims; i++) { - ASR::expr_t *idx = b.ArrayItem_01(result, {i32(i+1)}); + ASR::expr_t *idx = b.ArrayItem_01(result, {b.i32(i+1)}); if (extract_kind_from_ttype_t(type) != 4) { - if_body.push_back(b.Assignment(idx, i2i(idx_vars[i], type))); - result_idx.push_back(al, i2i32(idx)); + if_body.push_back(b.Assignment(idx, b.i2i(idx_vars[i], type))); + result_idx.push_back(al, b.i2i32(idx)); } else { if_body.push_back(b.Assignment(idx, idx_vars[i])); result_idx.push_back(al, idx); @@ -708,14 +931,14 @@ static inline ASR::expr_t *instantiate_MaxMinLoc(Allocator &al, loc, args[0], args[1], fn_symtab, body, idx_vars, target_idx_vars, doloop_body, [=, &al, &body, &b] () { - body.push_back(al, b.Assignment(result, i(1, type))); + body.push_back(al, b.Assignment(result, b.i(1, type))); }, [=, &al, &b, &idx_vars, &target_idx_vars, &doloop_body] () { ASR::expr_t *result_ref, *array_ref_02; if (is_array(return_type)) { result_ref = ArrayItem_02(result, target_idx_vars); Vec tmp_idx_vars; tmp_idx_vars.from_pointer_n_copy(al, idx_vars.p, idx_vars.n); - tmp_idx_vars.p[dim - 1] = i2i32(result_ref); + tmp_idx_vars.p[dim - 1] = b.i2i32(result_ref); array_ref_02 = ArrayItem_02(args[0], tmp_idx_vars); } else { // 1D scalar output @@ -725,7 +948,7 @@ static inline ASR::expr_t *instantiate_MaxMinLoc(Allocator &al, ASR::expr_t *array_ref_01 = ArrayItem_02(args[0], idx_vars); ASR::expr_t *res_idx = idx_vars.p[dim - 1]; if (extract_kind_from_ttype_t(type) != 4) { - res_idx = i2i(res_idx, type); + res_idx = b.i2i(res_idx, type); } if (static_cast(IntrinsicArrayFunctions::MaxLoc) == intrinsic_id) { doloop_body.push_back(al, b.If(b.Gt(array_ref_01, array_ref_02), { @@ -750,60 +973,71 @@ static inline ASR::expr_t *instantiate_MaxMinLoc(Allocator &al, namespace Shape { static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, diag::Diagnostics &diagnostics) { - ASRUtils::require_impl(x.n_args == 1 || x.n_args == 2, - "`shape` intrinsic accepts either 1 or 2 arguments", + ASRUtils::require_impl(x.n_args == 1, + "`shape` intrinsic accepts 1 argument", x.base.base.loc, diagnostics); ASRUtils::require_impl(x.m_args[0], "`source` argument of `shape` " "cannot be nullptr", x.base.base.loc, diagnostics); - ASRUtils::require_impl(x.m_args[1], "`kind` argument of `shape` " - "cannot be nullptr", x.base.base.loc, diagnostics); } static ASR::expr_t *eval_Shape(Allocator &al, const Location &loc, - ASR::ttype_t *type, Vec &args) { + ASR::ttype_t *type, Vec &args, diag::Diagnostics& /*diag*/) { ASR::dimension_t *m_dims; size_t n_dims = extract_dimensions_from_ttype(expr_type(args[0]), m_dims); Vec m_shapes; m_shapes.reserve(al, n_dims); - for (size_t i = 0; i < n_dims; i++) { - if (m_dims[i].m_length) { - ASR::expr_t *e = nullptr; - if (extract_kind_from_ttype_t(type) != 4) { - e = i2i(m_dims[i].m_length, extract_type(type)); - } else { - e = m_dims[i].m_length; + if( n_dims == 0 ){ + return EXPR(ASR::make_ArrayConstant_t(al, loc, m_shapes.p, 0, + type, ASR::arraystorageType::ColMajor)); + } else { + for (size_t i = 0; i < n_dims; i++) { + if (m_dims[i].m_length) { + ASR::expr_t *e = nullptr; + if (extract_kind_from_ttype_t(type) != 4) { + ASRUtils::ASRBuilder b(al, loc); + e = b.i2i(m_dims[i].m_length, extract_type(type)); + } else { + e = m_dims[i].m_length; + } + m_shapes.push_back(al, e); } - m_shapes.push_back(al, e); } } ASR::expr_t *value = nullptr; + bool all_args_evaluated_ = all_args_evaluated(m_shapes); if (m_shapes.n > 0) { - value = EXPR(ASR::make_ArrayConstant_t(al, loc, m_shapes.p, m_shapes.n, - type, ASR::arraystorageType::ColMajor)); + if (all_args_evaluated_) { + value = EXPR(ASR::make_ArrayConstant_t(al, loc, m_shapes.p, m_shapes.n, + type, ASR::arraystorageType::ColMajor)); + } else { + value = EXPR(ASR::make_ArrayConstructor_t(al, loc, m_shapes.p, m_shapes.n, + type, nullptr, ASR::arraystorageType::ColMajor)); + } } return value; } static inline ASR::asr_t* create_Shape(Allocator& al, const Location& loc, Vec& args, - const std::function err) { + diag::Diagnostics& diag) { ASRBuilder b(al, loc); Vecm_args; m_args.reserve(al, 1); m_args.push_back(al, args[0]); int kind = 4; // default kind if (args[1]) { if (!ASR::is_a(*expr_type(args[1]))) { - err("`kind` argument of `shape` must be a scalar integer", loc); + append_error(diag, "`kind` argument of `shape` must be a scalar integer", loc); + return nullptr; } if (!extract_value(args[1], kind)) { - err("Only constant value for `kind` is supported for now", loc); + append_error(diag, "Only constant value for `kind` is supported for now", loc); + return nullptr; } } // TODO: throw error for assumed size array int n_dims = extract_n_dims_from_ttype(expr_type(args[0])); ASR::ttype_t *return_type = b.Array({n_dims}, TYPE(ASR::make_Integer_t(al, loc, kind))); - ASR::expr_t *m_value = eval_Shape(al, loc, return_type, args); - + ASR::expr_t *m_value = eval_Shape(al, loc, return_type, args, diag); return ASRUtils::make_IntrinsicArrayFunction_t_util(al, loc, static_cast(ASRUtils::IntrinsicArrayFunctions::Shape), m_args.p, m_args.n, 0, return_type, m_value); @@ -818,14 +1052,13 @@ namespace Shape { auto result = declare(fn_name, return_type, ReturnVar); int iter = extract_n_dims_from_ttype(arg_types[0]) + 1; auto i = declare("i", int32, Local); - body.push_back(al, b.Assignment(i, i32(1))); - body.push_back(al, b.While(iLt(i, i32(iter)), { + body.push_back(al, b.Assignment(i, b.i32(1))); + body.push_back(al, b.While(b.iLt(i, b.i32(iter)), { b.Assignment(b.ArrayItem_01(result, {i}), - ArraySize_2(args[0], i, extract_type(return_type))), - b.Assignment(i, iAdd(i, i32(1))) + b.ArraySize_2(args[0], i, extract_type(return_type))), + b.Assignment(i, b.iAdd(i, b.i32(1))) })); body.push_back(al, Return()); - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); scope->add_symbol(fn_name, f_sym); @@ -900,13 +1133,14 @@ namespace Any { } static inline ASR::expr_t *eval_Any(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/) { + const Location & /*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { return nullptr; } static inline ASR::asr_t* create_Any( Allocator& al, const Location& loc, Vec& args, - const std::function err) { + diag::Diagnostics& diag) { int64_t overload_id = 0; Vec any_args; any_args.reserve(al, 2); @@ -917,8 +1151,9 @@ namespace Any { axis = args[1]; } if( ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(array)) == 0 ) { - err("mask argument to any must be an array and must not be a scalar", + append_error(diag, "mask argument to any must be an array and must not be a scalar", array->base.loc); + return nullptr; } // TODO: Add a check for range of values axis can take @@ -958,7 +1193,7 @@ namespace Any { logical_return_type = ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)); } } - value = eval_Any(al, loc, logical_return_type, arg_values); + value = eval_Any(al, loc, logical_return_type, arg_values, diag); any_args.push_back(al, array); if( axis ) { @@ -986,7 +1221,7 @@ namespace Any { }, [=, &al, &idx_vars, &doloop_body, &builder] () { ASR::expr_t* array_ref = PassUtils::create_array_ref(array, idx_vars, al); - ASR::expr_t* logical_or = builder.Or(return_var, array_ref, loc); + ASR::expr_t* logical_or = builder.LogicalOr(return_var, array_ref, loc); ASR::stmt_t* loop_invariant = builder.Assignment(return_var, logical_or); doloop_body.push_back(al, loop_invariant); } @@ -1123,14 +1358,15 @@ namespace Sum { } static inline ASR::expr_t *eval_Sum(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/) { + const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { return nullptr; } static inline ASR::asr_t* create_Sum(Allocator& al, const Location& loc, Vec& args, - const std::function err) { - return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, err, + diag::Diagnostics& diag) { + return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, diag, IntrinsicArrayFunctions::Sum); } @@ -1154,14 +1390,15 @@ namespace Product { } static inline ASR::expr_t *eval_Product(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/) { + const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { return nullptr; } static inline ASR::asr_t* create_Product(Allocator& al, const Location& loc, Vec& args, - const std::function err) { - return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, err, + diag::Diagnostics& diag) { + return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, diag, IntrinsicArrayFunctions::Product); } @@ -1185,14 +1422,15 @@ namespace MaxVal { } static inline ASR::expr_t *eval_MaxVal(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/) { + const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { return nullptr; } static inline ASR::asr_t* create_MaxVal(Allocator& al, const Location& loc, Vec& args, - const std::function err) { - return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, err, + diag::Diagnostics& diag) { + return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, diag, IntrinsicArrayFunctions::MaxVal); } @@ -1216,9 +1454,9 @@ namespace MaxLoc { static inline ASR::asr_t* create_MaxLoc(Allocator& al, const Location& loc, Vec& args, - const std::function err) { + diag::Diagnostics& diag) { return ArrIntrinsic::create_MaxMinLoc(al, loc, args, - static_cast(IntrinsicArrayFunctions::MaxLoc), err); + static_cast(IntrinsicArrayFunctions::MaxLoc), diag); } static inline ASR::expr_t *instantiate_MaxLoc(Allocator &al, @@ -1232,201 +1470,37 @@ namespace MaxLoc { } // namespace MaxLoc -namespace Merge { +namespace MinVal { static inline void verify_args(const ASR::IntrinsicArrayFunction_t& x, diag::Diagnostics& diagnostics) { - const Location& loc = x.base.base.loc; - ASR::expr_t *tsource = x.m_args[0], *fsource = x.m_args[1], *mask = x.m_args[2]; - ASR::ttype_t *tsource_type = ASRUtils::expr_type(tsource); - ASR::ttype_t *fsource_type = ASRUtils::expr_type(fsource); - ASR::ttype_t *mask_type = ASRUtils::expr_type(mask); - int tsource_ndims, fsource_ndims; - ASR::dimension_t *tsource_mdims = nullptr, *fsource_mdims = nullptr; - tsource_ndims = ASRUtils::extract_dimensions_from_ttype(tsource_type, tsource_mdims); - fsource_ndims = ASRUtils::extract_dimensions_from_ttype(fsource_type, fsource_mdims); - if( tsource_ndims > 0 && fsource_ndims > 0 ) { - ASRUtils::require_impl(tsource_ndims == fsource_ndims, - "All arguments of `merge` should be of same rank and dimensions", loc, diagnostics); - - if( ASRUtils::extract_physical_type(tsource_type) == ASR::array_physical_typeType::FixedSizeArray && - ASRUtils::extract_physical_type(fsource_type) == ASR::array_physical_typeType::FixedSizeArray ) { - ASRUtils::require_impl(ASRUtils::get_fixed_size_of_array(tsource_mdims, tsource_ndims) == - ASRUtils::get_fixed_size_of_array(fsource_mdims, fsource_ndims), - "`tsource` and `fsource` arguments should have matching size", loc, diagnostics); - } - } + ArrIntrinsic::verify_args(x, diagnostics, IntrinsicArrayFunctions::MinVal, + &ArrIntrinsic::verify_array_int_real); + } - ASRUtils::require_impl(ASRUtils::check_equal_type(tsource_type, fsource_type), - "`tsource` and `fsource` arguments to `merge` should be of same type, found " + - ASRUtils::get_type_code(tsource_type) + ", " + - ASRUtils::get_type_code(fsource_type), loc, diagnostics); - ASRUtils::require_impl(ASRUtils::is_logical(*mask_type), - "`mask` argument to `merge` should be of logical type, found " + - ASRUtils::get_type_code(mask_type), loc, diagnostics); + static inline ASR::expr_t *eval_MinVal(Allocator & /*al*/, + const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/, + diag::Diagnostics& /*diag*/) { + return nullptr; } - static inline ASR::expr_t* eval_Merge( - Allocator &/*al*/, const Location &/*loc*/, ASR::ttype_t *, - Vec& args) { - LCOMPILERS_ASSERT(args.size() == 3); - ASR::expr_t *tsource = args[0], *fsource = args[1], *mask = args[2]; - if( ASRUtils::is_array(ASRUtils::expr_type(mask)) ) { - return nullptr; - } + static inline ASR::asr_t* create_MinVal(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, diag, + IntrinsicArrayFunctions::MinVal); + } - bool mask_value = false; - if( ASRUtils::is_value_constant(mask, mask_value) ) { - if( mask_value ) { - return tsource; - } else { - return fsource; - } - } - return nullptr; + static inline ASR::expr_t* instantiate_MinVal(Allocator &al, + const Location &loc, SymbolTable *scope, Vec& arg_types, + ASR::ttype_t *return_type, Vec& new_args, + int64_t overload_id) { + return ArrIntrinsic::instantiate_ArrIntrinsic(al, loc, scope, arg_types, + return_type, new_args, overload_id, IntrinsicArrayFunctions::MinVal, + &get_maximum_value_with_given_type, &ASRBuilder::ElementalMin); } - static inline ASR::asr_t* create_Merge(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if( args.size() != 3 ) { - err("`merge` intrinsic accepts 3 positional arguments, found " + - std::to_string(args.size()), loc); - } - - ASR::expr_t *tsource = args[0], *fsource = args[1], *mask = args[2]; - ASR::ttype_t *tsource_type = ASRUtils::expr_type(tsource); - ASR::ttype_t *fsource_type = ASRUtils::expr_type(fsource); - ASR::ttype_t *mask_type = ASRUtils::expr_type(mask); - ASR::ttype_t* result_type = tsource_type; - int tsource_ndims, fsource_ndims, mask_ndims; - ASR::dimension_t *tsource_mdims = nullptr, *fsource_mdims = nullptr, *mask_mdims = nullptr; - tsource_ndims = ASRUtils::extract_dimensions_from_ttype(tsource_type, tsource_mdims); - fsource_ndims = ASRUtils::extract_dimensions_from_ttype(fsource_type, fsource_mdims); - mask_ndims = ASRUtils::extract_dimensions_from_ttype(mask_type, mask_mdims); - if( tsource_ndims > 0 && fsource_ndims > 0 ) { - if( tsource_ndims != fsource_ndims ) { - err("All arguments of `merge` should be of same rank and dimensions", loc); - } - - if( ASRUtils::extract_physical_type(tsource_type) == ASR::array_physical_typeType::FixedSizeArray && - ASRUtils::extract_physical_type(fsource_type) == ASR::array_physical_typeType::FixedSizeArray && - ASRUtils::get_fixed_size_of_array(tsource_mdims, tsource_ndims) != - ASRUtils::get_fixed_size_of_array(fsource_mdims, fsource_ndims) ) { - err("`tsource` and `fsource` arguments should have matching size", loc); - } - } else { - if( tsource_ndims > 0 && fsource_ndims == 0 ) { - result_type = tsource_type; - } else if( tsource_ndims == 0 && fsource_ndims > 0 ) { - result_type = fsource_type; - } else if( tsource_ndims == 0 && fsource_ndims == 0 && mask_ndims > 0 ) { - Vec mask_mdims_vec; - mask_mdims_vec.from_pointer_n(mask_mdims, mask_ndims); - result_type = ASRUtils::duplicate_type(al, tsource_type, &mask_mdims_vec, - ASRUtils::extract_physical_type(mask_type), true); - if( ASR::is_a(*mask_type) ) { - result_type = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, result_type)); - } - } - } - if( !ASRUtils::check_equal_type(tsource_type, fsource_type) ) { - err("`tsource` and `fsource` arguments to `merge` should be of same type, found " + - ASRUtils::get_type_code(tsource_type) + ", " + - ASRUtils::get_type_code(fsource_type), loc); - } - if( !ASRUtils::is_logical(*mask_type) ) { - err("`mask` argument to `merge` should be of logical type, found " + - ASRUtils::get_type_code(mask_type), loc); - } - - return ASR::make_IntrinsicArrayFunction_t(al, loc, - static_cast(ASRUtils::IntrinsicArrayFunctions::Merge), - args.p, args.size(), 0, result_type, nullptr); - } - - static inline ASR::expr_t* instantiate_Merge(Allocator &al, - const Location &loc, SymbolTable *scope, - Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - LCOMPILERS_ASSERT(arg_types.size() == 3); - - // Array inputs should be elementalised in array_op pass already - LCOMPILERS_ASSERT( !ASRUtils::is_array(arg_types[2]) ); - ASR::ttype_t *tsource_type = ASRUtils::duplicate_type(al, arg_types[0]); - ASR::ttype_t *fsource_type = ASRUtils::duplicate_type(al, arg_types[1]); - ASR::ttype_t *mask_type = ASRUtils::duplicate_type(al, arg_types[2]); - if( ASR::is_a(*tsource_type) ) { - ASR::Character_t* tsource_char = ASR::down_cast(tsource_type); - ASR::Character_t* fsource_char = ASR::down_cast(fsource_type); - tsource_char->m_len_expr = nullptr; fsource_char->m_len_expr = nullptr; - tsource_char->m_len = -2; fsource_char->m_len = -2; - } - std::string new_name = "_lcompilers_merge_" + get_type_code(tsource_type); - - declare_basic_variables(new_name); - if (scope->get_symbol(new_name)) { - ASR::symbol_t *s = scope->get_symbol(new_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - - auto tsource_arg = declare("tsource", tsource_type, In); - args.push_back(al, tsource_arg); - auto fsource_arg = declare("fsource", fsource_type, In); - args.push_back(al, fsource_arg); - auto mask_arg = declare("mask", mask_type, In); - args.push_back(al, mask_arg); - // TODO: In case of Character type, set len of ReturnVar to len(tsource) expression - auto result = declare("merge", type_get_past_allocatable(return_type), ReturnVar); - - { - Vec if_body; if_body.reserve(al, 1); - if_body.push_back(al, b.Assignment(result, tsource_arg)); - Vec else_body; else_body.reserve(al, 1); - else_body.push_back(al, b.Assignment(result, fsource_arg)); - body.push_back(al, STMT(ASR::make_If_t(al, loc, mask_arg, - if_body.p, if_body.n, else_body.p, else_body.n))); - } - - ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, new_symbol); - return b.Call(new_symbol, new_args, return_type, nullptr); - } - -} // namespace Merge - -namespace MinVal { - - static inline void verify_args(const ASR::IntrinsicArrayFunction_t& x, - diag::Diagnostics& diagnostics) { - ArrIntrinsic::verify_args(x, diagnostics, IntrinsicArrayFunctions::MinVal, - &ArrIntrinsic::verify_array_int_real); - } - - static inline ASR::expr_t *eval_MinVal(Allocator & /*al*/, - const Location & /*loc*/, ASR::ttype_t *, Vec& /*args*/) { - return nullptr; - } - - static inline ASR::asr_t* create_MinVal(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - return ArrIntrinsic::create_ArrIntrinsic(al, loc, args, err, - IntrinsicArrayFunctions::MinVal); - } - - static inline ASR::expr_t* instantiate_MinVal(Allocator &al, - const Location &loc, SymbolTable *scope, Vec& arg_types, - ASR::ttype_t *return_type, Vec& new_args, - int64_t overload_id) { - return ArrIntrinsic::instantiate_ArrIntrinsic(al, loc, scope, arg_types, - return_type, new_args, overload_id, IntrinsicArrayFunctions::MinVal, - &get_maximum_value_with_given_type, &ASRBuilder::ElementalMin); - } - -} // namespace MinVal +} // namespace MinVal namespace MinLoc { @@ -1437,9 +1511,9 @@ namespace MinLoc { static inline ASR::asr_t* create_MinLoc(Allocator& al, const Location& loc, Vec& args, - const std::function err) { + diag::Diagnostics& diag) { return ArrIntrinsic::create_MaxMinLoc(al, loc, args, - static_cast(IntrinsicArrayFunctions::MinLoc), err); + static_cast(IntrinsicArrayFunctions::MinLoc), diag); } static inline ASR::expr_t *instantiate_MinLoc(Allocator &al, @@ -1466,14 +1540,14 @@ namespace MatMul { } static inline ASR::expr_t *eval_MatMul(Allocator &, - const Location &, ASR::ttype_t *, Vec&) { + const Location &, ASR::ttype_t *, Vec&, diag::Diagnostics&) { // TODO return nullptr; } static inline ASR::asr_t* create_MatMul(Allocator& al, const Location& loc, Vec& args, - const std::function err) { + diag::Diagnostics& diag) { ASR::expr_t *matrix_a = args[0], *matrix_b = args[1]; bool is_type_allocatable = false; if (ASRUtils::is_allocatable(matrix_a) || ASRUtils::is_allocatable(matrix_b)) { @@ -1492,37 +1566,41 @@ namespace MatMul { is_real(*type_b) || is_complex(*type_b); bool matrix_b_logical = is_logical(*type_b); - if (is_complex(*type_a) || is_complex(*type_b) || - matrix_a_logical || matrix_b_logical) { + if (matrix_a_logical || matrix_b_logical) { // TODO - err("The `matmul` intrinsic doesn't handle logical or " - "complex type yet", loc); + append_error(diag, "The `matmul` intrinsic doesn't handle logical type yet", loc); + return nullptr; } if ( !matrix_a_numeric && !matrix_a_logical ) { - err("The argument `matrix_a` in `matmul` must be of type Integer, " + append_error(diag, "The argument `matrix_a` in `matmul` must be of type Integer, " "Real, Complex or Logical", matrix_a->base.loc); + return nullptr; } else if ( matrix_a_numeric ) { if( !matrix_b_numeric ) { - err("The argument `matrix_b` in `matmul` must be of type " + append_error(diag, "The argument `matrix_b` in `matmul` must be of type " "Integer, Real or Complex if first matrix is of numeric " "type", matrix_b->base.loc); + return nullptr; } } else { if( !matrix_b_logical ) { - err("The argument `matrix_b` in `matmul` must be of type Logical" + append_error(diag, "The argument `matrix_b` in `matmul` must be of type Logical" " if first matrix is of Logical type", matrix_b->base.loc); + return nullptr; } } if ( matrix_a_numeric || matrix_b_numeric ) { - if ( is_real(*type_a) ) { + if ( is_complex(*type_a) ) { + ret_type = extract_type(type_a); + } else if ( is_complex(*type_b) ) { + ret_type = extract_type(type_b); + } else if ( is_real(*type_a) ) { ret_type = extract_type(type_a); } else if ( is_real(*type_b) ) { ret_type = extract_type(type_b); } else { ret_type = extract_type(type_a); } - // TODO: Handle return_type for following types - LCOMPILERS_ASSERT(!is_complex(*type_a) && !is_complex(*type_b)) } LCOMPILERS_ASSERT(!matrix_a_logical && !matrix_b_logical) ASR::dimension_t* matrix_a_dims = nullptr; @@ -1530,11 +1608,13 @@ namespace MatMul { int matrix_a_rank = extract_dimensions_from_ttype(type_a, matrix_a_dims); int matrix_b_rank = extract_dimensions_from_ttype(type_b, matrix_b_dims); if ( matrix_a_rank != 1 && matrix_a_rank != 2 ) { - err("`matmul` accepts arrays of rank 1 or 2 only, provided an array " + append_error(diag, "`matmul` accepts arrays of rank 1 or 2 only, provided an array " "with rank, " + std::to_string(matrix_a_rank), matrix_a->base.loc); + return nullptr; } else if ( matrix_b_rank != 1 && matrix_b_rank != 2 ) { - err("`matmul` accepts arrays of rank 1 or 2 only, provided an array " + append_error(diag, "`matmul` accepts arrays of rank 1 or 2 only, provided an array " "with rank, " + std::to_string(matrix_b_rank), matrix_b->base.loc); + return nullptr; } ASRBuilder b(al, loc); @@ -1547,10 +1627,11 @@ namespace MatMul { int matrix_a_dim_1 = -1, matrix_b_dim_1 = -1; extract_value(matrix_a_dims[0].m_length, matrix_a_dim_1); extract_value(matrix_b_dims[0].m_length, matrix_b_dim_1); - err("The argument `matrix_b` must be of dimension " + append_error(diag, "The argument `matrix_b` must be of dimension " + std::to_string(matrix_a_dim_1) + ", provided an array " "with dimension " + std::to_string(matrix_b_dim_1) + " in `matrix_b('n', m)`", matrix_b->base.loc); + return nullptr; } else { result_dims.push_back(al, b.set_dim(matrix_b_dims[1].m_start, matrix_b_dims[1].m_length)); @@ -1564,10 +1645,11 @@ namespace MatMul { extract_value(matrix_b_dims[0].m_length, matrix_b_dim_1); std::string err_dims = "('n', m)"; if (matrix_b_rank == 1) err_dims = "('n')"; - err("The argument `matrix_b` must be of dimension " + append_error(diag, "The argument `matrix_b` must be of dimension " + std::to_string(matrix_a_dim_2) + ", provided an array " "with dimension " + std::to_string(matrix_b_dim_1) + " in matrix_b" + err_dims, matrix_b->base.loc); + return nullptr; } result_dims.push_back(al, b.set_dim(matrix_a_dims[0].m_start, matrix_a_dims[0].m_length)); @@ -1577,15 +1659,16 @@ namespace MatMul { matrix_b_dims[1].m_length)); } } else { - err("The argument `matrix_b` in `matmul` must be of rank 2, " + append_error(diag, "The argument `matrix_b` in `matmul` must be of rank 2, " "provided an array with rank, " + std::to_string(matrix_b_rank), matrix_b->base.loc); + return nullptr; } ret_type = ASRUtils::duplicate_type(al, ret_type, &result_dims); if (is_type_allocatable) { ret_type = TYPE(ASR::make_Allocatable_t(al, loc, ret_type)); } - ASR::expr_t *value = eval_MatMul(al, loc, ret_type, args); + ASR::expr_t *value = eval_MatMul(al, loc, ret_type, args, diag); return make_IntrinsicArrayFunction_t_util(al, loc, static_cast(IntrinsicArrayFunctions::MatMul), args.p, args.n, overload_id, ret_type, value); @@ -1603,9 +1686,31 @@ namespace MatMul { * [ 3, 4 ] â–¼ */ declare_basic_variables("_lcompilers_matmul"); - fill_func_arg("matrix_a", duplicate_type_with_empty_dims(al, arg_types[0])); - fill_func_arg("matrix_b", duplicate_type_with_empty_dims(al, arg_types[1])); - ASR::expr_t *result = declare("result", return_type, Out); + fill_func_arg("matrix_a_m", duplicate_type_with_empty_dims(al, arg_types[0])); + fill_func_arg("matrix_b_m", duplicate_type_with_empty_dims(al, arg_types[1])); + ASR::ttype_t* return_type_ = return_type; + if( !ASRUtils::is_fixed_size_array(return_type) ) { + bool is_allocatable = ASRUtils::is_allocatable(return_type); + Vec empty_dims; + int result_dims = 2; + if( overload_id == 1 || overload_id == 2 ) { + result_dims = 1; + } + empty_dims.reserve(al, result_dims); + for( int idim = 0; idim < result_dims; idim++ ) { + ASR::dimension_t empty_dim; + empty_dim.loc = loc; + empty_dim.m_start = nullptr; + empty_dim.m_length = nullptr; + empty_dims.push_back(al, empty_dim); + } + return_type_ = ASRUtils::make_Array_t_util(al, loc, + ASRUtils::extract_type(return_type_), empty_dims.p, empty_dims.size()); + if( is_allocatable ) { + return_type_ = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, return_type_)); + } + } + ASR::expr_t *result = declare("result", return_type_, Out); args.push_back(al, result); ASR::expr_t *i = declare("i", int32, Local); ASR::expr_t *j = declare("j", int32, Local); @@ -1616,7 +1721,7 @@ namespace MatMul { extract_dimensions_from_ttype(arg_types[1], matrix_b_dims); ASR::expr_t *res_ref, *a_ref, *b_ref, *a_lbound, *b_lbound; ASR::expr_t *dim_mismatch_check, *a_ubound, *b_ubound; - dim_mismatch_check = iEq(UBound(args[0], 2), UBound(args[1], 1)); + dim_mismatch_check = b.iEq(UBound(args[0], 2), UBound(args[1], 1)); a_lbound = LBound(args[0], 1); a_ubound = UBound(args[0], 1); b_lbound = LBound(args[1], 2); b_ubound = UBound(args[1], 2); std::string assert_msg = "'MatMul' intrinsic dimension mismatch: " @@ -1629,7 +1734,7 @@ namespace MatMul { b_ref = b.ArrayItem_01(args[1], {k, j}); a_ubound = a_lbound; alloc_dims.push_back(al, b.set_dim(LBound(args[1], 2), UBound(args[1], 2))); - dim_mismatch_check = iEq(UBound(args[0], 1), UBound(args[1], 1)); + dim_mismatch_check = b.iEq(UBound(args[0], 1), UBound(args[1], 1)); assert_msg += "`matrix_a(k)` and `matrix_b(k, j)`"; } else if ( overload_id == 2 ) { // r(i) = r(i) + a(i, k) * b(k) @@ -1656,9 +1761,21 @@ namespace MatMul { character(assert_msg.size())))))); ASR::expr_t *mul_value; if (is_real(*expr_type(a_ref)) && is_integer(*expr_type(b_ref))) { - mul_value = b.Mul(a_ref, i2r(b_ref, expr_type(a_ref))); + mul_value = b.Mul(a_ref, b.i2r(b_ref, expr_type(a_ref))); } else if (is_real(*expr_type(b_ref)) && is_integer(*expr_type(a_ref))) { - mul_value = b.Mul(i2r(a_ref, expr_type(b_ref)), b_ref); + mul_value = b.Mul(b.i2r(a_ref, expr_type(b_ref)), b_ref); + } else if (is_real(*expr_type(a_ref)) && is_complex(*expr_type(b_ref))){ + mul_value = b.Mul(EXPR(ASR::make_ComplexConstructor_t(al, loc, a_ref, b.f(0, expr_type(a_ref)), expr_type(b_ref), nullptr)), b_ref); + } else if (is_complex(*expr_type(a_ref)) && is_real(*expr_type(b_ref))){ + mul_value = b.Mul(a_ref, EXPR(ASR::make_ComplexConstructor_t(al, loc, b_ref, b.f(0, expr_type(b_ref)), expr_type(a_ref), nullptr))); + } else if (is_integer(*expr_type(a_ref)) && is_complex(*expr_type(b_ref))) { + int kind = ASRUtils::extract_kind_from_ttype_t(expr_type(b_ref)); + ASR::ttype_t* real_type = TYPE(ASR::make_Real_t(al, loc, kind)); + mul_value = b.Mul(EXPR(ASR::make_ComplexConstructor_t(al, loc, b.i2r(a_ref, real_type), b.f(0, real_type), expr_type(b_ref), nullptr)), b_ref); + } else if (is_complex(*expr_type(a_ref)) && is_integer(*expr_type(b_ref))) { + int kind = ASRUtils::extract_kind_from_ttype_t(expr_type(a_ref)); + ASR::ttype_t* real_type = TYPE(ASR::make_Real_t(al, loc, kind)); + mul_value = b.Mul(a_ref, EXPR(ASR::make_ComplexConstructor_t(al, loc, b.i2r(b_ref, real_type), b.f(0, real_type), expr_type(a_ref), nullptr))); } else { mul_value = b.Mul(a_ref, b_ref); } @@ -1679,6 +1796,1261 @@ namespace MatMul { } // namespace MatMul +namespace Count { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, + diag::Diagnostics& diagnostics) { + require_impl(x.n_args == 1 || x.n_args == 2 || x.n_args == 3, "`count` intrinsic accepts " + "one, two or three arguments", x.base.base.loc, diagnostics); + require_impl(x.m_args[0], "`mask` argument of `count` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + } + + static inline ASR::expr_t *eval_Count(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t */*return_type*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO + return nullptr; + } + + static inline ASR::asr_t* create_Count(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + int64_t id_mask = 0, id_mask_dim = 1; + int64_t overload_id = id_mask; + + ASR::expr_t *mask = args[0], *dim_ = nullptr, *kind = nullptr; + + if (args.size() == 2) { + dim_ = args[1]; + } else if (args.size() == 3) { + dim_ = args[1]; + kind = args[2]; + } + + ASR::ttype_t* mask_type = ASRUtils::expr_type(mask); + if ( dim_ != nullptr ) { + size_t dim_rank = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(dim_)); + if (dim_rank != 0) { + append_error(diag, "dim argument to count must be a scalar and must not be an array", + dim_->base.loc); + return nullptr; + } + + overload_id = id_mask_dim; + } + if ( kind != nullptr) { + size_t kind_rank = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(kind)); + if (kind_rank != 0) { + append_error(diag, "kind argument to count must be a scalar and must not be an array", + kind->base.loc); + return nullptr; + } + } + ASR::expr_t *value = nullptr; + Vec arg_values; arg_values.reserve(al, 2); + ASR::expr_t *mask_value = ASRUtils::expr_value(mask); + arg_values.push_back(al, mask_value); + if( mask ) { + ASR::expr_t *mask_value = ASRUtils::expr_value(mask); + arg_values.push_back(al, mask_value); + } + + ASR::ttype_t* return_type = nullptr; + if( overload_id == id_mask ) { + return_type = int32; + } else if( overload_id == id_mask_dim ) { + Vec dims; + size_t n_dims = ASRUtils::extract_n_dims_from_ttype(mask_type); + dims.reserve(al, (int) n_dims - 1); + for( int i = 0; i < (int) n_dims - 1; i++ ) { + ASR::dimension_t dim; + dim.loc = mask->base.loc; + dim.m_length = nullptr; + dim.m_start = nullptr; + dims.push_back(al, dim); + } + return_type = ASRUtils::make_Array_t_util(al, loc, + int32, dims.p, dims.n, ASR::abiType::Source, + false); + } else if ( kind ) { + int kind_value = ASR::down_cast(ASRUtils::expr_value(kind))->m_n; + return_type = TYPE(ASR::make_Integer_t(al, loc, kind_value)); + } + // value = eval_Count(al, loc, return_type, arg_values, diag); + value = nullptr; + + Vec arr_intrinsic_args; arr_intrinsic_args.reserve(al, 1); + arr_intrinsic_args.push_back(al, mask); + if( dim_ ) { + arr_intrinsic_args.push_back(al, dim_); + } + return make_IntrinsicArrayFunction_t_util(al, loc, + static_cast(IntrinsicArrayFunctions::Count), + arr_intrinsic_args.p, arr_intrinsic_args.n, overload_id, return_type, value); + } + + static inline ASR::expr_t *instantiate_Count(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec &arg_types, ASR::ttype_t *return_type, + Vec &m_args, int64_t overload_id) { + declare_basic_variables("_lcompilers_count"); + fill_func_arg("mask", duplicate_type_with_empty_dims(al, arg_types[0])); + if (overload_id == 0) { + ASR::expr_t *result = declare("result", return_type, ReturnVar); + /* + for array of rank 2, the following code is generated: + result = 0 + do i = lbound(mask, 2), ubound(mask, 2) + do j = lbound(mask, 1), ubound(mask, 1) + if (mask(j, i)) then + result = result + 1 + end if + end do + end do + */ + ASR::dimension_t* array_dims = nullptr; + int array_rank = extract_dimensions_from_ttype(arg_types[0], array_dims); + std::vector do_loop_variables; + for (int i = 0; i < array_rank; i++) { + do_loop_variables.push_back(declare("i_" + std::to_string(i), int32, Local)); + } + body.push_back(al, b.Assignment(result, b.i(0, return_type))); + ASR::stmt_t* do_loop = PassUtils::create_do_loop_helper_count(al, loc, do_loop_variables, args[0], result, array_rank); + body.push_back(al, do_loop); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } else { + fill_func_arg("dim", duplicate_type_with_empty_dims(al, arg_types[1])); + ASR::expr_t *result = declare("result", return_type, Out); + args.push_back(al, result); + /* + for array of rank 3, the following code is generated: + dim == 2 + do i = 1, ubound(mask, 1) + do k = 1, ubound(mask, 3) + c = 0 + do j = 1, ubound(mask, 2) + if (mask(i, j, k)) then + c = c + 1 + end if + end do + res(i, k) = c + end do + end do + */ + int dim = ASR::down_cast(m_args[1].m_value)->m_n; + ASR::dimension_t* array_dims = nullptr; + int array_rank = extract_dimensions_from_ttype(arg_types[0], array_dims); + std::vector res_idx; + for (int i = 0; i < array_rank - 1; i++) { + res_idx.push_back(declare("i_" + std::to_string(i), int32, Local)); + } + ASR::expr_t* j = declare("j", int32, Local); + ASR::expr_t* c = declare("c", int32, Local); + + std::vector idx; bool dim_found = false; + for (int i = 0; i < array_rank; i++) { + if (i == dim - 1) { + idx.push_back(j); + dim_found = true; + } else { + dim_found ? idx.push_back(res_idx[i-1]): + idx.push_back(res_idx[i]); + } + } + ASR::stmt_t* inner_most_do_loop = b.DoLoop(j, LBound(args[0], dim), UBound(args[0], dim), { + b.If(b.ArrayItem_01(args[0], idx), { + b.Assignment(c, b.Add(c, b.i32(1))), + }, {}) + }); + ASR::stmt_t* do_loop = PassUtils::create_do_loop_helper_count_dim(al, loc, + idx, res_idx, inner_most_do_loop, c, args[0], result, 0, dim); + body.push_back(al, do_loop); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, nullptr, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } + } + +} // namespace Count + +namespace Pack { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, + diag::Diagnostics& diagnostics) { + require_impl(x.n_args == 2 || x.n_args == 3, "`pack` intrinsic accepts " + "two or three arguments", x.base.base.loc, diagnostics); + require_impl(x.m_args[0], "`array` argument of `pack` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + require_impl(x.m_args[1], "`mask` argument of `pack` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + } + + template + void populate_vector(std::vector &a, ASR::expr_t *vector_a, int dim) { + if (!vector_a) return; + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_n; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_r; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_value; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + template + void populate_vector_complex(std::vector &a, ASR::expr_t *vector_a, int dim) { + if (!vector_a) return; + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + arg_a = ASR::down_cast(arg_a)->m_value; + } + if (arg_a && ASR::is_a(*arg_a)) { + ASR::ComplexConstant_t *c_a = ASR::down_cast(arg_a); + a[i] = {c_a->m_re, c_a->m_im}; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + template + void evaluate_Pack(std::vector &a, std::vector &b, std::vector &c, std::vector &res) { + int dim_array = a.size(); + int dim_vector = c.size(); + int i = 0; + for (i = 0; i < dim_array; i++) { + if (b[i]) res.push_back(a[i]); + } + + for (i = res.size(); i < dim_vector; i++) { + res.push_back(c[i]); + } + } + + static inline ASR::expr_t *eval_Pack(Allocator & al, + const Location & loc, ASR::ttype_t *return_type, Vec& args, diag::Diagnostics& diag) { + ASR::expr_t *array = args[0], *mask = args[1], *vector = args[2]; + ASR::ttype_t *type_array = ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(expr_type(array))); + ASR::ttype_t *type_vector = ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(expr_type(vector))); + ASR::ttype_t* type_a = ASRUtils::type_get_past_array(type_array); + + int kind = ASRUtils::extract_kind_from_ttype_t(type_a); + int dim_array = ASRUtils::get_fixed_size_of_array(type_array); + int dim_vector = 0; + + bool is_vector_present = false; + if (vector) is_vector_present = true; + if (is_vector_present) dim_vector = ASRUtils::get_fixed_size_of_array(type_vector); + + std::vector b(dim_array); + populate_vector(b, mask, dim_array); + + if (ASRUtils::is_real(*type_a)) { + if (kind == 4) { + std::vector a(dim_array), c(dim_vector), res; + populate_vector(a, array, dim_array); + populate_vector(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, it, real32))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector a(dim_array), c(dim_vector), res; + populate_vector(a, array, dim_array); + populate_vector(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, it, real64))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_integer(*type_a)) { + if (kind == 4) { + std::vector a(dim_array), c(dim_vector), res; + populate_vector(a, array, dim_array); + populate_vector(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, it, int32))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector a(dim_array), c(dim_vector), res; + populate_vector(a, array, dim_array); + populate_vector(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, it, int64))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_logical(*type_a)) { + std::vector a(dim_array), c(dim_vector), res; + populate_vector(a, array, dim_array); + populate_vector(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_LogicalConstant_t(al, loc, it, logical))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (ASRUtils::is_complex(*type_a)) { + if (kind == 4) { + std::vector> a(dim_array), c(dim_vector), res; + populate_vector_complex(a, array, dim_array); + populate_vector_complex(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, it.first, it.second, type_get_past_array(return_type)))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector> a(dim_array), c(dim_vector), res; + populate_vector_complex(a, array, dim_array); + populate_vector_complex(c, vector, dim_vector); + evaluate_Pack(a, b, c, res); + Vec values; values.reserve(al, res.size()); + for (auto it: res) { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, it.first, it.second, type_get_past_array(return_type)))); + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle type " + ASRUtils::get_type_code(type_a) + " yet", loc); + return nullptr; + } + return nullptr; + } + + static inline ASR::asr_t* create_Pack(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::expr_t *array = args[0], *mask = args[1], *vector = args[2]; + bool is_type_allocatable = false; + bool is_vector_present = false; + if (ASRUtils::is_allocatable(array) || ASRUtils::is_allocatable(mask)) { + // TODO: Use Array type as return type instead of allocatable + // for both Array and Allocatable as input arguments. + is_type_allocatable = true; + } + if (vector) { + is_vector_present = true; + } + + ASR::ttype_t *type_array = expr_type(array); + ASR::ttype_t *type_mask = expr_type(mask); + ASR::ttype_t *type_vector = nullptr; + if (is_vector_present) type_vector = expr_type(vector); + ASR::ttype_t *ret_type = expr_type(array); + bool mask_logical = is_logical(*type_mask); + if( !mask_logical ) { + append_error(diag, "The argument `mask` in `pack` must be of type Logical", mask->base.loc); + return nullptr; + } + ASR::dimension_t* array_dims = nullptr; + ASR::dimension_t* mask_dims = nullptr; + ASR::dimension_t* vector_dims = nullptr; + int array_rank = extract_dimensions_from_ttype(type_array, array_dims); + int mask_rank = extract_dimensions_from_ttype(type_mask, mask_dims); + int array_dim = -1, mask_dim = -1, fixed_size_array = -1; + fixed_size_array = ASRUtils::get_fixed_size_of_array(type_array); + extract_value(array_dims[0].m_length, array_dim); + if (mask_rank == 0) { + Vec mask_expr; mask_expr.reserve(al, fixed_size_array); + for (int i = 0; i < fixed_size_array; i++) { + mask_expr.push_back(al, mask); + } + if (all_args_evaluated(mask_expr)) { + mask = EXPR(ASR::make_ArrayConstant_t(al, mask->base.loc, mask_expr.p, mask_expr.n, + TYPE(ASR::make_Array_t(al, mask->base.loc, logical, array_dims, array_rank, ASR::array_physical_typeType::FixedSizeArray)), + ASR::arraystorageType::ColMajor)); + } else { + mask = EXPR(ASR::make_ArrayConstructor_t(al, mask->base.loc, mask_expr.p, mask_expr.n, + TYPE(ASR::make_Array_t(al, mask->base.loc, logical, array_dims, array_rank, ASR::array_physical_typeType::FixedSizeArray)), + nullptr, ASR::arraystorageType::ColMajor)); + } + type_mask = expr_type(mask); + mask_rank = extract_dimensions_from_ttype(type_mask, mask_dims); + } + int vector_rank = 0; + if (is_vector_present) { + vector_rank = extract_dimensions_from_ttype(type_vector, vector_dims); + } + if (array_rank != mask_rank) { + append_error(diag, "The argument `mask` must be of rank " + std::to_string(array_rank) + + ", provided an array with rank, " + std::to_string(mask_rank), mask->base.loc); + return nullptr; + } + if (!dimension_expr_equal(array_dims[0].m_length, + mask_dims[0].m_length)) { + append_error(diag, "The argument `mask` must be of dimension " + + std::to_string(array_dim) + ", provided an array " + "with dimension " + std::to_string(mask_dim), mask->base.loc); + return nullptr; + } + if (is_vector_present && vector_rank != 1) { + append_error(diag, "`pack` accepts vector of rank 1 only, provided an array " + "with rank, " + std::to_string(vector_rank), vector->base.loc); + return nullptr; + } + + ASRBuilder b(al, loc); + Vec result_dims; result_dims.reserve(al, 1); + int overload_id = 2; + if (is_vector_present) { + result_dims.push_back(al, b.set_dim(vector_dims[0].m_start, vector_dims[0].m_length)); + ret_type = ASRUtils::duplicate_type(al, ret_type, &result_dims); + } else { + Vec args_count; args_count.reserve(al, 1); args_count.push_back(al, mask); + ASR::expr_t* count = EXPR(Count::create_Count(al, loc, args_count, diag)); + result_dims.push_back(al, b.set_dim(array_dims[0].m_start, count)); + ret_type = ASRUtils::duplicate_type(al, ret_type, &result_dims, ASR::array_physical_typeType::DescriptorArray, true); + } + if (is_type_allocatable) { + ret_type = TYPE(ASR::make_Allocatable_t(al, loc, ret_type)); + } + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, array); m_args.push_back(al, mask); + if (is_vector_present) { + m_args.push_back(al, vector); + overload_id = 3; + } + ASR::expr_t *value = nullptr; + if (all_args_evaluated(m_args)) { + value = eval_Pack(al, loc, ret_type, m_args, diag); + } + return make_IntrinsicArrayFunction_t_util(al, loc, + static_cast(IntrinsicArrayFunctions::Pack), + m_args.p, m_args.n, overload_id, ret_type, value); + } + + static inline ASR::expr_t *instantiate_Pack(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec &arg_types, ASR::ttype_t *return_type, + Vec &m_args, int64_t overload_id) { + declare_basic_variables("_lcompilers_pack"); + fill_func_arg("array", duplicate_type_with_empty_dims(al, arg_types[0])); + fill_func_arg("mask", duplicate_type_with_empty_dims(al, arg_types[1])); + if (overload_id == 3) { + fill_func_arg("vector", duplicate_type_with_empty_dims(al, arg_types[2])); + } + ASR::ttype_t* ret_type = return_type; + if (overload_id == 2) { + ret_type = ASRUtils::duplicate_type(al, return_type, nullptr, ASRUtils::extract_physical_type(return_type), true); + LCOMPILERS_ASSERT(ASR::is_a(*ret_type)); + ASR::Array_t *ret_type_array = ASR::down_cast(ret_type); + if (ASR::is_a(*ret_type_array->m_dims[0].m_length)) { + ASR::FunctionCall_t *func_call = ASR::down_cast(ret_type_array->m_dims[0].m_length); + if (ASR::is_a(*func_call->m_args[0].m_value)) { + ASR::ArrayPhysicalCast_t *array_cast = ASR::down_cast(func_call->m_args[0].m_value); + array_cast->m_arg = args[1]; + array_cast->m_old = ASRUtils::extract_physical_type(arg_types[1]); + array_cast->m_type = ASRUtils::duplicate_type_with_empty_dims(al, array_cast->m_type); + + ret_type = TYPE(ASR::make_Array_t(al, loc, ret_type_array->m_type, ret_type_array->m_dims, + ret_type_array->n_dims, ret_type_array->m_physical_type)); + } else { + ret_type = return_type; + } + } else if (ASR::is_a(*ret_type_array->m_dims[0].m_length)) { + ASR::IntrinsicArrayFunction_t *intrinsic_array = ASR::down_cast(ret_type_array->m_dims[0].m_length); + if (ASR::is_a(*intrinsic_array->m_args[0])) { + ASR::ArrayPhysicalCast_t *array_cast = ASR::down_cast(intrinsic_array->m_args[0]); + array_cast->m_arg = args[1]; + array_cast->m_old = ASRUtils::extract_physical_type(arg_types[1]); + array_cast->m_type = ASRUtils::duplicate_type_with_empty_dims(al, array_cast->m_type); + + ret_type = TYPE(ASR::make_Array_t(al, loc, ret_type_array->m_type, ret_type_array->m_dims, + ret_type_array->n_dims, ret_type_array->m_physical_type)); + } else { + ret_type = return_type; + } + } else { + ret_type = return_type; + } + } + ASR::expr_t *result = declare("result", ret_type, Out); + args.push_back(al, result); + /* + For array of rank 2, the following code is generated: + k = lbound(vector, 1) + print *, k + do i = lbound(array, 2), ubound(array, 2) + do j = lbound(array, 1), ubound(array, 1) + ! print *, "mask(", j, ",", i, ") ", mask(j, i) + if (mask(j, i)) then + res(k) = array(j, i) + ! print *, "array(", j, ",", i, ") ", array(j, i) + ! print *, "res(", k, ") ", res(k) + k = k + 1 + end if + end do + end do + + do i = k, ubound(vector, 1) + res(k) = vector(k) + k = k + 1 + end do + */ + ASR::dimension_t* array_dims = nullptr; + int array_rank = extract_dimensions_from_ttype(arg_types[0], array_dims); + std::vector do_loop_variables; + for (int i = 0; i < array_rank; i++) { + do_loop_variables.push_back(declare("i_" + std::to_string(i), int32, Local)); + } + ASR::expr_t *k = declare("k", int32, Local); + body.push_back(al, b.Assignment(k, b.i32(1))); + ASR::stmt_t* do_loop = PassUtils::create_do_loop_helper_pack(al, loc, do_loop_variables, args[0], args[1], result, k, array_rank); + body.push_back(al, do_loop); + + if (overload_id == 3) { + body.push_back(al, b.DoLoop(do_loop_variables[0], k, UBound(args[2], 1), { + b.Assignment(b.ArrayItem_01(result, {k}), b.ArrayItem_01(args[2], {k})), + b.Assignment(k, b.Add(k, b.i32(1))) + })); + } + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, nullptr, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } + +} // namespace Pack + +namespace Unpack { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, + diag::Diagnostics& diagnostics) { + require_impl(x.n_args == 3, "`unpack` intrinsic accepts " + "three arguments", x.base.base.loc, diagnostics); + require_impl(x.m_args[0], "`vector` argument of `unpack` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + require_impl(x.m_args[1], "`mask` argument of `unpack` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + require_impl(x.m_args[2], "`field` argument of `unpack` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + } + + template + void populate_vector(std::vector &a, ASR::expr_t *vector_a, int dim) { + if (!vector_a) return; + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_n; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_r; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_value; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + template + void populate_vector_complex(std::vector &a, ASR::expr_t *vector_a, int dim) { + if (!vector_a) return; + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + arg_a = ASR::down_cast(arg_a)->m_value; + } + if (arg_a && ASR::is_a(*arg_a)) { + ASR::ComplexConstant_t *c_a = ASR::down_cast(arg_a); + a[i] = {c_a->m_re, c_a->m_im}; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + static inline ASR::expr_t *eval_Unpack(Allocator & al, + const Location & loc, ASR::ttype_t *return_type, Vec& args, diag::Diagnostics& diag) { + ASR::expr_t * vector= args[0], *mask = args[1], *field = args[2]; + ASR::ttype_t *type_vector = ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(expr_type(vector))); + ASR::ttype_t *type_mask = ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(expr_type(mask))); + ASR::ttype_t* type_a = ASRUtils::type_get_past_array(type_vector); + + int kind = ASRUtils::extract_kind_from_ttype_t(type_a); + int dim_mask = ASRUtils::get_fixed_size_of_array(type_mask); + int dim_vector = ASRUtils::get_fixed_size_of_array(type_vector); + + std::vector b(dim_mask); + populate_vector(b, mask, dim_mask); + + if (ASRUtils::is_real(*type_a)) { + if (kind == 4) { + std::vector a(dim_vector), c(dim_mask); + populate_vector(a, vector, dim_vector); + populate_vector(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, a[i], real32))); + } else { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, c[i], real32))); + } + } + + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector a(dim_vector), c(dim_mask); + populate_vector(a, vector, dim_vector); + populate_vector(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, a[i], real64))); + } else { + values.push_back(al, EXPR(ASR::make_RealConstant_t(al, loc, c[i], real64))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `unpack` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_integer(*type_a)) { + if (kind == 4) { + std::vector a(dim_vector), c(dim_mask); + populate_vector(a, vector, dim_vector); + populate_vector(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, a[i], int32))); + } else { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, c[i], int32))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector a(dim_vector), c(dim_mask); + populate_vector(a, vector, dim_vector); + populate_vector(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, a[i], int64))); + } else { + values.push_back(al, EXPR(ASR::make_IntegerConstant_t(al, loc, c[i], int64))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `unpack` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_logical(*type_a)) { + std::vector a(dim_vector), c(dim_mask); + populate_vector(a, vector, dim_vector); + populate_vector(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_LogicalConstant_t(al, loc, a[i], logical))); + } else { + values.push_back(al, EXPR(ASR::make_LogicalConstant_t(al, loc, c[i], logical))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + + } else if (ASRUtils::is_complex(*type_a)) { + if (kind == 4) { + std::vector> a(dim_vector), c(dim_mask); + populate_vector_complex(a, vector, dim_vector); + populate_vector_complex(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, a[i].first, a[i].second, type_get_past_array(return_type)))); + } else { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, c[i].first, c[i].second, type_get_past_array(return_type)))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else if (kind == 8) { + std::vector> a(dim_vector), c(dim_mask); + populate_vector_complex(a, vector, dim_vector); + populate_vector_complex(c, field, dim_mask); + Vec values; values.reserve(al, b.size()); + + for (int i = 0; i < dim_mask; i++) { + if (b[i]) { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, a[i].first, a[i].second, type_get_past_array(return_type)))); + } else { + values.push_back(al, EXPR(ASR::make_ComplexConstant_t(al, loc, c[i].first, c[i].second, type_get_past_array(return_type)))); + } + } + return EXPR(ASR::make_ArrayConstant_t(al, loc, values.p, values.n, return_type, ASR::arraystorageType::ColMajor)); + } else { + append_error(diag, "The `unpack` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else { + append_error(diag, "The `unpack` intrinsic doesn't handle type " + ASRUtils::get_type_code(type_a) + " yet", loc); + } + return nullptr; + } + + static inline ASR::asr_t* create_Unpack(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::expr_t *vector = args[0], *mask = args[1], *field = args[2]; + bool is_type_allocatable = false; + if (ASRUtils::is_allocatable(field) || ASRUtils::is_allocatable(mask)) { + // TODO: Use Array type as return type instead of allocatable + // for both Array and Allocatable as input arguments. + is_type_allocatable = true; + } + + ASR::ttype_t *type_vector = expr_type(vector); + ASR::ttype_t *type_mask = expr_type(mask); + ASR::ttype_t *type_field = expr_type(field); + ASR::ttype_t *ret_type = type_field; + bool mask_logical = is_logical(*type_mask); + if( !mask_logical ) { + append_error(diag, "The argument `mask` in `unpack` must be of type Logical", mask->base.loc); + return nullptr; + } + ASR::dimension_t* vector_dims = nullptr; + ASR::dimension_t* mask_dims = nullptr; + ASR::dimension_t* field_dims = nullptr; + int vector_rank = extract_dimensions_from_ttype(type_vector, vector_dims); + int mask_rank = extract_dimensions_from_ttype(type_mask, mask_dims); + int field_rank = extract_dimensions_from_ttype(type_field, field_dims); + int vector_dim = -1, mask_dim = -1, field_dim = -1; + extract_value(vector_dims[0].m_length, vector_dim); + extract_value(mask_dims[0].m_length, mask_dim); + extract_value(field_dims[0].m_length, field_dim); + if (vector_rank != 1) { + append_error(diag, "`unpack` accepts vector of rank 1 only, provided an array " + "with rank, " + std::to_string(vector_rank), vector->base.loc); + return nullptr; + } + if (mask_rank == 0) { + append_error(diag, "The argument `mask` in `unpack` must be an array and not a scalar", mask->base.loc); + } + if (field_rank != mask_rank) { + append_error(diag, "The argument `field` must be of rank " + std::to_string(mask_rank) + + ", provided an array with rank, " + std::to_string(field_rank), mask->base.loc); + return nullptr; + } + if (!dimension_expr_equal(field_dims[0].m_length, + mask_dims[0].m_length)) { + append_error(diag, "The argument `field` must be of dimension " + + std::to_string(mask_dim) + ", provided an array " + "with dimension " + std::to_string(field_dim), mask->base.loc); + return nullptr; + } + ASRBuilder b(al, loc); + Vec result_dims; result_dims.reserve(al, 1); + int overload_id = 2; + for (int i = 0; i < mask_rank; i++) { + result_dims.push_back(al, b.set_dim(mask_dims[i].m_start, mask_dims[i].m_length)); + } + ret_type = ASRUtils::duplicate_type(al, ret_type, &result_dims); + if (is_type_allocatable) { + ret_type = TYPE(ASR::make_Allocatable_t(al, loc, ret_type)); + } + Vec m_args; m_args.reserve(al, 3); + m_args.push_back(al, vector); m_args.push_back(al, mask); m_args.push_back(al, field); + ASR::expr_t *value = nullptr; + if (all_args_evaluated(m_args)) { + value = eval_Unpack(al, loc, ret_type, m_args, diag); + } + return make_IntrinsicArrayFunction_t_util(al, loc, + static_cast(IntrinsicArrayFunctions::Unpack), + m_args.p, m_args.n, overload_id, ret_type, value); + } + + static inline ASR::expr_t *instantiate_Unpack(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec &arg_types, ASR::ttype_t *return_type, + Vec &m_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_unpack"); + fill_func_arg("vector", duplicate_type_with_empty_dims(al, arg_types[0])); + fill_func_arg("mask", duplicate_type_with_empty_dims(al, arg_types[1])); + fill_func_arg("field", duplicate_type_with_empty_dims(al, arg_types[2])); + ASR::expr_t *result = declare("result", return_type, Out); + args.push_back(al, result); + /* + For array of rank 2, the following code is generated: + k = lbound(vector, 1) + res = field + do i = lbound(mask, 2), ubound(mask, 2) + do j = lbound(mask, 1), ubound(mask, 1) + print *, "mask(", j, i, ") = ", mask(j, i) + if (mask(j, i)) then + res(j, i) = vector(k) + k = k + 1 + end if + end do + end do + */ + ASR::dimension_t* array_dims = nullptr; + int mask_rank = extract_dimensions_from_ttype(arg_types[1], array_dims); + std::vector do_loop_variables; + for (int i = 0; i < mask_rank; i++) { + do_loop_variables.push_back(declare("i_" + std::to_string(i), int32, Local)); + } + ASR::expr_t *k = declare("k", int32, Local); + body.push_back(al, b.Assignment(k, LBound(args[0], 1))); + body.push_back(al, b.Assignment(result, args[2])); + ASR::stmt_t* do_loop = PassUtils::create_do_loop_helper_unpack(al, loc, do_loop_variables, args[0], args[1], result, k, mask_rank); + body.push_back(al, do_loop); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, nullptr, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } + +} // namespace Unpack + +namespace DotProduct { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, + diag::Diagnostics& diagnostics) { + require_impl(x.n_args == 2, "`dot_product` intrinsic accepts exactly" + "two arguments", x.base.base.loc, diagnostics); + require_impl(x.m_args[0], "`vector_a` argument of `dot_product` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + require_impl(x.m_args[1], "`vector_b` argument of `dot_product` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + } + + template + void populate_vector_complex(std::vector &a, std::vector& b, ASR::expr_t *vector_a, ASR::expr_t* vector_b, int dim) { + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + if (ASR::is_a(*vector_b)) { + vector_b = ASR::down_cast(vector_b)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a) && ASR::is_a(*vector_b)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + ASR::ArrayConstant_t *b_const = ASR::down_cast(vector_b); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + ASR::expr_t* arg_b = b_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + arg_a = ASR::down_cast(arg_a)->m_value; + } + if (ASR::is_a(*arg_b)) { + arg_b = ASR::down_cast(arg_b)->m_value; + } + + if (arg_a && arg_b && ASR::is_a(*arg_a)) { + ASR::ComplexConstant_t *c_a = ASR::down_cast(arg_a); + ASR::ComplexConstant_t *c_b = ASR::down_cast(arg_b); + a[i] = {c_a->m_re, c_a->m_im}; + b[i] = {c_b->m_re, c_b->m_im}; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + template + void populate_vector(std::vector &a, std::vector& b, ASR::expr_t *vector_a, ASR::expr_t* vector_b, int dim) { + if (ASR::is_a(*vector_a)) { + vector_a = ASR::down_cast(vector_a)->m_arg; + } + if (ASR::is_a(*vector_b)) { + vector_b = ASR::down_cast(vector_b)->m_arg; + } + LCOMPILERS_ASSERT(ASR::is_a(*vector_a) && ASR::is_a(*vector_b)); + ASR::ArrayConstant_t *a_const = ASR::down_cast(vector_a); + ASR::ArrayConstant_t *b_const = ASR::down_cast(vector_b); + + for (int i = 0; i < dim; i++) { + ASR::expr_t* arg_a = a_const->m_args[i]; + ASR::expr_t* arg_b = b_const->m_args[i]; + + if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_n; + b[i] = ASR::down_cast(arg_b)->m_n; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_r; + b[i] = ASR::down_cast(arg_b)->m_r; + } else if (ASR::is_a(*arg_a)) { + a[i] = ASR::down_cast(arg_a)->m_value; + b[i] = ASR::down_cast(arg_b)->m_value; + } else { + LCOMPILERS_ASSERT(false); + } + } + } + + static inline ASR::expr_t *eval_DotProduct(Allocator & al, + const Location & loc, ASR::ttype_t *return_type, Vec& args, diag::Diagnostics& diag) { + ASR::expr_t *vector_a = args[0], *vector_b = args[1]; + ASR::ttype_t *type_vector_a = ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_allocatable(expr_type(vector_a))); + ASR::ttype_t* type_a = ASRUtils::type_get_past_array(type_vector_a); + + int kind = ASRUtils::extract_kind_from_ttype_t(type_a); + int dim = ASRUtils::get_fixed_size_of_array(type_vector_a); + + if (ASRUtils::is_real(*type_a)) { + if (kind == 4) { + std::vector a(dim), b(dim); + populate_vector(a, b, vector_a, vector_b, dim); + float result = std::inner_product(a.begin(), a.end(), b.begin(), 0.0f); + return make_ConstantWithType(make_RealConstant_t, result, return_type, loc); + } else if (kind == 8) { + std::vector a(dim), b(dim); + populate_vector(a, b, vector_a, vector_b, dim); + double result = std::inner_product(a.begin(), a.end(), b.begin(), 0.0); + return make_ConstantWithType(make_RealConstant_t, result, return_type, loc); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_integer(*type_a)) { + if (kind == 4) { + std::vector a(dim), b(dim); + populate_vector(a, b, vector_a, vector_b, dim); + int32_t result = std::inner_product(a.begin(), a.end(), b.begin(), 0); + return make_ConstantWithType(make_IntegerConstant_t, result, return_type, loc); + } else if (kind == 8) { + std::vector a(dim), b(dim); + populate_vector(a, b, vector_a, vector_b, dim); + int64_t result = std::inner_product(a.begin(), a.end(), b.begin(), 0); + return make_ConstantWithType(make_IntegerConstant_t, result, return_type, loc); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else if (ASRUtils::is_logical(*type_a)) { + std::vector a(dim), b(dim); + populate_vector(a, b, vector_a, vector_b, dim); + bool result = false; + for (int i = 0; i < dim; i++) { + result = result || (a[i] && b[i]); + } + return make_ConstantWithType(make_LogicalConstant_t, result, return_type, loc); + } else if (ASRUtils::is_complex(*type_a)) { + if (kind == 4) { + std::vector> a(dim), b(dim); + populate_vector_complex(a, b, vector_a, vector_b, dim); + std::pair result = {0.0f, 0.0f}; + for (int i = 0; i < dim; i++) { + result.first += a[i].first * b[i].first + (a[i].second * b[i].second); + result.second += a[i].first * b[i].second + ((-a[i].second)* b[i].first); + } + return EXPR(make_ComplexConstant_t(al, loc, result.first, result.second, return_type)); + } else if (kind == 8) { + std::vector> a(dim), b(dim); + populate_vector_complex(a, b, vector_a, vector_b, dim); + std::pair result = {0.0, 0.0}; + for (int i = 0; i < dim; i++) { + result.first += a[i].first * b[i].first + (a[i].second * b[i].second); + result.second += a[i].first * b[i].second + ((-a[i].second)* b[i].first); + } + return EXPR(make_ComplexConstant_t(al, loc, result.first, result.second, return_type)); + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle kind " + std::to_string(kind) + " yet", loc); + return nullptr; + } + } else { + append_error(diag, "The `dot_product` intrinsic doesn't handle type " + ASRUtils::get_type_code(type_a) + " yet", loc); + return nullptr; + } + return nullptr; + } + + static inline ASR::asr_t* create_DotProduct(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::expr_t *matrix_a = args[0], *matrix_b = args[1]; + ASR::ttype_t *type_a = expr_type(matrix_a); + ASR::ttype_t *type_b = expr_type(matrix_b); + ASR::ttype_t *ret_type = nullptr; + bool matrix_a_numeric = is_integer(*type_a) || + is_real(*type_a) || + is_complex(*type_a); + bool matrix_a_logical = is_logical(*type_a); + bool matrix_b_numeric = is_integer(*type_b) || + is_real(*type_b) || + is_complex(*type_b); + bool matrix_b_logical = is_logical(*type_b); + if ( !matrix_a_numeric && !matrix_a_logical ) { + append_error(diag, "The argument `matrix_a` in `dot_product` must be of type Integer, " + "Real, Complex or Logical", matrix_a->base.loc); + return nullptr; + } else if ( matrix_a_numeric ) { + if( !matrix_b_numeric ) { + append_error(diag, "The argument `matrix_b` in `dot_product` must be of type " + "Integer, Real or Complex if first matrix is of numeric " + "type", matrix_b->base.loc); + return nullptr; + } + } else { + if( !matrix_b_logical ) { + append_error(diag, "The argument `matrix_b` in `dot_product` must be of type Logical" + " if first matrix is of Logical type", matrix_b->base.loc); + return nullptr; + } + } + ret_type = extract_type(type_a); + ASR::dimension_t* matrix_a_dims = nullptr; + ASR::dimension_t* matrix_b_dims = nullptr; + int matrix_a_rank = extract_dimensions_from_ttype(type_a, matrix_a_dims); + int matrix_b_rank = extract_dimensions_from_ttype(type_b, matrix_b_dims); + if ( matrix_a_rank != 1) { + append_error(diag, "`dot_product` accepts arrays of rank 1 only, provided an array " + "with rank, " + std::to_string(matrix_a_rank), matrix_a->base.loc); + return nullptr; + } else if ( matrix_b_rank != 1 ) { + append_error(diag, "`dot_product` accepts arrays of rank 1 only, provided an array " + "with rank, " + std::to_string(matrix_b_rank), matrix_b->base.loc); + return nullptr; + } + + int overload_id = 1; + int matrix_a_dim_1 = -1, matrix_b_dim_1 = -1; + if ( !dimension_expr_equal(matrix_a_dims[0].m_length, matrix_b_dims[0].m_length) ) { + append_error(diag, "The argument `matrix_b` must be of dimension " + + std::to_string(matrix_a_dim_1) + ", provided an array " + "with dimension " + std::to_string(matrix_b_dim_1) + + " in `matrix_b('n')`", matrix_b->base.loc); + return nullptr; + } + + ASR::expr_t *value = nullptr; + if (all_args_evaluated(args)) { + value = eval_DotProduct(al, loc, ret_type, args, diag); + } + return make_IntrinsicArrayFunction_t_util(al, loc, + static_cast(IntrinsicArrayFunctions::DotProduct), + args.p, args.n, overload_id, ret_type, value); + } + + static inline ASR::expr_t *instantiate_DotProduct(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec &arg_types, ASR::ttype_t *return_type, + Vec &m_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_dot_product"); + fill_func_arg("matrix_a", duplicate_type_with_empty_dims(al, arg_types[0])); + fill_func_arg("matrix_b", duplicate_type_with_empty_dims(al, arg_types[1])); + ASR::expr_t *result = declare("result", return_type, ReturnVar); + ASR::expr_t *i = declare("i", int32, Local); + /* + res = 0 + do i = LBound(matrix_a, 1), UBound(matrix_a, 1) + res = res + matrix_a(i) * matrix_b(i) + end do + */ + if (is_logical(*return_type)) { + body.push_back(al, b.Assignment(result, ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, false, return_type)))); + body.push_back(al, b.DoLoop(i, LBound(args[0], 1), UBound(args[0], 1), { + b.Assignment(result, b.LogicalOr(result, b.And(b.ArrayItem_01(args[0], {i}), b.ArrayItem_01(args[1], {i})), loc)) + })); + } else if (is_complex(*return_type)) { + body.push_back(al, b.Assignment(result, EXPR(ASR::make_ComplexConstant_t(al, loc, 0.0, 0.0, return_type)))); + + Vec new_args_conjg; new_args_conjg.reserve(al, 1); + ASR::call_arg_t call_arg; call_arg.loc = loc; + call_arg.m_value = b.ArrayItem_01(args[0], {i}); + new_args_conjg.push_back(al, call_arg); + + Vec arg_types_conjg; arg_types_conjg.reserve(al, 1); + arg_types_conjg.push_back(al, return_type); + + ASR::expr_t* func_call_conjg = Conjg::instantiate_Conjg(al, loc, scope, arg_types_conjg, return_type, new_args_conjg, 0); + body.push_back(al, b.DoLoop(i, LBound(args[0], 1), UBound(args[0], 1), { + b.Assignment(result, b.Add(result, EXPR(ASR::make_ComplexBinOp_t(al, loc, func_call_conjg, ASR::binopType::Mul, b.ArrayItem_01(args[1], {i}), return_type, nullptr)))) + }, nullptr)); + } else { + if (is_real(*return_type)) { + body.push_back(al, b.Assignment(result, make_ConstantWithType(make_RealConstant_t, 0.0, return_type, loc))); + } else { + body.push_back(al, b.Assignment(result, make_ConstantWithType(make_IntegerConstant_t, 0, return_type, loc))); + } + body.push_back(al, b.DoLoop(i, LBound(args[0], 1), UBound(args[0], 1), { + b.Assignment(result, b.Add(result, b.Mul(b.ArrayItem_01(args[0], {i}), b.ArrayItem_01(args[1], {i})))) + }, nullptr)); + } + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } + +} // namespace DotProduct + +namespace Transpose { + + static inline void verify_args(const ASR::IntrinsicArrayFunction_t &x, + diag::Diagnostics& diagnostics) { + require_impl(x.n_args == 1, "`transpose` intrinsic accepts exactly" + "one arguments", x.base.base.loc, diagnostics); + require_impl(x.m_args[0], "`matrix` argument of `transpose` intrinsic " + "cannot be nullptr", x.base.base.loc, diagnostics); + } + + static inline ASR::expr_t *eval_Transpose(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t */*return_type*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO + return nullptr; + } + + static inline ASR::asr_t* create_Transpose(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::expr_t *matrix_a = args[0]; + bool is_type_allocatable = false; + if (ASRUtils::is_allocatable(matrix_a)) { + // TODO: Use Array type as return type instead of allocatable + // for both Array and Allocatable as input arguments. + is_type_allocatable = true; + } + ASR::ttype_t *type_a = expr_type(matrix_a); + ASR::ttype_t *ret_type = nullptr; + ret_type = extract_type(type_a); + ASR::dimension_t* matrix_a_dims = nullptr; + int matrix_a_rank = extract_dimensions_from_ttype(type_a, matrix_a_dims); + if ( matrix_a_rank != 2 ) { + append_error(diag, "`transpose` accepts arrays of rank 2 only, provided an array " + "with rank, " + std::to_string(matrix_a_rank), matrix_a->base.loc); + return nullptr; + } + ASRBuilder b(al, loc); + Vec result_dims; result_dims.reserve(al, 2); + int overload_id = 2; + result_dims.push_back(al, b.set_dim(matrix_a_dims[0].m_start, + matrix_a_dims[1].m_length)); + result_dims.push_back(al, b.set_dim(matrix_a_dims[1].m_start, + matrix_a_dims[0].m_length)); + ret_type = ASRUtils::duplicate_type(al, ret_type, &result_dims); + if (is_type_allocatable) { + ret_type = TYPE(ASR::make_Allocatable_t(al, loc, ret_type)); + } + ASR::expr_t *value = nullptr; + if (all_args_evaluated(args)) { + value = eval_Transpose(al, loc, ret_type, args, diag); + } + return make_IntrinsicArrayFunction_t_util(al, loc, + static_cast(IntrinsicArrayFunctions::Transpose), + args.p, args.n, overload_id, ret_type, value); + } + + static inline ASR::expr_t *instantiate_Transpose(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec &arg_types, ASR::ttype_t *return_type, + Vec &m_args, int64_t /*overload_id*/) { + /* + do i = lbound(m,1), ubound(m,1) + do j = lbound(m,2), ubound(m,2) + result(j,i) = m(i,j) + end do + end do + */ + declare_basic_variables("_lcompilers_transpose"); + fill_func_arg("matrix_a_t", duplicate_type_with_empty_dims(al, arg_types[0])); + ASR::ttype_t* return_type_ = return_type; + if( !ASRUtils::is_fixed_size_array(return_type) ) { + bool is_allocatable = ASRUtils::is_allocatable(return_type); + Vec empty_dims; + empty_dims.reserve(al, 2); + for( int idim = 0; idim < 2; idim++ ) { + ASR::dimension_t empty_dim; + empty_dim.loc = loc; + empty_dim.m_start = nullptr; + empty_dim.m_length = nullptr; + empty_dims.push_back(al, empty_dim); + } + return_type_ = ASRUtils::make_Array_t_util(al, loc, + ASRUtils::extract_type(return_type_), empty_dims.p, empty_dims.size()); + if( is_allocatable ) { + return_type_ = ASRUtils::TYPE(ASR::make_Allocatable_t(al, loc, return_type_)); + } + } + ASR::expr_t *result = declare("result", return_type_, Out); + args.push_back(al, result); + ASR::expr_t *i = declare("i", int32, Local); + ASR::expr_t *j = declare("j", int32, Local); + body.push_back(al, b.DoLoop(i, LBound(args[0], 1), UBound(args[0], 1), { + b.DoLoop(j, LBound(args[0], 2), UBound(args[0], 2), { + b.Assignment(b.ArrayItem_01(result, {j, i}), b.ArrayItem_01(args[0], {i, j})) + }, nullptr) + }, nullptr)); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, nullptr, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, m_args, return_type, nullptr); + } + +} // namespace Transpose + namespace IntrinsicArrayFunctionRegistry { static const std::map(IntrinsicArrayFunctions::Sum), {&Sum::instantiate_Sum, &Sum::verify_args}}, + {static_cast(IntrinsicArrayFunctions::Transpose), + {&Transpose::instantiate_Transpose, &Transpose::verify_args}}, + {static_cast(IntrinsicArrayFunctions::Pack), + {&Pack::instantiate_Pack, &Pack::verify_args}}, + {static_cast(IntrinsicArrayFunctions::Unpack), + {&Unpack::instantiate_Unpack, &Unpack::verify_args}}, + {static_cast(IntrinsicArrayFunctions::Count), + {&Count::instantiate_Count, &Count::verify_args}}, + {static_cast(IntrinsicArrayFunctions::DotProduct), + {&DotProduct::instantiate_DotProduct, &DotProduct::verify_args}}, }; static const std::mapm_value) { *current_expr = x->m_value; return; } Vec new_args; new_args.reserve(al, x->n_args); - // Replace any IntrinsicScalarFunctions in the argument first: + // Replace any IntrinsicElementalFunctions in the argument first: for( size_t i = 0; i < x->n_args; i++ ) { ASR::expr_t** current_expr_copy_ = current_expr; current_expr = &(x->m_args[i]); @@ -64,7 +64,7 @@ class ReplaceIntrinsicFunctions: public ASR::BaseExprReplacer id and look it up. ASRUtils::impl_function instantiate_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_instantiate_function(x->m_intrinsic_id); + ASRUtils::IntrinsicElementalFunctionRegistry::get_instantiate_function(x->m_intrinsic_id); if( instantiate_function == nullptr ) { return ; } @@ -83,6 +83,7 @@ class ReplaceIntrinsicFunctions: public ASR::BaseExprReplacerm_value; return; } + replace_ttype(x->m_type); Vec new_args; new_args.reserve(al, x->n_args); // Replace any IntrinsicArrayFunctions in the argument first: for( size_t i = 0; i < x->n_args; i++ ) { @@ -122,7 +123,6 @@ class ReplaceIntrinsicFunctions: public ASR::BaseExprReplacerm_arr_intrinsic_id; } } - }; /* @@ -287,8 +287,12 @@ class ReplaceFunctionCallReturningArray: public ASR::BaseExprReplacerm_args[dim_index].m_value; if( !ASRUtils::is_value_constant(ASRUtils::expr_value(dim)) ) { - // Possibly can be replaced by calling "get_result_var_for_runtime_dim" - throw LCompilersException("Runtime values for dim argument is not supported yet."); + result_var_ = PassUtils::create_var(result_counter, + std::string(ASRUtils::symbol_name(x->m_name)) + "_res", + x->base.base.loc, x->m_type, al, current_scope); + if (func2intrinsicid[x_m_name] == ASRUtils::IntrinsicArrayFunctions::Sum) { + PassUtils::allocate_res_var(al, x, new_args, result_var_, pass_result, {0, 0, 1}); + } } else { int constant_dim; if (ASRUtils::extract_value(ASRUtils::expr_value(dim), constant_dim)) { @@ -300,9 +304,53 @@ class ReplaceFunctionCallReturningArray: public ASR::BaseExprReplacer(ASRUtils::symbol_get_past_external(x->m_name)); + ASR::symbol_t* res = pack->m_symtab->resolve_symbol("result"); + if (res) { + ASR::Variable_t* res_var = ASR::down_cast(res); + ASR::Array_t* res_arr = ASR::down_cast(res_var->m_type); + if (ASR::is_a(*res_arr->m_dims[0].m_length)) { + ASRUtils::ExprStmtDuplicator expr_stmt_duplicator(al); + func_call_count = res_arr->m_dims[0].m_length; + func_call_count = expr_stmt_duplicator.duplicate_expr(func_call_count); + + ASR::FunctionCall_t* func_call = ASR::down_cast(func_call_count); + if (ASR::is_a(*func_call->m_args[0].m_value)) { + ASR::ArrayPhysicalCast_t *array_cast = ASR::down_cast(func_call->m_args[0].m_value); + array_cast->m_arg = ASR::down_cast(new_args[1].m_value)->m_arg; + array_cast->m_old = ASRUtils::extract_physical_type(ASRUtils::expr_type(array_cast->m_arg)); + array_cast->m_type = ASRUtils::duplicate_type(al, ASRUtils::expr_type(array_cast->m_arg), nullptr, + ASR::array_physical_typeType::DescriptorArray, true); + + func_call->m_args[0].m_value = ASRUtils::EXPR((ASR::asr_t*) array_cast); + } + } + } + } result_var_ = PassUtils::create_var(result_counter, std::string(ASRUtils::symbol_name(x->m_name)) + "_res", x->base.base.loc, x->m_type, al, current_scope); + if (func_call_count) { + // allocate result array + Vec alloc_args; alloc_args.reserve(al, 1); + Vec alloc_dims; alloc_dims.reserve(al, 2); + ASR::alloc_arg_t alloc_arg; alloc_arg.loc = x->base.base.loc; + ASR::dimension_t dim; dim.loc = x->base.base.loc; + dim.m_start = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, x->base.base.loc, 1, + ASRUtils::TYPE(ASR::make_Integer_t(al, x->base.base.loc, 4)))); + dim.m_length = func_call_count; + alloc_dims.push_back(al, dim); + alloc_arg.m_a = result_var_; alloc_arg.m_len_expr = nullptr; + alloc_arg.m_type = nullptr; alloc_arg.m_dims = alloc_dims.p; + alloc_arg.n_dims = alloc_dims.size(); + alloc_args.push_back(al, alloc_arg); + + ASR::stmt_t* allocate_stmt = ASRUtils::STMT(ASR::make_Allocate_t(al, + x->base.base.loc, alloc_args.p, alloc_args.n, nullptr, nullptr, nullptr)); + pass_result.push_back(al, allocate_stmt); + } } else { LCOMPILERS_ASSERT(false); } @@ -314,7 +362,7 @@ class ReplaceFunctionCallReturningArray: public ASR::BaseExprReplacerbase.base.loc, x->m_name, x->m_original_name, new_args.p, - new_args.size(), x->m_dt, nullptr, false))); + new_args.size(), x->m_dt, nullptr, false, false))); *current_expr = new_args.p[new_args.size() - 1].m_value; } diff --git a/src/libasr/pass/intrinsic_function_registry.h b/src/libasr/pass/intrinsic_function_registry.h index 0b688aed77..21636cfeae 100644 --- a/src/libasr/pass/intrinsic_function_registry.h +++ b/src/libasr/pass/intrinsic_function_registry.h @@ -1,11 +1,7 @@ #ifndef LFORTRAN_PASS_INTRINSIC_FUNCTION_REGISTRY_H #define LFORTRAN_PASS_INTRINSIC_FUNCTION_REGISTRY_H -#include -#include -#include -#include -#include +#include #include #include @@ -15,3923 +11,721 @@ namespace LCompilers { namespace ASRUtils { -/* -To add a new function implementation, - -1. Create a new namespace like, `Sin`, `LogGamma` in this file. -2. In the above created namespace add `eval_*`, `instantiate_*`, and `create_*`. -3. Then register in the maps present in `IntrinsicScalarFunctionRegistry`. - -You can use helper macros and define your own helper macros to reduce -the code size. -*/ - -enum class IntrinsicScalarFunctions : int64_t { - ObjectType, - Sin, - Cos, - Tan, - Asin, - Acos, - Atan, - Sinh, - Cosh, - Tanh, - Atan2, - Gamma, - LogGamma, - Trunc, - Fix, - Abs, - Exp, - Exp2, - Expm1, - FMA, - FlipSign, - Mod, - Trailz, - FloorDiv, - ListIndex, - Partition, - ListReverse, - ListPop, - Reserve, - DictKeys, - DictValues, - SetAdd, - SetRemove, - Max, - Min, - Radix, - Sign, - SignFromValue, - Aint, - Sqrt, - Sngl, - SymbolicSymbol, - SymbolicAdd, - SymbolicSub, - SymbolicMul, - SymbolicDiv, - SymbolicPow, - SymbolicPi, - SymbolicE, - SymbolicInteger, - SymbolicDiff, - SymbolicExpand, - SymbolicSin, - SymbolicCos, - SymbolicLog, - SymbolicExp, - SymbolicAbs, - SymbolicHasSymbolQ, - SymbolicAddQ, - SymbolicMulQ, - SymbolicPowQ, - SymbolicLogQ, - SymbolicSinQ, - SymbolicGetArgument, - // ... -}; - -#define INTRINSIC_NAME_CASE(X) \ - case (static_cast(ASRUtils::IntrinsicScalarFunctions::X)) : { \ - return #X; \ - } - -inline std::string get_intrinsic_name(int x) { - switch (x) { - INTRINSIC_NAME_CASE(ObjectType) - INTRINSIC_NAME_CASE(Sin) - INTRINSIC_NAME_CASE(Cos) - INTRINSIC_NAME_CASE(Tan) - INTRINSIC_NAME_CASE(Asin) - INTRINSIC_NAME_CASE(Acos) - INTRINSIC_NAME_CASE(Atan) - INTRINSIC_NAME_CASE(Sinh) - INTRINSIC_NAME_CASE(Cosh) - INTRINSIC_NAME_CASE(Tanh) - INTRINSIC_NAME_CASE(Atan2) - INTRINSIC_NAME_CASE(Gamma) - INTRINSIC_NAME_CASE(LogGamma) - INTRINSIC_NAME_CASE(Trunc) - INTRINSIC_NAME_CASE(Fix) - INTRINSIC_NAME_CASE(Abs) - INTRINSIC_NAME_CASE(Exp) - INTRINSIC_NAME_CASE(Exp2) - INTRINSIC_NAME_CASE(Expm1) - INTRINSIC_NAME_CASE(FMA) - INTRINSIC_NAME_CASE(FlipSign) - INTRINSIC_NAME_CASE(FloorDiv) - INTRINSIC_NAME_CASE(Mod) - INTRINSIC_NAME_CASE(Trailz) - INTRINSIC_NAME_CASE(ListIndex) - INTRINSIC_NAME_CASE(Partition) - INTRINSIC_NAME_CASE(ListReverse) - INTRINSIC_NAME_CASE(ListPop) - INTRINSIC_NAME_CASE(Reserve) - INTRINSIC_NAME_CASE(DictKeys) - INTRINSIC_NAME_CASE(DictValues) - INTRINSIC_NAME_CASE(SetAdd) - INTRINSIC_NAME_CASE(SetRemove) - INTRINSIC_NAME_CASE(Max) - INTRINSIC_NAME_CASE(Min) - INTRINSIC_NAME_CASE(Sign) - INTRINSIC_NAME_CASE(SignFromValue) - INTRINSIC_NAME_CASE(Aint) - INTRINSIC_NAME_CASE(Sqrt) - INTRINSIC_NAME_CASE(Sngl) - INTRINSIC_NAME_CASE(SymbolicSymbol) - INTRINSIC_NAME_CASE(SymbolicAdd) - INTRINSIC_NAME_CASE(SymbolicSub) - INTRINSIC_NAME_CASE(SymbolicMul) - INTRINSIC_NAME_CASE(SymbolicDiv) - INTRINSIC_NAME_CASE(SymbolicPow) - INTRINSIC_NAME_CASE(SymbolicPi) - INTRINSIC_NAME_CASE(SymbolicE) - INTRINSIC_NAME_CASE(SymbolicInteger) - INTRINSIC_NAME_CASE(SymbolicDiff) - INTRINSIC_NAME_CASE(SymbolicExpand) - INTRINSIC_NAME_CASE(SymbolicSin) - INTRINSIC_NAME_CASE(SymbolicCos) - INTRINSIC_NAME_CASE(SymbolicLog) - INTRINSIC_NAME_CASE(SymbolicExp) - INTRINSIC_NAME_CASE(SymbolicAbs) - INTRINSIC_NAME_CASE(SymbolicHasSymbolQ) - INTRINSIC_NAME_CASE(SymbolicAddQ) - INTRINSIC_NAME_CASE(SymbolicMulQ) - INTRINSIC_NAME_CASE(SymbolicPowQ) - INTRINSIC_NAME_CASE(SymbolicLogQ) - INTRINSIC_NAME_CASE(SymbolicSinQ) - INTRINSIC_NAME_CASE(SymbolicGetArgument) - default : { - throw LCompilersException("pickle: intrinsic_id not implemented"); - } - } -} - -typedef ASR::expr_t* (*impl_function)( - Allocator&, const Location &, - SymbolTable*, Vec&, ASR::ttype_t *, - Vec&, int64_t); - -typedef ASR::expr_t* (*eval_intrinsic_function)( - Allocator&, const Location &, ASR::ttype_t *, - Vec&); - -typedef ASR::asr_t* (*create_intrinsic_function)( - Allocator&, const Location&, - Vec&, - const std::function); - -typedef void (*verify_function)( - const ASR::IntrinsicScalarFunction_t&, - diag::Diagnostics&); - -typedef ASR::expr_t* (*get_initial_value_func)(Allocator&, ASR::ttype_t*); - - -class ASRBuilder { - private: - - Allocator& al; - // TODO: use the location to point C++ code in `intrinsic_function_registry` - const Location &loc; - - public: - - ASRBuilder(Allocator& al_, const Location& loc_): al(al_), loc(loc_) {} - - #define make_ConstantWithKind(Constructor, TypeConstructor, value, kind, loc) ASRUtils::EXPR( \ - ASR::Constructor( al, loc, value, \ - ASRUtils::TYPE(ASR::TypeConstructor(al, loc, 4)))) \ - - #define make_ConstantWithType(Constructor, value, type, loc) ASRUtils::EXPR( \ - ASR::Constructor(al, loc, value, type)) \ - - #define declare_basic_variables(name) \ - std::string fn_name = scope->get_unique_name(name, false); \ - SymbolTable *fn_symtab = al.make_new(scope); \ - ASRBuilder b(al, loc); \ - Vec args; args.reserve(al, 1); \ - Vec body; body.reserve(al, 1); \ - SetChar dep; dep.reserve(al, 1); - - // Symbols ----------------------------------------------------------------- - ASR::expr_t *Variable(SymbolTable *symtab, std::string var_name, - ASR::ttype_t *type, ASR::intentType intent, - ASR::abiType abi=ASR::abiType::Source, bool a_value_attr=false) { - ASR::symbol_t* sym = ASR::down_cast( - ASR::make_Variable_t(al, loc, symtab, s2c(al, var_name), nullptr, 0, - intent, nullptr, nullptr, ASR::storage_typeType::Default, type, nullptr, abi, - ASR::Public, ASR::presenceType::Required, a_value_attr)); - symtab->add_symbol(s2c(al, var_name), sym); - return ASRUtils::EXPR(ASR::make_Var_t(al, loc, sym)); - } - - #define declare(var_name, type, intent) \ - b.Variable(fn_symtab, var_name, type, ASR::intentType::intent) - - #define fill_func_arg(arg_name, type) { \ - auto arg = declare(arg_name, type, In); \ - args.push_back(al, arg); } - - #define make_ASR_Function_t(name, symtab, dep, args, body, return_var, abi, \ - deftype, bindc_name) \ - ASR::down_cast( ASRUtils::make_Function_t_util(al, loc, \ - symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, \ - return_var, abi, ASR::accessType::Public, \ - deftype, bindc_name, false, false, false, false, \ - false, nullptr, 0, false, false, false)); - - #define make_Function_Without_ReturnVar_t(name, symtab, dep, args, body, \ - abi, deftype, bindc_name) \ - ASR::down_cast( ASRUtils::make_Function_t_util(al, loc, \ - symtab, s2c(al, name), dep.p, dep.n, args.p, args.n, body.p, body.n, \ - nullptr, abi, ASR::accessType::Public, \ - deftype, bindc_name, false, false, false, false, \ - false, nullptr, 0, false, false, false)); - - // Types ------------------------------------------------------------------- - #define int32 ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)) - #define int64 TYPE(ASR::make_Integer_t(al, loc, 8)) - #define real32 TYPE(ASR::make_Real_t(al, loc, 4)) - #define real64 TYPE(ASR::make_Real_t(al, loc, 8)) - #define logical ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)) - #define character(x) TYPE(ASR::make_Character_t(al, loc, 1, x, nullptr)) - #define List(x) TYPE(ASR::make_List_t(al, loc, x)) - - ASR::ttype_t *Tuple(std::vector tuple_type) { - Vec m_tuple_type; m_tuple_type.reserve(al, 3); - for (auto &x: tuple_type) { - m_tuple_type.push_back(al, x); - } - return TYPE(ASR::make_Tuple_t(al, loc, m_tuple_type.p, m_tuple_type.n)); - } - ASR::ttype_t *Array(std::vector dims, ASR::ttype_t *type) { - Vec m_dims; m_dims.reserve(al, 1); - for (auto &x: dims) { - ASR::dimension_t dim; - dim.loc = loc; - if (x == -1) { - dim.m_start = nullptr; - dim.m_length = nullptr; - } else { - dim.m_start = EXPR(ASR::make_IntegerConstant_t(al, loc, 1, int32)); - dim.m_length = EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)); - } - m_dims.push_back(al, dim); - } - return make_Array_t_util(al, loc, type, m_dims.p, m_dims.n); - } - - // Expressions ------------------------------------------------------------- - #define i(x, t) EXPR(ASR::make_IntegerConstant_t(al, loc, x, t)) - #define i32(x) ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, x, int32)) - #define i32_n(x) EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, i32(abs(x)), \ - int32, i32(x))) - #define i32_neg(x, t) EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, x, t, nullptr)) - - #define f(x, t) EXPR(ASR::make_RealConstant_t(al, loc, x, t)) - #define f32(x) EXPR(ASR::make_RealConstant_t(al, loc, x, real32)) - #define f32_neg(x, t) EXPR(ASR::make_RealUnaryMinus_t(al, loc, x, t, nullptr)) - - #define bool32(x) EXPR(ASR::make_LogicalConstant_t(al, loc, x, logical)) - - #define ListItem(x, pos, type) EXPR(ASR::make_ListItem_t(al, loc, x, pos, \ - type, nullptr)) - #define ListAppend(x, val) STMT(ASR::make_ListAppend_t(al, loc, x, val)) - - #define StringSection(s, start, end) EXPR(ASR::make_StringSection_t(al, loc,\ - s, start, end, nullptr, character(-2), nullptr)) - #define StringItem(x, idx) EXPR(ASR::make_StringItem_t(al, loc, x, idx, \ - character(-2), nullptr)) - #define StringConstant(s, type) EXPR(ASR::make_StringConstant_t(al, loc, \ - s2c(al, s), type)) - #define StringLen(s) EXPR(ASR::make_StringLen_t(al, loc, s, int32, nullptr)) - - // Cast -------------------------------------------------------------------- - #define r2i32(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::RealToInteger, int32, nullptr)) - #define r2i64(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::RealToInteger, int64, nullptr)) - #define i2r32(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToReal, real32, nullptr)) - #define i2r64(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToReal, real64, nullptr)) - #define i2i(x, t) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToInteger, t, nullptr)) - #define i2i64(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToInteger, int64, nullptr)) - #define i2i32(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToInteger, int32, nullptr)) - #define r2r32(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::RealToReal, real32, nullptr)) - #define r2r64(x) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::RealToReal, real64, nullptr)) - #define r2r(x, t) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::RealToReal, t, nullptr)) - #define i2r(x, t) EXPR(ASR::make_Cast_t(al, loc, x, \ - ASR::cast_kindType::IntegerToReal, t, nullptr)) - - // Binop ------------------------------------------------------------------- - #define iAdd(left, right) EXPR(ASR::make_IntegerBinOp_t(al, loc, left, \ - ASR::binopType::Add, right, int32, nullptr)) - - #define iMul(left, right) EXPR(ASR::make_IntegerBinOp_t(al, loc, left, \ - ASR::binopType::Mul, right, int32, nullptr)) - #define iSub(left, right) EXPR(ASR::make_IntegerBinOp_t(al, loc, left, \ - ASR::binopType::Sub, right, int32, nullptr)) - #define iDiv(left, right) r2i32(EXPR(ASR::make_RealBinOp_t(al, loc, \ - i2r32(left), ASR::binopType::Div, i2r32(right), real32, nullptr))) - #define i64Sub(left, right) EXPR(ASR::make_IntegerBinOp_t(al, loc, left, \ - ASR::binopType::Sub, right, int64, nullptr)) - #define iAdd64(left, right) EXPR(ASR::make_IntegerBinOp_t(al, loc, left, \ - ASR::binopType::Add, right, int64, nullptr)) - #define iDiv64(left, right) r2i64(EXPR(ASR::make_RealBinOp_t(al, loc, \ - i2r32(left), ASR::binopType::Div, i2r32(right), real32, nullptr))) - #define r32Div(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, \ - left, ASR::binopType::Div, right, real32, nullptr)) - #define r64Div(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, \ - left, ASR::binopType::Div, right, real64, nullptr)) - - #define r32Sub(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, left, \ - ASR::binopType::Sub, right, real32, nullptr)) - #define r64Sub(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, left, \ - ASR::binopType::Sub, right, real64, nullptr)) - #define r32Mul(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, left, \ - ASR::binopType::Mul, right, real32, nullptr)) - #define r64Mul(left, right) EXPR(ASR::make_RealBinOp_t(al, loc, left, \ - ASR::binopType::Mul, right, real64, nullptr)) - #define rDiv(left, right) ASRUtils::make_ArrayBroadcast_t_util(al, loc, left, right); \ - EXPR(ASR::make_RealBinOp_t(al, loc, left, \ - ASR::binopType::Div, right, real32, nullptr)) \ - - #define And(x, y) EXPR(ASR::make_LogicalBinOp_t(al, loc, x, \ - ASR::logicalbinopType::And, y, logical, nullptr)) - #define Not(x) EXPR(ASR::make_LogicalNot_t(al, loc, x, logical, nullptr)) - - ASR::expr_t *Add(ASR::expr_t *left, ASR::expr_t *right) { - LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); - ASR::ttype_t *type = expr_type(left); - ASRUtils::make_ArrayBroadcast_t_util(al, loc, left, right); - switch (type->type) { - case ASR::ttypeType::Integer : { - return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, - ASR::binopType::Add, right, type, nullptr)); - break; - } - case ASR::ttypeType::Real : { - return EXPR(ASR::make_RealBinOp_t(al, loc, left, - ASR::binopType::Add, right, type, nullptr)); - break; - } - default: { - LCOMPILERS_ASSERT(false); - return nullptr; - } - } - } - - ASR::expr_t *Mul(ASR::expr_t *left, ASR::expr_t *right) { - LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); - ASR::ttype_t *type = expr_type(left); - ASRUtils::make_ArrayBroadcast_t_util(al, loc, left, right); - switch (type->type) { - case ASR::ttypeType::Integer : { - return EXPR(ASR::make_IntegerBinOp_t(al, loc, left, - ASR::binopType::Mul, right, type, nullptr)); - break; - } - case ASR::ttypeType::Real : { - return EXPR(ASR::make_RealBinOp_t(al, loc, left, - ASR::binopType::Mul, right, type, nullptr)); - break; - } - default: { - LCOMPILERS_ASSERT(false); - return nullptr; - } - } - } - - // Compare ----------------------------------------------------------------- - #define iEq(x, y) ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::Eq, y, logical, nullptr)) - #define iNotEq(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::NotEq, y, logical, nullptr)) - #define iLt(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::Lt, y, logical, nullptr)) - #define iLtE(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::LtE, y, logical, nullptr)) - #define iGtE(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::GtE, y, logical, nullptr)) - #define iGt(x, y) EXPR(ASR::make_IntegerCompare_t(al, loc, x, \ - ASR::cmpopType::Gt, y, logical, nullptr)) - - #define ArraySize_1(x, dim) EXPR(make_ArraySize_t_util(al, loc, x, dim, \ - int32, nullptr)) - #define ArraySize_2(x, dim, t) EXPR(make_ArraySize_t_util(al, loc, x, dim, \ - t, nullptr)) - - #define fGtE(x, y) EXPR(ASR::make_RealCompare_t(al, loc, x, \ - ASR::cmpopType::GtE, y, logical, nullptr)) - #define fLt(x, y) EXPR(ASR::make_RealCompare_t(al, loc, x, \ - ASR::cmpopType::Lt, y, logical, nullptr)) - #define fGt(x, y) EXPR(ASR::make_RealCompare_t(al, loc, x, \ - ASR::cmpopType::Gt, y, logical, nullptr)) - #define fNotEq(x, y) EXPR(ASR::make_RealCompare_t(al, loc, x, \ - ASR::cmpopType::NotEq, y, logical, nullptr)) - - #define sEq(x, y) EXPR(ASR::make_StringCompare_t(al, loc, x, \ - ASR::cmpopType::Eq, y, logical, nullptr)) - #define sNotEq(x, y) EXPR(ASR::make_StringCompare_t(al, loc, x, \ - ASR::cmpopType::NotEq, y, logical, nullptr)) - - ASR::expr_t *Gt(ASR::expr_t *left, ASR::expr_t *right) { - LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); - if (is_real(*expr_type(left))) { - return fGt(left, right); - } else if (is_integer(*expr_type(left))) { - return iGt(left, right); - } else { - LCOMPILERS_ASSERT(false); - return nullptr; - } - } - - ASR::expr_t *Lt(ASR::expr_t *left, ASR::expr_t *right) { - LCOMPILERS_ASSERT(check_equal_type(expr_type(left), expr_type(right))); - if (is_real(*expr_type(left))) { - return fLt(left, right); - } else if (is_integer(*expr_type(left))) { - return iLt(left, right); - } else { - LCOMPILERS_ASSERT(false); - return nullptr; - } - } - - ASR::stmt_t *If(ASR::expr_t *a_test, std::vector if_body, - std::vector else_body) { - Vec m_if_body; m_if_body.reserve(al, 1); - for (auto &x: if_body) m_if_body.push_back(al, x); - - Vec m_else_body; m_else_body.reserve(al, 1); - for (auto &x: else_body) m_else_body.push_back(al, x); - - return STMT(ASR::make_If_t(al, loc, a_test, m_if_body.p, m_if_body.n, - m_else_body.p, m_else_body.n)); - } - - ASR::stmt_t *While(ASR::expr_t *a_test, std::vector body) { - Vec m_body; m_body.reserve(al, 1); - for (auto &x: body) m_body.push_back(al, x); - - return STMT(ASR::make_WhileLoop_t(al, loc, nullptr, a_test, - m_body.p, m_body.n, nullptr, 0)); - } - - ASR::expr_t *TupleConstant(std::vector ele, ASR::ttype_t *type) { - Vec m_ele; m_ele.reserve(al, 3); - for (auto &x: ele) m_ele.push_back(al, x); - return EXPR(ASR::make_TupleConstant_t(al, loc, m_ele.p, m_ele.n, type)); - } - - #define make_Compare(Constructor, left, op, right) ASRUtils::EXPR(ASR::Constructor( \ - al, loc, left, ASR::cmpopType::op, right, \ - ASRUtils::TYPE(ASR::make_Logical_t( \ - al, loc, 4)), nullptr)); \ - - #define create_ElementalBinOp(OpType, BinOpName, OpName, value) case ASR::ttypeType::OpType: { \ - return ASRUtils::EXPR(ASR::BinOpName(al, loc, \ - left, ASR::binopType::OpName, right, \ - ASRUtils::expr_type(left), value)); \ - } \ - - ASR::expr_t* ElementalAdd(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - ASR::ttype_t *left_type = ASRUtils::expr_type(left); - left_type = ASRUtils::type_get_past_pointer(left_type); - switch (left_type->type) { - create_ElementalBinOp(Real, make_RealBinOp_t, Add, value) - create_ElementalBinOp(Integer, make_IntegerBinOp_t, Add, value) - create_ElementalBinOp(Complex, make_ComplexBinOp_t, Add, value) - default: { - throw LCompilersException("Expression type, " + - std::to_string(left_type->type) + - " not yet supported"); - } - } - } - - ASR::expr_t* ElementalSub(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - switch (ASRUtils::expr_type(left)->type) { - create_ElementalBinOp(Real, make_RealBinOp_t, Sub, value) - create_ElementalBinOp(Integer, make_IntegerBinOp_t, Sub, value) - create_ElementalBinOp(Complex, make_ComplexBinOp_t, Sub, value) - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + - " not yet supported"); - } - } - } - - ASR::expr_t* ElementalDiv(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - switch (ASRUtils::expr_type(left)->type) { - create_ElementalBinOp(Real, make_RealBinOp_t, Div, value) - create_ElementalBinOp(Integer, make_IntegerBinOp_t, Div, value) - create_ElementalBinOp(Complex, make_ComplexBinOp_t, Div, value) - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + - " not yet supported"); - } - } - } - - ASR::expr_t* ElementalMul(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - switch (ASRUtils::expr_type(left)->type) { - create_ElementalBinOp(Real, make_RealBinOp_t, Mul, value) - create_ElementalBinOp(Integer, make_IntegerBinOp_t, Mul, value) - create_ElementalBinOp(Complex, make_ComplexBinOp_t, Mul, value) - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + - " not yet supported"); - } - } - } - - ASR::expr_t* ElementalPow(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - switch (ASRUtils::expr_type(left)->type) { - create_ElementalBinOp(Real, make_RealBinOp_t, Pow, value) - create_ElementalBinOp(Integer, make_IntegerBinOp_t, Pow, value) - create_ElementalBinOp(Complex, make_ComplexBinOp_t, Pow, value) - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + - " not yet supported"); - } - } - } - - ASR::expr_t* ElementalMax(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - ASR::expr_t* test_condition = nullptr; - switch (ASRUtils::expr_type(left)->type) { - case ASR::ttypeType::Integer: { - test_condition = make_Compare(make_IntegerCompare_t, left, Gt, right); - break; - } - case ASR::ttypeType::Real: { - test_condition = make_Compare(make_RealCompare_t, left, Gt, right); - break; - } - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + " not yet supported"); - } - } - return ASRUtils::EXPR(ASR::make_IfExp_t(al, loc, test_condition, left, right, ASRUtils::expr_type(left), value)); - } - - ASR::expr_t* ElementalMin(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc, ASR::expr_t* value=nullptr) { - ASR::expr_t* test_condition = nullptr; - switch (ASRUtils::expr_type(left)->type) { - case ASR::ttypeType::Integer: { - test_condition = make_Compare(make_IntegerCompare_t, left, Lt, right); - break; - } - case ASR::ttypeType::Real: { - test_condition = make_Compare(make_RealCompare_t, left, Lt, right); - break; - } - default: { - throw LCompilersException("Expression type, " + - std::to_string(expr_type(left)->type) + " not yet supported"); - } - } - return ASRUtils::EXPR(ASR::make_IfExp_t(al, loc, test_condition, left, right, ASRUtils::expr_type(left), value)); - } - - ASR::expr_t* ElementalOr(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc) { - return ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, - left, ASR::Or, right, - ASRUtils::TYPE(ASR::make_Logical_t( al, loc, 4)), nullptr)); - } - - ASR::expr_t* Or(ASR::expr_t* left, ASR::expr_t* right, - const Location& loc) { - return ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, - left, ASR::Or, right, ASRUtils::expr_type(left), - nullptr)); - } - - ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, - ASR::ttype_t* return_type) { - return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - s, s, args.p, args.size(), return_type, nullptr, nullptr)); - } - - ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, - ASR::ttype_t* return_type) { - Vec args_; args_.reserve(al, 2); - visit_expr_list(al, args, args_); - return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - s, s, args_.p, args_.size(), return_type, nullptr, nullptr)); - } - - ASR::expr_t* Call(ASR::symbol_t* s, Vec& args, - ASR::ttype_t* return_type, ASR::expr_t* value) { - return ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util(al, loc, - s, s, args.p, args.size(), return_type, value, nullptr)); - } - - ASR::expr_t *ArrayItem_01(ASR::expr_t *arr, std::vector idx) { - Vec idx_vars; idx_vars.reserve(al, 1); - for (auto &x: idx) idx_vars.push_back(al, x); - return PassUtils::create_array_ref(arr, idx_vars, al); - } - - #define ArrayItem_02(arr, idx_vars) PassUtils::create_array_ref(arr, \ - idx_vars, al) - - ASR::expr_t *ArrayConstant(std::vector elements, - ASR::ttype_t *base_type, bool cast2descriptor=true) { - // This function only creates array with rank one - // TODO: Support other dimensions - Vec m_eles; m_eles.reserve(al, 1); - for (auto &x: elements) m_eles.push_back(al, x); - - ASR::ttype_t *fixed_size_type = Array({(int64_t) elements.size()}, base_type); - ASR::expr_t *arr_constant = EXPR(ASR::make_ArrayConstant_t(al, loc, - m_eles.p, m_eles.n, fixed_size_type, ASR::arraystorageType::ColMajor)); - - if (cast2descriptor) { - return cast_to_descriptor(al, arr_constant); - } else { - return arr_constant; - } - } - - ASR::dimension_t set_dim(ASR::expr_t *start, ASR::expr_t *length) { - ASR::dimension_t dim; - dim.loc = loc; - dim.m_start = start; - dim.m_length = length; - return dim; - } - - // Statements -------------------------------------------------------------- - #define Return() STMT(ASR::make_Return_t(al, loc)) - - ASR::stmt_t *Assignment(ASR::expr_t *lhs, ASR::expr_t *rhs) { - LCOMPILERS_ASSERT(check_equal_type(expr_type(lhs), expr_type(rhs))); - return STMT(ASR::make_Assignment_t(al, loc, lhs, rhs, nullptr)); - } - - template - ASR::stmt_t *Assign_Constant(ASR::expr_t *lhs, T init_value) { - ASR::ttype_t *type = expr_type(lhs); - switch(type->type) { - case ASR::ttypeType::Integer : { - return Assignment(lhs, i(init_value, type)); - } - case ASR::ttypeType::Real : { - return Assignment(lhs, f(init_value, type)); - } - default : { - LCOMPILERS_ASSERT(false); - return nullptr; - } - } - } - - ASR::stmt_t *Allocate(ASR::expr_t *m_a, Vec dims) { - Vec alloc_args; alloc_args.reserve(al, 1); - ASR::alloc_arg_t alloc_arg; - alloc_arg.loc = loc; - alloc_arg.m_a = m_a; - alloc_arg.m_dims = dims.p; - alloc_arg.n_dims = dims.n; - alloc_arg.m_type = nullptr; - alloc_arg.m_len_expr = nullptr; - alloc_args.push_back(al, alloc_arg); - return STMT(ASR::make_Allocate_t(al, loc, alloc_args.p, 1, - nullptr, nullptr, nullptr)); - } - - #define UBound(arr, dim) PassUtils::get_bound(arr, dim, "ubound", al) - #define LBound(arr, dim) PassUtils::get_bound(arr, dim, "lbound", al) - - ASR::stmt_t *DoLoop(ASR::expr_t *m_v, ASR::expr_t *start, ASR::expr_t *end, - std::vector loop_body, ASR::expr_t *step=nullptr) { - ASR::do_loop_head_t head; - head.loc = m_v->base.loc; - head.m_v = m_v; - head.m_start = start; - head.m_end = end; - head.m_increment = step; - Vec body; - body.from_pointer_n_copy(al, &loop_body[0], loop_body.size()); - return STMT(ASR::make_DoLoop_t(al, loc, nullptr, head, body.p, body.n, nullptr, 0)); - } - - template - ASR::stmt_t* create_do_loop( - const Location& loc, int rank, ASR::expr_t* array, - SymbolTable* scope, Vec& idx_vars, - Vec& doloop_body, LOOP_BODY loop_body) { - PassUtils::create_idx_vars(idx_vars, rank, loc, al, scope, "_i"); - - ASR::stmt_t* doloop = nullptr; - for( int i = (int) idx_vars.size() - 1; i >= 0; i-- ) { - ASR::do_loop_head_t head; - head.m_v = idx_vars[i]; - head.m_start = PassUtils::get_bound(array, i + 1, "lbound", al); - head.m_end = PassUtils::get_bound(array, i + 1, "ubound", al); - head.m_increment = nullptr; - - head.loc = head.m_v->base.loc; - doloop_body.reserve(al, 1); - if( doloop == nullptr ) { - loop_body(); - } else { - doloop_body.push_back(al, doloop); - } - doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, - head, doloop_body.p, doloop_body.size(), nullptr, 0)); - } - return doloop; - } - - template - ASR::stmt_t* create_do_loop( - const Location& loc, ASR::expr_t* array, - Vec& loop_vars, std::vector& loop_dims, - Vec& doloop_body, LOOP_BODY loop_body) { - - ASR::stmt_t* doloop = nullptr; - for( int i = (int) loop_vars.size() - 1; i >= 0; i-- ) { - ASR::do_loop_head_t head; - head.m_v = loop_vars[i]; - head.m_start = PassUtils::get_bound(array, loop_dims[i], "lbound", al); - head.m_end = PassUtils::get_bound(array, loop_dims[i], "ubound", al); - head.m_increment = nullptr; - - head.loc = head.m_v->base.loc; - doloop_body.reserve(al, 1); - if( doloop == nullptr ) { - loop_body(); - } else { - doloop_body.push_back(al, doloop); - } - doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, - head, doloop_body.p, doloop_body.size(), nullptr, 0)); - } - return doloop; - } - - template - void generate_reduction_intrinsic_stmts_for_scalar_output(const Location& loc, - ASR::expr_t* array, SymbolTable* fn_scope, - Vec& fn_body, Vec& idx_vars, - Vec& doloop_body, INIT init_stmts, LOOP_BODY loop_body) { - init_stmts(); - int rank = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(array)); - ASR::stmt_t* doloop = create_do_loop(loc, - rank, array, fn_scope, idx_vars, doloop_body, - loop_body); - fn_body.push_back(al, doloop); - } - - template - void generate_reduction_intrinsic_stmts_for_array_output(const Location& loc, - ASR::expr_t* array, ASR::expr_t* dim, SymbolTable* fn_scope, - Vec& fn_body, Vec& idx_vars, - Vec& target_idx_vars, Vec& doloop_body, - INIT init_stmts, LOOP_BODY loop_body) { - init_stmts(); - int n_dims = ASRUtils::extract_n_dims_from_ttype(ASRUtils::expr_type(array)); - ASR::stmt_t** else_ = nullptr; - size_t else_n = 0; - idx_vars.reserve(al, n_dims); - PassUtils::create_idx_vars(idx_vars, n_dims, loc, al, fn_scope, "_j"); - for( int i = 1; i <= n_dims; i++ ) { - ASR::expr_t* current_dim = i32(i); - ASR::expr_t* test_expr = make_Compare(make_IntegerCompare_t, dim, - Eq, current_dim); - - Vec loop_vars; - std::vector loop_dims; - loop_dims.reserve(n_dims); - loop_vars.reserve(al, n_dims); - target_idx_vars.reserve(al, n_dims - 1); - for( int j = 1; j <= n_dims; j++ ) { - if( j == i ) { - continue ; - } - target_idx_vars.push_back(al, idx_vars[j - 1]); - loop_dims.push_back(j); - loop_vars.push_back(al, idx_vars[j - 1]); - } - loop_dims.push_back(i); - loop_vars.push_back(al, idx_vars[i - 1]); - - ASR::stmt_t* doloop = create_do_loop(loc, - array, loop_vars, loop_dims, doloop_body, - loop_body); - Vec if_body; - if_body.reserve(al, 1); - if_body.push_back(al, doloop); - ASR::stmt_t* if_ = ASRUtils::STMT(ASR::make_If_t(al, loc, test_expr, - if_body.p, if_body.size(), else_, else_n)); - Vec if_else_if; - if_else_if.reserve(al, 1); - if_else_if.push_back(al, if_); - else_ = if_else_if.p; - else_n = if_else_if.size(); - } - fn_body.push_back(al, else_[0]); - } - - ASR::stmt_t *Print(std::vector items) { - // Used for debugging - Vec x_exprs; - x_exprs.from_pointer_n_copy(al, &items[0], items.size()); - return STMT(ASR::make_Print_t(al, loc, x_exprs.p, x_exprs.n, - nullptr, nullptr)); - } - -}; - -namespace UnaryIntrinsicFunction { - -static inline ASR::expr_t* instantiate_functions(Allocator &al, - const Location &loc, SymbolTable *scope, std::string new_name, - ASR::ttype_t *arg_type, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string c_func_name; - switch (arg_type->type) { - case ASR::ttypeType::Complex : { - if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { - c_func_name = "_lfortran_c" + new_name; - } else { - c_func_name = "_lfortran_z" + new_name; - } - break; - } - default : { - if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { - c_func_name = "_lfortran_s" + new_name; - } else { - c_func_name = "_lfortran_d" + new_name; - } - } - } - new_name = "_lcompilers_" + new_name + "_" + type_to_str_python(arg_type); - - declare_basic_variables(new_name); - if (scope->get_symbol(new_name)) { - ASR::symbol_t *s = scope->get_symbol(new_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var)); - } - fill_func_arg("x", arg_type); - auto result = declare(new_name, return_type, ReturnVar); - - { - SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); - Vec args_1; - { - args_1.reserve(al, 1); - ASR::expr_t *arg = b.Variable(fn_symtab_1, "x", arg_type, - ASR::intentType::In, ASR::abiType::BindC, true); - args_1.push_back(al, arg); - } - - ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, - arg_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); - - SetChar dep_1; dep_1.reserve(al, 1); - Vec body_1; body_1.reserve(al, 1); - ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, - body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); - fn_symtab->add_symbol(c_func_name, s); - dep.push_back(al, s2c(al, c_func_name)); - body.push_back(al, b.Assignment(result, b.Call(s, args, arg_type))); - } - - ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, new_symbol); - return b.Call(new_symbol, new_args, return_type); -} - -static inline ASR::asr_t* create_UnaryFunction(Allocator& al, const Location& loc, - Vec& args, eval_intrinsic_function eval_function, - int64_t intrinsic_id, int64_t overload_id, ASR::ttype_t* type) { - ASR::expr_t *value = nullptr; - ASR::expr_t *arg_value = ASRUtils::expr_value(args[0]); - if (arg_value) { - Vec arg_values; - arg_values.reserve(al, 1); - arg_values.push_back(al, arg_value); - value = eval_function(al, loc, type, arg_values); - } - - return ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, intrinsic_id, - args.p, args.n, overload_id, type, value); -} - -static inline ASR::symbol_t *create_KMP_function(Allocator &al, - const Location &loc, SymbolTable *scope) -{ - /* - * Knuth-Morris-Pratt (KMP) string-matching - * This function takes two parameters: - * the sub-string or pattern string and the target string, - * then returns the position of the first occurrence of the - * string in the pattern. - */ - declare_basic_variables("KMP_string_matching"); - fill_func_arg("target_string", character(-2)); - fill_func_arg("pattern", character(-2)); - - auto result = declare("result", int32, ReturnVar); - auto pi_len = declare("pi_len", int32, Local); - auto i = declare("i", int32, Local); - auto j = declare("j", int32, Local); - auto s_len = declare("s_len", int32, Local); - auto pat_len = declare("pat_len", int32, Local); - auto flag = declare("flag", logical, Local); - auto lps = declare("lps", List(int32), Local); - - body.push_back(al, b.Assignment(s_len, StringLen(args[0]))); - body.push_back(al, b.Assignment(pat_len, StringLen(args[1]))); - body.push_back(al, b.Assignment(result, i32_n(-1))); - body.push_back(al, b.If(iEq(pat_len, i32(0)), { - b.Assignment(result, i32(0)), Return() - }, { - b.If(iEq(s_len, i32(0)), { Return() }, {}) - })); - body.push_back(al, b.Assignment(lps, - EXPR(ASR::make_ListConstant_t(al, loc, nullptr, 0, List(int32))))); - body.push_back(al, b.Assignment(i, i32(0))); - body.push_back(al, b.While(iLtE(i, iSub(pat_len, i32(1))), { - b.Assignment(i, iAdd(i, i32(1))), - ListAppend(lps, i32(0)) - })); - body.push_back(al, b.Assignment(flag, bool32(false))); - body.push_back(al, b.Assignment(i, i32(1))); - body.push_back(al, b.Assignment(pi_len, i32(0))); - body.push_back(al, b.While(iLt(i, pat_len), { - b.If(sEq(StringItem(args[1], iAdd(i, i32(1))), - StringItem(args[1], iAdd(pi_len, i32(1)))), { - b.Assignment(pi_len, iAdd(pi_len, i32(1))), - b.Assignment(ListItem(lps, i, int32), pi_len), - b.Assignment(i, iAdd(i, i32(1))) - }, { - b.If(iNotEq(pi_len, i32(0)), { - b.Assignment(pi_len, ListItem(lps, iSub(pi_len, i32(1)), int32)) - }, { - b.Assignment(i, iAdd(i, i32(1))) - }) - }) - })); - body.push_back(al, b.Assignment(j, i32(0))); - body.push_back(al, b.Assignment(i, i32(0))); - body.push_back(al, b.While(And(iGtE(iSub(s_len, i), - iSub(pat_len, j)), Not(flag)), { - b.If(sEq(StringItem(args[1], iAdd(j, i32(1))), - StringItem(args[0], iAdd(i, i32(1)))), { - b.Assignment(i, iAdd(i, i32(1))), - b.Assignment(j, iAdd(j, i32(1))) - }, {}), - b.If(iEq(j, pat_len), { - b.Assignment(result, iSub(i, j)), - b.Assignment(flag, bool32(true)), - b.Assignment(j, ListItem(lps, iSub(j, i32(1)), int32)) - }, { - b.If(And(iLt(i, s_len), sNotEq(StringItem(args[1], iAdd(j, i32(1))), - StringItem(args[0], iAdd(i, i32(1))))), { - b.If(iNotEq(j, i32(0)), { - b.Assignment(j, ListItem(lps, iSub(j, i32(1)), int32)) - }, { - b.Assignment(i, iAdd(i, i32(1))) - }) - }, {}) - }) - })); - body.push_back(al, Return()); - ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, fn_sym); - return fn_sym; -} - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - const Location& loc = x.base.base.loc; - ASRUtils::require_impl(x.n_args == 1, - "Elemental intrinsics must have only 1 input argument", - loc, diagnostics); - - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t* output_type = x.m_type; - ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), - "The input and output type of elemental intrinsics must exactly match, input type: " + - ASRUtils::get_type_code(input_type) + " output type: " + ASRUtils::get_type_code(output_type), - loc, diagnostics); -} - -} // namespace UnaryIntrinsicFunction - -namespace BinaryIntrinsicFunction { - -static inline ASR::expr_t* instantiate_functions(Allocator &al, - const Location &loc, SymbolTable *scope, std::string new_name, - ASR::ttype_t *arg_type, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string c_func_name; - switch (arg_type->type) { - case ASR::ttypeType::Complex : { - if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { - c_func_name = "_lfortran_c" + new_name; - } else { - c_func_name = "_lfortran_z" + new_name; - } - break; - } - default : { - if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { - c_func_name = "_lfortran_s" + new_name; - } else { - c_func_name = "_lfortran_d" + new_name; - } - } - } - new_name = "_lcompilers_" + new_name + "_" + type_to_str_python(arg_type); - - declare_basic_variables(new_name); - if (scope->get_symbol(new_name)) { - ASR::symbol_t *s = scope->get_symbol(new_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var)); - } - fill_func_arg("x", arg_type); - fill_func_arg("y", arg_type) - auto result = declare(new_name, return_type, ReturnVar); - - { - SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); - Vec args_1; - { - args_1.reserve(al, 2); - ASR::expr_t *arg_1 = b.Variable(fn_symtab_1, "x", arg_type, - ASR::intentType::In, ASR::abiType::BindC, true); - ASR::expr_t *arg_2 = b.Variable(fn_symtab_1, "y", arg_type, - ASR::intentType::In, ASR::abiType::BindC, true); - args_1.push_back(al, arg_1); - args_1.push_back(al, arg_2); - } - - ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, - arg_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); - - SetChar dep_1; dep_1.reserve(al, 1); - Vec body_1; body_1.reserve(al, 1); - ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, - body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); - fn_symtab->add_symbol(c_func_name, s); - dep.push_back(al, s2c(al, c_func_name)); - body.push_back(al, b.Assignment(result, b.Call(s, args, arg_type))); - } - - ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, new_symbol); - return b.Call(new_symbol, new_args, return_type); -} - -static inline ASR::asr_t* create_BinaryFunction(Allocator& al, const Location& loc, - Vec& args, eval_intrinsic_function eval_function, - int64_t intrinsic_id, int64_t overload_id, ASR::ttype_t* type) { - ASR::expr_t *value = nullptr; - ASR::expr_t *arg_value_1 = ASRUtils::expr_value(args[0]); - ASR::expr_t *arg_value_2 = ASRUtils::expr_value(args[1]); - if (arg_value_1 && arg_value_2) { - Vec arg_values; - arg_values.reserve(al, 2); - arg_values.push_back(al, arg_value_1); - arg_values.push_back(al, arg_value_2); - value = eval_function(al, loc, type, arg_values); - } - - return ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, intrinsic_id, - args.p, args.n, overload_id, type, value); -} - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - const Location& loc = x.base.base.loc; - ASRUtils::require_impl(x.n_args == 2, - "Binary intrinsics must have only 2 input arguments", - loc, diagnostics); - - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t* input_type_2 = ASRUtils::expr_type(x.m_args[1]); - ASR::ttype_t* output_type = x.m_type; - ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, input_type_2, true), - "The types of both the arguments of binary intrinsics must exactly match, argument 1 type: " + - ASRUtils::get_type_code(input_type) + " argument 2 type: " + ASRUtils::get_type_code(input_type_2), - loc, diagnostics); - ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), - "The input and output type of elemental intrinsics must exactly match, input type: " + - ASRUtils::get_type_code(input_type) + " output type: " + ASRUtils::get_type_code(output_type), - loc, diagnostics); -} - -} // namespace BinaryIntrinsicFunction - - -namespace ObjectType { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, - "ASR Verify: type() takes only 1 argument `object`", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_ObjectType(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec& /*args*/) { - std::string object_type = "type) { - case ASR::ttypeType::Integer : { - object_type += "int"; break; - } case ASR::ttypeType::Real : { - object_type += "float"; break; - } case ASR::ttypeType::Character : { - object_type += "str"; break; - } case ASR::ttypeType::List : { - object_type += "list"; break; - } case ASR::ttypeType::Dict : { - object_type += "dict"; break; - } default: { - LCOMPILERS_ASSERT_MSG(false, "Unsupported type"); - break; - } - } - object_type += "'>"; - return StringConstant(object_type, character(object_type.length())); - } - - static inline ASR::asr_t* create_ObjectType(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("type() takes exactly 1 argument `object` for now", loc); - } - ASR::expr_t *m_value = nullptr; - Vec arg_values; - - m_value = eval_ObjectType(al, loc, expr_type(args[0]), arg_values); - - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::ObjectType), - args.p, args.n, 0, ASRUtils::expr_type(m_value), m_value); - } - - -} // namespace ObjectType - - -namespace LogGamma { - -static inline ASR::expr_t *eval_log_gamma(Allocator &al, const Location &loc, - ASR::ttype_t *t, Vec& args) { - double rv = ASR::down_cast(args[0])->m_r; - double val = lgamma(rv); - return make_ConstantWithType(make_RealConstant_t, val, t, loc); -} - -static inline ASR::asr_t* create_LogGamma(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); - - if (args.n != 1) { - err("Intrinsic `log_gamma` accepts exactly one argument", loc); - } else if (!ASRUtils::is_real(*type)) { - err("`x` argument of `log_gamma` must be real", - args[0]->base.loc); - } - - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, - eval_log_gamma, static_cast(IntrinsicScalarFunctions::LogGamma), - 0, type); -} - -static inline ASR::expr_t* instantiate_LogGamma (Allocator &al, - const Location &loc, SymbolTable *scope, Vec& arg_types, - ASR::ttype_t *return_type, Vec& new_args, - int64_t overload_id) { - ASR::ttype_t* arg_type = arg_types[0]; - return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, - "log_gamma", arg_type, return_type, new_args, overload_id); -} - -} // namespace LogGamma - -#define create_trunc_macro(X, stdeval) \ -namespace X { \ - static inline ASR::expr_t *eval_##X(Allocator &al, const Location &loc, \ - ASR::ttype_t *t, Vec& args) { \ - LCOMPILERS_ASSERT(args.size() == 1); \ - double rv = ASR::down_cast(args[0])->m_r; \ - if (ASRUtils::extract_value(args[0], rv)) { \ - double val = std::stdeval(rv); \ - return make_ConstantWithType(make_RealConstant_t, val, t, loc); \ - } \ - return nullptr; \ - } \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) { \ - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ - if (args.n != 1) { \ - err("Intrinsic `#X` accepts exactly one argument", loc); \ - } else if (!ASRUtils::is_real(*type)) { \ - err("`x` argument of `#X` must be real", \ - args[0]->base.loc); \ - } \ - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, \ - eval_##X, static_cast(IntrinsicScalarFunctions::Trunc), \ - 0, type); \ - } \ - static inline ASR::expr_t* instantiate_##X (Allocator &al, \ - const Location &loc, SymbolTable *scope, Vec& arg_types, \ - ASR::ttype_t *return_type, Vec& new_args, \ - int64_t overload_id) { \ - ASR::ttype_t* arg_type = arg_types[0]; \ - return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, \ - "#X", arg_type, return_type, new_args, overload_id); \ - } \ -} // namespace X - -create_trunc_macro(Trunc, trunc) - -namespace Fix { - static inline ASR::expr_t *eval_Fix(Allocator &al, const Location &loc, - ASR::ttype_t *t, Vec& args) { - LCOMPILERS_ASSERT(args.size() == 1); - double rv = ASR::down_cast(args[0])->m_r; - double val; - if (rv > 0.0) { - val = floor(rv); - } else { - val = ceil(rv); - } - return make_ConstantWithType(make_RealConstant_t, val, t, loc); - } - - static inline ASR::asr_t* create_Fix(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); - if (args.n != 1) { - err("Intrinsic `fix` accepts exactly one argument", loc); - } else if (!ASRUtils::is_real(*type)) { - err("`fix` argument of `fix` must be real", - args[0]->base.loc); - } - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, - eval_Fix, static_cast(IntrinsicScalarFunctions::Fix), - 0, type); - } - - static inline ASR::expr_t* instantiate_Fix (Allocator &al, - const Location &loc, SymbolTable *scope, Vec& arg_types, - ASR::ttype_t *return_type, Vec& new_args, - int64_t overload_id) { - ASR::ttype_t* arg_type = arg_types[0]; - return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, - "fix", arg_type, return_type, new_args, overload_id); - } - -} // namespace Fix - -// `X` is the name of the function in the IntrinsicScalarFunctions enum and -// we use the same name for `create_X` and other places -// `stdeval` is the name of the function in the `std` namespace for compile -// numerical time evaluation -// `lcompilers_name` is the name that we use in the C runtime library -#define create_trig(X, stdeval, lcompilers_name) \ -namespace X { \ - static inline ASR::expr_t *eval_##X(Allocator &al, const Location &loc, \ - ASR::ttype_t *t, Vec& args) { \ - LCOMPILERS_ASSERT(args.size() == 1); \ - double rv = -1; \ - if( ASRUtils::extract_value(args[0], rv) ) { \ - double val = std::stdeval(rv); \ - return make_ConstantWithType(make_RealConstant_t, val, t, loc); \ - } else { \ - std::complex crv; \ - if( ASRUtils::extract_value(args[0], crv) ) { \ - std::complex val = std::stdeval(crv); \ - return ASRUtils::EXPR(ASR::make_ComplexConstant_t( \ - al, loc, val.real(), val.imag(), t)); \ - } \ - } \ - return nullptr; \ - } \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) \ - { \ - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ - if (args.n != 1) { \ - err("Intrinsic `"#X"` accepts exactly one argument", loc); \ - } else if (!ASRUtils::is_real(*type) && !ASRUtils::is_complex(*type)) { \ - err("`x` argument of `"#X"` must be real or complex", \ - args[0]->base.loc); \ - } \ - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, \ - eval_##X, static_cast(IntrinsicScalarFunctions::X), \ - 0, type); \ - } \ - static inline ASR::expr_t* instantiate_##X (Allocator &al, \ - const Location &loc, SymbolTable *scope, \ - Vec& arg_types, ASR::ttype_t *return_type, \ - Vec& new_args,int64_t overload_id) { \ - ASR::ttype_t* arg_type = arg_types[0]; \ - return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, \ - #lcompilers_name, arg_type, return_type, new_args, overload_id); \ - } \ -} // namespace X - -create_trig(Sin, sin, sin) -create_trig(Cos, cos, cos) -create_trig(Tan, tan, tan) -create_trig(Asin, asin, asin) -create_trig(Acos, acos, acos) -create_trig(Atan, atan, atan) -create_trig(Sinh, sinh, sinh) -create_trig(Cosh, cosh, cosh) -create_trig(Tanh, tanh, tanh) - -namespace Atan2 { - static inline ASR::expr_t *eval_Atan2(Allocator &al, const Location &loc, - ASR::ttype_t *t, Vec& args) { - LCOMPILERS_ASSERT(args.size() == 2); - double rv = -1, rv2 = -1; - if( ASRUtils::extract_value(args[0], rv) && ASRUtils::extract_value(args[1], rv2) ) { - double val = std::atan2(rv,rv2); - return make_ConstantWithType(make_RealConstant_t, val, t, loc); - } - return nullptr; - } - static inline ASR::asr_t* create_Atan2(Allocator& al, const Location& loc, - Vec& args, - const std::function err) - { - ASR::ttype_t *type_1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type_2 = ASRUtils::expr_type(args[1]); - if (!ASRUtils::is_real(*type_1)) { - err("`x` argument of \"atan2\" must be real",args[0]->base.loc); - } else if (!ASRUtils::is_real(*type_2)) { - err("`y` argument of \"atan2\" must be real",args[1]->base.loc); - } - return BinaryIntrinsicFunction::create_BinaryFunction(al, loc, args, - eval_Atan2, static_cast(IntrinsicScalarFunctions::Atan2), - 0, type_1); - } - static inline ASR::expr_t* instantiate_Atan2 (Allocator &al, - const Location &loc, SymbolTable *scope, - Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args,int64_t overload_id) { - ASR::ttype_t* arg_type = arg_types[0]; - return BinaryIntrinsicFunction::instantiate_functions(al, loc, scope, - "atan2", arg_type, return_type, new_args, overload_id); - } -} - -namespace Abs { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - const Location& loc = x.base.base.loc; - ASRUtils::require_impl(x.n_args == 1, - "Elemental intrinsics must have only 1 input argument", - loc, diagnostics); - - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t* output_type = x.m_type; - std::string input_type_str = ASRUtils::get_type_code(input_type); - std::string output_type_str = ASRUtils::get_type_code(output_type); - if( ASR::is_a(*ASRUtils::type_get_past_pointer(input_type)) ) { - ASRUtils::require_impl(ASR::is_a(*output_type), - "Abs intrinsic must return output of real for complex input, found: " + output_type_str, - loc, diagnostics); - int input_kind = ASRUtils::extract_kind_from_ttype_t(input_type); - int output_kind = ASRUtils::extract_kind_from_ttype_t(output_type); - ASRUtils::require_impl(input_kind == output_kind, - "The input and output type of Abs intrinsic must be of same kind, input kind: " + - std::to_string(input_kind) + " output kind: " + std::to_string(output_kind), - loc, diagnostics); - ASR::dimension_t *input_dims, *output_dims; - size_t input_n_dims = ASRUtils::extract_dimensions_from_ttype(input_type, input_dims); - size_t output_n_dims = ASRUtils::extract_dimensions_from_ttype(output_type, output_dims); - ASRUtils::require_impl(ASRUtils::dimensions_equal(input_dims, input_n_dims, output_dims, output_n_dims), - "The dimensions of input and output arguments of Abs intrinsic must be same, input: " + - input_type_str + " output: " + output_type_str, loc, diagnostics); - } else { - ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), - "The input and output type of elemental intrinsics must exactly match, input type: " + - input_type_str + " output type: " + output_type_str, loc, diagnostics); - } - } - - static ASR::expr_t *eval_Abs(Allocator &al, const Location &loc, - ASR::ttype_t *t, Vec &args) { - LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); - ASR::expr_t* arg = args[0]; - if (ASRUtils::is_real(*expr_type(arg))) { - double rv = ASR::down_cast(arg)->m_r; - double val = std::abs(rv); - return make_ConstantWithType(make_RealConstant_t, val, t, loc); - } else if (ASRUtils::is_integer(*expr_type(arg))) { - int64_t rv = ASR::down_cast(arg)->m_n; - int64_t val = std::abs(rv); - return make_ConstantWithType(make_IntegerConstant_t, val, t, loc); - } else if (ASRUtils::is_complex(*expr_type(arg))) { - double re = ASR::down_cast(arg)->m_re; - double im = ASR::down_cast(arg)->m_im; - std::complex x(re, im); - double result = std::abs(x); - return make_ConstantWithType(make_RealConstant_t, result, t, loc); - } else { - return nullptr; - } - } - - static inline ASR::asr_t* create_Abs(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("Intrinsic abs function accepts exactly 1 argument", loc); - } - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); - if (!ASRUtils::is_integer(*type) && !ASRUtils::is_real(*type) - && !ASRUtils::is_complex(*type)) { - err("Argument of the abs function must be Integer, Real or Complex", - args[0]->base.loc); - } - if (is_complex(*type)) { - type = TYPE(ASR::make_Real_t(al, type->base.loc, - ASRUtils::extract_kind_from_ttype_t(type))); - } - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_Abs, - static_cast(IntrinsicScalarFunctions::Abs), 0, type); - } - - static inline ASR::expr_t* instantiate_Abs(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string func_name = "_lcompilers_abs_" + type_to_str_python(arg_types[0]); - declare_basic_variables(func_name); - if (scope->get_symbol(func_name)) { - ASR::symbol_t *s = scope->get_symbol(func_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - fill_func_arg("x", arg_types[0]); - - auto result = declare(func_name, return_type, ReturnVar); - - if (is_integer(*arg_types[0]) || is_real(*arg_types[0])) { - /* - * if (x >= 0) then - * r = x - * else - * r = -x - * end if - */ - ASR::expr_t *test; - ASR::expr_t *negative_x; - if (is_integer(*arg_types[0])) { - ASR::expr_t* zero = make_ConstantWithType(make_IntegerConstant_t, 0, arg_types[0], loc); - test = make_Compare(make_IntegerCompare_t, args[0], GtE, zero); - negative_x = EXPR(ASR::make_IntegerUnaryMinus_t(al, loc, args[0], - arg_types[0], nullptr)); - } else { - ASR::expr_t* zero = make_ConstantWithType(make_RealConstant_t, 0.0, arg_types[0], loc); - test = make_Compare(make_RealCompare_t, args[0], GtE, zero); - negative_x = EXPR(ASR::make_RealUnaryMinus_t(al, loc, args[0], - arg_types[0], nullptr)); - } - - Vec if_body; if_body.reserve(al, 1); - if_body.push_back(al, b.Assignment(result, args[0])); - Vec else_body; else_body.reserve(al, 1); - else_body.push_back(al, b.Assignment(result, negative_x)); - body.push_back(al, STMT(ASR::make_If_t(al, loc, test, - if_body.p, if_body.n, else_body.p, else_body.n))); - } else { - // * Complex type: `r = (real(x)**2 + aimag(x)**2)**0.5` - ASR::ttype_t *real_type = TYPE(ASR::make_Real_t(al, loc, - ASRUtils::extract_kind_from_ttype_t(arg_types[0]))); - ASR::symbol_t *sym_result = ASR::down_cast(result)->m_v; - ASR::Variable_t *r_var = ASR::down_cast(sym_result); - r_var->m_type = return_type = real_type; - ASR::expr_t *aimag_of_x; - { - std::string c_func_name; - if (ASRUtils::extract_kind_from_ttype_t(arg_types[0]) == 4) { - c_func_name = "_lfortran_caimag"; - } else { - c_func_name = "_lfortran_zaimag"; - } - SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); - Vec args_1; - { - args_1.reserve(al, 1); - auto arg = b.Variable(fn_symtab_1, "x", arg_types[0], - ASR::intentType::In, ASR::abiType::BindC, true); - args_1.push_back(al, arg); - } - - auto return_var_1 = b.Variable(fn_symtab_1, c_func_name, real_type, - ASR::intentType::ReturnVar, ASR::abiType::BindC, false); - - SetChar dep_1; dep_1.reserve(al, 1); - Vec body_1; body_1.reserve(al, 1); - ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, - body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); - fn_symtab->add_symbol(c_func_name, s); - dep.push_back(al, s2c(al, c_func_name)); - Vec call_args; - { - call_args.reserve(al, 1); - ASR::call_arg_t arg; - arg.loc = args[0]->base.loc; - arg.m_value = args[0]; - call_args.push_back(al, arg); - } - aimag_of_x = b.Call(s, call_args, real_type); - } - ASR::expr_t *constant_two = make_ConstantWithType(make_RealConstant_t, 2.0, real_type, loc); - ASR::expr_t *constant_point_five = make_ConstantWithType(make_RealConstant_t, 0.5, real_type, loc); - ASR::expr_t *real_of_x = EXPR(ASR::make_Cast_t(al, loc, args[0], - ASR::cast_kindType::ComplexToReal, real_type, nullptr)); - - ASR::expr_t *bin_op_1 = b.ElementalPow(real_of_x, constant_two, loc); - ASR::expr_t *bin_op_2 = b.ElementalPow(aimag_of_x, constant_two, loc); - - bin_op_1 = b.ElementalAdd(bin_op_1, bin_op_2, loc); - - body.push_back(al, b.Assignment(result, - b.ElementalPow(bin_op_1, constant_point_five, loc))); - } - - ASR::symbol_t *f_sym = make_ASR_Function_t(func_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(func_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Abs - -namespace Radix { - - // Helper function to verify arguments - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.m_args[0], "Argument of the `radix` " - "can be a nullptr", x.base.base.loc, diagnostics); - } - - // Function to create an instance of the 'radix' intrinsic function - static inline ASR::asr_t* create_Radix(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if ( args.n != 1 ) { - err("Intrinsic `radix` accepts exactly one argument", loc); - } else if ( !is_real(*expr_type(args[0])) - && !is_integer(*expr_type(args[0])) ) { - err("Argument of the `radix` must be Integer or Real", loc); - } - - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Radix), - args.p, args.n, 0, int32, i32(2)); - } - -} // namespace Radix - -namespace Sign { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, - "ASR Verify: Call to sign must have exactly two arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - ASRUtils::require_impl((is_real(*type1) || is_integer(*type2)), - "ASR Verify: Arguments to sign must be of real or integer type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl((ASRUtils::check_equal_type(type1, type2)), - "ASR Verify: All arguments must be of the same type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_Sign(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - if (ASRUtils::is_real(*t1)) { - double rv1 = std::abs(ASR::down_cast(args[0])->m_r); - double rv2 = ASR::down_cast(args[1])->m_r; - rv1 = copysign(rv1, rv2); - return make_ConstantWithType(make_RealConstant_t, rv1, t1, loc); - } else { - int64_t iv1 = std::abs(ASR::down_cast(args[0])->m_n); - int64_t iv2 = ASR::down_cast(args[1])->m_n; - if (iv2 < 0) iv1 = -iv1; - return make_ConstantWithType(make_IntegerConstant_t, iv1, t1, loc); - } - } - - static inline ASR::asr_t* create_Sign(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Intrinsic sign function accepts exactly 2 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - if (!ASRUtils::is_integer(*type1) && !ASRUtils::is_real(*type1)) { - err("Argument of the sign function must be Integer or Real", - args[0]->base.loc); - } - if (!ASRUtils::check_equal_type(type1, type2)) { - err("Type mismatch in statement function: " - "the second argument must have the same type " - "and kind as the first argument.", args[1]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 2); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - m_value = eval_Sign(al, loc, expr_type(args[0]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Sign), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_Sign(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_sign_" + type_to_str_python(arg_types[0])); - fill_func_arg("x", arg_types[0]); - fill_func_arg("y", arg_types[0]); - auto result = declare(fn_name, return_type, ReturnVar); - if (is_real(*arg_types[0])) { - Vec args; args.reserve(al, 2); - visit_expr_list(al, new_args, args); - ASR::expr_t* real_copy_sign = ASRUtils::EXPR(ASR::make_RealCopySign_t(al, loc, args[0], args[1], arg_types[0], nullptr)); - return real_copy_sign; - } else { - /* - * r = abs(x) - * if (y < 0) then - * r = -r - * end if - */ - ASR::expr_t *zero = i(0, arg_types[0]); - body.push_back(al, b.If(iGtE(args[0], zero), { - b.Assignment(result, args[0]) - }, /* else */ { - b.Assignment(result, i32_neg(args[0], arg_types[0])) - })); - body.push_back(al, b.If(iLt(args[1], zero), { - b.Assignment(result, i32_neg(result, arg_types[0])) - }, {})); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - } - -} // namespace Sign - -namespace Aint { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args > 0 && x.n_args < 3, - "ASR Verify: Call to aint must have one or two arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(ASRUtils::is_real(*type), - "ASR Verify: Arguments to aint must be of real type", - x.base.base.loc, diagnostics); - if (x.n_args == 2) { - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - ASRUtils::require_impl(ASRUtils::is_integer(*type2), - "ASR Verify: Second Argument to aint must be of integer type", - x.base.base.loc, diagnostics); - } - } - - static ASR::expr_t *eval_Aint(Allocator &al, const Location &loc, - ASR::ttype_t* arg_type, Vec &args) { - double rv = ASR::down_cast(expr_value(args[0]))->m_r; - return f(std::trunc(rv), arg_type); - } - - static inline ASR::asr_t* create_Aint( - Allocator& al, const Location& loc, Vec& args, - const std::function err) { - ASR::ttype_t* return_type = expr_type(args[0]); - if (!(args.size() == 1 || args.size() == 2)) { - err("Intrinsic `aint` function accepts exactly 1 or 2 arguments", loc); - } else if (!ASRUtils::is_real(*return_type)) { - err("Argument of the `aint` function must be Real", args[0]->base.loc); - } - Vec m_args; m_args.reserve(al, 1); - m_args.push_back(al, args[0]); - if ( args[1] ) { - int kind = -1; - if (!ASR::is_a(*expr_type(args[1])) || - !extract_value(args[1], kind)) { - err("`kind` argument of the `aint` function must be an " - "scalar Integer constant", args[1]->base.loc); - } - return_type = TYPE(ASR::make_Real_t(al, return_type->base.loc, kind)); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(m_args)) { - m_value = eval_Aint(al, loc, return_type, m_args); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Aint), - m_args.p, m_args.n, 0, return_type, m_value); - } - - static inline ASR::expr_t* instantiate_Aint(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string func_name = "_lcompilers_aint_" + type_to_str_python(arg_types[0]); - std::string fn_name = scope->get_unique_name(func_name); - SymbolTable *fn_symtab = al.make_new(scope); - Vec args; - args.reserve(al, new_args.size()); - ASRBuilder b(al, loc); - Vec body; body.reserve(al, 1); - SetChar dep; dep.reserve(al, 1); - if (scope->get_symbol(fn_name)) { - ASR::symbol_t *s = scope->get_symbol(fn_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - fill_func_arg("a", arg_types[0]); - auto result = declare(fn_name, return_type, ReturnVar); - - // Cast: Real -> Integer -> Real - // TODO: this approach doesn't work for numbers > i64_max - body.push_back(al, b.Assignment(result, i2r(r2i64(args[0]), return_type))); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Aint - -namespace Sqrt { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, - "ASR Verify: Call `sqrt` must have exactly one argument", - x.base.base.loc, diagnostics); - ASR::ttype_t *type = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(ASRUtils::is_real(*type) || ASRUtils::is_complex(*type), - "ASR Verify: Arguments to `sqrt` must be of real or complex type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_Sqrt(Allocator &al, const Location &loc, - ASR::ttype_t* arg_type, Vec &args) { - if (is_real(*arg_type)) { - double val = ASR::down_cast(expr_value(args[0]))->m_r; - return f(std::sqrt(val), arg_type); - } else { - std::complex crv; - if( ASRUtils::extract_value(args[0], crv) ) { - std::complex val = std::sqrt(crv); - return ASRUtils::EXPR(ASR::make_ComplexConstant_t( - al, loc, val.real(), val.imag(), arg_type)); - } else { - return nullptr; - } - } - } - - static inline ASR::asr_t* create_Sqrt(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - ASR::ttype_t* return_type = expr_type(args[0]); - if ( args.n != 1 ) { - err("Intrinsic `sqrt` accepts exactly one argument", loc); - } else if ( !(is_real(*return_type) || is_complex(*return_type)) ) { - err("Argument of the `sqrt` must be Real or Complex", loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - m_value = eval_Sqrt(al, loc, return_type, args); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Sqrt), - args.p, args.n, 0, return_type, m_value); - } - - static inline ASR::expr_t* instantiate_Sqrt(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t overload_id) { - ASR::ttype_t* arg_type = arg_types[0]; - if (is_real(*arg_type)) { - return EXPR(ASR::make_IntrinsicFunctionSqrt_t(al, loc, - new_args[0].m_value, return_type, nullptr)); - } else { - return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, - "sqrt", arg_type, return_type, new_args, overload_id); - } - } - -} // namespace Sqrt - -namespace Sngl { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, - "ASR Verify: Call `sngl` must have exactly one argument", - x.base.base.loc, diagnostics); - ASR::ttype_t *type = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(ASRUtils::is_real(*type), - "ASR Verify: Arguments to `sngl` must be of real type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_Sngl(Allocator &al, const Location &loc, - ASR::ttype_t* arg_type, Vec &args) { - double val = ASR::down_cast(expr_value(args[0]))->m_r; - return f(val, arg_type); - } - - static inline ASR::asr_t* create_Sngl( - Allocator& al, const Location& loc, Vec& args, - const std::function err) { - ASR::ttype_t* return_type = real32; - if ( args.n != 1 ) { - err("Intrinsic `sngl` accepts exactly one argument", loc); - } else if ( !is_real(*expr_type(args[0])) ) { - err("Argument of the `sngl` must be Real", loc); - } - Vec m_args; m_args.reserve(al, 1); - m_args.push_back(al, args[0]); - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(m_args)) { - m_value = eval_Sngl(al, loc, return_type, m_args); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Sngl), - m_args.p, m_args.n, 0, return_type, m_value); - } - - static inline ASR::expr_t* instantiate_Sngl(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string func_name = "_lcompilers_sngl_" + type_to_str_python(arg_types[0]); - std::string fn_name = scope->get_unique_name(func_name); - SymbolTable *fn_symtab = al.make_new(scope); - Vec args; - args.reserve(al, new_args.size()); - ASRBuilder b(al, loc); - Vec body; body.reserve(al, 1); - SetChar dep; dep.reserve(al, 1); - if (scope->get_symbol(fn_name)) { - ASR::symbol_t *s = scope->get_symbol(fn_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - fill_func_arg("a", arg_types[0]); - auto result = declare(fn_name, return_type, ReturnVar); - body.push_back(al, b.Assignment(result, r2r32(args[0]))); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Sngl - -namespace FMA { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 3, - "ASR Verify: Call to FMA must have exactly 3 arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - ASR::ttype_t *type3 = ASRUtils::expr_type(x.m_args[2]); - ASRUtils::require_impl((is_real(*type1) && is_real(*type2) && is_real(*type3)), - "ASR Verify: Arguments to FMA must be of real type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_FMA(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - double a = ASR::down_cast(args[0])->m_r; - double b = ASR::down_cast(args[1])->m_r; - double c = ASR::down_cast(args[2])->m_r; - return make_ConstantWithType(make_RealConstant_t, a + b*c, t1, loc); - } - - static inline ASR::asr_t* create_FMA(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 3) { - err("Intrinsic FMA function accepts exactly 3 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - ASR::ttype_t *type3 = ASRUtils::expr_type(args[2]); - if (!ASRUtils::is_real(*type1) || !ASRUtils::is_real(*type2) || !ASRUtils::is_real(*type3)) { - err("Argument of the FMA function must be Real", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 3); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - arg_values.push_back(al, expr_value(args[2])); - m_value = eval_FMA(al, loc, expr_type(args[0]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::FMA), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_FMA(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_fma_" + type_to_str_python(arg_types[0])); - fill_func_arg("a", arg_types[0]); - fill_func_arg("b", arg_types[0]); - fill_func_arg("c", arg_types[0]); - auto result = declare(fn_name, return_type, ReturnVar); - /* - * result = a + b*c - */ - - ASR::expr_t *op1 = b.ElementalMul(args[1], args[2], loc); - body.push_back(al, b.Assignment(result, - b.ElementalAdd(args[0], op1, loc))); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace FMA - - -namespace SignFromValue { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, - "ASR Verify: Call to SignFromValue must have exactly 2 arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - bool eq_type = ASRUtils::types_equal(type1, type2); - ASRUtils::require_impl(((is_real(*type1) || is_integer(*type1)) && - (is_real(*type2) || is_integer(*type2)) && eq_type), - "ASR Verify: Arguments to SignFromValue must be of equal type and " - "should be either real or integer", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_SignFromValue(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - if (is_real(*t1)) { - double a = ASR::down_cast(args[0])->m_r; - double b = ASR::down_cast(args[1])->m_r; - a = (b < 0 ? -a : a); - return make_ConstantWithType(make_RealConstant_t, a, t1, loc); - } - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t b = ASR::down_cast(args[1])->m_n; - a = (b < 0 ? -a : a); - return make_ConstantWithType(make_IntegerConstant_t, a, t1, loc); - - } - - static inline ASR::asr_t* create_SignFromValue(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Intrinsic SignFromValue function accepts exactly 2 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - bool eq_type = ASRUtils::types_equal(type1, type2); - if (!((is_real(*type1) || is_integer(*type1)) && - (is_real(*type2) || is_integer(*type2)) && eq_type)) { - err("Argument of the SignFromValue function must be either Real or Integer " - "and must be of equal type", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 2); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - m_value = eval_SignFromValue(al, loc, expr_type(args[0]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::SignFromValue), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_SignFromValue(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_signfromvalue_" + type_to_str_python(arg_types[0])); - fill_func_arg("a", arg_types[0]); - fill_func_arg("b", arg_types[1]); - auto result = declare(fn_name, return_type, ReturnVar); - /* - elemental real(real32) function signfromvaluer32r32(a, b) result(d) - real(real32), intent(in) :: a, b - d = a * asignr32(1.0_real32, b) - end function - */ - if (is_real(*arg_types[0])) { - ASR::expr_t *zero = f(0.0, arg_types[1]); - body.push_back(al, b.If(fLt(args[1], zero), { - b.Assignment(result, f32_neg(args[0], arg_types[0])) - }, { - b.Assignment(result, args[0]) - })); - } else { - ASR::expr_t *zero = i(0, arg_types[1]); - body.push_back(al, b.If(iLt(args[1], zero), { - b.Assignment(result, i32_neg(args[0], arg_types[0])) - }, { - b.Assignment(result, args[0]) - })); - } - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace SignFromValue - - -namespace FlipSign { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, - "ASR Verify: Call to FlipSign must have exactly 2 arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - ASRUtils::require_impl((is_integer(*type1) && is_real(*type2)), - "ASR Verify: Arguments to FlipSign must be of int and real type respectively", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_FlipSign(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - int a = ASR::down_cast(args[0])->m_n; - double b = ASR::down_cast(args[1])->m_r; - if (a % 2 == 1) b = -b; - return make_ConstantWithType(make_RealConstant_t, b, t1, loc); - } - - static inline ASR::asr_t* create_FlipSign(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Intrinsic FlipSign function accepts exactly 2 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - if (!ASRUtils::is_integer(*type1) || !ASRUtils::is_real(*type2)) { - err("Argument of the FlipSign function must be int and real respectively", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 2); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - m_value = eval_FlipSign(al, loc, expr_type(args[1]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::FlipSign), - args.p, args.n, 0, ASRUtils::expr_type(args[1]), m_value); - } - - static inline ASR::expr_t* instantiate_FlipSign(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_flipsign_" + type_to_str_python(arg_types[1])); - fill_func_arg("signal", arg_types[0]); - fill_func_arg("variable", arg_types[1]); - auto result = declare(fn_name, return_type, ReturnVar); - /* - real(real32) function flipsigni32r32(signal, variable) - integer(int32), intent(in) :: signal - real(real32), intent(out) :: variable - integer(int32) :: q - q = signal/2 - flipsigni32r32 = variable - if (signal - 2*q == 1 ) flipsigni32r32 = -variable - end subroutine - */ - - ASR::expr_t *two = i(2, arg_types[0]); - ASR::expr_t *q = iDiv(args[0], two); - ASR::expr_t *cond = iSub(args[0], iMul(two, q)); - body.push_back(al, b.If(iEq(cond, i(1, arg_types[0])), { - b.Assignment(result, f32_neg(args[1], arg_types[1])) - }, { - b.Assignment(result, args[1]) - })); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace FlipSign - -namespace FloorDiv { - - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, - "ASR Verify: Call to FloorDiv must have exactly 2 arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - type1 = ASRUtils::type_get_past_const(type1); - type2 = ASRUtils::type_get_past_const(type2); - ASRUtils::require_impl((is_integer(*type1) && is_integer(*type2)) || - (is_unsigned_integer(*type1) && is_unsigned_integer(*type2)) || - (is_real(*type1) && is_real(*type2)) || - (is_logical(*type1) && is_logical(*type2)), - "ASR Verify: Arguments to FloorDiv must be of real, integer, unsigned integer or logical type", - x.base.base.loc, diagnostics); - } - - - static ASR::expr_t *eval_FloorDiv(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - type1 = ASRUtils::type_get_past_const(type1); - type2 = ASRUtils::type_get_past_const(type2); - bool is_real1 = is_real(*type1); - bool is_real2 = is_real(*type2); - bool is_int1 = is_integer(*type1); - bool is_int2 = is_integer(*type2); - bool is_unsigned_int1 = is_unsigned_integer(*type1); - bool is_unsigned_int2 = is_unsigned_integer(*type2); - bool is_logical1 = is_logical(*type1); - bool is_logical2 = is_logical(*type2); - - - if (is_int1 && is_int2) { - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t b = ASR::down_cast(args[1])->m_n; - return make_ConstantWithType(make_IntegerConstant_t, a / b, t1, loc); - } else if (is_unsigned_int1 && is_unsigned_int2) { - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t b = ASR::down_cast(args[1])->m_n; - return make_ConstantWithType(make_UnsignedIntegerConstant_t, a / b, t1, loc); - } else if (is_logical1 && is_logical2) { - bool a = ASR::down_cast(args[0])->m_value; - bool b = ASR::down_cast(args[1])->m_value; - return make_ConstantWithType(make_LogicalConstant_t, a / b, t1, loc); - } else if (is_real1 && is_real2) { - double a = ASR::down_cast(args[0])->m_r; - double b = ASR::down_cast(args[1])->m_r; - double r = a / b; - int64_t result = (int64_t)r; - if ( r >= 0.0 || (double)result == r) { - return make_ConstantWithType(make_RealConstant_t, (double)result, t1, loc); - } - return make_ConstantWithType(make_RealConstant_t, (double)(result - 1), t1, loc); - } - return nullptr; - } - - - - static inline ASR::asr_t* create_FloorDiv(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Intrinsic FloorDiv function accepts exactly 2 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - type1 = ASRUtils::type_get_past_const(type1); - type2 = ASRUtils::type_get_past_const(type2); - if (!((ASRUtils::is_integer(*type1) && ASRUtils::is_integer(*type2)) || - (ASRUtils::is_unsigned_integer(*type1) && ASRUtils::is_unsigned_integer(*type2)) || - (ASRUtils::is_real(*type1) && ASRUtils::is_real(*type2)) || - (ASRUtils::is_logical(*type1) && ASRUtils::is_logical(*type2)))) { - err("Argument of the FloorDiv function must be either Real, Integer, Unsigned Integer or Logical", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - double compile_time_arg2_val; - if (ASRUtils::extract_value(expr_value(args[1]), compile_time_arg2_val)) { - if (compile_time_arg2_val == 0.0) { - err("Division by 0 is not allowed", args[1]->base.loc); - } - } - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 2); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - m_value = eval_FloorDiv(al, loc, expr_type(args[1]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::FloorDiv), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_FloorDiv(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_floordiv_" + type_to_str_python(arg_types[1])); - fill_func_arg("a", arg_types[0]); - fill_func_arg("b", arg_types[1]); - auto r = declare("r", real64, Local); - auto tmp = declare("tmp", int64, Local); - auto result = declare("result", return_type, ReturnVar); - /* - @overload - def _lpython_floordiv(a: i32, b: i32) -> i32: - r: f64 # f32 rounds things up and gives incorrect tmps - tmp: i64 - result: i32 - r = float(a)/float(b) - tmp = i64(r) - if r < 0.0 and f64(tmp) != r: - tmp = tmp - 1 - result = i32(tmp) - return result - */ - - - ASR::expr_t *op1 = r64Div(CastingUtil::perform_casting(args[0], arg_types[0], real64, al, loc), - CastingUtil::perform_casting(args[1], arg_types[1], real64, al, loc)); - body.push_back(al, b.Assignment(r, op1)); - body.push_back(al, b.Assignment(tmp, r2i64(r))); - body.push_back(al, b.If(And(fLt(r, f(0.0, real64)), fNotEq(i2r64(tmp), r)), { - b.Assignment(tmp, i64Sub(tmp, i(1, int64))) - }, {})); - body.push_back(al, b.Assignment(result, CastingUtil::perform_casting(tmp, int64, return_type, al, loc))); - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace FloorDiv - -namespace Mod { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, - "ASR Verify: Call to Mod must have exactly 2 arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(x.m_args[1]); - ASRUtils::require_impl((is_integer(*type1) && is_integer(*type2)) || - (is_real(*type1) && is_real(*type2)), - "ASR Verify: Arguments to Mod must be of real or integer type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_Mod(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - bool is_real1 = is_real(*ASRUtils::expr_type(args[0])); - bool is_real2 = is_real(*ASRUtils::expr_type(args[1])); - bool is_int1 = is_integer(*ASRUtils::expr_type(args[0])); - bool is_int2 = is_integer(*ASRUtils::expr_type(args[1])); - - if (is_int1 && is_int2) { - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t b = ASR::down_cast(args[1])->m_n; - return make_ConstantWithType(make_IntegerConstant_t, a % b, t1, loc); - } else if (is_real1 && is_real2) { - double a = ASR::down_cast(args[0])->m_r; - double b = ASR::down_cast(args[1])->m_r; - return make_ConstantWithType(make_RealConstant_t, std::fmod(a, b), t1, loc); - } - return nullptr; - } - - static inline ASR::asr_t* create_Mod(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Intrinsic Mod function accepts exactly 2 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); - if (!((ASRUtils::is_integer(*type1) && ASRUtils::is_integer(*type2)) || - (ASRUtils::is_real(*type1) && ASRUtils::is_real(*type2)))) { - err("Argument of the Mod function must be either Real or Integer", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 2); - arg_values.push_back(al, expr_value(args[0])); - arg_values.push_back(al, expr_value(args[1])); - m_value = eval_Mod(al, loc, expr_type(args[1]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Mod), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_Mod(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_mod_" + type_to_str_python(arg_types[1])); - fill_func_arg("a", arg_types[0]); - fill_func_arg("p", arg_types[1]); - auto result = declare(fn_name, return_type, ReturnVar); - /* - function modi32i32(a, p) result(d) - integer(int32), intent(in) :: a, p - integer(int32) :: q - q = a/p - d = a - p*q - end function - */ - - ASR::expr_t *q = nullptr, *op1 = nullptr, *op2 = nullptr; - if (is_real(*arg_types[1])) { - int kind = ASRUtils::extract_kind_from_ttype_t(arg_types[1]); - if (kind == 4) { - q = r2i32(r32Div(args[0], args[1])); - op1 = r32Mul(args[1], i2r32(q)); - op2 = r32Sub(args[0], op1); - } else { - q = r2i64(r64Div(args[0], args[1])); - op1 = r64Mul(args[1], i2r64(q)); - op2 = r64Sub(args[0], op1); - } - } else { - q = iDiv(args[0], args[1]); - op1 = iMul(args[1], q); - op2 = iSub(args[0], op1); - } - body.push_back(al, b.Assignment(result, op2)); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Mod - -namespace Trailz { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, - "ASR Verify: Call to Trailz must have exactly 1 argument", - x.base.base.loc, diagnostics); - ASR::ttype_t *type1 = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(is_integer(*type1), - "ASR Verify: Arguments to Trailz must be of integer type", - x.base.base.loc, diagnostics); - } - - static ASR::expr_t *eval_Trailz(Allocator &al, const Location &loc, - ASR::ttype_t* t1, Vec &args) { - int64_t a = ASR::down_cast(args[0])->m_n; - int64_t trailing_zeros = ASRUtils::compute_trailing_zeros(a); - return make_ConstantWithType(make_IntegerConstant_t, trailing_zeros, t1, loc); - } - - static inline ASR::asr_t* create_Trailz(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("Intrinsic Trailz function accepts exactly 1 arguments", loc); - } - ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); - if (!(ASRUtils::is_integer(*type1))) { - err("Argument of the Trailz function must be Integer", - args[0]->base.loc); - } - ASR::expr_t *m_value = nullptr; - if (all_args_evaluated(args)) { - Vec arg_values; arg_values.reserve(al, 1); - arg_values.push_back(al, expr_value(args[0])); - m_value = eval_Trailz(al, loc, expr_type(args[0]), arg_values); - } - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Trailz), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), m_value); - } - - static inline ASR::expr_t* instantiate_Trailz(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - declare_basic_variables("_lcompilers_optimization_trailz_" + type_to_str_python(arg_types[0])); - fill_func_arg("n", arg_types[0]); - auto result = declare(fn_name, arg_types[0], ReturnVar); - // This is not the most efficient way to do this, but it works for now. - /* - function trailz(n) result(result) - integer :: n - integer :: result - result = 0 - if (n == 0) then - result = 32 - else - do while (mod(n,2) == 0) - n = n/2 - result = result + 1 - end do - end if - end function - */ - - body.push_back(al, b.Assignment(result, i(0, arg_types[0]))); - ASR::expr_t *two = i(2, arg_types[0]); - int arg_0_kind = ASRUtils::extract_kind_from_ttype_t(arg_types[0]); - - Vec arg_types_mod; arg_types_mod.reserve(al, 2); - arg_types_mod.push_back(al, arg_types[0]); arg_types_mod.push_back(al, ASRUtils::expr_type(two)); - - Vec new_args_mod; new_args_mod.reserve(al, 2); - ASR::call_arg_t arg1; arg1.loc = loc; arg1.m_value = args[0]; - ASR::call_arg_t arg2; arg2.loc = loc; arg2.m_value = two; - new_args_mod.push_back(al, arg1); new_args_mod.push_back(al, arg2); - - ASR::expr_t* func_call_mod = Mod::instantiate_Mod(al, loc, scope, arg_types_mod, return_type, new_args_mod, 0); - ASR::expr_t *cond = iEq(func_call_mod, i(0, arg_types[0])); - - std::vector while_loop_body; - if (arg_0_kind == 4) { - while_loop_body.push_back(b.Assignment(args[0], iDiv(args[0], two))); - while_loop_body.push_back(b.Assignment(result, iAdd(result, i(1, arg_types[0])))); - } else { - while_loop_body.push_back(b.Assignment(args[0], iDiv64(args[0], two))); - while_loop_body.push_back(b.Assignment(result, iAdd64(result, i(1, arg_types[0])))); - } - - ASR::expr_t* check_zero = iEq(args[0], i(0, arg_types[0])); - std::vector if_body; if_body.push_back(b.Assignment(result, i(32, arg_types[0]))); - std::vector else_body; else_body.push_back(b.While(cond, while_loop_body)); - body.push_back(al, b.If(check_zero, if_body, else_body)); - - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Trailz - -#define create_exp_macro(X, stdeval) \ -namespace X { \ - static inline ASR::expr_t* eval_##X(Allocator &al, const Location &loc, \ - ASR::ttype_t *t, Vec &args) { \ - LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); \ - double rv = -1; \ - if( ASRUtils::extract_value(args[0], rv) ) { \ - double val = std::stdeval(rv); \ - return ASRUtils::EXPR(ASR::make_RealConstant_t(al, loc, val, t)); \ - } \ - return nullptr; \ - } \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) { \ - if (args.size() != 1) { \ - err("Intrinsic function `"#X"` accepts exactly 1 argument", loc); \ - } \ - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ - if (!ASRUtils::is_real(*type)) { \ - err("Argument of the `"#X"` function must be either Real", \ - args[0]->base.loc); \ - } \ - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ - static_cast(IntrinsicScalarFunctions::X), 0, type); \ - } \ -} // namespace X - -create_exp_macro(Exp, exp) -create_exp_macro(Exp2, exp2) -create_exp_macro(Expm1, expm1) - -namespace ListIndex { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args <= 4, "Call to list.index must have at most four arguments", - x.base.base.loc, diagnostics); - ASR::ttype_t *list_type = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); - ASRUtils::require_impl(ASR::is_a(*list_type) && - ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), - ASRUtils::get_contained_type(list_type)), - "First argument to list.index must be of list type and " - "second argument must be of same type as list elemental type", - x.base.base.loc, diagnostics); - if(x.n_args >= 3) { - ASRUtils::require_impl( - ASR::is_a(*ASRUtils::expr_type(x.m_args[2])), - "Third argument to list.index must be an integer", - x.base.base.loc, diagnostics); - } - if(x.n_args == 4) { - ASRUtils::require_impl( - ASR::is_a(*ASRUtils::expr_type(x.m_args[3])), - "Fourth argument to list.index must be an integer", - x.base.base.loc, diagnostics); - } - ASRUtils::require_impl(ASR::is_a(*x.m_type), - "Return type of list.index must be an integer", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_list_index(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/) { - // TODO: To be implemented for ListConstant expression - return nullptr; -} - - -static inline ASR::asr_t* create_ListIndex(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - int64_t overload_id = 0; - ASR::expr_t* list_expr = args[0]; - ASR::ttype_t *type = ASRUtils::type_get_past_const(ASRUtils::expr_type(list_expr)); - ASR::ttype_t *list_type = ASR::down_cast(type)->m_type; - ASR::ttype_t *ele_type = ASRUtils::expr_type(args[1]); - if (!ASRUtils::check_equal_type(ele_type, list_type)) { - std::string fnd = ASRUtils::get_type_code(ele_type); - std::string org = ASRUtils::get_type_code(list_type); - err( - "Type mismatch in 'index', the types must be compatible " - "(found: '" + fnd + "', expected: '" + org + "')", loc); - } - if (args.size() >= 3) { - overload_id = 1; - if(!ASR::is_a(*ASRUtils::expr_type(args[2]))) { - err("Third argument to list.index must be an integer", loc); - } - } - if (args.size() == 4) { - overload_id = 2; - if(!ASR::is_a(*ASRUtils::expr_type(args[3]))) { - err("Fourth argument to list.index must be an integer", loc); - } - } - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::ttype_t *to_type = int32; - ASR::expr_t* compile_time_value = eval_list_index(al, loc, to_type, arg_values); - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::ListIndex), - args.p, args.size(), overload_id, to_type, compile_time_value); -} - -} // namespace ListIndex - -namespace ListReverse { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, "Call to list.reverse must have exactly one argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "Argument to list.reverse must be of list type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(x.m_type == nullptr, - "Return type of list.reverse must be empty", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_list_reverse(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/) { - // TODO: To be implemented for ListConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_ListReverse(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("list.reverse() takes no arguments", loc); - } - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::expr_t* compile_time_value = eval_list_reverse(al, loc, nullptr, arg_values); - return ASR::make_Expr_t(al, loc, - ASRUtils::EXPR(ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, - static_cast(IntrinsicScalarFunctions::ListReverse), - args.p, args.size(), 0, nullptr, compile_time_value))); -} - -} // namespace ListReverse - -namespace ListPop { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args <= 2, "Call to list.pop must have at most one argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "Argument to list.pop must be of list type", - x.base.base.loc, diagnostics); - switch(x.m_overload_id) { - case 0: - break; - case 1: - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[1])), - "Argument to list.pop must be an integer", - x.base.base.loc, diagnostics); - break; - } - ASRUtils::require_impl(ASRUtils::check_equal_type(x.m_type, - ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), - "Return type of list.pop must be of same type as list's element type", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_list_pop(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/) { - // TODO: To be implemented for ListConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_ListPop(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() > 2) { - err("Call to list.pop must have at most one argument", loc); - } - if (args.size() == 2 && - !ASR::is_a(*ASRUtils::expr_type(args[1]))) { - err("Argument to list.pop must be an integer", loc); - } - - ASR::expr_t* list_expr = args[0]; - ASR::ttype_t *type = ASRUtils::expr_type(list_expr); - ASR::ttype_t *list_type = ASR::down_cast(type)->m_type; - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::ttype_t *to_type = list_type; - ASR::expr_t* compile_time_value = eval_list_pop(al, loc, to_type, arg_values); - int64_t overload_id = (args.size() == 2); - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::ListPop), - args.p, args.size(), overload_id, to_type, compile_time_value); -} - -} // namespace ListPop - -namespace Reserve { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Call to reserve must have exactly one argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "First argument to reserve must be of list type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[1])), - "Second argument to reserve must be an integer", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(x.m_type == nullptr, - "Return type of reserve must be empty", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_reserve(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO: To be implemented for ListConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_Reserve(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Call to reserve must have exactly two argument", loc); - } - if (!ASR::is_a(*ASRUtils::expr_type(args[0]))) { - err("First argument to reserve must be of list type", loc); - } - if (!ASR::is_a(*ASRUtils::expr_type(args[1]))) { - err("Second argument to reserve must be an integer", loc); - } - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::expr_t* compile_time_value = eval_reserve(al, loc, nullptr, arg_values); - return ASR::make_Expr_t(al, loc, - ASRUtils::EXPR(ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, - static_cast(IntrinsicScalarFunctions::Reserve), - args.p, args.size(), 0, nullptr, compile_time_value))); -} - -} // namespace Reserve - -namespace DictKeys { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, "Call to dict.keys must have no argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "Argument to dict.keys must be of dict type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*x.m_type) && - ASRUtils::check_equal_type(ASRUtils::get_contained_type(x.m_type), - ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]), 0)), - "Return type of dict.keys must be of list of dict key element type", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_dict_keys(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO: To be implemented for DictConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_DictKeys(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("Call to dict.keys must have no argument", loc); - } - - ASR::expr_t* dict_expr = args[0]; - ASR::ttype_t *type = ASRUtils::expr_type(dict_expr); - ASR::ttype_t *dict_keys_type = ASR::down_cast(type)->m_key_type; - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::ttype_t *to_type = List(dict_keys_type); - ASR::expr_t* compile_time_value = eval_dict_keys(al, loc, to_type, arg_values); - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::DictKeys), - args.p, args.size(), 0, to_type, compile_time_value); -} - -} // namespace DictKeys - -namespace DictValues { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, "Call to dict.values must have no argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "Argument to dict.values must be of dict type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*x.m_type) && - ASRUtils::check_equal_type(ASRUtils::get_contained_type(x.m_type), - ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]), 1)), - "Return type of dict.values must be of list of dict value element type", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_dict_values(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO: To be implemented for DictConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_DictValues(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("Call to dict.values must have no argument", loc); - } - - ASR::expr_t* dict_expr = args[0]; - ASR::ttype_t *type = ASRUtils::expr_type(dict_expr); - ASR::ttype_t *dict_values_type = ASR::down_cast(type)->m_value_type; - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::ttype_t *to_type = List(dict_values_type); - ASR::expr_t* compile_time_value = eval_dict_values(al, loc, to_type, arg_values); - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::DictValues), - args.p, args.size(), 0, to_type, compile_time_value); -} - -} // namespace DictValues - -namespace SetAdd { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Call to set.add must have exactly one argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "First argument to set.add must be of set type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), - ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), - "Second argument to set.add must be of same type as set's element type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(x.m_type == nullptr, - "Return type of set.add must be empty", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_set_add(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO: To be implemented for SetConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_SetAdd(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Call to set.add must have exactly one argument", loc); - } - if (!ASRUtils::check_equal_type(ASRUtils::expr_type(args[1]), - ASRUtils::get_contained_type(ASRUtils::expr_type(args[0])))) { - err("Argument to set.add must be of same type as set's " - "element type", loc); - } - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::expr_t* compile_time_value = eval_set_add(al, loc, nullptr, arg_values); - return ASR::make_Expr_t(al, loc, - ASRUtils::EXPR(ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::SetAdd), - args.p, args.size(), 0, nullptr, compile_time_value))); -} - -} // namespace SetAdd - -namespace SetRemove { - -static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Call to set.remove must have exactly one argument", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "First argument to set.remove must be of set type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), - ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), - "Second argument to set.remove must be of same type as set's element type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(x.m_type == nullptr, - "Return type of set.remove must be empty", - x.base.base.loc, diagnostics); -} - -static inline ASR::expr_t *eval_set_remove(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO: To be implemented for SetConstant expression - return nullptr; -} - -static inline ASR::asr_t* create_SetRemove(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 2) { - err("Call to set.remove must have exactly one argument", loc); - } - if (!ASRUtils::check_equal_type(ASRUtils::expr_type(args[1]), - ASRUtils::get_contained_type(ASRUtils::expr_type(args[0])))) { - err("Argument to set.remove must be of same type as set's " - "element type", loc); - } - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - ASR::expr_t* compile_time_value = eval_set_remove(al, loc, nullptr, arg_values); - return ASR::make_Expr_t(al, loc, - ASRUtils::EXPR(ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::SetRemove), - args.p, args.size(), 0, nullptr, compile_time_value))); -} - -} // namespace SetRemove - -namespace Max { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args > 1, "ASR Verify: Call to max0 must have at least two arguments", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])) || - ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "ASR Verify: Arguments to max0 must be of real or integer type", - x.base.base.loc, diagnostics); - for(size_t i=0;i(*ASRUtils::expr_type(x.m_args[i])) && - ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))) || - (ASR::is_a(*ASRUtils::expr_type(x.m_args[i])) && - ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))), - "ASR Verify: All arguments must be of the same type", - x.base.base.loc, diagnostics); - } - } - - static ASR::expr_t *eval_Max(Allocator &al, const Location &loc, - ASR::ttype_t* arg_type, Vec &args) { - LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); - if (ASR::is_a(*arg_type)) { - double max_val = ASR::down_cast(args[0])->m_r; - for (size_t i = 1; i < args.size(); i++) { - double val = ASR::down_cast(args[i])->m_r; - max_val = std::fmax(max_val, val); - } - return ASR::down_cast(ASR::make_RealConstant_t(al, loc, max_val, arg_type)); - } else if (ASR::is_a(*arg_type)) { - int64_t max_val = ASR::down_cast(args[0])->m_n; - for (size_t i = 1; i < args.size(); i++) { - int64_t val = ASR::down_cast(args[i])->m_n; - max_val = std::fmax(max_val, val); - } - return ASR::down_cast(ASR::make_IntegerConstant_t(al, loc, max_val, arg_type)); - } else { - return nullptr; - } - } - - static inline ASR::asr_t* create_Max( - Allocator& al, const Location& loc, Vec& args, - const std::function err) { - bool is_compile_time = true; - for(size_t i=0; i<100;i++){ - args.erase(nullptr); - } - if (args.size() < 2) { - err("Intrinsic max0 must have 2 arguments", loc); - } - Vec arg_values; - arg_values.reserve(al, args.size()); - ASR::expr_t *arg_value; - for(size_t i=0;i(IntrinsicScalarFunctions::Max), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), value); - } else { - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Max), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), nullptr); - } - } - - static inline ASR::expr_t* instantiate_Max(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string func_name = "_lcompilers_max0_" + type_to_str_python(arg_types[0]); - std::string fn_name = scope->get_unique_name(func_name); - SymbolTable *fn_symtab = al.make_new(scope); - Vec args; - args.reserve(al, new_args.size()); - ASRBuilder b(al, loc); - Vec body; body.reserve(al, args.size()); - SetChar dep; dep.reserve(al, 1); - if (scope->get_symbol(fn_name)) { - ASR::symbol_t *s = scope->get_symbol(fn_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - for (size_t i = 0; i < new_args.size(); i++) { - fill_func_arg("x" + std::to_string(i), arg_types[0]); - } - - auto result = declare(fn_name, return_type, ReturnVar); - - ASR::expr_t* test; - body.push_back(al, b.Assignment(result, args[0])); - for (size_t i = 1; i < args.size(); i++) { - test = make_Compare(make_IntegerCompare_t, args[i], Gt, result); - Vec if_body; if_body.reserve(al, 1); - if_body.push_back(al, b.Assignment(result, args[i])); - body.push_back(al, STMT(ASR::make_If_t(al, loc, test, - if_body.p, if_body.n, nullptr, 0))); - } - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Max - -namespace Min { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args > 1, "ASR Verify: Call to min0 must have at least two arguments", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])) || - ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), - "ASR Verify: Arguments to min0 must be of real or integer type", - x.base.base.loc, diagnostics); - for(size_t i=0;i(*ASRUtils::expr_type(x.m_args[i])) && - ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))) || - (ASR::is_a(*ASRUtils::expr_type(x.m_args[i])) && - ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))), - "ASR Verify: All arguments must be of the same type", - x.base.base.loc, diagnostics); - } - } - - static ASR::expr_t *eval_Min(Allocator &al, const Location &loc, - ASR::ttype_t *arg_type, Vec &args) { - LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); - if (ASR::is_a(*arg_type)) { - double min_val = ASR::down_cast(args[0])->m_r; - for (size_t i = 1; i < args.size(); i++) { - double val = ASR::down_cast(args[i])->m_r; - min_val = std::fmin(min_val, val); - } - return ASR::down_cast(ASR::make_RealConstant_t(al, loc, min_val, arg_type)); - } else if (ASR::is_a(*arg_type)) { - int64_t min_val = ASR::down_cast(args[0])->m_n; - for (size_t i = 1; i < args.size(); i++) { - int64_t val = ASR::down_cast(args[i])->m_n; - min_val = std::fmin(min_val, val); - } - return ASR::down_cast(ASR::make_IntegerConstant_t(al, loc, min_val, arg_type)); - } else { - return nullptr; - } - } - - static inline ASR::asr_t* create_Min( - Allocator& al, const Location& loc, Vec& args, - const std::function err) { - bool is_compile_time = true; - for(size_t i=0; i<100;i++){ - args.erase(nullptr); - } - if (args.size() < 2) { - err("Intrinsic min0 must have 2 arguments", loc); - } - Vec arg_values; - arg_values.reserve(al, args.size()); - ASR::expr_t *arg_value; - for(size_t i=0;i(IntrinsicScalarFunctions::Min), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), value); - } else { - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Min), - args.p, args.n, 0, ASRUtils::expr_type(args[0]), nullptr); - } - } - - static inline ASR::expr_t* instantiate_Min(Allocator &al, const Location &loc, - SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - std::string func_name = "_lcompilers_min0_" + type_to_str_python(arg_types[0]); - std::string fn_name = scope->get_unique_name(func_name); - SymbolTable *fn_symtab = al.make_new(scope); - Vec args; - args.reserve(al, new_args.size()); - ASRBuilder b(al, loc); - Vec body; body.reserve(al, args.size()); - SetChar dep; dep.reserve(al, 1); - if (scope->get_symbol(fn_name)) { - ASR::symbol_t *s = scope->get_symbol(fn_name); - ASR::Function_t *f = ASR::down_cast(s); - return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); - } - for (size_t i = 0; i < new_args.size(); i++) { - fill_func_arg("x" + std::to_string(i), arg_types[0]); - } - - auto result = declare(fn_name, return_type, ReturnVar); - - ASR::expr_t* test; - body.push_back(al, b.Assignment(result, args[0])); - if (return_type->type == ASR::ttypeType::Integer) { - for (size_t i = 1; i < args.size(); i++) { - test = make_Compare(make_IntegerCompare_t, args[i], Lt, result); - Vec if_body; if_body.reserve(al, 1); - if_body.push_back(al, b.Assignment(result, args[i])); - body.push_back(al, STMT(ASR::make_If_t(al, loc, test, - if_body.p, if_body.n, nullptr, 0))); - } - } else if (return_type->type == ASR::ttypeType::Real) { - for (size_t i = 1; i < args.size(); i++) { - test = make_Compare(make_RealCompare_t, args[i], Lt, result); - Vec if_body; if_body.reserve(al, 1); - if_body.push_back(al, b.Assignment(result, args[i])); - body.push_back(al, STMT(ASR::make_If_t(al, loc, test, - if_body.p, if_body.n, nullptr, 0))); - } - } else { - throw LCompilersException("Arguments to min0 must be of real or integer type"); - } - ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, f_sym); - return b.Call(f_sym, new_args, return_type, nullptr); - } - -} // namespace Min - -namespace Partition { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Call to partition must have exactly two arguments", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])) && - ASR::is_a(*ASRUtils::expr_type(x.m_args[1])), - "Both arguments to partition must be of character type", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*x.m_type), - "Return type of partition must be a tuple", - x.base.base.loc, diagnostics); - } - - static inline ASR::expr_t* eval_Partition(Allocator &al, const Location &loc, - std::string &s_var, std::string &sep) { - /* - using KMP algorithm to find separator inside string - res_tuple: stores the resulting 3-tuple expression ---> - (if separator exist) tuple: (left of separator, separator, right of separator) - (if separator does not exist) tuple: (string, "", "") - res_tuple_type: stores the type of each expression present in resulting 3-tuple - */ - ASRBuilder b(al, loc); - int sep_pos = ASRUtils::KMP_string_match(s_var, sep); - std::string first_res, second_res, third_res; - if(sep_pos == -1) { - /* seperator does not exist */ - first_res = s_var; - second_res = ""; - third_res = ""; - } else { - first_res = s_var.substr(0, sep_pos); - second_res = sep; - third_res = s_var.substr(sep_pos + sep.size()); - } - - Vec res_tuple; res_tuple.reserve(al, 3); - ASR::ttype_t *first_res_type = character(first_res.size()); - ASR::ttype_t *second_res_type = character(second_res.size()); - ASR::ttype_t *third_res_type = character(third_res.size()); - return b.TupleConstant({ StringConstant(first_res, first_res_type), - StringConstant(second_res, second_res_type), - StringConstant(third_res, third_res_type) }, - b.Tuple({first_res_type, second_res_type, third_res_type})); - } - - static inline ASR::asr_t *create_partition(Allocator &al, const Location &loc, - Vec &args, ASR::expr_t *s_var, - const std::function err) { - ASRBuilder b(al, loc); - if (args.size() != 1) { - err("str.partition() takes exactly one argument", loc); - } - ASR::expr_t *arg = args[0]; - if (!ASRUtils::is_character(*expr_type(arg))) { - err("str.partition() takes one arguments of type: str", arg->base.loc); - } - - Vec e_args; e_args.reserve(al, 2); - e_args.push_back(al, s_var); - e_args.push_back(al, arg); - - ASR::ttype_t *return_type = b.Tuple({character(-2), character(-2), character(-2)}); - ASR::expr_t *value = nullptr; - if (ASR::is_a(*s_var) - && ASR::is_a(*arg)) { - std::string s_sep = ASR::down_cast(arg)->m_s; - std::string s_str = ASR::down_cast(s_var)->m_s; - if (s_sep.size() == 0) { - err("Separator cannot be an empty string", arg->base.loc); - } - value = eval_Partition(al, loc, s_str, s_sep); - } - - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::Partition), - e_args.p, e_args.n, 0, return_type, value); - } - - static inline ASR::expr_t *instantiate_Partition(Allocator &al, - const Location &loc, SymbolTable *scope, - Vec& /*arg_types*/, ASR::ttype_t *return_type, - Vec& new_args, int64_t /*overload_id*/) { - // TODO: show runtime error for empty separator or pattern - declare_basic_variables("_lpython_str_partition"); - fill_func_arg("target_string", character(-2)); - fill_func_arg("pattern", character(-2)); - - auto result = declare("result", return_type, ReturnVar); - auto index = declare("index", int32, Local); - body.push_back(al, b.Assignment(index, b.Call(UnaryIntrinsicFunction:: - create_KMP_function(al, loc, scope), args, int32))); - body.push_back(al, b.If(iEq(index, i32_n(-1)), { - b.Assignment(result, b.TupleConstant({ args[0], - StringConstant("", character(0)), - StringConstant("", character(0)) }, - b.Tuple({character(-2), character(0), character(0)}))) - }, { - b.Assignment(result, b.TupleConstant({ - StringSection(args[0], i32(0), index), args[1], - StringSection(args[0], iAdd(index, StringLen(args[1])), - StringLen(args[0]))}, return_type)) - })); - body.push_back(al, Return()); - ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, - body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); - scope->add_symbol(fn_name, fn_sym); - return b.Call(fn_sym, new_args, return_type, nullptr); - } - -} // namespace Partition - -namespace SymbolicSymbol { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - const Location& loc = x.base.base.loc; - ASRUtils::require_impl(x.n_args == 1, - "SymbolicSymbol intrinsic must have exactly 1 input argument", - loc, diagnostics); - - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(ASR::is_a(*input_type), - "SymbolicSymbol intrinsic expects a character input argument", - loc, diagnostics); - } - - static inline ASR::expr_t *eval_SymbolicSymbol(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO - return nullptr; - } - - static inline ASR::asr_t* create_SymbolicSymbol(Allocator& al, const Location& loc, - Vec& args, - const std::function err) { - if (args.size() != 1) { - err("Intrinsic Symbol function accepts exactly 1 argument", loc); - } - - ASR::ttype_t *type = ASRUtils::expr_type(args[0]); - if (!ASRUtils::is_character(*type)) { - err("Argument of the Symbol function must be a Character", - args[0]->base.loc); - } - - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicSymbol, - static_cast(IntrinsicScalarFunctions::SymbolicSymbol), 0, to_type); - } - -} // namespace SymbolicSymbol - -#define create_symbolic_binary_macro(X) \ -namespace X{ \ - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, \ - diag::Diagnostics& diagnostics) { \ - ASRUtils::require_impl(x.n_args == 2, "Intrinsic function `"#X"` accepts" \ - "exactly 2 arguments", x.base.base.loc, diagnostics); \ - \ - ASR::ttype_t* left_type = ASRUtils::expr_type(x.m_args[0]); \ - ASR::ttype_t* right_type = ASRUtils::expr_type(x.m_args[1]); \ - \ - ASRUtils::require_impl(ASR::is_a(*left_type) && \ - ASR::is_a(*right_type), \ - "Both arguments of `"#X"` must be of type SymbolicExpression", \ - x.base.base.loc, diagnostics); \ - } \ - \ - static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ - ASR::ttype_t *, Vec &/*args*/) { \ - /*TODO*/ \ - return nullptr; \ - } \ - \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) { \ - if (args.size() != 2) { \ - err("Intrinsic function `"#X"` accepts exactly 2 arguments", loc); \ - } \ - \ - for (size_t i = 0; i < args.size(); i++) { \ - ASR::ttype_t* argtype = ASRUtils::expr_type(args[i]); \ - if(!ASR::is_a(*argtype)) { \ - err("Arguments of `"#X"` function must be of type SymbolicExpression", \ - args[i]->base.loc); \ - } \ - } \ - \ - Vec arg_values; \ - arg_values.reserve(al, args.size()); \ - for( size_t i = 0; i < args.size(); i++ ) { \ - arg_values.push_back(al, ASRUtils::expr_value(args[i])); \ - } \ - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ - ASR::expr_t* compile_time_value = eval_##X(al, loc, to_type, arg_values); \ - return ASR::make_IntrinsicScalarFunction_t(al, loc, \ - static_cast(IntrinsicScalarFunctions::X), \ - args.p, args.size(), 0, to_type, compile_time_value); \ - } \ -} // namespace X - -create_symbolic_binary_macro(SymbolicAdd) -create_symbolic_binary_macro(SymbolicSub) -create_symbolic_binary_macro(SymbolicMul) -create_symbolic_binary_macro(SymbolicDiv) -create_symbolic_binary_macro(SymbolicPow) -create_symbolic_binary_macro(SymbolicDiff) - -#define create_symbolic_constants_macro(X) \ -namespace X { \ - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, \ - diag::Diagnostics& diagnostics) { \ - const Location& loc = x.base.base.loc; \ - ASRUtils::require_impl(x.n_args == 0, \ - #X " does not take arguments", loc, diagnostics); \ - } \ - \ - static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ - ASR::ttype_t *, Vec &/*args*/) { \ - /*TODO*/ \ - return nullptr; \ - } \ - \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function /*err*/) { \ - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ - ASR::expr_t* compile_time_value = eval_##X(al, loc, to_type, args); \ - return ASR::make_IntrinsicScalarFunction_t(al, loc, \ - static_cast(IntrinsicScalarFunctions::X), \ - nullptr, 0, 0, to_type, compile_time_value); \ - } \ -} // namespace X - -create_symbolic_constants_macro(SymbolicPi) -create_symbolic_constants_macro(SymbolicE) - -namespace SymbolicInteger { - - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 1, - "SymbolicInteger intrinsic must have exactly 1 input argument", - x.base.base.loc, diagnostics); - - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); - ASRUtils::require_impl(ASR::is_a(*input_type), - "SymbolicInteger intrinsic expects an integer input argument", - x.base.base.loc, diagnostics); - } - - static inline ASR::expr_t* eval_SymbolicInteger(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/) { - // TODO - return nullptr; - } - - static inline ASR::asr_t* create_SymbolicInteger(Allocator& al, const Location& loc, - Vec& args, - const std::function /*err*/) { - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicInteger, - static_cast(IntrinsicScalarFunctions::SymbolicInteger), 0, to_type); - } - -} // namespace SymbolicInteger - -namespace SymbolicHasSymbolQ { - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Intrinsic function SymbolicHasSymbolQ" - "accepts exactly 2 arguments", x.base.base.loc, diagnostics); - - ASR::ttype_t* left_type = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t* right_type = ASRUtils::expr_type(x.m_args[1]); - - ASRUtils::require_impl(ASR::is_a(*left_type) && - ASR::is_a(*right_type), - "Both arguments of SymbolicHasSymbolQ must be of type SymbolicExpression", - x.base.base.loc, diagnostics); - } - - static inline ASR::expr_t* eval_SymbolicHasSymbolQ(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec &/*args*/) { - /*TODO*/ - return nullptr; - } - - static inline ASR::asr_t* create_SymbolicHasSymbolQ(Allocator& al, - const Location& loc, Vec& args, - const std::function err) { - - if (args.size() != 2) { - err("Intrinsic function SymbolicHasSymbolQ accepts exactly 2 arguments", loc); - } - - for (size_t i = 0; i < args.size(); i++) { - ASR::ttype_t* argtype = ASRUtils::expr_type(args[i]); - if(!ASR::is_a(*argtype)) { - err("Arguments of SymbolicHasSymbolQ function must be of type SymbolicExpression", - args[i]->base.loc); - } - } - - Vec arg_values; - arg_values.reserve(al, args.size()); - for( size_t i = 0; i < args.size(); i++ ) { - arg_values.push_back(al, ASRUtils::expr_value(args[i])); - } - - ASR::expr_t* compile_time_value = eval_SymbolicHasSymbolQ(al, loc, logical, arg_values); - return ASR::make_IntrinsicScalarFunction_t(al, loc, - static_cast(IntrinsicScalarFunctions::SymbolicHasSymbolQ), - args.p, args.size(), 0, logical, compile_time_value); - } -} // namespace SymbolicHasSymbolQ - -namespace SymbolicGetArgument { - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, - diag::Diagnostics& diagnostics) { - ASRUtils::require_impl(x.n_args == 2, "Intrinsic function SymbolicGetArgument" - "accepts exactly 2 argument", x.base.base.loc, diagnostics); - - ASR::ttype_t* arg1_type = ASRUtils::expr_type(x.m_args[0]); - ASR::ttype_t* arg2_type = ASRUtils::expr_type(x.m_args[1]); - ASRUtils::require_impl(ASR::is_a(*arg1_type), - "SymbolicGetArgument expects the first argument to be of type SymbolicExpression", - x.base.base.loc, diagnostics); - ASRUtils::require_impl(ASR::is_a(*arg2_type), - "SymbolicGetArgument expects the second argument to be of type Integer", - x.base.base.loc, diagnostics); - } - - static inline ASR::expr_t* eval_SymbolicGetArgument(Allocator &/*al*/, - const Location &/*loc*/, ASR::ttype_t *, Vec &/*args*/) { - /*TODO*/ - return nullptr; +#define INTRINSIC_NAME_CASE(X) \ + case (static_cast(ASRUtils::IntrinsicElementalFunctions::X)) : { \ + return #X; \ } - static inline ASR::asr_t* create_SymbolicGetArgument(Allocator& al, - const Location& loc, Vec& args, - const std::function err) { - - if (args.size() != 2) { - err("Intrinsic function SymbolicGetArguments accepts exactly 2 argument", loc); - } - - ASR::ttype_t* arg1_type = ASRUtils::expr_type(args[0]); - ASR::ttype_t* arg2_type = ASRUtils::expr_type(args[1]); - if (!ASR::is_a(*arg1_type)) { - err("The first argument of SymbolicGetArgument function must be of type SymbolicExpression", - args[0]->base.loc); - } - if (!ASR::is_a(*arg2_type)) { - err("The second argument of SymbolicGetArgument function must be of type Integer", - args[1]->base.loc); +inline std::string get_intrinsic_name(int x) { + switch (x) { + INTRINSIC_NAME_CASE(ObjectType) + INTRINSIC_NAME_CASE(Kind) + INTRINSIC_NAME_CASE(Rank) + INTRINSIC_NAME_CASE(Sin) + INTRINSIC_NAME_CASE(Cos) + INTRINSIC_NAME_CASE(Tan) + INTRINSIC_NAME_CASE(Asin) + INTRINSIC_NAME_CASE(Acos) + INTRINSIC_NAME_CASE(Atan) + INTRINSIC_NAME_CASE(Sinh) + INTRINSIC_NAME_CASE(Cosh) + INTRINSIC_NAME_CASE(Tanh) + INTRINSIC_NAME_CASE(Atan2) + INTRINSIC_NAME_CASE(Asinh) + INTRINSIC_NAME_CASE(Acosh) + INTRINSIC_NAME_CASE(Atanh) + INTRINSIC_NAME_CASE(Erf) + INTRINSIC_NAME_CASE(Erfc) + INTRINSIC_NAME_CASE(Gamma) + INTRINSIC_NAME_CASE(Log) + INTRINSIC_NAME_CASE(Log10) + INTRINSIC_NAME_CASE(LogGamma) + INTRINSIC_NAME_CASE(Trunc) + INTRINSIC_NAME_CASE(Fix) + INTRINSIC_NAME_CASE(Abs) + INTRINSIC_NAME_CASE(Aimag) + INTRINSIC_NAME_CASE(Exp) + INTRINSIC_NAME_CASE(Exp2) + INTRINSIC_NAME_CASE(Expm1) + INTRINSIC_NAME_CASE(FMA) + INTRINSIC_NAME_CASE(FlipSign) + INTRINSIC_NAME_CASE(FloorDiv) + INTRINSIC_NAME_CASE(Mod) + INTRINSIC_NAME_CASE(Trailz) + INTRINSIC_NAME_CASE(BesselJ0) + INTRINSIC_NAME_CASE(BesselJ1) + INTRINSIC_NAME_CASE(BesselY0) + INTRINSIC_NAME_CASE(Mvbits) + INTRINSIC_NAME_CASE(Shiftr) + INTRINSIC_NAME_CASE(Rshift) + INTRINSIC_NAME_CASE(Shiftl) + INTRINSIC_NAME_CASE(Dshiftl) + INTRINSIC_NAME_CASE(Ishft) + INTRINSIC_NAME_CASE(Bgt) + INTRINSIC_NAME_CASE(Blt) + INTRINSIC_NAME_CASE(Bge) + INTRINSIC_NAME_CASE(Ble) + INTRINSIC_NAME_CASE(Lgt) + INTRINSIC_NAME_CASE(Llt) + INTRINSIC_NAME_CASE(Lge) + INTRINSIC_NAME_CASE(Lle) + INTRINSIC_NAME_CASE(Exponent) + INTRINSIC_NAME_CASE(Fraction) + INTRINSIC_NAME_CASE(SetExponent) + INTRINSIC_NAME_CASE(Not) + INTRINSIC_NAME_CASE(Iand) + INTRINSIC_NAME_CASE(Ior) + INTRINSIC_NAME_CASE(Ieor) + INTRINSIC_NAME_CASE(Ibclr) + INTRINSIC_NAME_CASE(Ibset) + INTRINSIC_NAME_CASE(Btest) + INTRINSIC_NAME_CASE(Ibits) + INTRINSIC_NAME_CASE(Leadz) + INTRINSIC_NAME_CASE(ToLowerCase) + INTRINSIC_NAME_CASE(Digits) + INTRINSIC_NAME_CASE(Rrspacing) + INTRINSIC_NAME_CASE(Repeat) + INTRINSIC_NAME_CASE(StringContainsSet) + INTRINSIC_NAME_CASE(StringFindSet) + INTRINSIC_NAME_CASE(SubstrIndex) + INTRINSIC_NAME_CASE(Range) + INTRINSIC_NAME_CASE(Hypot) + INTRINSIC_NAME_CASE(SelectedIntKind) + INTRINSIC_NAME_CASE(SelectedRealKind) + INTRINSIC_NAME_CASE(SelectedCharKind) + INTRINSIC_NAME_CASE(Adjustl) + INTRINSIC_NAME_CASE(Adjustr) + INTRINSIC_NAME_CASE(Ichar) + INTRINSIC_NAME_CASE(Char) + INTRINSIC_NAME_CASE(MinExponent) + INTRINSIC_NAME_CASE(MaxExponent) + INTRINSIC_NAME_CASE(Ishftc) + INTRINSIC_NAME_CASE(ListIndex) + INTRINSIC_NAME_CASE(Partition) + INTRINSIC_NAME_CASE(ListReverse) + INTRINSIC_NAME_CASE(ListPop) + INTRINSIC_NAME_CASE(ListReserve) + INTRINSIC_NAME_CASE(DictKeys) + INTRINSIC_NAME_CASE(DictValues) + INTRINSIC_NAME_CASE(SetAdd) + INTRINSIC_NAME_CASE(SetRemove) + INTRINSIC_NAME_CASE(Max) + INTRINSIC_NAME_CASE(Min) + INTRINSIC_NAME_CASE(Sign) + INTRINSIC_NAME_CASE(SignFromValue) + INTRINSIC_NAME_CASE(Nint) + INTRINSIC_NAME_CASE(Aint) + INTRINSIC_NAME_CASE(Popcnt) + INTRINSIC_NAME_CASE(Poppar) + INTRINSIC_NAME_CASE(Dim) + INTRINSIC_NAME_CASE(Anint) + INTRINSIC_NAME_CASE(Sqrt) + INTRINSIC_NAME_CASE(Scale) + INTRINSIC_NAME_CASE(Sngl) + INTRINSIC_NAME_CASE(Ifix) + INTRINSIC_NAME_CASE(Idint) + INTRINSIC_NAME_CASE(Floor) + INTRINSIC_NAME_CASE(Ceiling) + INTRINSIC_NAME_CASE(Maskr) + INTRINSIC_NAME_CASE(Maskl) + INTRINSIC_NAME_CASE(Epsilon) + INTRINSIC_NAME_CASE(Precision) + INTRINSIC_NAME_CASE(Tiny) + INTRINSIC_NAME_CASE(Conjg) + INTRINSIC_NAME_CASE(Huge) + INTRINSIC_NAME_CASE(Dprod) + INTRINSIC_NAME_CASE(SymbolicSymbol) + INTRINSIC_NAME_CASE(SymbolicAdd) + INTRINSIC_NAME_CASE(SymbolicSub) + INTRINSIC_NAME_CASE(SymbolicMul) + INTRINSIC_NAME_CASE(SymbolicDiv) + INTRINSIC_NAME_CASE(SymbolicPow) + INTRINSIC_NAME_CASE(SymbolicPi) + INTRINSIC_NAME_CASE(SymbolicE) + INTRINSIC_NAME_CASE(SymbolicInteger) + INTRINSIC_NAME_CASE(SymbolicDiff) + INTRINSIC_NAME_CASE(SymbolicExpand) + INTRINSIC_NAME_CASE(SymbolicSin) + INTRINSIC_NAME_CASE(SymbolicCos) + INTRINSIC_NAME_CASE(SymbolicLog) + INTRINSIC_NAME_CASE(SymbolicExp) + INTRINSIC_NAME_CASE(SymbolicAbs) + INTRINSIC_NAME_CASE(SymbolicHasSymbolQ) + INTRINSIC_NAME_CASE(SymbolicAddQ) + INTRINSIC_NAME_CASE(SymbolicMulQ) + INTRINSIC_NAME_CASE(SymbolicPowQ) + INTRINSIC_NAME_CASE(SymbolicLogQ) + INTRINSIC_NAME_CASE(SymbolicSinQ) + INTRINSIC_NAME_CASE(SymbolicGetArgument) + default : { + throw LCompilersException("pickle: intrinsic_id not implemented"); } - - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicGetArgument, - static_cast(IntrinsicScalarFunctions::SymbolicGetArgument), - 0, to_type); } -} // namespace SymbolicGetArgument - -#define create_symbolic_query_macro(X) \ -namespace X { \ - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, \ - diag::Diagnostics& diagnostics) { \ - const Location& loc = x.base.base.loc; \ - ASRUtils::require_impl(x.n_args == 1, \ - #X " must have exactly 1 input argument", loc, diagnostics); \ - \ - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); \ - ASRUtils::require_impl(ASR::is_a(*input_type), \ - #X " expects an argument of type SymbolicExpression", loc, diagnostics); \ - } \ - \ - static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ - ASR::ttype_t *, Vec &/*args*/) { \ - /*TODO*/ \ - return nullptr; \ - } \ - \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) { \ - if (args.size() != 1) { \ - err("Intrinsic " #X " function accepts exactly 1 argument", loc); \ - } \ - \ - ASR::ttype_t* argtype = ASRUtils::expr_type(args[0]); \ - if (!ASR::is_a(*argtype)) { \ - err("Argument of " #X " function must be of type SymbolicExpression", \ - args[0]->base.loc); \ - } \ - \ - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ - static_cast(IntrinsicScalarFunctions::X), 0, logical); \ - } \ -} // namespace X - -create_symbolic_query_macro(SymbolicAddQ) -create_symbolic_query_macro(SymbolicMulQ) -create_symbolic_query_macro(SymbolicPowQ) -create_symbolic_query_macro(SymbolicLogQ) -create_symbolic_query_macro(SymbolicSinQ) - -#define create_symbolic_unary_macro(X) \ -namespace X { \ - static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, \ - diag::Diagnostics& diagnostics) { \ - const Location& loc = x.base.base.loc; \ - ASRUtils::require_impl(x.n_args == 1, \ - #X " must have exactly 1 input argument", loc, diagnostics); \ - \ - ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); \ - ASRUtils::require_impl(ASR::is_a(*input_type), \ - #X " expects an argument of type SymbolicExpression", loc, diagnostics); \ - } \ - \ - static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ - ASR::ttype_t *, Vec &/*args*/) { \ - /*TODO*/ \ - return nullptr; \ - } \ - \ - static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ - Vec& args, \ - const std::function err) { \ - if (args.size() != 1) { \ - err("Intrinsic " #X " function accepts exactly 1 argument", loc); \ - } \ - \ - ASR::ttype_t* argtype = ASRUtils::expr_type(args[0]); \ - if (!ASR::is_a(*argtype)) { \ - err("Argument of " #X " function must be of type SymbolicExpression", \ - args[0]->base.loc); \ - } \ - \ - ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ - return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ - static_cast(IntrinsicScalarFunctions::X), 0, to_type); \ - } \ -} // namespace X - -create_symbolic_unary_macro(SymbolicSin) -create_symbolic_unary_macro(SymbolicCos) -create_symbolic_unary_macro(SymbolicLog) -create_symbolic_unary_macro(SymbolicExp) -create_symbolic_unary_macro(SymbolicAbs) -create_symbolic_unary_macro(SymbolicExpand) - +} -namespace IntrinsicScalarFunctionRegistry { +namespace IntrinsicElementalFunctionRegistry { static const std::map>& intrinsic_function_by_id_db = { - {static_cast(IntrinsicScalarFunctions::ObjectType), + {static_cast(IntrinsicElementalFunctions::ObjectType), {nullptr, &ObjectType::verify_args}}, - {static_cast(IntrinsicScalarFunctions::LogGamma), + {static_cast(IntrinsicElementalFunctions::Gamma), + {&Gamma::instantiate_Gamma, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Log10), + {&Log10::instantiate_Log10, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Log), + {&Log::instantiate_Log, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::LogGamma), {&LogGamma::instantiate_LogGamma, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Trunc), + {static_cast(IntrinsicElementalFunctions::Erf), + {&Erf::instantiate_Erf, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Erfc), + {&Erfc::instantiate_Erfc, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Trunc), {&Trunc::instantiate_Trunc, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Fix), + {static_cast(IntrinsicElementalFunctions::Fix), {&Fix::instantiate_Fix, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Sin), + {static_cast(IntrinsicElementalFunctions::Sin), {&Sin::instantiate_Sin, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Cos), + {static_cast(IntrinsicElementalFunctions::Cos), {&Cos::instantiate_Cos, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Tan), + {static_cast(IntrinsicElementalFunctions::Tan), {&Tan::instantiate_Tan, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Asin), + {static_cast(IntrinsicElementalFunctions::Asin), {&Asin::instantiate_Asin, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Acos), + {static_cast(IntrinsicElementalFunctions::Acos), {&Acos::instantiate_Acos, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Atan), + {static_cast(IntrinsicElementalFunctions::Atan), {&Atan::instantiate_Atan, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Sinh), + {static_cast(IntrinsicElementalFunctions::Sinh), {&Sinh::instantiate_Sinh, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Cosh), + {static_cast(IntrinsicElementalFunctions::Cosh), {&Cosh::instantiate_Cosh, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Tanh), + {static_cast(IntrinsicElementalFunctions::Tanh), {&Tanh::instantiate_Tanh, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Atan2), + {static_cast(IntrinsicElementalFunctions::Atan2), {&Atan2::instantiate_Atan2, &BinaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Exp), + {static_cast(IntrinsicElementalFunctions::Asinh), + {&Asinh::instantiate_Asinh, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Acosh), + {&Acosh::instantiate_Acosh, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Atanh), + {&Atanh::instantiate_Atanh, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Exp), + {&Exp::instantiate_Exp, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Exp2), {nullptr, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Exp2), + {static_cast(IntrinsicElementalFunctions::Expm1), {nullptr, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Expm1), - {nullptr, &UnaryIntrinsicFunction::verify_args}}, - {static_cast(IntrinsicScalarFunctions::FMA), + {static_cast(IntrinsicElementalFunctions::FMA), {&FMA::instantiate_FMA, &FMA::verify_args}}, - {static_cast(IntrinsicScalarFunctions::FlipSign), + {static_cast(IntrinsicElementalFunctions::FlipSign), {&FlipSign::instantiate_FlipSign, &FlipSign::verify_args}}, - {static_cast(IntrinsicScalarFunctions::FloorDiv), + {static_cast(IntrinsicElementalFunctions::FloorDiv), {&FloorDiv::instantiate_FloorDiv, &FloorDiv::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Mod), + {static_cast(IntrinsicElementalFunctions::Mod), {&Mod::instantiate_Mod, &Mod::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Trailz), + {static_cast(IntrinsicElementalFunctions::Trailz), {&Trailz::instantiate_Trailz, &Trailz::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Abs), + {static_cast(IntrinsicElementalFunctions::BesselJ0), + {&BesselJ0::instantiate_BesselJ0, &BesselJ0::verify_args}}, + {static_cast(IntrinsicElementalFunctions::BesselJ1), + {&BesselJ1::instantiate_BesselJ1, &BesselJ1::verify_args}}, + {static_cast(IntrinsicElementalFunctions::BesselY0), + {&BesselY0::instantiate_BesselY0, &BesselY0::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Mvbits), + {&Mvbits::instantiate_Mvbits, &Mvbits::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Shiftr), + {&Shiftr::instantiate_Shiftr, &Shiftr::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Adjustl), + {&Adjustl::instantiate_Adjustl, &Adjustl::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Adjustr), + {&Adjustr::instantiate_Adjustr, &Adjustr::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ichar), + {&Ichar::instantiate_Ichar, &Ichar::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Char), + {&Char::instantiate_Char, &Char::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Rshift), + {&Rshift::instantiate_Rshift, &Rshift::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Shiftl), + {&Shiftl::instantiate_Shiftl, &Shiftl::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Dshiftl), + {&Dshiftl::instantiate_Dshiftl, &Dshiftl::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ishft), + {&Ishft::instantiate_Ishft, &Ishft::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Bgt), + {&Bgt::instantiate_Bgt, &Bgt::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Blt), + {&Blt::instantiate_Blt, &Blt::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Bge), + {&Bge::instantiate_Bge, &Bge::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Exponent), + {&Exponent::instantiate_Exponent, &Exponent::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Fraction), + {&Fraction::instantiate_Fraction, &Fraction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SetExponent), + {&SetExponent::instantiate_SetExponent, &SetExponent::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ble), + {&Ble::instantiate_Ble, &Ble::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Lgt), + {&Lgt::instantiate_Lgt, &Lgt::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Llt), + {&Llt::instantiate_Llt, &Llt::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Lge), + {&Lge::instantiate_Lge, &Lge::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Lle), + {&Lle::instantiate_Lle, &Lle::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Not), + {&Not::instantiate_Not, &Not::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Iand), + {&Iand::instantiate_Iand, &Iand::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ior), + {&Ior::instantiate_Ior, &Ior::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ieor), + {&Ieor::instantiate_Ieor, &Ieor::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ibclr), + {&Ibclr::instantiate_Ibclr, &Ibclr::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Btest), + {&Btest::instantiate_Btest, &Btest::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ibset), + {&Ibset::instantiate_Ibset, &Ibset::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ibits), + {&Ibits::instantiate_Ibits, &Ibits::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Leadz), + {&Leadz::instantiate_Leadz, &Leadz::verify_args}}, + {static_cast(IntrinsicElementalFunctions::ToLowerCase), + {&ToLowerCase::instantiate_ToLowerCase, &ToLowerCase::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Hypot), + {&Hypot::instantiate_Hypot, &Hypot::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Kind), + {&Kind::instantiate_Kind, &Kind::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Rank), + {nullptr, &Rank::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Digits), + {&Digits::instantiate_Digits, &Digits::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Rrspacing), + {&Rrspacing::instantiate_Rrspacing, &Rrspacing::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Repeat), + {&Repeat::instantiate_Repeat, &Repeat::verify_args}}, + {static_cast(IntrinsicElementalFunctions::StringContainsSet), + {&StringContainsSet::instantiate_StringContainsSet, &StringContainsSet::verify_args}}, + {static_cast(IntrinsicElementalFunctions::StringFindSet), + {&StringFindSet::instantiate_StringFindSet, &StringFindSet::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SubstrIndex), + {&SubstrIndex::instantiate_SubstrIndex, &SubstrIndex::verify_args}}, + {static_cast(IntrinsicElementalFunctions::MinExponent), + {&MinExponent::instantiate_MinExponent, &MinExponent::verify_args}}, + {static_cast(IntrinsicElementalFunctions::MaxExponent), + {&MaxExponent::instantiate_MaxExponent, &MaxExponent::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Abs), {&Abs::instantiate_Abs, &Abs::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Partition), + {static_cast(IntrinsicElementalFunctions::Aimag), + {&Aimag::instantiate_Aimag, &Aimag::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Partition), {&Partition::instantiate_Partition, &Partition::verify_args}}, - {static_cast(IntrinsicScalarFunctions::ListIndex), + {static_cast(IntrinsicElementalFunctions::ListIndex), {nullptr, &ListIndex::verify_args}}, - {static_cast(IntrinsicScalarFunctions::ListReverse), + {static_cast(IntrinsicElementalFunctions::ListReverse), {nullptr, &ListReverse::verify_args}}, - {static_cast(IntrinsicScalarFunctions::DictKeys), + {static_cast(IntrinsicElementalFunctions::DictKeys), {nullptr, &DictKeys::verify_args}}, - {static_cast(IntrinsicScalarFunctions::DictValues), + {static_cast(IntrinsicElementalFunctions::DictValues), {nullptr, &DictValues::verify_args}}, - {static_cast(IntrinsicScalarFunctions::ListPop), + {static_cast(IntrinsicElementalFunctions::ListPop), {nullptr, &ListPop::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Reserve), - {nullptr, &Reserve::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SetAdd), + {static_cast(IntrinsicElementalFunctions::ListReserve), + {nullptr, &ListReserve::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SetAdd), {nullptr, &SetAdd::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SetRemove), + {static_cast(IntrinsicElementalFunctions::SetRemove), {nullptr, &SetRemove::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Max), + {static_cast(IntrinsicElementalFunctions::Max), {&Max::instantiate_Max, &Max::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Min), + {static_cast(IntrinsicElementalFunctions::Min), {&Min::instantiate_Min, &Min::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Sign), + {static_cast(IntrinsicElementalFunctions::Sign), {&Sign::instantiate_Sign, &Sign::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Radix), + {static_cast(IntrinsicElementalFunctions::Radix), {nullptr, &Radix::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Aint), + {static_cast(IntrinsicElementalFunctions::Scale), + {&Scale::instantiate_Scale, &Scale::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Dprod), + {&Dprod::instantiate_Dprod, &Dprod::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Range), + {nullptr, &Range::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Aint), {&Aint::instantiate_Aint, &Aint::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Sqrt), + {static_cast(IntrinsicElementalFunctions::Popcnt), + {&Popcnt::instantiate_Popcnt, &Popcnt::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Poppar), + {&Poppar::instantiate_Poppar, &Poppar::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Nint), + {&Nint::instantiate_Nint, &Nint::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Anint), + {&Anint::instantiate_Anint, &Anint::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Dim), + {&Dim::instantiate_Dim, &Dim::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Floor), + {&Floor::instantiate_Floor, &Floor::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ceiling), + {&Ceiling::instantiate_Ceiling, &Ceiling::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Maskr), + {&Maskr::instantiate_Maskr, &Maskr::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Maskl), + {&Maskl::instantiate_Maskl, &Maskl::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Sqrt), {&Sqrt::instantiate_Sqrt, &Sqrt::verify_args}}, - {static_cast(IntrinsicScalarFunctions::Sngl), + {static_cast(IntrinsicElementalFunctions::Sngl), {&Sngl::instantiate_Sngl, &Sngl::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SignFromValue), + {static_cast(IntrinsicElementalFunctions::Ifix), + {&Ifix::instantiate_Ifix, &Ifix::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Idint), + {&Idint::instantiate_Idint, &Idint::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Ishftc), + {&Ishftc::instantiate_Ishftc, &Ishftc::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Conjg), + {&Conjg::instantiate_Conjg, &Conjg::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SignFromValue), {&SignFromValue::instantiate_SignFromValue, &SignFromValue::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicSymbol), + {static_cast(IntrinsicElementalFunctions::Epsilon), + {nullptr, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Precision), + {nullptr, &Precision::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Tiny), + {nullptr, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::Huge), + {nullptr, &UnaryIntrinsicFunction::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SelectedIntKind), + {&SelectedIntKind::instantiate_SelectedIntKind, &SelectedIntKind::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SelectedRealKind), + {&SelectedRealKind::instantiate_SelectedRealKind, &SelectedRealKind::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SelectedCharKind), + {&SelectedCharKind::instantiate_SelectedCharKind, &SelectedCharKind::verify_args}}, + {static_cast(IntrinsicElementalFunctions::SymbolicSymbol), {nullptr, &SymbolicSymbol::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicAdd), + {static_cast(IntrinsicElementalFunctions::SymbolicAdd), {nullptr, &SymbolicAdd::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicSub), + {static_cast(IntrinsicElementalFunctions::SymbolicSub), {nullptr, &SymbolicSub::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicMul), + {static_cast(IntrinsicElementalFunctions::SymbolicMul), {nullptr, &SymbolicMul::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicDiv), + {static_cast(IntrinsicElementalFunctions::SymbolicDiv), {nullptr, &SymbolicDiv::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicPow), + {static_cast(IntrinsicElementalFunctions::SymbolicPow), {nullptr, &SymbolicPow::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicPi), + {static_cast(IntrinsicElementalFunctions::SymbolicPi), {nullptr, &SymbolicPi::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicE), + {static_cast(IntrinsicElementalFunctions::SymbolicE), {nullptr, &SymbolicE::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicInteger), + {static_cast(IntrinsicElementalFunctions::SymbolicInteger), {nullptr, &SymbolicInteger::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicDiff), + {static_cast(IntrinsicElementalFunctions::SymbolicDiff), {nullptr, &SymbolicDiff::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicExpand), + {static_cast(IntrinsicElementalFunctions::SymbolicExpand), {nullptr, &SymbolicExpand::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicSin), + {static_cast(IntrinsicElementalFunctions::SymbolicSin), {nullptr, &SymbolicSin::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicCos), + {static_cast(IntrinsicElementalFunctions::SymbolicCos), {nullptr, &SymbolicCos::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicLog), + {static_cast(IntrinsicElementalFunctions::SymbolicLog), {nullptr, &SymbolicLog::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicExp), + {static_cast(IntrinsicElementalFunctions::SymbolicExp), {nullptr, &SymbolicExp::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicAbs), + {static_cast(IntrinsicElementalFunctions::SymbolicAbs), {nullptr, &SymbolicAbs::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicHasSymbolQ), + {static_cast(IntrinsicElementalFunctions::SymbolicHasSymbolQ), {nullptr, &SymbolicHasSymbolQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicAddQ), + {static_cast(IntrinsicElementalFunctions::SymbolicAddQ), {nullptr, &SymbolicAddQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicMulQ), + {static_cast(IntrinsicElementalFunctions::SymbolicMulQ), {nullptr, &SymbolicMulQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicPowQ), + {static_cast(IntrinsicElementalFunctions::SymbolicPowQ), {nullptr, &SymbolicPowQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicLogQ), + {static_cast(IntrinsicElementalFunctions::SymbolicLogQ), {nullptr, &SymbolicLogQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicSinQ), + {static_cast(IntrinsicElementalFunctions::SymbolicSinQ), {nullptr, &SymbolicSinQ::verify_args}}, - {static_cast(IntrinsicScalarFunctions::SymbolicGetArgument), + {static_cast(IntrinsicElementalFunctions::SymbolicGetArgument), {nullptr, &SymbolicGetArgument::verify_args}}, }; static const std::map& intrinsic_function_id_to_name = { - {static_cast(IntrinsicScalarFunctions::ObjectType), + {static_cast(IntrinsicElementalFunctions::ObjectType), "type"}, - {static_cast(IntrinsicScalarFunctions::LogGamma), + {static_cast(IntrinsicElementalFunctions::Gamma), + "gamma"}, + {static_cast(IntrinsicElementalFunctions::Log), + "log"}, + {static_cast(IntrinsicElementalFunctions::Log10), + "log10"}, + {static_cast(IntrinsicElementalFunctions::LogGamma), "log_gamma"}, - {static_cast(IntrinsicScalarFunctions::Trunc), + {static_cast(IntrinsicElementalFunctions::Erf), + "erf"}, + {static_cast(IntrinsicElementalFunctions::Erfc), + "erfc"}, + {static_cast(IntrinsicElementalFunctions::Trunc), "trunc"}, - {static_cast(IntrinsicScalarFunctions::Fix), + {static_cast(IntrinsicElementalFunctions::Fix), "fix"}, - {static_cast(IntrinsicScalarFunctions::Sin), + {static_cast(IntrinsicElementalFunctions::Sin), "sin"}, - {static_cast(IntrinsicScalarFunctions::Cos), + {static_cast(IntrinsicElementalFunctions::Cos), "cos"}, - {static_cast(IntrinsicScalarFunctions::Tan), + {static_cast(IntrinsicElementalFunctions::Tan), "tan"}, - {static_cast(IntrinsicScalarFunctions::Asin), + {static_cast(IntrinsicElementalFunctions::Asin), "asin"}, - {static_cast(IntrinsicScalarFunctions::Acos), + {static_cast(IntrinsicElementalFunctions::Acos), "acos"}, - {static_cast(IntrinsicScalarFunctions::Atan), + {static_cast(IntrinsicElementalFunctions::Atan), "atan"}, - {static_cast(IntrinsicScalarFunctions::Sinh), + {static_cast(IntrinsicElementalFunctions::Sinh), "sinh"}, - {static_cast(IntrinsicScalarFunctions::Cosh), + {static_cast(IntrinsicElementalFunctions::Cosh), "cosh"}, - {static_cast(IntrinsicScalarFunctions::Tanh), + {static_cast(IntrinsicElementalFunctions::Tanh), "tanh"}, - {static_cast(IntrinsicScalarFunctions::Atan2), + {static_cast(IntrinsicElementalFunctions::Atan2), "atan2"}, - {static_cast(IntrinsicScalarFunctions::Abs), + {static_cast(IntrinsicElementalFunctions::Asinh), + "asinh"}, + {static_cast(IntrinsicElementalFunctions::Acosh), + "acosh"}, + {static_cast(IntrinsicElementalFunctions::Atanh), + "atanh"}, + {static_cast(IntrinsicElementalFunctions::Abs), "abs"}, - {static_cast(IntrinsicScalarFunctions::Exp), + {static_cast(IntrinsicElementalFunctions::Aimag), + "aimag"}, + {static_cast(IntrinsicElementalFunctions::Exp), "exp"}, - {static_cast(IntrinsicScalarFunctions::Exp2), + {static_cast(IntrinsicElementalFunctions::Exp2), "exp2"}, - {static_cast(IntrinsicScalarFunctions::FMA), + {static_cast(IntrinsicElementalFunctions::FMA), "fma"}, - {static_cast(IntrinsicScalarFunctions::FlipSign), + {static_cast(IntrinsicElementalFunctions::FlipSign), "flipsign"}, - {static_cast(IntrinsicScalarFunctions::FloorDiv), + {static_cast(IntrinsicElementalFunctions::FloorDiv), "floordiv"}, - {static_cast(IntrinsicScalarFunctions::Mod), + {static_cast(IntrinsicElementalFunctions::Mod), "mod"}, - {static_cast(IntrinsicScalarFunctions::Trailz), + {static_cast(IntrinsicElementalFunctions::Trailz), "trailz"}, - {static_cast(IntrinsicScalarFunctions::Expm1), + {static_cast(IntrinsicElementalFunctions::BesselJ0), + "bessel_j0"}, + {static_cast(IntrinsicElementalFunctions::BesselY0), + "bessel_y0"}, + {static_cast(IntrinsicElementalFunctions::Mvbits), + "mvbits"}, + {static_cast(IntrinsicElementalFunctions::Shiftr), + "shiftr"}, + {static_cast(IntrinsicElementalFunctions::Rshift), + "rshift"}, + {static_cast(IntrinsicElementalFunctions::Adjustl), + "adjustl"}, + {static_cast(IntrinsicElementalFunctions::Adjustr), + "adjustr"}, + {static_cast(IntrinsicElementalFunctions::Ichar), + "ichar"}, + {static_cast(IntrinsicElementalFunctions::Char), + "char"}, + {static_cast(IntrinsicElementalFunctions::Shiftl), + "shiftl"}, + {static_cast(IntrinsicElementalFunctions::Dshiftl), + "dshiftl"}, + {static_cast(IntrinsicElementalFunctions::Ishft), + "ishft"}, + {static_cast(IntrinsicElementalFunctions::Bgt), + "bgt"}, + {static_cast(IntrinsicElementalFunctions::Blt), + "blt"}, + {static_cast(IntrinsicElementalFunctions::Bge), + "bge"}, + {static_cast(IntrinsicElementalFunctions::Ble), + "ble"}, + {static_cast(IntrinsicElementalFunctions::Lgt), + "lgt"}, + {static_cast(IntrinsicElementalFunctions::Llt), + "llt"}, + {static_cast(IntrinsicElementalFunctions::Lge), + "lge"}, + {static_cast(IntrinsicElementalFunctions::Lle), + "lle"}, + {static_cast(IntrinsicElementalFunctions::Exponent), + "exponent"}, + {static_cast(IntrinsicElementalFunctions::Fraction), + "fraction"}, + {static_cast(IntrinsicElementalFunctions::SetExponent), + "set_exponent"}, + {static_cast(IntrinsicElementalFunctions::Not), + "not"}, + {static_cast(IntrinsicElementalFunctions::Iand), + "iand"}, + {static_cast(IntrinsicElementalFunctions::Ior), + "ior"}, + {static_cast(IntrinsicElementalFunctions::Ieor), + "ieor"}, + {static_cast(IntrinsicElementalFunctions::Ibclr), + "ibclr"}, + {static_cast(IntrinsicElementalFunctions::Ibset), + "ibset"}, + {static_cast(IntrinsicElementalFunctions::Btest), + "btest"}, + {static_cast(IntrinsicElementalFunctions::Ibits), + "ibits"}, + {static_cast(IntrinsicElementalFunctions::Leadz), + "leadz"}, + {static_cast(IntrinsicElementalFunctions::ToLowerCase), + "_lfortran_tolowercase"}, + {static_cast(IntrinsicElementalFunctions::Hypot), + "hypot"}, + {static_cast(IntrinsicElementalFunctions::SelectedIntKind), + "selected_int_kind"}, + {static_cast(IntrinsicElementalFunctions::SelectedRealKind), + "selected_real_kind"}, + {static_cast(IntrinsicElementalFunctions::SelectedCharKind), + "selected_char_kind"}, + {static_cast(IntrinsicElementalFunctions::Kind), + "kind"}, + {static_cast(IntrinsicElementalFunctions::Rank), + "rank"}, + {static_cast(IntrinsicElementalFunctions::Digits), + "Digits"}, + {static_cast(IntrinsicElementalFunctions::Rrspacing), + "rrspacing"}, + {static_cast(IntrinsicElementalFunctions::Repeat), + "Repeat"}, + {static_cast(IntrinsicElementalFunctions::StringContainsSet), + "Verify"}, + {static_cast(IntrinsicElementalFunctions::StringFindSet), + "Scan"}, + {static_cast(IntrinsicElementalFunctions::SubstrIndex), + "Index"}, + {static_cast(IntrinsicElementalFunctions::MinExponent), + "minexponent"}, + {static_cast(IntrinsicElementalFunctions::MaxExponent), + "maxexponent"}, + {static_cast(IntrinsicElementalFunctions::Expm1), "expm1"}, - {static_cast(IntrinsicScalarFunctions::ListIndex), + {static_cast(IntrinsicElementalFunctions::ListIndex), "list.index"}, - {static_cast(IntrinsicScalarFunctions::ListReverse), + {static_cast(IntrinsicElementalFunctions::ListReverse), "list.reverse"}, - {static_cast(IntrinsicScalarFunctions::ListPop), + {static_cast(IntrinsicElementalFunctions::ListPop), "list.pop"}, - {static_cast(IntrinsicScalarFunctions::Reserve), - "reserve"}, - {static_cast(IntrinsicScalarFunctions::DictKeys), + {static_cast(IntrinsicElementalFunctions::ListReserve), + "list.reserve"}, + {static_cast(IntrinsicElementalFunctions::DictKeys), "dict.keys"}, - {static_cast(IntrinsicScalarFunctions::DictValues), + {static_cast(IntrinsicElementalFunctions::DictValues), "dict.values"}, - {static_cast(IntrinsicScalarFunctions::SetAdd), + {static_cast(IntrinsicElementalFunctions::SetAdd), "set.add"}, - {static_cast(IntrinsicScalarFunctions::SetRemove), + {static_cast(IntrinsicElementalFunctions::SetRemove), "set.remove"}, - {static_cast(IntrinsicScalarFunctions::Max), + {static_cast(IntrinsicElementalFunctions::Max), "max"}, - {static_cast(IntrinsicScalarFunctions::Min), + {static_cast(IntrinsicElementalFunctions::Min), "min"}, - {static_cast(IntrinsicScalarFunctions::Radix), + {static_cast(IntrinsicElementalFunctions::Ishftc), + "ishftc"}, + {static_cast(IntrinsicElementalFunctions::Radix), "radix"}, - {static_cast(IntrinsicScalarFunctions::Sign), + {static_cast(IntrinsicElementalFunctions::Scale), + "scale"}, + {static_cast(IntrinsicElementalFunctions::Dprod), + "dprod"}, + {static_cast(IntrinsicElementalFunctions::Range), + "range"}, + {static_cast(IntrinsicElementalFunctions::Sign), "sign"}, - {static_cast(IntrinsicScalarFunctions::Aint), + {static_cast(IntrinsicElementalFunctions::Aint), "aint"}, - {static_cast(IntrinsicScalarFunctions::Sqrt), + {static_cast(IntrinsicElementalFunctions::Popcnt), + "popcnt"}, + {static_cast(IntrinsicElementalFunctions::Poppar), + "poppar"}, + {static_cast(IntrinsicElementalFunctions::Nint), + "nint"}, + {static_cast(IntrinsicElementalFunctions::Anint), + "anint"}, + {static_cast(IntrinsicElementalFunctions::Dim), + "dim"}, + {static_cast(IntrinsicElementalFunctions::Floor), + "floor"}, + {static_cast(IntrinsicElementalFunctions::Ceiling), + "ceiling"}, + {static_cast(IntrinsicElementalFunctions::Maskr), + "Maskr"}, + {static_cast(IntrinsicElementalFunctions::Maskl), + "maskl"}, + {static_cast(IntrinsicElementalFunctions::Sqrt), "sqrt"}, - {static_cast(IntrinsicScalarFunctions::Sngl), + {static_cast(IntrinsicElementalFunctions::Sngl), "sngl"}, - {static_cast(IntrinsicScalarFunctions::SignFromValue), + {static_cast(IntrinsicElementalFunctions::Idint), + "idint"}, + {static_cast(IntrinsicElementalFunctions::Ifix), + "ifix"}, + {static_cast(IntrinsicElementalFunctions::Conjg), + "conjg"}, + {static_cast(IntrinsicElementalFunctions::SignFromValue), "signfromvalue"}, - {static_cast(IntrinsicScalarFunctions::SymbolicSymbol), + {static_cast(IntrinsicElementalFunctions::Epsilon), + "epsilon"}, + {static_cast(IntrinsicElementalFunctions::Precision), + "precision"}, + {static_cast(IntrinsicElementalFunctions::Tiny), + "tiny"}, + {static_cast(IntrinsicElementalFunctions::Huge), + "huge"}, + {static_cast(IntrinsicElementalFunctions::SymbolicSymbol), "Symbol"}, - {static_cast(IntrinsicScalarFunctions::SymbolicAdd), + {static_cast(IntrinsicElementalFunctions::SymbolicAdd), "SymbolicAdd"}, - {static_cast(IntrinsicScalarFunctions::SymbolicSub), + {static_cast(IntrinsicElementalFunctions::SymbolicSub), "SymbolicSub"}, - {static_cast(IntrinsicScalarFunctions::SymbolicMul), + {static_cast(IntrinsicElementalFunctions::SymbolicMul), "SymbolicMul"}, - {static_cast(IntrinsicScalarFunctions::SymbolicDiv), + {static_cast(IntrinsicElementalFunctions::SymbolicDiv), "SymbolicDiv"}, - {static_cast(IntrinsicScalarFunctions::SymbolicPow), + {static_cast(IntrinsicElementalFunctions::SymbolicPow), "SymbolicPow"}, - {static_cast(IntrinsicScalarFunctions::SymbolicPi), + {static_cast(IntrinsicElementalFunctions::SymbolicPi), "pi"}, - {static_cast(IntrinsicScalarFunctions::SymbolicE), + {static_cast(IntrinsicElementalFunctions::SymbolicE), "E"}, - {static_cast(IntrinsicScalarFunctions::SymbolicInteger), + {static_cast(IntrinsicElementalFunctions::SymbolicInteger), "SymbolicInteger"}, - {static_cast(IntrinsicScalarFunctions::SymbolicDiff), + {static_cast(IntrinsicElementalFunctions::SymbolicDiff), "SymbolicDiff"}, - {static_cast(IntrinsicScalarFunctions::SymbolicExpand), + {static_cast(IntrinsicElementalFunctions::SymbolicExpand), "SymbolicExpand"}, - {static_cast(IntrinsicScalarFunctions::SymbolicSin), + {static_cast(IntrinsicElementalFunctions::SymbolicSin), "SymbolicSin"}, - {static_cast(IntrinsicScalarFunctions::SymbolicCos), + {static_cast(IntrinsicElementalFunctions::SymbolicCos), "SymbolicCos"}, - {static_cast(IntrinsicScalarFunctions::SymbolicLog), + {static_cast(IntrinsicElementalFunctions::SymbolicLog), "SymbolicLog"}, - {static_cast(IntrinsicScalarFunctions::SymbolicExp), + {static_cast(IntrinsicElementalFunctions::SymbolicExp), "SymbolicExp"}, - {static_cast(IntrinsicScalarFunctions::SymbolicAbs), + {static_cast(IntrinsicElementalFunctions::SymbolicAbs), "SymbolicAbs"}, - {static_cast(IntrinsicScalarFunctions::SymbolicHasSymbolQ), + {static_cast(IntrinsicElementalFunctions::SymbolicHasSymbolQ), "SymbolicHasSymbolQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicAddQ), + {static_cast(IntrinsicElementalFunctions::SymbolicAddQ), "SymbolicAddQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicMulQ), + {static_cast(IntrinsicElementalFunctions::SymbolicMulQ), "SymbolicMulQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicPowQ), + {static_cast(IntrinsicElementalFunctions::SymbolicPowQ), "SymbolicPowQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicLogQ), + {static_cast(IntrinsicElementalFunctions::SymbolicLogQ), "SymbolicLogQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicSinQ), + {static_cast(IntrinsicElementalFunctions::SymbolicSinQ), "SymbolicSinQ"}, - {static_cast(IntrinsicScalarFunctions::SymbolicGetArgument), + {static_cast(IntrinsicElementalFunctions::SymbolicGetArgument), "SymbolicGetArgument"}, }; @@ -3940,7 +734,12 @@ namespace IntrinsicScalarFunctionRegistry { std::tuple>& intrinsic_function_by_name_db = { {"type", {&ObjectType::create_ObjectType, &ObjectType::eval_ObjectType}}, - {"log_gamma", {&LogGamma::create_LogGamma, &LogGamma::eval_log_gamma}}, + {"gamma", {&Gamma::create_Gamma, &Gamma::eval_Gamma}}, + {"log", {&Log::create_Log, &Log::eval_Log}}, + {"log10", {&Log10::create_Log10, &Log10::eval_Log10}}, + {"log_gamma", {&LogGamma::create_LogGamma, &LogGamma::eval_LogGamma}}, + {"erf", {&Erf::create_Erf, &Erf::eval_Erf}}, + {"erfc", {&Erfc::create_Erfc, &Erfc::eval_Erfc}}, {"trunc", {&Trunc::create_Trunc, &Trunc::eval_Trunc}}, {"fix", {&Fix::create_Fix, &Fix::eval_Fix}}, {"sin", {&Sin::create_Sin, &Sin::eval_Sin}}, @@ -3953,7 +752,11 @@ namespace IntrinsicScalarFunctionRegistry { {"cosh", {&Cosh::create_Cosh, &Cosh::eval_Cosh}}, {"tanh", {&Tanh::create_Tanh, &Tanh::eval_Tanh}}, {"atan2", {&Atan2::create_Atan2, &Atan2::eval_Atan2}}, + {"asinh", {&Asinh::create_Asinh, &Asinh::eval_Asinh}}, + {"acosh", {&Acosh::create_Acosh, &Acosh::eval_Acosh}}, + {"atanh", {&Atanh::create_Atanh, &Atanh::eval_Atanh}}, {"abs", {&Abs::create_Abs, &Abs::eval_Abs}}, + {"aimag", {&Aimag::create_Aimag, &Aimag::eval_Aimag}}, {"exp", {&Exp::create_Exp, &Exp::eval_Exp}}, {"exp2", {&Exp2::create_Exp2, &Exp2::eval_Exp2}}, {"expm1", {&Expm1::create_Expm1, &Expm1::eval_Expm1}}, @@ -3961,22 +764,92 @@ namespace IntrinsicScalarFunctionRegistry { {"floordiv", {&FloorDiv::create_FloorDiv, &FloorDiv::eval_FloorDiv}}, {"mod", {&Mod::create_Mod, &Mod::eval_Mod}}, {"trailz", {&Trailz::create_Trailz, &Trailz::eval_Trailz}}, + {"bessel_j0", {&BesselJ0::create_BesselJ0, &BesselJ0::eval_BesselJ0}}, + {"bessel_j1", {&BesselJ1::create_BesselJ1, &BesselJ1::eval_BesselJ1}}, + {"bessel_y0", {&BesselY0::create_BesselY0, &BesselY0::eval_BesselY0}}, + {"mvbits", {&Mvbits::create_Mvbits, &Mvbits::eval_Mvbits}}, + {"shiftr", {&Shiftr::create_Shiftr, &Shiftr::eval_Shiftr}}, + {"rshift", {&Rshift::create_Rshift, &Rshift::eval_Rshift}}, + {"shiftl", {&Shiftl::create_Shiftl, &Shiftl::eval_Shiftl}}, + {"lshift", {&Shiftl::create_Shiftl, &Shiftl::eval_Shiftl}}, + {"dshiftl", {&Dshiftl::create_Dshiftl, &Dshiftl::eval_Dshiftl}}, + {"ishft", {&Ishft::create_Ishft, &Ishft::eval_Ishft}}, + {"bgt", {&Bgt::create_Bgt, &Bgt::eval_Bgt}}, + {"blt", {&Blt::create_Blt, &Blt::eval_Blt}}, + {"bge", {&Bge::create_Bge, &Bge::eval_Bge}}, + {"ble", {&Ble::create_Ble, &Ble::eval_Ble}}, + {"lgt", {&Lgt::create_Lgt, &Lgt::eval_Lgt}}, + {"llt", {&Llt::create_Llt, &Llt::eval_Llt}}, + {"lge", {&Lge::create_Lge, &Lge::eval_Lge}}, + {"lle", {&Lle::create_Lle, &Lle::eval_Lle}}, + {"exponent", {&Exponent::create_Exponent, &Exponent::eval_Exponent}}, + {"fraction", {&Fraction::create_Fraction, &Fraction::eval_Fraction}}, + {"set_exponent", {&SetExponent::create_SetExponent, &SetExponent::eval_SetExponent}}, + {"not", {&Not::create_Not, &Not::eval_Not}}, + {"iand", {&Iand::create_Iand, &Iand::eval_Iand}}, + {"ior", {&Ior::create_Ior, &Ior::eval_Ior}}, + {"ieor", {&Ieor::create_Ieor, &Ieor::eval_Ieor}}, + {"ibclr", {&Ibclr::create_Ibclr, &Ibclr::eval_Ibclr}}, + {"ibset", {&Ibset::create_Ibset, &Ibset::eval_Ibset}}, + {"btest", {&Btest::create_Btest, &Btest::eval_Btest}}, + {"ibits", {&Ibits::create_Ibits, &Ibits::eval_Ibits}}, + {"leadz", {&Leadz::create_Leadz, &Leadz::eval_Leadz}}, + {"_lfortran_tolowercase", {&ToLowerCase::create_ToLowerCase, &ToLowerCase::eval_ToLowerCase}}, + {"hypot", {&Hypot::create_Hypot, &Hypot::eval_Hypot}}, + {"selected_int_kind", {&SelectedIntKind::create_SelectedIntKind, &SelectedIntKind::eval_SelectedIntKind}}, + {"selected_real_kind", {&SelectedRealKind::create_SelectedRealKind, &SelectedRealKind::eval_SelectedRealKind}}, + {"selected_char_kind", {&SelectedCharKind::create_SelectedCharKind, &SelectedCharKind::eval_SelectedCharKind}}, + {"kind", {&Kind::create_Kind, &Kind::eval_Kind}}, + {"rank", {&Rank::create_Rank, &Rank::eval_Rank}}, + {"digits", {&Digits::create_Digits, &Digits::eval_Digits}}, + {"rrspacing", {&Rrspacing::create_Rrspacing, &Rrspacing::eval_Rrspacing}}, + {"repeat", {&Repeat::create_Repeat, &Repeat::eval_Repeat}}, + {"verify", {&StringContainsSet::create_StringContainsSet, &StringContainsSet::eval_StringContainsSet}}, + {"scan", {&StringFindSet::create_StringFindSet, &StringFindSet::eval_StringFindSet}}, + {"index", {&SubstrIndex::create_SubstrIndex, &SubstrIndex::eval_SubstrIndex}}, + {"minexponent", {&MinExponent::create_MinExponent, &MinExponent::eval_MinExponent}}, + {"maxexponent", {&MaxExponent::create_MaxExponent, &MaxExponent::eval_MaxExponent}}, {"list.index", {&ListIndex::create_ListIndex, &ListIndex::eval_list_index}}, - {"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_list_reverse}}, + {"list.reverse", {&ListReverse::create_ListReverse, &ListReverse::eval_ListReverse}}, {"list.pop", {&ListPop::create_ListPop, &ListPop::eval_list_pop}}, - {"reserve", {&Reserve::create_Reserve, &Reserve::eval_reserve}}, + {"list.reserve", {&ListReserve::create_ListReserve, &ListReserve::eval_ListReserve}}, {"dict.keys", {&DictKeys::create_DictKeys, &DictKeys::eval_dict_keys}}, {"dict.values", {&DictValues::create_DictValues, &DictValues::eval_dict_values}}, {"set.add", {&SetAdd::create_SetAdd, &SetAdd::eval_set_add}}, {"set.remove", {&SetRemove::create_SetRemove, &SetRemove::eval_set_remove}}, {"max0", {&Max::create_Max, &Max::eval_Max}}, + {"adjustl", {&Adjustl::create_Adjustl, &Adjustl::eval_Adjustl}}, + {"adjustr", {&Adjustr::create_Adjustr, &Adjustr::eval_Adjustr}}, + {"ichar", {&Ichar::create_Ichar, &Ichar::eval_Ichar}}, + {"char", {&Char::create_Char, &Char::eval_Char}}, {"min0", {&Min::create_Min, &Min::eval_Min}}, + {"max", {&Max::create_Max, &Max::eval_Max}}, {"min", {&Min::create_Min, &Min::eval_Min}}, - {"radix", {&Radix::create_Radix, nullptr}}, + {"ishftc", {&Ishftc::create_Ishftc, &Ishftc::eval_Ishftc}}, + {"radix", {&Radix::create_Radix, &Radix::eval_Radix}}, + {"scale", {&Scale::create_Scale, &Scale::eval_Scale}}, + {"dprod", {&Dprod::create_Dprod, &Dprod::eval_Dprod}}, + {"range", {&Range::create_Range, &Range::eval_Range}}, {"sign", {&Sign::create_Sign, &Sign::eval_Sign}}, {"aint", {&Aint::create_Aint, &Aint::eval_Aint}}, + {"popcnt", {&Popcnt::create_Popcnt, &Popcnt::eval_Popcnt}}, + {"poppar", {&Poppar::create_Poppar, &Poppar::eval_Poppar}}, + {"nint", {&Nint::create_Nint, &Nint::eval_Nint}}, + {"anint", {&Anint::create_Anint, &Anint::eval_Anint}}, + {"dim", {&Dim::create_Dim, &Dim::eval_Dim}}, + {"floor", {&Floor::create_Floor, &Floor::eval_Floor}}, + {"ceiling", {&Ceiling::create_Ceiling, &Ceiling::eval_Ceiling}}, + {"maskr", {&Maskr::create_Maskr, &Maskr::eval_Maskr}}, + {"maskl", {&Maskl::create_Maskl, &Maskl::eval_Maskl}}, {"sqrt", {&Sqrt::create_Sqrt, &Sqrt::eval_Sqrt}}, {"sngl", {&Sngl::create_Sngl, &Sngl::eval_Sngl}}, + {"ifix", {&Ifix::create_Ifix, &Ifix::eval_Ifix}}, + {"idint", {&Idint::create_Idint, &Idint::eval_Idint}}, + {"epsilon", {&Epsilon::create_Epsilon, &Epsilon::eval_Epsilon}}, + {"precision", {&Precision::create_Precision, &Precision::eval_Precision}}, + {"tiny", {&Tiny::create_Tiny, &Tiny::eval_Tiny}}, + {"conjg", {&Conjg::create_Conjg, &Conjg::eval_Conjg}}, + {"huge", {&Huge::create_Huge, &Huge::eval_Huge}}, {"Symbol", {&SymbolicSymbol::create_SymbolicSymbol, &SymbolicSymbol::eval_SymbolicSymbol}}, {"SymbolicAdd", {&SymbolicAdd::create_SymbolicAdd, &SymbolicAdd::eval_SymbolicAdd}}, {"SymbolicSub", {&SymbolicSub::create_SymbolicSub, &SymbolicSub::eval_SymbolicSub}}, @@ -4010,24 +883,6 @@ namespace IntrinsicScalarFunctionRegistry { return intrinsic_function_by_id_db.find(id) != intrinsic_function_by_id_db.end(); } - static inline bool is_elemental(int64_t id) { - IntrinsicScalarFunctions id_ = static_cast(id); - return ( id_ == IntrinsicScalarFunctions::Abs || - id_ == IntrinsicScalarFunctions::Cos || - id_ == IntrinsicScalarFunctions::Gamma || - id_ == IntrinsicScalarFunctions::LogGamma || - id_ == IntrinsicScalarFunctions::Trunc || - id_ == IntrinsicScalarFunctions::Fix || - id_ == IntrinsicScalarFunctions::Sin || - id_ == IntrinsicScalarFunctions::Exp || - id_ == IntrinsicScalarFunctions::Exp2 || - id_ == IntrinsicScalarFunctions::Expm1 || - id_ == IntrinsicScalarFunctions::Min || - id_ == IntrinsicScalarFunctions::Max || - id_ == IntrinsicScalarFunctions::Sqrt || - id_ == IntrinsicScalarFunctions::SymbolicSymbol); - } - static inline create_intrinsic_function get_create_function(const std::string& name) { return std::get<0>(intrinsic_function_by_name_db.at(name)); } @@ -4051,21 +906,13 @@ namespace IntrinsicScalarFunctionRegistry { return intrinsic_function_id_to_name.at(id); } - static inline bool is_input_type_supported(const std::string& name, Vec& args) { - if( name == "exp" ) { - if( !ASRUtils::is_real(*ASRUtils::expr_type(args[0])) ) { - return false; - } - } - return true; - } - -} // namespace IntrinsicScalarFunctionRegistry +} // namespace IntrinsicElementalFunctionRegistry /************************* Intrinsic Impure Function **************************/ enum class IntrinsicImpureFunctions : int64_t { IsIostatEnd, IsIostatEor, + Allocated, // ... }; @@ -4073,7 +920,7 @@ namespace IsIostatEnd { static inline ASR::asr_t* create_IsIostatEnd(Allocator& al, const Location& loc, Vec& args, - const std::function /*err*/) { + diag::Diagnostics& /*diag*/) { // Compile time value cannot be computed return ASR::make_IntrinsicImpureFunction_t(al, loc, static_cast(ASRUtils::IntrinsicImpureFunctions::IsIostatEnd), @@ -4082,11 +929,33 @@ namespace IsIostatEnd { } // namespace IsIostatEnd +namespace Allocated { + + static inline ASR::asr_t* create_Allocated(Allocator& al, const Location& loc, + Vec& args, diag::Diagnostics& diag) { + // Compile time value cannot be computed + if( args.n != 1 ) { + append_error(diag, "Intrinsic `allocated` accepts exactly one argument", \ + loc); \ + return nullptr; + } + if( !ASRUtils::is_allocatable(args.p[0]) ) { + append_error(diag, "Intrinsic `allocated` can be called only on" \ + " allocatable argument", loc); + return nullptr; + } + return ASR::make_IntrinsicImpureFunction_t(al, loc, + static_cast(ASRUtils::IntrinsicImpureFunctions::Allocated), + args.p, args.n, 0, logical, nullptr); + } + +} // namespace Allocated + namespace IsIostatEor { static inline ASR::asr_t* create_IsIostatEor(Allocator& al, const Location& loc, Vec& args, - const std::function /*err*/) { + diag::Diagnostics& /*diag*/) { // Compile time value cannot be computed return ASR::make_IntrinsicImpureFunction_t(al, loc, static_cast(ASRUtils::IntrinsicImpureFunctions::IsIostatEor), @@ -4101,6 +970,7 @@ namespace IntrinsicImpureFunctionRegistry { eval_intrinsic_function>>& function_by_name_db = { {"is_iostat_end", {&IsIostatEnd::create_IsIostatEnd, nullptr}}, {"is_iostat_eor", {&IsIostatEor::create_IsIostatEor, nullptr}}, + {"allocated", {&Allocated::create_Allocated, nullptr}}, }; static inline bool is_intrinsic_function(const std::string& name) { @@ -4123,6 +993,7 @@ inline std::string get_impure_intrinsic_name(int x) { switch (x) { IMPURE_INTRINSIC_NAME_CASE(IsIostatEnd) IMPURE_INTRINSIC_NAME_CASE(IsIostatEor) + IMPURE_INTRINSIC_NAME_CASE(Allocated) default : { throw LCompilersException("pickle: intrinsic_id not implemented"); } diff --git a/src/libasr/pass/intrinsic_function_registry_util.h b/src/libasr/pass/intrinsic_function_registry_util.h new file mode 100644 index 0000000000..f8b60174bd --- /dev/null +++ b/src/libasr/pass/intrinsic_function_registry_util.h @@ -0,0 +1,3555 @@ +#ifndef LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H +#define LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H + +#include + +namespace LCompilers { + +namespace ASRUtils { + +namespace Kind { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Kind expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)) || (is_real(*arg_type0)) || (is_logical(*arg_type0)) || (is_character(*arg_type0)) || (is_complex(*arg_type0)), "Unexpected args, Kind expects (int) or (real) or (bool) or (char) or (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Kind takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(is_integer(*x.m_type), "Unexpected return type, Kind expects `int` as return type", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Kind(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)) || (is_real(*arg_type0)) || (is_logical(*arg_type0)) || (is_character(*arg_type0)) || (is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Kind expects (int) or (real) or (bool) or (char) or (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Kind takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Kind(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Kind), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace FMA { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 3) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for FMA expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASRUtils::require_impl((is_real(*arg_type0) && is_real(*arg_type1) && is_real(*arg_type2)), "Unexpected args, FMA expects (real, real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, FMA takes 3 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_FMA(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 3) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + if(!((is_real(*arg_type0) && is_real(*arg_type1) && is_real(*arg_type2)))) { + append_error(diag, "Unexpected args, FMA expects (real, real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, FMA takes 3 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 3); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 3); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + m_value = eval_FMA(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::FMA), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace FlipSign { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for FlipSign expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_real(*arg_type1)), "Unexpected args, FlipSign expects (int, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, FlipSign takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_FlipSign(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, FlipSign expects (int, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, FlipSign takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[1])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_FlipSign(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::FlipSign), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace FloorDiv { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for FloorDiv expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_unsigned_integer(*arg_type0) && is_unsigned_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)) || (is_logical(*arg_type0) && is_logical(*arg_type1)), "Unexpected args, FloorDiv expects (int, int) or (uint, uint) or (real, real) or (bool, bool) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, FloorDiv takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_FloorDiv(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_unsigned_integer(*arg_type0) && is_unsigned_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)) || (is_logical(*arg_type0) && is_logical(*arg_type1)))) { + append_error(diag, "Unexpected args, FloorDiv expects (int, int) or (uint, uint) or (real, real) or (bool, bool) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, FloorDiv takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_FloorDiv(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::FloorDiv), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Mod { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Mod expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, Mod expects (int, int) or (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Mod takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Mod(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, Mod expects (int, int) or (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Mod takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Mod(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Mod), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Trailz { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Trailz expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Trailz expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Trailz takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Trailz(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Trailz expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Trailz takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Trailz(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Trailz), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace BesselJ0 { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for BesselJ0 expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, BesselJ0 expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, BesselJ0 takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_BesselJ0(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, BesselJ0 expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, BesselJ0 takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_BesselJ0(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::BesselJ0), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace BesselJ1 { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for BesselJ1 expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, BesselJ1 expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, BesselJ1 takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_BesselJ1(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, BesselJ1 expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, BesselJ1 takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_BesselJ1(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::BesselJ1), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace BesselY0 { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for BesselY0 expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, BesselY0 expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, BesselY0 takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_BesselY0(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, BesselY0 expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, BesselY0 takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_BesselY0(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::BesselY0), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Mvbits { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 5) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Mvbits expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[3])); + ASR::ttype_t *arg_type4 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[4])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2) && is_integer(*arg_type3) && is_integer(*arg_type4)), "Unexpected args, Mvbits expects (int, int, int, int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Mvbits takes 5 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Mvbits(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 5) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[3])); + ASR::ttype_t *arg_type4 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[4])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2) && is_integer(*arg_type3) && is_integer(*arg_type4)))) { + append_error(diag, "Unexpected args, Mvbits expects (int, int, int, int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Mvbits takes 5 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[3])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 5); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + m_args.push_back(al, args[3]); + m_args.push_back(al, args[4]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 5); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + args_values.push_back(al, expr_value(m_args[3])); + args_values.push_back(al, expr_value(m_args[4])); + m_value = eval_Mvbits(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Mvbits), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Leadz { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Leadz expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Leadz expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Leadz takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Leadz(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Leadz expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Leadz takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Leadz(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Leadz), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace ToLowerCase { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for ToLowerCase expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_character(*arg_type0)), "Unexpected args, ToLowerCase expects (char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, ToLowerCase takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_ToLowerCase(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_character(*arg_type0)))) { + append_error(diag, "Unexpected args, ToLowerCase expects (char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, ToLowerCase takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_ToLowerCase(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::ToLowerCase), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Hypot { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Hypot expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, Hypot expects (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Hypot takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Hypot(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, Hypot expects (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Hypot takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Hypot(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Hypot), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SelectedIntKind { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SelectedIntKind expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, SelectedIntKind expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SelectedIntKind takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SelectedIntKind(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, SelectedIntKind expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SelectedIntKind takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_SelectedIntKind(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SelectedIntKind), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SelectedRealKind { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 3) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SelectedRealKind expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)), "Unexpected args, SelectedRealKind expects (int, int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SelectedRealKind takes 3 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SelectedRealKind(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 3) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)))) { + append_error(diag, "Unexpected args, SelectedRealKind expects (int, int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SelectedRealKind takes 3 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 3); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 3); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + m_value = eval_SelectedRealKind(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SelectedRealKind), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SelectedCharKind { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SelectedCharKind expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_character(*arg_type0)), "Unexpected args, SelectedCharKind expects (char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SelectedCharKind takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SelectedCharKind(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_character(*arg_type0)))) { + append_error(diag, "Unexpected args, SelectedCharKind expects (char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SelectedCharKind takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_SelectedCharKind(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SelectedCharKind), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Digits { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Digits expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)) || (is_real(*arg_type0)), "Unexpected args, Digits expects (int) or (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Digits takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Digits(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)) || (is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Digits expects (int) or (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Digits takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Digits(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Digits), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Repeat { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Repeat expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Repeat expects (char, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Repeat takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Repeat(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_character(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Repeat expects (char, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Repeat takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Repeat(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Repeat), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace StringContainsSet { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 4) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for StringContainsSet expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[3])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)), "Unexpected args, StringContainsSet expects (char, char, bool, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, StringContainsSet takes 4 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_StringContainsSet(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 4) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[3])); + if(!((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)))) { + append_error(diag, "Unexpected args, StringContainsSet expects (char, char, bool, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, StringContainsSet takes 4 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[3])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 4); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + m_args.push_back(al, args[3]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 4); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + args_values.push_back(al, expr_value(m_args[3])); + m_value = eval_StringContainsSet(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::StringContainsSet), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace StringFindSet { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 4) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for StringFindSet expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[3])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)), "Unexpected args, StringFindSet expects (char, char, bool, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, StringFindSet takes 4 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_StringFindSet(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 4) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[3])); + if(!((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)))) { + append_error(diag, "Unexpected args, StringFindSet expects (char, char, bool, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, StringFindSet takes 4 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[3])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 4); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + m_args.push_back(al, args[3]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 4); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + args_values.push_back(al, expr_value(m_args[3])); + m_value = eval_StringFindSet(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::StringFindSet), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SubstrIndex { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 4) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SubstrIndex expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[3])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)), "Unexpected args, SubstrIndex expects (char, char, bool, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SubstrIndex takes 4 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SubstrIndex(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 4) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + ASR::ttype_t *arg_type3 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[3])); + if(!((is_character(*arg_type0) && is_character(*arg_type1) && is_logical(*arg_type2) && is_integer(*arg_type3)))) { + append_error(diag, "Unexpected args, SubstrIndex expects (char, char, bool, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SubstrIndex takes 4 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[3])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 4); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + m_args.push_back(al, args[3]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 4); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + args_values.push_back(al, expr_value(m_args[3])); + m_value = eval_SubstrIndex(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SubstrIndex), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace MinExponent { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for MinExponent expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, MinExponent expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, MinExponent takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_MinExponent(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, MinExponent expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, MinExponent takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_MinExponent(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::MinExponent), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace MaxExponent { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for MaxExponent expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, MaxExponent expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, MaxExponent takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_MaxExponent(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, MaxExponent expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, MaxExponent takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_MaxExponent(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::MaxExponent), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Partition { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Partition expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1)), "Unexpected args, Partition expects (char, char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Partition takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(ASR::is_a(*x.m_type), "Unexpected return type, Partition expects `tuple` as return type", x.base.base.loc, diagnostics); + } + +} + +namespace ListReverse { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for ListReverse expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((ASR::is_a(*arg_type0)), "Unexpected args, ListReverse expects (list) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, ListReverse takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_type == nullptr, "Unexpected return type, ListReverse expects `null` as return type", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_ListReverse(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((ASR::is_a(*arg_type0)))) { + append_error(diag, "Unexpected args, ListReverse expects (list) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, ListReverse takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = nullptr; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_ListReverse(al, loc, return_type, args_values, diag); + } + return ASR::make_Expr_t(al, loc, ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::ListReverse), m_args.p, m_args.n, 0, return_type, m_value))); + } +} + +namespace ListReserve { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for ListReserve expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((ASR::is_a(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, ListReserve expects (list, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, ListReserve takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_type == nullptr, "Unexpected return type, ListReserve expects `null` as return type", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_ListReserve(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((ASR::is_a(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, ListReserve expects (list, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, ListReserve takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = nullptr; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_ListReserve(al, loc, return_type, args_values, diag); + } + return ASR::make_Expr_t(al, loc, ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::ListReserve), m_args.p, m_args.n, 0, return_type, m_value))); + } +} + +namespace Sign { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Sign expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, Sign expects (int, int) or (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Sign takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Sign(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, Sign expects (int, int) or (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Sign takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Sign(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Sign), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Radix { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Radix expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)) || (is_real(*arg_type0)), "Unexpected args, Radix expects (int) or (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Radix takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Radix` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + ASRUtils::require_impl(is_integer(*x.m_type), "Unexpected return type, Radix expects `int` as return type", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Radix(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)) || (is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Radix expects (int) or (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Radix takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Radix(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Radix), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Adjustl { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Adjustl expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_character(*arg_type0)), "Unexpected args, Adjustl expects (char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Adjustl takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Adjustl(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_character(*arg_type0)))) { + append_error(diag, "Unexpected args, Adjustl expects (char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Adjustl takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = character(-1); + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Adjustl(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Adjustl), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Adjustr { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Adjustr expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_character(*arg_type0)), "Unexpected args, Adjustr expects (char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Adjustr takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Adjustr(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_character(*arg_type0)))) { + append_error(diag, "Unexpected args, Adjustr expects (char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Adjustr takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = character(-1); + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Adjustr(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Adjustr), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Aint { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Aint expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Aint expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Aint takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Aint(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Aint expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Aint takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Aint` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Aint(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Aint), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Nint { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Nint expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Nint expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Nint takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Nint(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Nint expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Nint takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Nint` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Nint(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Nint), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Anint { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Anint expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Anint expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Anint takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Anint(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Anint expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Anint takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Anint` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Anint(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Anint), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Floor { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Floor expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Floor expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Floor takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Floor(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Floor expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Floor takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Floor` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Floor(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Floor), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ceiling { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ceiling expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Ceiling expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ceiling takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ceiling(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Ceiling expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ceiling takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Ceiling` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Ceiling(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ceiling), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Sqrt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Sqrt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)) || (is_complex(*arg_type0)), "Unexpected args, Sqrt expects (real) or (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Sqrt takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Sqrt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)) || (is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Sqrt expects (real) or (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Sqrt takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Sqrt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Sqrt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Sngl { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Sngl expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Sngl expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Sngl takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Sngl(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Sngl expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Sngl takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = real32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Sngl(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Sngl), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SignFromValue { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SignFromValue expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, SignFromValue expects (int, int) or (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SignFromValue takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SignFromValue(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, SignFromValue expects (int, int) or (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SignFromValue takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_SignFromValue(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SignFromValue), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ifix { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ifix expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Ifix expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ifix takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ifix(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Ifix expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ifix takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Ifix(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ifix), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Idint { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Idint expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Idint expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Idint takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Idint(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Idint expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Idint takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Idint(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Idint), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ishft { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ishft expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ishft expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ishft takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ishft(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ishft expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ishft takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ishft(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ishft), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Bgt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Bgt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Bgt expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Bgt takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Bgt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Bgt expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Bgt takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Bgt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Bgt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Blt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Blt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Blt expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Blt takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Blt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Blt expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Blt takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Blt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Blt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Bge { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Bge expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Bge expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Bge takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Bge(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Bge expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Bge takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Bge(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Bge), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ble { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ble expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ble expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ble takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ble(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ble expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ble takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ble(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ble), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Lgt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Lgt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1)), "Unexpected args, Lgt expects (char, char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Lgt takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Lgt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_character(*arg_type0) && is_character(*arg_type1)))) { + append_error(diag, "Unexpected args, Lgt expects (char, char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Lgt takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Lgt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Lgt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Llt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Llt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1)), "Unexpected args, Llt expects (char, char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Llt takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Llt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_character(*arg_type0) && is_character(*arg_type1)))) { + append_error(diag, "Unexpected args, Llt expects (char, char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Llt takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Llt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Llt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Lge { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Lge expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1)), "Unexpected args, Lge expects (char, char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Lge takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Lge(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_character(*arg_type0) && is_character(*arg_type1)))) { + append_error(diag, "Unexpected args, Lge expects (char, char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Lge takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Lge(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Lge), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Lle { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Lle expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_character(*arg_type0) && is_character(*arg_type1)), "Unexpected args, Lle expects (char, char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Lle takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Lle(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_character(*arg_type0) && is_character(*arg_type1)))) { + append_error(diag, "Unexpected args, Lle expects (char, char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Lle takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Lle(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Lle), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Not { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Not expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Not expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Not takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Not(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Not expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Not takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Not(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Not), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Iand { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Iand expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Iand expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Iand takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Iand(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Iand expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Iand takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Iand(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Iand), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ior { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ior expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ior expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ior takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ior(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ior expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ior takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ior(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ior), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ieor { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ieor expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ieor expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ieor takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ieor(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ieor expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ieor takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ieor(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ieor), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ibclr { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ibclr expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ibclr expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ibclr takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ibclr(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ibclr expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ibclr takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ibclr(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ibclr), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ibset { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ibset expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ibset expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ibset takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ibset(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ibset expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ibset takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ibset(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ibset), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Btest { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Btest expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Btest expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Btest takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Btest(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Btest expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Btest takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = logical; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Btest(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Btest), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ibits { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 3) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ibits expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)), "Unexpected args, Ibits expects (int, int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ibits takes 3 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ibits(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 3) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)))) { + append_error(diag, "Unexpected args, Ibits expects (int, int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ibits takes 3 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 3); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 3); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + m_value = eval_Ibits(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ibits), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Shiftr { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Shiftr expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Shiftr expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Shiftr takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Shiftr(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Shiftr expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Shiftr takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Shiftr(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Shiftr), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Rshift { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Rshift expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Rshift expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Rshift takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Rshift(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Rshift expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Rshift takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Rshift(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Rshift), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Shiftl { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Shiftl expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Shiftl expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Shiftl takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Shiftl(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Shiftl expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Shiftl takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Shiftl(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Shiftl), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Aimag { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Aimag expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_complex(*arg_type0)), "Unexpected args, Aimag expects (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Aimag takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Aimag(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Aimag expects (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Aimag takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = real32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Aimag` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Aimag(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Aimag), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Rank { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Rank expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((!ASR::is_a(*arg_type0)), "Unexpected args, Rank expects (any) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Rank takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Rank` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Rank(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((!ASR::is_a(*arg_type0)))) { + append_error(diag, "Unexpected args, Rank expects (any) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Rank takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Rank(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Rank), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Range { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Range expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)) || (is_real(*arg_type0)) || (is_complex(*arg_type0)), "Unexpected args, Range expects (int) or (real) or (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Range takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Range` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Range(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)) || (is_real(*arg_type0)) || (is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Range expects (int) or (real) or (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Range takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Range(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Range), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Epsilon { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Epsilon expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Epsilon expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Epsilon takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Epsilon` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Epsilon(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Epsilon expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Epsilon takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Epsilon(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Epsilon), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Precision { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Precision expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)) || (is_complex(*arg_type0)), "Unexpected args, Precision expects (real) or (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Precision takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Precision` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Precision(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)) || (is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Precision expects (real) or (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Precision takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Precision(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Precision), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Tiny { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Tiny expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Tiny expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Tiny takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Tiny` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Tiny(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Tiny expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Tiny takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Tiny(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Tiny), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Conjg { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Conjg expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_complex(*arg_type0)), "Unexpected args, Conjg expects (complex) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Conjg takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Conjg(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_complex(*arg_type0)))) { + append_error(diag, "Unexpected args, Conjg expects (complex) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Conjg takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Conjg(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Conjg), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Scale { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Scale expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_real(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Scale expects (real, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Scale takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Scale(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_real(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Scale expects (real, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Scale takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Scale(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Scale), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Huge { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Huge expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)) || (is_real(*arg_type0)), "Unexpected args, Huge expects (int) or (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Huge takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(x.m_value, "Missing compile time value, `Huge` intrinsic output must be computed during compile time", x.base.base.loc, diagnostics); + } + + static inline ASR::asr_t* create_Huge(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)) || (is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Huge expects (int) or (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Huge takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + return_type = ASRUtils::extract_type(return_type); + m_value = eval_Huge(al, loc, return_type, args, diag); + return ASR::make_TypeInquiry_t(al, loc, static_cast(IntrinsicElementalFunctions::Huge), ASRUtils::expr_type(m_args[0]), m_args[0], return_type, m_value); + } +} + +namespace Dprod { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Dprod expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, Dprod expects (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Dprod takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Dprod(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, Dprod expects (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Dprod takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = real64; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Dprod(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Dprod), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Dim { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Dim expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)), "Unexpected args, Dim expects (int, int) or (real, real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Dim takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Dim(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)) || (is_real(*arg_type0) && is_real(*arg_type1)))) { + append_error(diag, "Unexpected args, Dim expects (int, int) or (real, real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Dim takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Dim(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Dim), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Maskl { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Maskl expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Maskl expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Maskl takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Maskl(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Maskl expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Maskl takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Maskl` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Maskl(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Maskl), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Maskr { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Maskr expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Maskr expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Maskr takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Maskr(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Maskr expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Maskr takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Maskr` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Maskr(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Maskr), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ishftc { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ishftc expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, Ishftc expects (int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ishftc takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ishftc(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, Ishftc expects (int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ishftc takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_Ishftc(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ishftc), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Ichar { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Ichar expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_character(*arg_type0)), "Unexpected args, Ichar expects (char) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Ichar takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Ichar(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_character(*arg_type0)))) { + append_error(diag, "Unexpected args, Ichar expects (char) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Ichar takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Ichar` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Ichar(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Ichar), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Char { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Char expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Char expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Char takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Char(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Char expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Char takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = character(1); + if ( args[1] != nullptr ) { + int kind = -1; + if (!ASR::is_a(*expr_type(args[1])) || !extract_value(args[1], kind)) { + append_error(diag, "`kind` argument of the `Char` function must be a scalar Integer constant", args[1]->base.loc); + return nullptr; + } + set_kind_to_ttype_t(return_type, kind); + } + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Char(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Char), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Exponent { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Exponent expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Exponent expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Exponent takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Exponent(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Exponent expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Exponent takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Exponent(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Exponent), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Fraction { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Fraction expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Fraction expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Fraction takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Fraction(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Fraction expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Fraction takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Fraction(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Fraction), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace SetExponent { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 2) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for SetExponent expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASRUtils::require_impl((is_real(*arg_type0) && is_integer(*arg_type1)), "Unexpected args, SetExponent expects (real, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, SetExponent takes 2 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_SetExponent(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 2) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + if(!((is_real(*arg_type0) && is_integer(*arg_type1)))) { + append_error(diag, "Unexpected args, SetExponent expects (real, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, SetExponent takes 2 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 2); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 2); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + m_value = eval_SetExponent(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::SetExponent), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Rrspacing { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Rrspacing expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_real(*arg_type0)), "Unexpected args, Rrspacing expects (real) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Rrspacing takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Rrspacing(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_real(*arg_type0)))) { + append_error(diag, "Unexpected args, Rrspacing expects (real) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Rrspacing takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Rrspacing(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Rrspacing), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Dshiftl { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 3) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Dshiftl expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[2])); + ASRUtils::require_impl((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)), "Unexpected args, Dshiftl expects (int, int, int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Dshiftl takes 3 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Dshiftl(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 3) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + ASR::ttype_t *arg_type1 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[1])); + ASR::ttype_t *arg_type2 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[2])); + if(!((is_integer(*arg_type0) && is_integer(*arg_type1) && is_integer(*arg_type2)))) { + append_error(diag, "Unexpected args, Dshiftl expects (int, int, int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Dshiftl takes 3 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASRUtils::ExprStmtDuplicator expr_duplicator(al); + expr_duplicator.allow_procedure_calls = true; + ASR::ttype_t* type_ = expr_duplicator.duplicate_ttype(expr_type(args[0])); + ASR::ttype_t *return_type = type_; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 3); + m_args.push_back(al, args[0]); + m_args.push_back(al, args[1]); + m_args.push_back(al, args[2]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 3); + args_values.push_back(al, expr_value(m_args[0])); + args_values.push_back(al, expr_value(m_args[1])); + args_values.push_back(al, expr_value(m_args[2])); + m_value = eval_Dshiftl(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Dshiftl), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Popcnt { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Popcnt expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Popcnt expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Popcnt takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Popcnt(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Popcnt expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Popcnt takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Popcnt(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Popcnt), m_args.p, m_args.n, 0, return_type, m_value); + } +} + +namespace Poppar { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for Poppar expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl((is_integer(*arg_type0)), "Unexpected args, Poppar expects (int) as arguments", x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, Poppar takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_Poppar(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& diag) { + if (args.size() == 1) { + ASR::ttype_t *arg_type0 = ASRUtils::type_get_past_const(ASRUtils::expr_type(args[0])); + if(!((is_integer(*arg_type0)))) { + append_error(diag, "Unexpected args, Poppar expects (int) as arguments", loc); + return nullptr; + } + } + else { + append_error(diag, "Unexpected number of args, Poppar takes 1 arguments, found " + std::to_string(args.size()), loc); + return nullptr; + } + ASR::ttype_t *return_type = int32; + ASR::expr_t *m_value = nullptr; + Vec m_args; m_args.reserve(al, 1); + m_args.push_back(al, args[0]); + if (all_args_evaluated(m_args)) { + Vec args_values; args_values.reserve(al, 1); + args_values.push_back(al, expr_value(m_args[0])); + m_value = eval_Poppar(al, loc, return_type, args_values, diag); + } + return ASR::make_IntrinsicElementalFunction_t(al, loc, static_cast(IntrinsicElementalFunctions::Poppar), m_args.p, m_args.n, 0, return_type, m_value); + } +} + + +} // namespace ASRUtil + +} // namespace LCompilers + +#endif // LIBASR_PASS_INTRINSIC_FUNC_REG_UTIL_H diff --git a/src/libasr/pass/intrinsic_functions.h b/src/libasr/pass/intrinsic_functions.h new file mode 100644 index 0000000000..af48083ef2 --- /dev/null +++ b/src/libasr/pass/intrinsic_functions.h @@ -0,0 +1,5765 @@ +#ifndef LIBASR_PASS_INTRINSIC_FUNCTIONS_H +#define LIBASR_PASS_INTRINSIC_FUNCTIONS_H + +#include +#include + +namespace LCompilers::ASRUtils { + +/* +To add a new function implementation, + +1. Create a new namespace like, `Sin`, `LogGamma` in this file. +2. In the above created namespace add `eval_*`, `instantiate_*`, and `create_*`. +3. Then register in the maps present in `IntrinsicElementalFunctionRegistry`. + +You can use helper macros and define your own helper macros to reduce +the code size. +*/ + +enum class IntrinsicElementalFunctions : int64_t { + ObjectType, + Kind, // if kind is reordered, update `extract_kind` in `asr_utils.h` + Rank, + Sin, + Cos, + Tan, + Asin, + Acos, + Atan, + Sinh, + Cosh, + Tanh, + Atan2, + Asinh, + Acosh, + Atanh, + Erf, + Erfc, + Gamma, + Log, + Log10, + LogGamma, + Trunc, + Fix, + Abs, + Aimag, + Exp, + Exp2, + Expm1, + FMA, + FlipSign, + Mod, + Trailz, + BesselJ0, + BesselJ1, + BesselY0, + Mvbits, + Shiftr, + Rshift, + Shiftl, + Dshiftl, + Ishft, + Bgt, + Blt, + Bge, + Ble, + Lgt, + Llt, + Lge, + Lle, + Exponent, + Fraction, + SetExponent, + Not, + Iand, + Ior, + Ieor, + Ibclr, + Ibset, + Btest, + Ibits, + Leadz, + ToLowerCase, + Digits, + Rrspacing, + Repeat, + StringContainsSet, + StringFindSet, + SubstrIndex, + Hypot, + SelectedIntKind, + SelectedRealKind, + SelectedCharKind, + Adjustl, + Adjustr, + Ichar, + Char, + MinExponent, + MaxExponent, + FloorDiv, + ListIndex, + Partition, + ListReverse, + ListPop, + ListReserve, + DictKeys, + DictValues, + SetAdd, + SetRemove, + Max, + Min, + Radix, + Scale, + Dprod, + Range, + Sign, + SignFromValue, + Nint, + Aint, + Anint, + Dim, + Sqrt, + Sngl, + Ifix, + Idint, + Floor, + Ceiling, + Ishftc, + Maskr, + Maskl, + Epsilon, + Precision, + Tiny, + Conjg, + Huge, + Popcnt, + Poppar, + SymbolicSymbol, + SymbolicAdd, + SymbolicSub, + SymbolicMul, + SymbolicDiv, + SymbolicPow, + SymbolicPi, + SymbolicE, + SymbolicInteger, + SymbolicDiff, + SymbolicExpand, + SymbolicSin, + SymbolicCos, + SymbolicLog, + SymbolicExp, + SymbolicAbs, + SymbolicHasSymbolQ, + SymbolicAddQ, + SymbolicMulQ, + SymbolicPowQ, + SymbolicLogQ, + SymbolicSinQ, + SymbolicGetArgument, + // ... +}; + +typedef ASR::expr_t* (*impl_function)( + Allocator&, const Location &, + SymbolTable*, Vec&, ASR::ttype_t *, + Vec&, int64_t); + +typedef ASR::expr_t* (*eval_intrinsic_function)( + Allocator&, const Location &, ASR::ttype_t *, + Vec&, diag::Diagnostics&); + +typedef ASR::asr_t* (*create_intrinsic_function)( + Allocator&, const Location&, + Vec&, + diag::Diagnostics&); + +typedef void (*verify_function)( + const ASR::IntrinsicElementalFunction_t&, + diag::Diagnostics&); + +typedef ASR::expr_t* (*get_initial_value_func)(Allocator&, ASR::ttype_t*); + +namespace UnaryIntrinsicFunction { + +static inline ASR::expr_t* instantiate_functions(Allocator &al, + const Location &loc, SymbolTable *scope, std::string new_name, + ASR::ttype_t *arg_type, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + switch (arg_type->type) { + case ASR::ttypeType::Complex : { + if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { + c_func_name = "_lfortran_c" + new_name; + } else { + c_func_name = "_lfortran_z" + new_name; + } + break; + } + default : { + if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { + c_func_name = "_lfortran_s" + new_name; + } else { + c_func_name = "_lfortran_d" + new_name; + } + } + } + new_name = "_lcompilers_" + new_name + "_" + type_to_str_python(arg_type); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var)); + } + fill_func_arg("x", arg_type); + auto result = declare(new_name, ASRUtils::extract_type(return_type), ReturnVar); + + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 1); + ASR::expr_t *arg = b.Variable(fn_symtab_1, "x", arg_type, + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + return_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, return_type))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type); +} + +static inline ASR::asr_t* create_UnaryFunction(Allocator& al, const Location& loc, + Vec& args, eval_intrinsic_function eval_function, + int64_t intrinsic_id, int64_t overload_id, ASR::ttype_t* type, diag::Diagnostics& diag) { + ASR::expr_t *value = nullptr; + if (ASRUtils::all_args_evaluated(args)) { + Vec arg_values; arg_values.reserve(al, 1); + arg_values.push_back(al, ASRUtils::expr_value(args[0])); + value = eval_function(al, loc, type, arg_values, diag); + } + + return ASRUtils::make_IntrinsicElementalFunction_t_util(al, loc, intrinsic_id, + args.p, args.n, overload_id, type, value); +} + +static inline ASR::symbol_t *create_KMP_function(Allocator &al, + const Location &loc, SymbolTable *scope) +{ + /* + * Knuth-Morris-Pratt (KMP) string-matching + * This function takes two parameters: + * the sub-string or pattern string and the target string, + * then returns the position of the first occurrence of the + * string in the pattern. + */ + declare_basic_variables("KMP_string_matching"); + fill_func_arg("target_string", character(-2)); + fill_func_arg("pattern", character(-2)); + + auto result = declare("result", int32, ReturnVar); + auto pi_len = declare("pi_len", int32, Local); + auto i = declare("i", int32, Local); + auto j = declare("j", int32, Local); + auto s_len = declare("s_len", int32, Local); + auto pat_len = declare("pat_len", int32, Local); + auto flag = declare("flag", logical, Local); + auto lps = declare("lps", List(int32), Local); + + body.push_back(al, b.Assignment(s_len, b.StringLen(args[0]))); + body.push_back(al, b.Assignment(pat_len, b.StringLen(args[1]))); + body.push_back(al, b.Assignment(result, b.i32_n(-1))); + body.push_back(al, b.If(b.iEq(pat_len, b.i32(0)), { + b.Assignment(result, b.i32(0)), Return() + }, { + b.If(b.iEq(s_len, b.i32(0)), { Return() }, {}) + })); + body.push_back(al, b.Assignment(lps, + EXPR(ASR::make_ListConstant_t(al, loc, nullptr, 0, List(int32))))); + body.push_back(al, b.Assignment(i, b.i32(0))); + body.push_back(al, b.While(b.iLtE(i, b.iSub(pat_len, b.i32(1))), { + b.Assignment(i, b.iAdd(i, b.i32(1))), + b.ListAppend(lps, b.i32(0)) + })); + body.push_back(al, b.Assignment(flag, b.bool32(false))); + body.push_back(al, b.Assignment(i, b.i32(1))); + body.push_back(al, b.Assignment(pi_len, b.i32(0))); + body.push_back(al, b.While(b.iLt(i, pat_len), { + b.If(b.sEq(b.StringItem(args[1], b.iAdd(i, b.i32(1))), + b.StringItem(args[1], b.iAdd(pi_len, b.i32(1)))), { + b.Assignment(pi_len, b.iAdd(pi_len, b.i32(1))), + b.Assignment(b.ListItem(lps, i, int32), pi_len), + b.Assignment(i, b.iAdd(i, b.i32(1))) + }, { + b.If(b.iNotEq(pi_len, b.i32(0)), { + b.Assignment(pi_len, b.ListItem(lps, b.iSub(pi_len, b.i32(1)), int32)) + }, { + b.Assignment(i, b.iAdd(i, b.i32(1))) + }) + }) + })); + body.push_back(al, b.Assignment(j, b.i32(0))); + body.push_back(al, b.Assignment(i, b.i32(0))); + body.push_back(al, b.While(b.And(b.iGtE(b.iSub(s_len, i), + b.iSub(pat_len, j)), b.Not(flag)), { + b.If(b.sEq(b.StringItem(args[1], b.iAdd(j, b.i32(1))), + b.StringItem(args[0], b.iAdd(i, b.i32(1)))), { + b.Assignment(i, b.iAdd(i, b.i32(1))), + b.Assignment(j, b.iAdd(j, b.i32(1))) + }, {}), + b.If(b.iEq(j, pat_len), { + b.Assignment(result, b.iSub(i, j)), + b.Assignment(flag, b.bool32(true)), + b.Assignment(j, b.ListItem(lps, b.iSub(j, b.i32(1)), int32)) + }, { + b.If(b.And(b.iLt(i, s_len), b.sNotEq(b.StringItem(args[1], b.iAdd(j, b.i32(1))), + b.StringItem(args[0], b.iAdd(i, b.i32(1))))), { + b.If(b.iNotEq(j, b.i32(0)), { + b.Assignment(j, b.ListItem(lps, b.iSub(j, b.i32(1)), int32)) + }, { + b.Assignment(i, b.iAdd(i, b.i32(1))) + }) + }, {}) + }) + })); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return fn_sym; +} + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, + diag::Diagnostics& diagnostics) { + const Location& loc = x.base.base.loc; + ASRUtils::require_impl(x.n_args == 1, + "Elemental intrinsics must have only 1 input argument", + loc, diagnostics); + + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t* output_type = x.m_type; + ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), + "The input and output type of elemental intrinsics must exactly match, input type: " + + ASRUtils::get_type_code(input_type) + " output type: " + ASRUtils::get_type_code(output_type), + loc, diagnostics); +} + +} // namespace UnaryIntrinsicFunction + +namespace BinaryIntrinsicFunction { + +static inline ASR::expr_t* instantiate_functions(Allocator &al, + const Location &loc, SymbolTable *scope, std::string new_name, + ASR::ttype_t *arg_type, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + switch (arg_type->type) { + case ASR::ttypeType::Complex : { + if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { + c_func_name = "_lfortran_c" + new_name; + } else { + c_func_name = "_lfortran_z" + new_name; + } + break; + } + default : { + if (ASRUtils::extract_kind_from_ttype_t(arg_type) == 4) { + c_func_name = "_lfortran_s" + new_name; + } else { + c_func_name = "_lfortran_d" + new_name; + } + } + } + new_name = "_lcompilers_" + new_name + "_" + type_to_str_python(arg_type); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var)); + } + fill_func_arg("x", arg_type); + fill_func_arg("y", arg_type) + auto result = declare(new_name, return_type, ReturnVar); + + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 2); + ASR::expr_t *arg_1 = b.Variable(fn_symtab_1, "x", arg_type, + ASR::intentType::In, ASR::abiType::BindC, true); + ASR::expr_t *arg_2 = b.Variable(fn_symtab_1, "y", arg_type, + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg_1); + args_1.push_back(al, arg_2); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + arg_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, arg_type))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type); +} + +static inline ASR::asr_t* create_BinaryFunction(Allocator& al, const Location& loc, + Vec& args, eval_intrinsic_function eval_function, + int64_t intrinsic_id, int64_t overload_id, ASR::ttype_t* type, diag::Diagnostics& diag) { + ASR::expr_t *value = nullptr; + ASR::expr_t *arg_value_1 = ASRUtils::expr_value(args[0]); + ASR::expr_t *arg_value_2 = ASRUtils::expr_value(args[1]); + if (arg_value_1 && arg_value_2) { + Vec arg_values; + arg_values.reserve(al, 2); + arg_values.push_back(al, arg_value_1); + arg_values.push_back(al, arg_value_2); + value = eval_function(al, loc, type, arg_values, diag); + } + + return ASRUtils::make_IntrinsicElementalFunction_t_util(al, loc, intrinsic_id, + args.p, args.n, overload_id, type, value); +} + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, + diag::Diagnostics& diagnostics) { + const Location& loc = x.base.base.loc; + ASRUtils::require_impl(x.n_args == 2, + "Binary intrinsics must have only 2 input arguments", + loc, diagnostics); + + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t* input_type_2 = ASRUtils::expr_type(x.m_args[1]); + ASR::ttype_t* output_type = x.m_type; + ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, input_type_2, true), + "The types of both the arguments of binary intrinsics must exactly match, argument 1 type: " + + ASRUtils::get_type_code(input_type) + " argument 2 type: " + ASRUtils::get_type_code(input_type_2), + loc, diagnostics); + ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), + "The input and output type of elemental intrinsics must exactly match, input type: " + + ASRUtils::get_type_code(input_type) + " output type: " + ASRUtils::get_type_code(output_type), + loc, diagnostics); +} + +} // namespace BinaryIntrinsicFunction + +// `X` is the name of the function in the IntrinsicElementalFunctions enum and +// we use the same name for `create_X` and other places +// `eval_X` is the name of the function in the `std` namespace for compile +// numerical time evaluation +// `lc_rt_name` is the name that we use in the C runtime library +#define create_unary_function(X, eval_X, lc_rt_name) \ +namespace X { \ + static inline ASR::expr_t *eval_##X(Allocator &al, const Location &loc, \ + ASR::ttype_t *t, Vec &args, \ + diag::Diagnostics& /*diag*/) { \ + double rv = ASR::down_cast(args[0])->m_r; \ + ASRUtils::ASRBuilder b(al, loc); \ + return b.f(std::eval_X(rv), t); \ + } \ + static inline ASR::asr_t* create_##X(Allocator &al, const Location &loc, \ + Vec &args, \ + diag::Diagnostics& diag) { \ + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ + if (args.n != 1) { \ + append_error(diag, "Intrinsic `"#X"` accepts exactly one argument", \ + loc); \ + return nullptr; \ + } else if (!ASRUtils::is_real(*type)) { \ + append_error(diag, "`x` argument of `"#X"` must be real", \ + args[0]->base.loc); \ + return nullptr; \ + } \ + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, \ + eval_##X, static_cast(IntrinsicElementalFunctions::X), \ + 0, type, diag); \ + } \ + static inline ASR::expr_t* instantiate_##X (Allocator &al, \ + const Location &loc, SymbolTable *scope, \ + Vec &arg_types, ASR::ttype_t *return_type, \ + Vec &new_args, int64_t overload_id) { \ + return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, \ + #lc_rt_name, arg_types[0], return_type, new_args, overload_id); \ + } \ +} // namespace X + +create_unary_function(Trunc, trunc, trunc) +create_unary_function(Gamma, tgamma, gamma) +create_unary_function(LogGamma, lgamma, log_gamma) +create_unary_function(Log10, log10, log10) +create_unary_function(Erf, erf, erf) +create_unary_function(Erfc, erfc, erfc) + +namespace ObjectType { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 1, + "ASR Verify: type() takes only 1 argument `object`", + x.base.base.loc, diagnostics); + } + + static ASR::expr_t *eval_ObjectType(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + ASRBuilder b(al, loc); + std::string object_type = "type) { + case ASR::ttypeType::Integer : { + object_type += "int"; break; + } case ASR::ttypeType::Real : { + object_type += "float"; break; + } case ASR::ttypeType::Character : { + object_type += "str"; break; + } case ASR::ttypeType::List : { + object_type += "list"; break; + } case ASR::ttypeType::Dict : { + object_type += "dict"; break; + } default: { + LCOMPILERS_ASSERT_MSG(false, "Unsupported type"); + break; + } + } + object_type += "'>"; + return b.StringConstant(object_type, character(object_type.length())); + } + + static inline ASR::asr_t* create_ObjectType(Allocator& al, const Location& loc, + Vec& args, diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "type() takes exactly 1 argument `object` for now", loc); + } + ASR::expr_t *m_value = nullptr; + Vec arg_values; + + + m_value = eval_ObjectType(al, loc, expr_type(args[0]), arg_values, diag); + + + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::ObjectType), + args.p, args.n, 0, ASRUtils::expr_type(m_value), m_value); + } + +} // namespace ObjectType + +namespace Fix { + static inline ASR::expr_t *eval_Fix(Allocator &al, const Location &loc, + ASR::ttype_t *t, Vec& args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(args.size() == 1); + double rv = ASR::down_cast(args[0])->m_r; + double val; + if (rv > 0.0) { + val = floor(rv); + } else { + val = ceil(rv); + } + return make_ConstantWithType(make_RealConstant_t, val, t, loc); + } + + static inline ASR::asr_t* create_Fix(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); + if (args.n != 1) { + append_error(diag, "Intrinsic `fix` accepts exactly one argument", loc); + return nullptr; + } else if (!ASRUtils::is_real(*type)) { + append_error(diag, "`fix` argument of `fix` must be real", + args[0]->base.loc); + return nullptr; + } + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, + eval_Fix, static_cast(IntrinsicElementalFunctions::Fix), + 0, type, diag); + } + + static inline ASR::expr_t* instantiate_Fix (Allocator &al, + const Location &loc, SymbolTable *scope, Vec& arg_types, + ASR::ttype_t *return_type, Vec& new_args, + int64_t overload_id) { + ASR::ttype_t* arg_type = arg_types[0]; + return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, + "fix", arg_type, return_type, new_args, overload_id); + } + +} // namespace Fix + +// `X` is the name of the function in the IntrinsicElementalFunctions enum and +// we use the same name for `create_X` and other places +// `stdeval` is the name of the function in the `std` namespace for compile +// numerical time evaluation +// `lcompilers_name` is the name that we use in the C runtime library +#define create_trig(X, stdeval, lcompilers_name) \ +namespace X { \ + static inline ASR::expr_t *eval_##X(Allocator &al, const Location &loc, \ + ASR::ttype_t *t, Vec& args, \ + diag::Diagnostics& /*diag*/) { \ + LCOMPILERS_ASSERT(args.size() == 1); \ + double rv = -1; \ + if( ASRUtils::extract_value(args[0], rv) ) { \ + double val = std::stdeval(rv); \ + return make_ConstantWithType(make_RealConstant_t, val, t, loc); \ + } else { \ + std::complex crv; \ + if( ASRUtils::extract_value(args[0], crv) ) { \ + std::complex val = std::stdeval(crv); \ + return ASRUtils::EXPR(ASR::make_ComplexConstant_t( \ + al, loc, val.real(), val.imag(), t)); \ + } \ + } \ + return nullptr; \ + } \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) \ + { \ + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ + if (args.n != 1) { \ + append_error(diag, "Intrinsic `"#X"` accepts exactly one argument", \ + loc); \ + return nullptr; \ + } else if (!ASRUtils::is_real(*type) && !ASRUtils::is_complex(*type)) { \ + append_error(diag, "`x` argument of `"#X"` must be real or complex",\ + args[0]->base.loc); \ + return nullptr; \ + } \ + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, \ + eval_##X, static_cast(IntrinsicElementalFunctions::X), \ + 0, type, diag); \ + } \ + static inline ASR::expr_t* instantiate_##X (Allocator &al, \ + const Location &loc, SymbolTable *scope, \ + Vec& arg_types, ASR::ttype_t *return_type, \ + Vec& new_args,int64_t overload_id) { \ + ASR::ttype_t* arg_type = arg_types[0]; \ + return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, \ + #lcompilers_name, arg_type, return_type, new_args, overload_id); \ + } \ +} // namespace X + +create_trig(Sin, sin, sin) +create_trig(Cos, cos, cos) +create_trig(Tan, tan, tan) +create_trig(Asin, asin, asin) +create_trig(Acos, acos, acos) +create_trig(Atan, atan, atan) +create_trig(Sinh, sinh, sinh) +create_trig(Cosh, cosh, cosh) +create_trig(Tanh, tanh, tanh) +create_trig(Asinh, asinh, asinh) +create_trig(Acosh, acosh, acosh) +create_trig(Atanh, atanh, atanh) +create_trig(Log, log, log) + +namespace Aimag { + + static inline ASR::expr_t *eval_Aimag(Allocator &al, const Location &loc, + ASR::ttype_t *t, Vec& args, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + std::complex crv; + if( ASRUtils::extract_value(args[0], crv) ) { + return b.f(crv.imag(), t); + } else { + return nullptr; + } + } + + static inline ASR::expr_t* instantiate_Aimag (Allocator &al, + const Location &loc, SymbolTable* /*scope*/, + Vec& /*arg_types*/, ASR::ttype_t *return_type, + Vec &new_args,int64_t /*overload_id*/) { + return EXPR(ASR::make_ComplexIm_t(al, loc, new_args[0].m_value, + return_type, nullptr)); + } + +} // namespace Aimag + +namespace Atan2 { + static inline ASR::expr_t *eval_Atan2(Allocator &al, const Location &loc, + ASR::ttype_t *t, Vec& args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(args.size() == 2); + double rv = -1, rv2 = -1; + if( ASRUtils::extract_value(args[0], rv) && ASRUtils::extract_value(args[1], rv2) ) { + double val = std::atan2(rv,rv2); + return make_ConstantWithType(make_RealConstant_t, val, t, loc); + } + return nullptr; + } + static inline ASR::asr_t* create_Atan2(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) + { + ASR::ttype_t *type_1 = ASRUtils::expr_type(args[0]); + ASR::ttype_t *type_2 = ASRUtils::expr_type(args[1]); + if (!ASRUtils::is_real(*type_1)) { + append_error(diag, "`x` argument of \"atan2\" must be real",args[0]->base.loc); + return nullptr; + } else if (!ASRUtils::is_real(*type_2)) { + append_error(diag, "`y` argument of \"atan2\" must be real",args[1]->base.loc); + return nullptr; + } + return BinaryIntrinsicFunction::create_BinaryFunction(al, loc, args, + eval_Atan2, static_cast(IntrinsicElementalFunctions::Atan2), + 0, type_1, diag); + } + static inline ASR::expr_t* instantiate_Atan2 (Allocator &al, + const Location &loc, SymbolTable *scope, + Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args,int64_t overload_id) { + ASR::ttype_t* arg_type = arg_types[0]; + return BinaryIntrinsicFunction::instantiate_functions(al, loc, scope, + "atan2", arg_type, return_type, new_args, overload_id); + } +} + +namespace Abs { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + const Location& loc = x.base.base.loc; + ASRUtils::require_impl(x.n_args == 1, + "Elemental intrinsics must have only 1 input argument", + loc, diagnostics); + + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t* output_type = x.m_type; + std::string input_type_str = ASRUtils::get_type_code(input_type); + std::string output_type_str = ASRUtils::get_type_code(output_type); + if( ASR::is_a(*ASRUtils::type_get_past_pointer(ASRUtils::type_get_past_array(input_type))) ) { + ASRUtils::require_impl(ASR::is_a(*output_type), + "Abs intrinsic must return output of real for complex input, found: " + output_type_str, + loc, diagnostics); + int input_kind = ASRUtils::extract_kind_from_ttype_t(input_type); + int output_kind = ASRUtils::extract_kind_from_ttype_t(output_type); + ASRUtils::require_impl(input_kind == output_kind, + "The input and output type of Abs intrinsic must be of same kind, input kind: " + + std::to_string(input_kind) + " output kind: " + std::to_string(output_kind), + loc, diagnostics); + } else { + ASRUtils::require_impl(ASRUtils::check_equal_type(input_type, output_type, true), + "The input and output type of elemental intrinsics must exactly match, input type: " + + input_type_str + " output type: " + output_type_str, loc, diagnostics); + } + } + + static ASR::expr_t *eval_Abs(Allocator &al, const Location &loc, + ASR::ttype_t *t, Vec &args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); + ASR::expr_t* arg = args[0]; + if (ASRUtils::is_real(*expr_type(arg))) { + double rv = ASR::down_cast(arg)->m_r; + double val = std::abs(rv); + return make_ConstantWithType(make_RealConstant_t, val, t, loc); + } else if (ASRUtils::is_integer(*expr_type(arg))) { + int64_t rv = ASR::down_cast(arg)->m_n; + int64_t val = std::abs(rv); + return make_ConstantWithType(make_IntegerConstant_t, val, t, loc); + } else if (ASRUtils::is_complex(*expr_type(arg))) { + double re = ASR::down_cast(arg)->m_re; + double im = ASR::down_cast(arg)->m_im; + std::complex x(re, im); + double result = std::abs(x); + return make_ConstantWithType(make_RealConstant_t, result, t, loc); + } else { + return nullptr; + } + } + + static inline ASR::asr_t* create_Abs(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "Intrinsic abs function accepts exactly 1 argument", loc); + return nullptr; + } + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); + if (!ASRUtils::is_integer(*type) && !ASRUtils::is_real(*type) + && !ASRUtils::is_complex(*type)) { + append_error(diag, "Argument of the abs function must be Integer, Real or Complex", + args[0]->base.loc); + return nullptr; + } + if (is_complex(*type)) { + type = TYPE(ASR::make_Real_t(al, type->base.loc, + ASRUtils::extract_kind_from_ttype_t(type))); + } + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_Abs, + static_cast(IntrinsicElementalFunctions::Abs), 0, + ASRUtils::type_get_past_allocatable(type), diag); + } + + static inline ASR::expr_t* instantiate_Abs(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string func_name = "_lcompilers_abs_" + type_to_str_python(arg_types[0]); + declare_basic_variables(func_name); + if (scope->get_symbol(func_name)) { + ASR::symbol_t *s = scope->get_symbol(func_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); + } + fill_func_arg("x", arg_types[0]); + auto result = declare(func_name, return_type, ReturnVar); + /* + * if (x >= 0) then + * r = x + * else + * r = -x + * end if + */ + if (is_integer(*arg_types[0]) || is_real(*arg_types[0])) { + if (is_integer(*arg_types[0])) { + body.push_back(al, b.If(b.iGtE(args[0], b.i(0, arg_types[0])), { + b.Assignment(result, args[0]) + }, { + b.Assignment(result, b.i32_neg(args[0], arg_types[0])) + })); + } else { + body.push_back(al, b.If(b.fGtE(args[0], b.f(0, arg_types[0])), { + b.Assignment(result, args[0]) + }, { + b.Assignment(result, b.f32_neg(args[0], arg_types[0])) + })); + } + } else { + // * Complex type: `r = (real(x)**2 + aimag(x)**2)**0.5` + ASR::ttype_t *real_type = TYPE(ASR::make_Real_t(al, loc, + ASRUtils::extract_kind_from_ttype_t(arg_types[0]))); + ASR::down_cast(ASR::down_cast(result)->m_v)->m_type = return_type = real_type; + body.push_back(al, b.Assignment(result, + b.ElementalPow(b.ElementalAdd(b.ElementalPow(EXPR(ASR::make_ComplexRe_t(al, loc, + args[0], real_type, nullptr)), b.f(2.0, real_type), loc), b.ElementalPow(EXPR(ASR::make_ComplexIm_t(al, loc, + args[0], real_type, nullptr)), b.f(2.0, real_type), loc), loc), b.f(0.5, real_type), loc))); + } + ASR::symbol_t *f_sym = make_ASR_Function_t(func_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(func_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Abs + +namespace Radix { + + static ASR::expr_t *eval_Radix(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + return b.i32(2); + } + +} // namespace Radix + +namespace Scale { + static ASR::expr_t *eval_Scale(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + double value_X = ASR::down_cast(expr_value(args[0]))->m_r; + int64_t value_I = ASR::down_cast(expr_value(args[1]))->m_n; + double result = value_X * std::pow(2, value_I); + ASRUtils::ASRBuilder b(al, loc); + return b.f(result, arg_type); + } + + static inline ASR::expr_t* instantiate_Scale(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = scale(x, y) + * r = x * 2**y + */ + + //TODO: Radix for most of the device is 2, so we can use the b.i2r32(2) instead of args[1]. Fix (find a way to get the radix of the device and use it here) + body.push_back(al, b.Assignment(result, b.r_tMul(args[0], b.i2r32(b.iPow(b.i(2, arg_types[1]), args[1], arg_types[1])), arg_types[0]))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace Scale + +namespace Dprod { + static ASR::expr_t *eval_Dprod(Allocator &al, const Location &loc, + ASR::ttype_t* return_type, Vec &args, diag::Diagnostics& /*diag*/) { + double value_X = ASR::down_cast(expr_value(args[0]))->m_r; + double value_Y = ASR::down_cast(expr_value(args[1]))->m_r; + double result = value_X * value_Y; + ASRUtils::ASRBuilder b(al, loc); + return b.f(result, return_type); + } + + static inline ASR::expr_t* instantiate_Dprod(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = dprod(x, y) + * r = x * y + */ + body.push_back(al, b.Assignment(result, b.r2r64(b.r32Mul(args[0],args[1])))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Dprod + +namespace Range { + + static ASR::expr_t *eval_Range(Allocator &al, const Location &loc, + ASR::ttype_t */*return_type*/, Vec &args, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + int64_t range_val = -1; + ASR::ttype_t *arg_type = expr_type(args[0]); + int32_t kind = extract_kind_from_ttype_t(arg_type); + if ( is_integer(*arg_type) ) { + switch ( kind ) { + case 1: { + range_val = 2; break; + } case 2: { + range_val = 4; break; + } case 4: { + range_val = 9; break; + } case 8: { + range_val = 18; break; + } default: { + break; + } + } + } else if ( is_real(*arg_type) || is_complex(*arg_type) ) { + switch ( kind ) { + case 4: { + range_val = 37; break; + } case 8: { + range_val = 307; break; + } default: { + break; + } + } + } + return b.i32(range_val); + } + +} // namespace Range + +namespace Sign { + + static ASR::expr_t *eval_Sign(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + if (ASRUtils::is_real(*t1)) { + double rv1 = std::abs(ASR::down_cast(args[0])->m_r); + double rv2 = ASR::down_cast(args[1])->m_r; + rv1 = copysign(rv1, rv2); + return make_ConstantWithType(make_RealConstant_t, rv1, t1, loc); + } else { + int64_t iv1 = std::abs(ASR::down_cast(args[0])->m_n); + int64_t iv2 = ASR::down_cast(args[1])->m_n; + if (iv2 < 0) iv1 = -iv1; + return make_ConstantWithType(make_IntegerConstant_t, iv1, t1, loc); + } + } + + static inline ASR::expr_t* instantiate_Sign(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_sign_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + if (is_real(*arg_types[0])) { + Vec args; args.reserve(al, 2); + visit_expr_list(al, new_args, args); + return ASRUtils::EXPR(ASR::make_RealCopySign_t(al, loc, args[0], args[1], arg_types[0], nullptr)); + } else { + /* + * r = abs(x) + * if (y < 0) then + * r = -r + * end if + */ + body.push_back(al, b.If(b.iGtE(args[0], b.i(0, arg_types[0])), { + b.Assignment(result, args[0]) + }, { + b.Assignment(result, b.i32_neg(args[0], arg_types[0])) + })); + body.push_back(al, b.If(b.iLt(args[1], b.i(0, arg_types[0])), { + b.Assignment(result, b.i32_neg(result, arg_types[0])) + }, {})); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + } + +} // namespace Sign + +namespace Shiftr { + + static ASR::expr_t *eval_Shiftr(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t val = val1 >> val2; + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + static inline ASR::expr_t* instantiate_Shiftr(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = shiftr(x, y) + * r = x >> y + */ + body.push_back(al, b.Assignment(result, b.i_BitRshift(args[0], b.i2i(args[1], arg_types[0]), arg_types[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + + static inline ASR::expr_t* SHIFTR(ASRBuilder& b, ASR::expr_t* i, ASR::expr_t* shift, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(i), expr_type(shift)}, {i, shift}, expr_type(i), 0, Shiftr::instantiate_Shiftr); + } + +} // namespace Shiftr + +namespace Rshift { + + static ASR::expr_t *eval_Rshift(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t val = val1 >> val2; + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + static inline ASR::expr_t* instantiate_Rshift(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = rshift(x, y) + * r = x >> y + */ + body.push_back(al, b.Assignment(result, b.i_BitRshift(args[0], args[1], arg_types[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Rshift + +namespace Shiftl { + + static ASR::expr_t *eval_Shiftl(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t val = val1 << val2; + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + static inline ASR::expr_t* instantiate_Shiftl(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_shiftl_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = shiftl(x, y) + * r = x << y + */ + body.push_back(al, b.Assignment(result, b.i_BitLshift(args[0], b.i2i(args[1], arg_types[0]), arg_types[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + + static inline ASR::expr_t* SHIFTL(ASRBuilder& b, ASR::expr_t* i, ASR::expr_t* shift, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(i), expr_type(shift)}, {i, shift}, expr_type(i), 0, Shiftl::instantiate_Shiftl); + } + +} // namespace Shiftl + +namespace Dshiftl { + + static ASR::expr_t *eval_Dshiftl(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& diag) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t shift = ASR::down_cast(args[2])->m_n; + int kind1 = ASRUtils::extract_kind_from_ttype_t(ASR::down_cast(args[0])->m_type); + int kind2 = ASRUtils::extract_kind_from_ttype_t(ASR::down_cast(args[1])->m_type); + if(kind1 != kind2) { + append_error(diag, "The kind of first argument of 'dshiftl' intrinsic must be the same as second arguement", loc); + return nullptr; + } + if(shift < 0){ + append_error(diag, "The shift argument of 'dshiftl' intrinsic must be non-negative integer", loc); + return nullptr; + } + int k_val = (kind1 == 8) ? 64: 32; + int64_t val = (val1 << shift) | (val2 >> (k_val - shift)); + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + + static inline ASR::expr_t* instantiate_Dshiftl(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_dshiftl_" + type_to_str_python(arg_types[0])); + fill_func_arg("i", arg_types[0]); + fill_func_arg("j", arg_types[1]); + fill_func_arg("shift", arg_types[2]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = Dshiftl(x, y, shift) + * r = x << shift | y >> (32 - shift) ! kind = 4 + * r = x << shift | y >> (64 - shift) ! kind = 8 + */ + body.push_back(al, b.Assignment(result, b.i_BitLshift(args[0], b.i2i(args[2], return_type), return_type))); + body.push_back(al, b.If(b.iEq(b.i(extract_kind_from_ttype_t(arg_types[0]), int32), b.i(4, int32)), { + b.Assignment(result, b.i_BitOr(result, b.i_BitRshift(args[1], b.i_tSub(b.i(32, return_type), args[2], return_type), return_type), return_type)) + }, { + b.Assignment(result, b.i_BitOr(result, b.i_BitRshift(args[1], b.i_tSub(b.i(64, return_type), args[2], return_type), return_type), return_type)) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Dshiftl + + +namespace Ishft { + + static ASR::expr_t *eval_Ishft(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t val; + if(val2<=0){ + val2 = val2 * -1; + val = val1 >> val2; + } else { + val = val1 << val2; + } + return make_ConstantWithType(make_IntegerConstant_t, val, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ishft(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ishft_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ishft(x, y) + * if ( y <= 0) { + * r = x >> ( -1 * y) + * } else { + * r = x << y + * } + */ + body.push_back(al, b.If(b.iLtE(args[1], b.i(0, arg_types[0])), { + b.Assignment(result, b.i_BitRshift(args[0], b.iMul(b.i(-1, arg_types[0]), args[1]), arg_types[0])) + }, { + b.Assignment(result, b.i_BitLshift(args[0], args[1], arg_types[0])) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ishft + +namespace Bgt { + + static ASR::expr_t *eval_Bgt(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + bool result = false; + if (val1 * val2 > 0 || ((val1 * val2 == 0) && (val1 > 0 || val2 > 0))) { + if (val1 > val2) { + result = true; + } + } else { + if (val1 < val2) { + result = true; + } + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Bgt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t */*return_type*/, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_bgt_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, logical, ReturnVar); + body.push_back(al, b.Assignment(result, b.bool32(0))); + body.push_back(al, b.If(b.Or(b.iGt(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.And(b.iEq(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.Or(b.iGt(args[0], b.i(0, arg_types[0])), b.iGt(args[1], b.i(0, arg_types[0]))))), { + b.If(b.iGt(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + }, { + b.If(b.iLt(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Bgt + +namespace Blt { + + static ASR::expr_t *eval_Blt(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + bool result = false; + if (val1 * val2 > 0 || ((val1 * val2 == 0) && (val1 > 0 || val2 > 0))) { + if (val1 < val2) { + result = true; + } + } else { + if (val1 > val2) { + result = true; + } + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Blt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t */*return_type*/, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_blt_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, logical, ReturnVar); + body.push_back(al, b.Assignment(result, b.bool32(0))); + body.push_back(al, b.If(b.Or(b.iGt(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.And(b.iEq(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.Or(b.iGt(args[0], b.i(0, arg_types[0])), b.iGt(args[1], b.i(0, arg_types[0]))))), { + b.If(b.iLt(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + }, { + b.If(b.iGt(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Blt + +namespace Bge { + + static ASR::expr_t *eval_Bge(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + bool result = false; + if (val1 * val2 > 0 || ((val1 * val2 == 0) && (val1 > 0 || val2 > 0))) { + if (val1 >= val2) { + result = true; + } + } else { + if (val1 <= val2) { + result = true; + } + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Bge(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t */*return_type*/, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_bge_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, logical, ReturnVar); + body.push_back(al, b.Assignment(result, b.bool32(0))); + body.push_back(al, b.If(b.Or(b.iGt(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.And(b.iEq(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.Or(b.iGt(args[0], b.i(0, arg_types[0])), b.iGt(args[1], b.i(0, arg_types[0]))))), { + b.If(b.iGtE(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + }, { + b.If(b.iLtE(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Bge + +namespace Ble { + + static ASR::expr_t *eval_Ble(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + bool result = false; + if (val1 * val2 > 0 || ((val1 * val2 == 0) && (val1 > 0 || val2 > 0))) { + if (val1 <= val2) { + result = true; + } + } else { + if (val1 >= val2) { + result = true; + } + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ble(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t */*return_type*/, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ble_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, logical, ReturnVar); + body.push_back(al, b.Assignment(result, b.bool32(0))); + body.push_back(al, b.If(b.Or(b.iGt(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.And(b.iEq(b.iMul(args[0], args[1]), b.i(0, arg_types[0])), b.Or(b.iGt(args[0], b.i(0, arg_types[0])), b.iGt(args[1], b.i(0, arg_types[0]))))), { + b.If(b.iLtE(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + }, { + b.If(b.iGtE(args[0], args[1]), { + b.Assignment(result, b.bool32(1)) + }, {}) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Ble + +namespace Lgt { + + static ASR::expr_t *eval_Lgt(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* string_A = ASR::down_cast(args[0])->m_s; + char* string_B = ASR::down_cast(args[1])->m_s; + bool result = false; + if (strcmp(string_A, string_B) > 0) { + result = true; + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Lgt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_lgt_" + type_to_str_python(type_get_past_allocatable(arg_types[0]))); + fill_func_arg("x", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("y", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.sGt(args[0], args[1]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Lgt + +namespace Llt { + + static ASR::expr_t *eval_Llt(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* string_A = ASR::down_cast(args[0])->m_s; + char* string_B = ASR::down_cast(args[1])->m_s; + bool result = false; + if (strcmp(string_A, string_B) < 0) { + result = true; + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Llt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_llt_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("y", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.sLt(args[0], args[1]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Llt + +namespace Lge { + + static ASR::expr_t *eval_Lge(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* string_A = ASR::down_cast(args[0])->m_s; + char* string_B = ASR::down_cast(args[1])->m_s; + bool result = false; + if (strcmp(string_A, string_B) >= 0) { + result = true; + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Lge(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_lge_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("y", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.sGtE(args[0], args[1]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Lge + +namespace Lle { + + static ASR::expr_t *eval_Lle(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* string_A = ASR::down_cast(args[0])->m_s; + char* string_B = ASR::down_cast(args[1])->m_s; + bool result = false; + if (strcmp(string_A, string_B) <= 0) { + result = true; + } + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Lle(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_lle_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("y", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.sLtE(args[0], args[1]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, logical, nullptr); + } + +} // namespace Lle + +namespace Not { + + static ASR::expr_t *eval_Not(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val = ASR::down_cast(args[0])->m_n; + int64_t result = ~val; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Not(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_not_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = not(x) + * r = ~x + */ + body.push_back(al, b.Assignment(result, b.i_BitNot(args[0], return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + + static inline ASR::expr_t* NOT(ASRBuilder &b, ASR::expr_t* x, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(x)}, {x}, expr_type(x), 0, Not::instantiate_Not); + } + +} // namespace Not + +namespace Iand { + + static ASR::expr_t *eval_Iand(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t result; + result = val1 & val2; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Iand(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_iand_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = iand(x, y) + * r = x & y + */ + body.push_back(al, b.Assignment(result, b.i_BitAnd(args[0], args[1], return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + + static inline ASR::expr_t* IAND(ASRBuilder &b, ASR::expr_t* i, ASR::expr_t* j, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(i), expr_type(j)}, {i, j}, expr_type(i), 0, Iand::instantiate_Iand); + } + +} // namespace Iand + +namespace Ior { + + static ASR::expr_t *eval_Ior(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t result; + result = val1 | val2; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ior(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ior_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ior(x, y) + * r = x | y + */ + body.push_back(al, b.Assignment(result, b.i_BitOr(args[0], args[1], return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + + static inline ASR::expr_t* IOR(ASRBuilder& b, ASR::expr_t* i, ASR::expr_t* j, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(i), expr_type(j)}, {i, j}, expr_type(i), 0, Ior::instantiate_Ior); + } + +} // namespace Ior + +namespace Ieor { + + static ASR::expr_t *eval_Ieor(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t result; + result = val1 ^ val2; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ieor(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ieor_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ieor(x, y) + * r = x ^ y + */ + body.push_back(al, b.Assignment(result, b.i_BitXor(args[0], args[1], return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ieor + +namespace Ibclr { + + static ASR::expr_t *eval_Ibclr(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t result; + result = val1 & ~(1 << val2); + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ibclr(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ibclr_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ibclr(x, y) + * r = x & ~( 1 << y ) + */ + body.push_back(al, b.Assignment(result, b.i_BitAnd(args[0], b.i_BitNot(b.i_BitLshift(b.i(1, arg_types[0]), args[1], return_type), return_type), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ibclr + +namespace Ibset { + + static ASR::expr_t *eval_Ibset(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t result; + result = val1 | (1 << val2); + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ibset(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ibset_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ibset(x, y) + * r = x | ( 1 << y ) + */ + body.push_back(al, b.Assignment(result, b.i_BitOr(args[0], b.i_BitLshift(b.i(1, arg_types[0]), args[1], return_type), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ibset + +namespace Btest { + + static ASR::expr_t *eval_Btest(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + bool result; + if ((val1 & (1 << val2)) == 0) result = false; + else result = true; + return make_ConstantWithType(make_LogicalConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Btest(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_btest_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = btest(x, y) + * r = (( x & ( 1 << y )) == 0) ? .false. : .true. + */ + body.push_back(al, b.If(b.iEq(b.i_BitAnd(args[0], b.i_BitLshift(b.i(1, arg_types[0]), args[1], arg_types[0]), arg_types[0]), b.i(0, arg_types[0])), { + b.Assignment(result, b.bool32(0)) + }, { + b.Assignment(result, b.bool32(1)) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Btest + +namespace Ibits { + + static ASR::expr_t *eval_Ibits(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val1 = ASR::down_cast(args[0])->m_n; + int64_t val2 = ASR::down_cast(args[1])->m_n; + int64_t val3 = ASR::down_cast(args[2])->m_n; + int64_t result; + result = (val1 >> val2) & ((1 << val3) - 1); + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ibits(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ibits_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + fill_func_arg("z", arg_types[2]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = ibits(x, y, z) + * r = ( x >> y ) & ( ( 1 << z ) - 1 ) + */ + body.push_back(al, b.Assignment(result, b.i_BitAnd(b.i_BitRshift(args[0], b.i2i(args[1], arg_types[0]), return_type), b.iSub(b.i_BitLshift(b.i(1, arg_types[0]), b.i2i(args[2], arg_types[0]), return_type), b.i(1, arg_types[0])), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ibits + +namespace Aint { + + static ASR::expr_t *eval_Aint(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + double rv = ASR::down_cast(expr_value(args[0]))->m_r; + ASRUtils::ASRBuilder b(al, loc); + return b.f(std::trunc(rv), arg_type); + } + + static inline ASR::expr_t* instantiate_Aint(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_aint_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + + // Cast: Real -> Integer -> Real + // TODO: this approach doesn't work for numbers > i64_max + body.push_back(al, b.Assignment(result, b.i2r(b.r2i64(args[0]), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Aint + +namespace Anint { + + static ASR::expr_t *eval_Anint(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + double rv = ASR::down_cast(expr_value(args[0]))->m_r; + ASRUtils::ASRBuilder b(al, loc); + return b.f(std::round(rv), arg_type); + } + + static inline ASR::expr_t* instantiate_Anint(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_anint_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * if (x > 0) then + * r = aint(x+0.5) + * else + * r = aint(x-0.5) + * end if + */ + body.push_back(al, b.If(b.fGt(args[0], b.f(0, arg_types[0])), { + b.Assignment(result, b.CallIntrinsic(scope, {arg_types[0]}, {b.rAdd(args[0], b.f(0.5, arg_types[0]), arg_types[0])}, + return_type, 0, Aint::instantiate_Aint)) + }, { + b.Assignment(result, b.CallIntrinsic(scope, {arg_types[0]}, {b.rSub(args[0], b.f(0.5, arg_types[0]), arg_types[0])}, + return_type, 0, Aint::instantiate_Aint)) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Anint + +namespace Nint { + + static ASR::expr_t *eval_Nint(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + double rv = ASR::down_cast(expr_value(args[0]))->m_r; + double near_integer = std::round(rv); + int64_t result = int64_t(near_integer); + return make_ConstantWithType(make_IntegerConstant_t, result, arg_type, loc); + } + + static inline ASR::expr_t* instantiate_Nint(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_nint_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = nint(x) + * r = int(anint(x)) + */ + body.push_back(al,b.Assignment(result, b.r2i(b.CallIntrinsic(scope, {arg_types[0]}, {args[0]}, arg_types[0], 0, Anint::instantiate_Anint), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace Nint + + +namespace Floor { + + static ASR::expr_t *eval_Floor(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + float val = ASR::down_cast(args[0])->m_r; + int64_t result = int64_t(val); + if(val<=0.0 && val!=result) { + result = result-1; + } + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Floor(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_floor_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = floor(x) + * r = int(x) + * if(x <= 0.00 && x != r){ + * r = int(x) - 1 + * } + */ + body.push_back(al, b.Assignment(result, b.r2i(args[0], return_type))); + body.push_back(al, b.If(b.And(b.fLtE(args[0], b.f(0, arg_types[0])), b.fNotEq(b.i2r(b.r2i(args[0], return_type), return_type), b.r2r(args[0], return_type))), + { + b.Assignment(result, b.i_tSub(b.r2i(args[0], return_type), b.i(1, return_type), return_type)) + }, {})); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Floor + +namespace Ceiling { + + static ASR::expr_t *eval_Ceiling(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + double val = ASR::down_cast(args[0])->m_r; + double difference = val - double(int(val)); + int64_t result; + if (difference == 0.0) { + result = int(val); + } else if(val <= 0.0){ + result = int(val); + } else{ + result = int(val) + 1; + } + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ceiling(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ceiling_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = Ceiling(x) + * if(x >= 0.00){ + * if(x == int(x)){ + * r = int(x) + * } else { + * r = int(x) + 1 + * } + * } else { + * r = int(x) + * } + */ + body.push_back(al, b.If(b.fGtE(args[0], b.f(0, arg_types[0])), + { + b.If(b.fEq(b.r2r(args[0], return_type), + b.i2r(b.r2i(args[0], return_type), return_type) + ), + { + b.Assignment(result, b.r2i(args[0], return_type)) + }, { + b.Assignment(result, b.i_tAdd(b.r2i(args[0], return_type), b.i(1, return_type), return_type)) + }) + }, { + b.Assignment(result, b.r2i(args[0], return_type)) + })); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Ceiling + +namespace Dim { + + static ASR::expr_t *eval_Dim(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + if (is_real(*t1)) { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + double result; + double zero = 0.0; + if (a > b) { + result = a - b; + } else { + result = zero; + } + return make_ConstantWithType(make_RealConstant_t, result, t1, loc); + } + LCOMPILERS_ASSERT(is_integer(*t1)); + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + int64_t result; + if (a > b) { + result = a - b; + } else { + result = 0; + } + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Dim(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_dim_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = Dim(x) + * if (x > y) { + * r = x - y + * } else { + * r = 0 + * } + */ + if (is_real(*arg_types[0])) { + body.push_back(al, b.If(b.fGt(args[0], args[1]), { + b.Assignment(result, b.r_tSub(args[0], args[1], arg_types[0])) + }, { + b.Assignment(result, b.f(0.0, arg_types[0])) + })); + } else { + body.push_back(al, b.If(b.iGt(args[0], args[1]), { + b.Assignment(result, b.i_tSub(args[0], args[1], arg_types[0])) + }, { + b.Assignment(result, b.i(0, arg_types[0])) + })); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Dim + +namespace Sqrt { + + static ASR::expr_t *eval_Sqrt(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + if (is_real(*arg_type)) { + double val = ASR::down_cast(expr_value(args[0]))->m_r; + return b.f(std::sqrt(val), arg_type); + } else { + std::complex crv; + if( ASRUtils::extract_value(args[0], crv) ) { + std::complex val = std::sqrt(crv); + return ASRUtils::EXPR(ASR::make_ComplexConstant_t( + al, loc, val.real(), val.imag(), arg_type)); + } else { + return nullptr; + } + } + } + + static inline ASR::expr_t* instantiate_Sqrt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t overload_id) { + ASR::ttype_t* arg_type = arg_types[0]; + if (is_real(*arg_type)) { + return EXPR(ASR::make_RealSqrt_t(al, loc, + new_args[0].m_value, return_type, nullptr)); + } else { + return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, + "sqrt", arg_type, return_type, new_args, overload_id); + } + } + +} // namespace Sqrt + +namespace Exponent { + + static ASR::expr_t* eval_Exponent(Allocator& al, const Location& loc, + ASR::ttype_t* arg_type, Vec& args, diag::Diagnostics& /*diag*/) { + ASR::ttype_t* arguement_type = expr_type(args[0]); + int32_t kind = extract_kind_from_ttype_t(arguement_type); + + if (kind == 4) { + float x = ASR::down_cast(args[0])->m_r; + if (x == 0.0) { + return make_ConstantWithType(make_IntegerConstant_t, 0, arg_type, loc); + } + int32_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + int32_t exponent = ((ix >> 23) & 0xff) - 126; + return make_ConstantWithType(make_IntegerConstant_t, exponent, arg_type, loc); + } + else if (kind == 8) { + double x = ASR::down_cast(args[0])->m_r; + if (x == 0.0) { + return make_ConstantWithType(make_IntegerConstant_t, 0, arg_type, loc); + } + int64_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + int64_t exponent = ((ix >> 52) & 0x7ff) - 1022; + return make_ConstantWithType(make_IntegerConstant_t, exponent, arg_type, loc); + } + return nullptr; + } + + + static inline ASR::expr_t* instantiate_Exponent(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompiler_optimization_exponent_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + int32_t kind = extract_kind_from_ttype_t(arg_types[0]); + /* + if (x == 0.0) then + result = 0 + else + result = iand(shiftr(transfer(x, 0), 23), int(Z'0FF', kind=4)) - 126 ! for real kind = 4 + result = iand(shiftr(transfer(x, 0), 52), int(Z'7FF', kind=8)) - 1022 ! for real kind = 8 + end if + */ + if (kind == 8) { + body.push_back(al, b.If(b.fEq(args[0], b.f(0.0, arg_types[0])), { + b.Assignment(result, b.i32(0)) + }, { + b.Assignment(result, b.i2i32(b.i_tSub(b.i_tAnd(b.i_BitRshift(ASRUtils::EXPR(ASR::make_BitCast_t(al, loc, args[0], b.i64(0), nullptr, int64, nullptr)), + b.i64(52), int64), b.i64(0x7FF), int64), b.i64(1022), int64))) + })); + } else { + body.push_back(al, b.If(b.fEq(args[0], b.f(0.0, arg_types[0])), { + b.Assignment(result, b.i32(0)) + }, { + b.Assignment(result, b.i_tSub(b.i_tAnd(b.i_BitRshift(ASRUtils::EXPR(ASR::make_BitCast_t(al, loc, args[0], b.i32(0), nullptr, int32, nullptr)), + b.i32(23), int32), b.i32(0x0FF), int32), b.i32(126), int32)) + })); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace Exponent + +namespace Fraction { + static ASR::expr_t *eval_Fraction(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + ASR::ttype_t* arguement_type = expr_type(args[0]); + int32_t kind = extract_kind_from_ttype_t(arguement_type); + if (kind == 4) { + float x = ASR::down_cast(args[0])->m_r; + int32_t exponent; + if (x == 0.0) { + exponent = 0; + float result = x * std::pow((2), (-1*(exponent))); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + else{ + int32_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 23) & 0xff) - 126; + float result = x * std::pow((2), (-1*(exponent))); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + } + else if (kind == 8) { + double x = ASR::down_cast(args[0])->m_r; + int64_t exponent; + if (x == 0.0) { + exponent = 0; + double result = x * std::pow((2), (-1*(exponent))); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + else{ + int64_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 52) & 0x7ff) - 1022; + double result = x * std::pow((2), (-1*(exponent))); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + } + return nullptr; + } + + static inline ASR::expr_t* instantiate_Fraction(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_fraction_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = fraction(x, y) + * r = x * radix(x)**(-exp(x)) + */ + ASR::expr_t* func_call_exponent = b.CallIntrinsic(scope, {arg_types[0]}, {args[0]}, int32, 0, Exponent::instantiate_Exponent); + body.push_back(al, b.Assignment(result, b.r_tMul(args[0], b.rPow(b.i2r(b.i(2, int32),return_type), b.r_tMul(b.i2r(b.i(-1,int32), return_type),b.i2r(func_call_exponent, return_type), return_type), return_type), return_type))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace Fraction + +namespace SetExponent { + static ASR::expr_t *eval_SetExponent(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + ASR::ttype_t* arguement_type = expr_type(args[0]); + int32_t kind = extract_kind_from_ttype_t(arguement_type); + if (kind == 4) { + float x = ASR::down_cast(args[0])->m_r; + int32_t I = ASR::down_cast(args[1])->m_n; + int32_t exponent; + if (x == 0.0) { + exponent = 0; + float result1 = x * std::pow((2), (-1*(exponent))); + float result = result1 * std::pow((2), I); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } else { + int32_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 23) & 0xff) - 126; + float result1 = x * std::pow((2), (-1*(exponent))); + float result = result1 * std::pow((2), I); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + } + else if (kind == 8) { + double x = ASR::down_cast(args[0])->m_r; + int64_t I = ASR::down_cast(args[1])->m_n; + int64_t exponent; + if (x == 0.0) { + exponent = 0; + double result1 = x * std::pow((2), (-1*(exponent))); + double result = result1 * std::pow((2), I); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } else { + int64_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 52) & 0x7ff) - 1022; + double result1 = x * std::pow((2), (-1*(exponent))); + double result = result1 * std::pow((2), I); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + } + } + return nullptr; + } + + static inline ASR::expr_t* instantiate_SetExponent(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_setexponent_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("i", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + + /* + * r = setexponent(x, I) + * r = fraction(x) * radix(x)**(I) + */ + ASR::expr_t* func_call_fraction = b.CallIntrinsic(scope, {arg_types[0]}, {args[0]}, return_type, 0, Fraction::instantiate_Fraction); + body.push_back(al, b.Assignment(result, b.r_tMul(func_call_fraction, b.rPow(b.i2r(b.i32(2),return_type),b.i2r(args[1], return_type), return_type), return_type))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace SetExponent + +namespace Sngl { + + static ASR::expr_t *eval_Sngl(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + double val = ASR::down_cast(expr_value(args[0]))->m_r; + return b.f(val, arg_type); + } + + static inline ASR::expr_t* instantiate_Sngl(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_sngl_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.r2r32(args[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Sngl + +namespace Ifix { + + static ASR::expr_t *eval_Ifix(Allocator &al, const Location &loc, + ASR::ttype_t* /*arg_type*/, Vec &args, diag::Diagnostics& /*diag*/) { + int val = ASR::down_cast(expr_value(args[0]))->m_r; + return make_ConstantWithType(make_IntegerConstant_t, val, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), loc); + } + + static inline ASR::expr_t* instantiate_Ifix(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_ifix_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.r2i32(args[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ifix + +namespace Idint { + + static ASR::expr_t *eval_Idint(Allocator &al, const Location &loc, + ASR::ttype_t* /*arg_type*/, Vec &args, diag::Diagnostics& /*diag*/) { + int val = ASR::down_cast(expr_value(args[0]))->m_r; + return make_ConstantWithType(make_IntegerConstant_t, val, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), loc); + } + + static inline ASR::expr_t* instantiate_Idint(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_idint_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, b.r2i32(args[0]))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} + +namespace FMA { + + static ASR::expr_t *eval_FMA(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + double c = ASR::down_cast(args[2])->m_r; + return make_ConstantWithType(make_RealConstant_t, a + b*c, t1, loc); + } + + static inline ASR::expr_t* instantiate_FMA(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_fma_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + fill_func_arg("b", arg_types[0]); + fill_func_arg("c", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * result = a + b*c + */ + body.push_back(al, b.Assignment(result, + b.ElementalAdd(args[0], b.ElementalMul(args[1], args[2], loc), loc))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace FMA + + +namespace SignFromValue { + + static ASR::expr_t *eval_SignFromValue(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + if (is_real(*t1)) { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + a = (b < 0 ? -a : a); + return make_ConstantWithType(make_RealConstant_t, a, t1, loc); + } + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + a = (b < 0 ? -a : a); + return make_ConstantWithType(make_IntegerConstant_t, a, t1, loc); + + } + + static inline ASR::expr_t* instantiate_SignFromValue(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_signfromvalue_" + type_to_str_python(arg_types[0])); + fill_func_arg("a", arg_types[0]); + fill_func_arg("b", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + elemental real(real32) function signfromvaluer32r32(a, b) result(d) + real(real32), intent(in) :: a, b + d = a * asignr32(1.0_real32, b) + end function + */ + if (is_real(*arg_types[0])) { + body.push_back(al, b.If(b.fLt(args[1], b.f(0.0, arg_types[1])), { + b.Assignment(result, b.f32_neg(args[0], arg_types[0])) + }, { + b.Assignment(result, args[0]) + })); + } else { + body.push_back(al, b.If(b.iLt(args[1], b.i(0, arg_types[1])), { + b.Assignment(result, b.i32_neg(args[0], arg_types[0])) + }, { + b.Assignment(result, args[0]) + })); + } + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace SignFromValue + + +namespace FlipSign { + + static ASR::expr_t *eval_FlipSign(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int a = ASR::down_cast(args[0])->m_n; + double b = ASR::down_cast(args[1])->m_r; + if (a % 2 == 1) b = -b; + return make_ConstantWithType(make_RealConstant_t, b, t1, loc); + } + + static inline ASR::expr_t* instantiate_FlipSign(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_flipsign_" + type_to_str_python(arg_types[1])); + fill_func_arg("signal", arg_types[0]); + fill_func_arg("variable", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + real(real32) function flipsigni32r32(signal, variable) + integer(int32), intent(in) :: signal + real(real32), intent(out) :: variable + integer(int32) :: q + q = signal/2 + flipsigni32r32 = variable + if (signal - 2*q == 1 ) flipsigni32r32 = -variable + end subroutine + */ + + body.push_back(al, b.If(b.iEq(b.iSub(args[0], b.iMul(b.i(2, arg_types[0]), b.iDiv(args[0], b.i(2, arg_types[0])))), b.i(1, arg_types[0])), { + b.Assignment(result, b.f32_neg(args[1], arg_types[1])) + }, { + b.Assignment(result, args[1]) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace FlipSign + +namespace FloorDiv { + + static ASR::expr_t *eval_FloorDiv(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& diag) { + ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); + ASR::ttype_t *type2 = ASRUtils::expr_type(args[1]); + type1 = ASRUtils::type_get_past_const(type1); + type2 = ASRUtils::type_get_past_const(type2); + bool is_real1 = is_real(*type1); + bool is_real2 = is_real(*type2); + bool is_int1 = is_integer(*type1); + bool is_int2 = is_integer(*type2); + bool is_unsigned_int1 = is_unsigned_integer(*type1); + bool is_unsigned_int2 = is_unsigned_integer(*type2); + bool is_logical1 = is_logical(*type1); + bool is_logical2 = is_logical(*type2); + + + if (is_int1 && is_int2) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + if (b == 0) { + append_error(diag, "Division by `0` is not allowed", loc); + return nullptr; + } + return make_ConstantWithType(make_IntegerConstant_t, a / b, t1, loc); + } else if (is_unsigned_int1 && is_unsigned_int2) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + if (b == 0) { + append_error(diag, "Division by `0` is not allowed", loc); + return nullptr; + } + return make_ConstantWithType(make_UnsignedIntegerConstant_t, a / b, t1, loc); + } else if (is_logical1 && is_logical2) { + bool a = ASR::down_cast(args[0])->m_value; + bool b = ASR::down_cast(args[1])->m_value; + if (b == 0) { + append_error(diag, "Division by `0` is not allowed", loc); + return nullptr; + } + return make_ConstantWithType(make_LogicalConstant_t, a / b, t1, loc); + } else if (is_real1 && is_real2) { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + if (b == 0.0) { + append_error(diag, "Division by `0` is not allowed", loc); + return nullptr; + } + double r = a / b; + int64_t result = (int64_t)r; + if ( r >= 0.0 || (double)result == r) { + return make_ConstantWithType(make_RealConstant_t, (double)result, t1, loc); + } + return make_ConstantWithType(make_RealConstant_t, (double)(result - 1), t1, loc); + } + return nullptr; + } + + static inline ASR::expr_t* instantiate_FloorDiv(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_floordiv_" + type_to_str_python(arg_types[1])); + fill_func_arg("a", arg_types[0]); + fill_func_arg("b", arg_types[1]); + auto r = declare("r", real64, Local); + auto tmp = declare("tmp", int64, Local); + auto result = declare("result", return_type, ReturnVar); + /* + @overload + def _lpython_floordiv(a: i32, b: i32) -> i32: + r: f64 # f32 rounds things up and gives incorrect tmps + tmp: i64 + result: i32 + r = float(a)/float(b) + tmp = i64(r) + if r < 0.0 and f64(tmp) != r: + tmp = tmp - 1 + result = i32(tmp) + return result + */ + body.push_back(al, b.Assignment(r, b.r64Div(CastingUtil::perform_casting(args[0], real64, al, loc), + CastingUtil::perform_casting(args[1], real64, al, loc)))); + body.push_back(al, b.Assignment(tmp, b.r2i64(r))); + body.push_back(al, b.If(b.And(b.fLt(r, b.f(0.0, real64)), b.fNotEq(b.i2r64(tmp), r)), { + b.Assignment(tmp, b.i64Sub(tmp, b.i(1, int64))) + }, {})); + body.push_back(al, b.Assignment(result, CastingUtil::perform_casting(tmp, return_type, al, loc))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace FloorDiv + +namespace Mod { + + static ASR::expr_t *eval_Mod(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + bool is_real1 = is_real(*ASRUtils::expr_type(args[0])); + bool is_real2 = is_real(*ASRUtils::expr_type(args[1])); + bool is_int1 = is_integer(*ASRUtils::expr_type(args[0])); + bool is_int2 = is_integer(*ASRUtils::expr_type(args[1])); + + if (is_int1 && is_int2) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t b = ASR::down_cast(args[1])->m_n; + return make_ConstantWithType(make_IntegerConstant_t, a % b, t1, loc); + } else if (is_real1 && is_real2) { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + return make_ConstantWithType(make_RealConstant_t, std::fmod(a, b), t1, loc); + } + return nullptr; + } + + static inline ASR::expr_t* instantiate_Mod(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_mod_" + type_to_str_python(arg_types[1])); + fill_func_arg("a", arg_types[0]); + fill_func_arg("p", arg_types[1]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + function modi32i32(a, p) result(d) + integer(int32), intent(in) :: a, p + integer(int32) :: q + q = a/p + d = a - p*q + end function + */ + int kind = ASRUtils::extract_kind_from_ttype_t(arg_types[1]); + if (is_real(*arg_types[1])) { + if (kind == 4) { + body.push_back(al, b.Assignment(result, b.r32Sub(args[0], b.r32Mul(args[1], b.i2r32(b.r2i32(b.r32Div(args[0], args[1]))))))); + } else { + body.push_back(al, b.Assignment(result, b.r64Sub(args[0], b.r64Mul(args[1], b.i2r64(b.r2i64(b.r64Div(args[0], args[1]))))))); + } + } else { + if (kind == 1) { + body.push_back(al, b.Assignment(result, b.i8Sub(args[0], b.i8Mul(args[1], b.i8Div(args[0], args[1]))))); + } else if (kind == 2) { + body.push_back(al, b.Assignment(result, b.i16Sub(args[0], b.i16Mul(args[1], b.i16Div(args[0], args[1]))))); + } else if (kind == 4) { + body.push_back(al, b.Assignment(result, b.iSub(args[0], b.iMul(args[1], b.iDiv(args[0], args[1]))))); + } else if (kind == 8) { + body.push_back(al, b.Assignment(result, b.i64Sub(args[0], b.i64Mul(args[1], b.i64Div(args[0], args[1]))))); + } else { + LCOMPILERS_ASSERT(false); + } + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + static inline ASR::expr_t* MOD(ASRBuilder &b, ASR::expr_t* a, ASR::expr_t* p, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(a), expr_type(p)}, {a, p}, expr_type(a), 0, Mod::instantiate_Mod); + } + +} // namespace Mod + +namespace Popcnt { + + template + int compute_count(T mask, int64_t val) { + int count = 0; + while (mask != 0) { + if (val & mask) count++; + mask = mask << 1; + } + return count; + } + + static ASR::expr_t *eval_Popcnt(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int kind = ASRUtils::extract_kind_from_ttype_t(ASR::down_cast(args[0])->m_type); + int64_t val = static_cast(ASR::down_cast(args[0])->m_n); + int64_t mask1 = 1; + int32_t mask2 = 1; + int count = 0; + if (val < 0) { + count = kind == 4 ? compute_count(mask2, val) : compute_count(mask1, val); + } else { + while (val) { + count += val & 1; + val >>= 1; + } + } + return make_ConstantWithType(make_IntegerConstant_t, count, t1, loc); + } + + static inline ASR::expr_t* instantiate_Popcnt(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_popcnt_" + type_to_str_python(arg_types[0])); + fill_func_arg("i", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + auto count = declare("j", arg_types[0], Local); + auto val = declare("k", arg_types[0], Local); + auto mask = declare("l", arg_types[0], Local); + /* + function popcnt(i) result(r) + integer, intent(in) :: i + integer :: r, count, mask + count = 0 + mask = 1 + if (i >= 0) then + ! For positive numbers + do while (i /= 0) + count = count + mod(i, 2) + i = i / 2 + end do + else + ! For negative numbers + do while (mask /= 0) + if ((i .and. mask) /= 0) then + count = count + 1 + end if + mask = mask * 2 + end do + end if + r = count + end function popcnt + */ + body.push_back(al, b.Assignment(count, b.i(0,arg_types[0]))); + body.push_back(al, b.Assignment(val, args[0])); + body.push_back(al, b.Assignment(mask, b.i(1,arg_types[0]))); + body.push_back(al, b.If(b.iGtE(args[0], b.i(0,arg_types[0])), { + b.While(b.iNotEq(val, b.i(0, arg_types[0])), { + b.Assignment(count, b.i_tAdd(count, Mod::MOD(b, val, b.i(2, arg_types[0]), scope), arg_types[0])), + b.Assignment(val, b.i_tDiv(val, b.i(2, arg_types[0]), arg_types[0])) + }) + }, { + b.While(b.iNotEq(mask, b.i(0, arg_types[0])), { + b.If(b.iNotEq(b.i(0,arg_types[0]), (b.i_BitAnd(val,mask, arg_types[0]))), {b.Assignment(count, b.i_tAdd(count, b.i(1, arg_types[0]), arg_types[0]))}, + {}), + b.Assignment(mask, b.i_BitLshift(mask, b.i(1, arg_types[0]), arg_types[0])) + }) + })); + body.push_back(al, b.Assignment(result, b.i2i(count, return_type))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + static inline ASR::expr_t* POPCNT(ASRBuilder &b, ASR::expr_t* a, ASR::ttype_t *return_type, SymbolTable* scope) { + return b.CallIntrinsic(scope, {expr_type(a)}, {a}, return_type, 0, Popcnt::instantiate_Popcnt); + } +} // namespace Popcnt + +namespace Maskl { + static ASR::expr_t* eval_Maskl(Allocator& al, const Location& loc, + ASR::ttype_t* t1, Vec& args, diag::Diagnostics& /*diag*/) { + int32_t kind = ASRUtils::extract_kind_from_ttype_t(t1); + int64_t i = ASR::down_cast(args[0])->m_n; + if (((kind == 4) && i > 32) || (kind == 8 && i > 64) || i < 0) { + return nullptr; + } else { + int64_t one = 1; + int64_t minus_one = -1; + int64_t sixty_four = 64; + int64_t result = (i == 64) ? minus_one : ((one << i) - one) << (sixty_four - i); + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + } + + static inline ASR::expr_t* instantiate_Maskl(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = Maskl(x) + * r = (x == 64) ? -1 : ((1 << x) - 1) << (64 - x) + */ + body.push_back(al, b.If((b.iEq(b.i2i(args[0], return_type), b.i(64, return_type))), { + b.Assignment(result, b.i(-1, return_type)) + }, { + b.Assignment(result, b.i_BitLshift(b.i_tSub(b.i_BitLshift(b.i(1, return_type), b.i2i(args[0], return_type), return_type), b.i(1, return_type), return_type), + b.i_tSub(b.i(64, return_type), b.i2i(args[0], return_type), return_type), return_type)) + })); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Maskl + +namespace Maskr { + static ASR::expr_t* eval_Maskr(Allocator& al, const Location& loc, + ASR::ttype_t* t1, Vec& args, diag::Diagnostics& /*diag*/) { + int32_t kind = ASRUtils::extract_kind_from_ttype_t(t1); + int64_t i = ASR::down_cast(args[0])->m_n; + if (((kind == 4) && i > 32) || (kind == 8 && i > 64) || i < 0) { + return nullptr; + } + if(i == 64){ + return make_ConstantWithType(make_IntegerConstant_t, -1, t1, loc); + } + int64_t one = 1; + int64_t result = (one << i) - one; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Maskr(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = Maskr(x) + * r = (1 << x) - 1 + */ + body.push_back(al, b.If((b.iEq(b.i2i(args[0], return_type), b.i(64, return_type))), { + b.Assignment(result, b.i(-1, return_type)) + }, { + b.Assignment(result, b.i_tSub(b.i_BitLshift(b.i(1, return_type), b.i2i(args[0], return_type), return_type), b.i(1, return_type), return_type)) + })); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } +} // namespace Maskr + +namespace Trailz { + + static ASR::expr_t *eval_Trailz(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t kind = ASRUtils::extract_kind_from_ttype_t(t1); + int64_t trailing_zeros = ASRUtils::compute_trailing_zeros(a, kind); + return make_ConstantWithType(make_IntegerConstant_t, trailing_zeros, t1, loc); + } + + static inline ASR::expr_t* instantiate_Trailz(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_trailz_" + type_to_str_python(arg_types[0])); + fill_func_arg("n", arg_types[0]); + auto result = declare(fn_name, arg_types[0], ReturnVar); + // This is not the most efficient way to do this, but it works for now. + /* + function trailz(n) result(result) + integer :: n + integer :: result + integer :: k + k = kind(n) + result = 0 + if (n == 0) then + if (k == 4) then + result = 32 + else + result = 64 + end if + else + do while (mod(n,2) == 0) + n = n/2 + result = result + 1 + end do + end if + end function + */ + body.push_back(al, b.Assignment(result, b.i(0, arg_types[0]))); + body.push_back(al, b.If(b.iEq(args[0], b.i(0, arg_types[0])), { + b.Assignment(result, b.i(8*ASRUtils::extract_kind_from_ttype_t(arg_types[0]), arg_types[0])) + }, { + b.While(b.iEq(b.CallIntrinsic(scope, {arg_types[0], arg_types[0] + }, { + args[0], b.i(2, arg_types[0])}, return_type, 0, Mod::instantiate_Mod), b.i(0, arg_types[0])), + { + b.Assignment(args[0], b.i_tDiv(args[0], b.i(2, arg_types[0]), arg_types[0])), + b.Assignment(result, b.i_tAdd(result, b.i(1, arg_types[0]), arg_types[0])) + }) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Trailz + +namespace BesselJ0 { + + static ASR::expr_t *eval_BesselJ0(Allocator &/*al*/, const Location &/*loc*/, + ASR::ttype_t* /*t1*/, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + return nullptr; + } + + static inline ASR::expr_t* instantiate_BesselJ0(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + if (ASRUtils::extract_kind_from_ttype_t(arg_types[0]) == 4) { + c_func_name = "_lfortran_sbesselj0"; + } else { + c_func_name = "_lfortran_dbesselj0"; + } + std::string new_name = "_lcompilers_bessel_j0_"+ type_to_str_python(arg_types[0]); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var)); + } + fill_func_arg("x", arg_types[0]); + auto result = declare(new_name, return_type, ReturnVar); + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 1); + ASR::expr_t *arg = b.Variable(fn_symtab_1, "x", arg_types[0], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + return_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, return_type))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type); + } + +} // namespace BesselJ0 + +namespace BesselJ1 { + + static ASR::expr_t *eval_BesselJ1(Allocator &/*al*/, const Location &/*loc*/, + ASR::ttype_t* /*t1*/, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + return nullptr; + } + + static inline ASR::expr_t* instantiate_BesselJ1(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + if (ASRUtils::extract_kind_from_ttype_t(arg_types[0]) == 4) { + c_func_name = "_lfortran_sbesselj1"; + } else { + c_func_name = "_lfortran_dbesselj1"; + } + std::string new_name = "_lcompilers_bessel_j1_"+ type_to_str_python(arg_types[0]); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var)); + } + fill_func_arg("x", arg_types[0]); + auto result = declare(new_name, return_type, ReturnVar); + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 1); + ASR::expr_t *arg = b.Variable(fn_symtab_1, "x", arg_types[0], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + return_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, return_type))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type); + } + +} // namespace BesselJ1 + +namespace BesselY0 { + + static ASR::expr_t *eval_BesselY0(Allocator &/*al*/, const Location &/*loc*/, + ASR::ttype_t* /*t1*/, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + return nullptr; + } + + static inline ASR::expr_t* instantiate_BesselY0(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + if (ASRUtils::extract_kind_from_ttype_t(arg_types[0]) == 4) { + c_func_name = "_lfortran_sbessely0"; + } else { + c_func_name = "_lfortran_dbessely0"; + } + std::string new_name = "_lcompilers_bessel_y0_"+ type_to_str_python(arg_types[0]); + + declare_basic_variables(new_name); + if (scope->get_symbol(new_name)) { + ASR::symbol_t *s = scope->get_symbol(new_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var)); + } + fill_func_arg("x", arg_types[0]); + auto result = declare(new_name, return_type, ReturnVar); + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 1); + ASR::expr_t *arg = b.Variable(fn_symtab_1, "x", arg_types[0], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + return_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, return_type))); + } + + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.Call(new_symbol, new_args, return_type); + } + +} // namespace BesselY0 + +namespace Poppar { + + static ASR::expr_t *eval_Poppar(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& diag) { + ASR::expr_t* count = Popcnt::eval_Popcnt(al, loc, t1, args, diag); + int result = ASR::down_cast(count)->m_n; + result = result % 2 == 0 ? 0 : 1; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Poppar(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_poppar_" + type_to_str_python(arg_types[0])); + fill_func_arg("i", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + function poppar(n) result(result) + integer, intent(in) :: n + integer :: result + integer :: count + count = popcnt(n) + result = mod(count, 2) + end function + */ + ASR::expr_t *func_call_poppar =Popcnt::POPCNT(b, args[0], return_type, scope); + body.push_back(al, b.Assignment(result, Mod::MOD(b, func_call_poppar, b.i(2, return_type), scope))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Poppar + +namespace Mvbits { + + static ASR::expr_t *eval_Mvbits(Allocator &/*al*/, const Location &/*loc*/, + ASR::ttype_t* /*t1*/, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + return nullptr; + } + + static inline ASR::expr_t* instantiate_Mvbits(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + if (ASRUtils::extract_kind_from_ttype_t(arg_types[0]) == 4) { + c_func_name = "_lfortran_mvbits32"; + } else { + c_func_name = "_lfortran_mvbits64"; + } + std::string new_name = "_lcompilers_mvbits_" + type_to_str_python(arg_types[0]); + declare_basic_variables(new_name); + fill_func_arg("from", arg_types[0]); + fill_func_arg("frompos", arg_types[1]); + fill_func_arg("len", arg_types[2]); + fill_func_arg("to", arg_types[3]); + fill_func_arg("topos", arg_types[4]); + auto result = declare(new_name, ASRUtils::extract_type(return_type), ReturnVar); + { + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; + { + args_1.reserve(al, 5); + ASR::expr_t *arg = b.Variable(fn_symtab_1, "from", arg_types[0], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + arg = b.Variable(fn_symtab_1, "frompos", arg_types[1], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + arg = b.Variable(fn_symtab_1, "len", arg_types[2], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + arg = b.Variable(fn_symtab_1, "to", arg_types[3], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + arg = b.Variable(fn_symtab_1, "topos", arg_types[4], + ASR::intentType::In, ASR::abiType::BindC, true); + args_1.push_back(al, arg); + } + + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + return_type, ASRUtils::intent_return_var, ASR::abiType::BindC, false); + + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + body.push_back(al, b.Assignment(result, b.Call(s, args, return_type))); + } + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + + static inline ASR::expr_t* MVBITS(ASRBuilder &b, ASR::expr_t* from, ASR::expr_t* frompos, + ASR::expr_t* len, ASR::expr_t* to, ASR::expr_t* topos, SymbolTable *scope) { + return b.CallIntrinsic( scope, {ASRUtils::expr_type(from), ASRUtils::expr_type(frompos), + ASRUtils::expr_type(len), ASRUtils::expr_type(to), ASRUtils::expr_type(topos)}, + {from, frompos, len, to, topos}, ASRUtils::expr_type(to), 0, Mvbits::instantiate_Mvbits); + } + +} // namespace Mvbits + +namespace Leadz { + + static ASR::expr_t *eval_Leadz(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t a = ASR::down_cast(args[0])->m_n; + int64_t kind = ASRUtils::extract_kind_from_ttype_t(t1); + int64_t leading_zeros = ASRUtils::compute_leading_zeros(a, kind); + return make_ConstantWithType(make_IntegerConstant_t, leading_zeros, t1, loc); + } + + static inline ASR::expr_t* instantiate_Leadz(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_leadz_" + type_to_str_python(arg_types[0])); + fill_func_arg("n", arg_types[0]); + auto result = declare(fn_name, arg_types[0], ReturnVar); + auto total_bits = declare("r", arg_types[0], Local); + auto number = declare("num", arg_types[0], Local); + /* + function leadz(n) result(result) + integer :: n, k, total_bits + integer :: result + k = kind(n) + total_bits = 32 + if (k == 8) total_bits = 64 + if (n<0) then + result = 0 + else + do while (total_bits > 0) + if (mod(n,2) == 0) then + result = result + 1 + else + result = 0 + end if + n = n/2 + total_bits = total_bits - 1 + end do + end if + end function + */ + body.push_back(al, b.Assignment(result, b.i(0, arg_types[0]))); + body.push_back(al, b.Assignment(number, args[0])); + body.push_back(al, b.Assignment(total_bits, b.i(8*ASRUtils::extract_kind_from_ttype_t(arg_types[0]), arg_types[0]))); + body.push_back(al, b.If(b.iLt(number, b.i(0, arg_types[0])), { + b.Assignment(result, b.i(0, arg_types[0])) + }, { + b.While(b.iGt(total_bits, b.i(0, arg_types[0])), { + b.If(b.iEq(b.CallIntrinsic(scope, {arg_types[0], arg_types[0]}, + {number, b.i(2, arg_types[0])}, return_type, 0, Mod::instantiate_Mod), b.i(0, arg_types[0])), { + b.Assignment(result, b.i_tAdd(result, b.i(1, arg_types[0]), arg_types[0])) + }, { + b.Assignment(result, b.i(0, arg_types[0])) + }), + b.Assignment(number, b.i_tDiv(number, b.i(2, arg_types[0]), arg_types[0])), + b.Assignment(total_bits, b.i_tSub(total_bits, b.i(1, arg_types[0]), arg_types[0])), + }), + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Leadz + +namespace Ishftc { + + static uint64_t cutoff_extra_bits(uint64_t num, uint32_t bits_size, uint32_t max_bits_size) { + if (bits_size == max_bits_size) { + return num; + } + return (num & ((1lu << bits_size) - 1lu)); + } + + static ASR::expr_t *eval_Ishftc(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& diag) { + uint64_t val = (uint64_t)ASR::down_cast(args[0])->m_n; + int64_t shift_signed = ASR::down_cast(args[1])->m_n; + int kind = ASRUtils::extract_kind_from_ttype_t(ASR::down_cast(args[0])->m_type); + bool negative_shift = (shift_signed < 0); + uint32_t shift = abs(shift_signed); + uint32_t bits_size = 8u * (uint32_t)kind; + uint32_t max_bits_size = 64; + if (bits_size < shift) { + append_error(diag, "The absolute value of SHIFT argument must be less than or equal to BIT_SIZE('I')", loc); + return nullptr; + } + val = cutoff_extra_bits(val, bits_size, max_bits_size); + uint64_t result; + if (negative_shift) { + result = (val >> shift) | cutoff_extra_bits(val << (bits_size - shift), bits_size, max_bits_size); + } else { + result = cutoff_extra_bits(val << shift, bits_size, max_bits_size) | ((val >> (bits_size - shift))); + } + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ishftc(Allocator & /*al*/, const Location & /*loc*/, + SymbolTable */*scope*/, Vec& /*arg_types*/, ASR::ttype_t */*return_type*/, + Vec& /*new_args*/, int64_t /*overload_id*/) { + // TO DO: Implement the runtime function for ISHFTC + throw LCompilersException("Runtime implementation for `ishftc` is not yet implemented."); + } + +} // namespace Ishftc + +namespace Hypot { + + static ASR::expr_t *eval_Hypot(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int kind = ASRUtils::extract_kind_from_ttype_t(t1); + if (kind == 4) { + float a = ASR::down_cast(args[0])->m_r; + float b = ASR::down_cast(args[1])->m_r; + return make_ConstantWithType(make_RealConstant_t, std::hypot(a, b), t1, loc); + } else { + double a = ASR::down_cast(args[0])->m_r; + double b = ASR::down_cast(args[1])->m_r; + return make_ConstantWithType(make_RealConstant_t, std::hypot(a, b), t1, loc); + } + } + + static inline ASR::expr_t* instantiate_Hypot(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_hypot_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, arg_types[0], ReturnVar); + /* + real function hypot_(x,y) result(hypot) + real :: x,y + hypot = sqrt(x*x + y*y) + end function + */ + body.push_back(al, b.Assignment(result, b.CallIntrinsic(scope, { + ASRUtils::expr_type(b.r_tAdd(b.r_tMul(args[0], args[0], arg_types[0]), b.r_tMul(args[1], args[1], arg_types[0]), arg_types[0])) + }, { + b.r_tAdd(b.r_tMul(args[0], args[0], arg_types[0]), b.r_tMul(args[1], args[1], arg_types[0]), arg_types[0]) + }, return_type, 0, Sqrt::instantiate_Sqrt))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Hypot + +namespace ToLowerCase { + + static ASR::expr_t *eval_ToLowerCase(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + + char* str = ASR::down_cast(args[0])->m_s; + std::transform(str, str + std::strlen(str), str, [](unsigned char c) { return std::tolower(c); }); + return make_ConstantWithType(make_StringConstant_t, str, t1, loc); + } + + static inline ASR::expr_t* instantiate_ToLowerCase(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("s", arg_types[0]); + ASR::ttype_t* char_type = ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, 0, nullptr)); + auto result = declare(fn_name, char_type, ReturnVar); + auto itr = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + + /* + function toLowerCase(str) result(result) + character(len=5) :: str + character(len=len(str)) :: result + integer :: i, ln + i = 1 + ln = len(str) + result = str + do while (i < ln) + if (result(i:i) >= 'A' .and. result(i:i) <= 'Z') then + result(i:i) = char(ichar(result(i:i)) + ichar('a') - ichar('A')) + end if + i = i + 1 + end do + print*, result + end function + */ + + body.push_back(al, b.Assignment(itr, b.i32(1))); + body.push_back(al, b.While(b.iLtE(itr, b.StringLen(args[0])), { + b.If(b.And(b.iGtE(ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, char_type, nullptr)), int32, nullptr)), b.Ichar("A", arg_types[0], int32)), + b.iLtE(ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, char_type, nullptr)), int32, nullptr)), b.Ichar("Z", arg_types[0], int32))), { + b.Assignment(result, b.StringConcat(result, ASRUtils::EXPR(ASR::make_StringChr_t(al, loc, + b.iSub(b.iAdd(ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, char_type, nullptr)), int32, nullptr)), b.Ichar("a", arg_types[0], int32)), + b.Ichar("A", arg_types[0], int32)), return_type, nullptr)), char_type)) + }, { + b.Assignment(result, b.StringConcat(result, ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, char_type, nullptr)), char_type)) + }), + b.Assignment(itr, b.i_tAdd(itr, b.i32(1), int32)), + })); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace ToLowerCase + +namespace SelectedIntKind { + + static ASR::expr_t *eval_SelectedIntKind(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t val = ASR::down_cast(args[0])->m_n; + ASRUtils::ASRBuilder b(al, loc); + int64_t result; + if (val <= 2) { + result = 1; + } else if (val <= 4) { + result = 2; + } else if (val <= 9) { + result = 4; + } else { + result = 8; + } + return b.i32(result); + } + + static inline ASR::expr_t* instantiate_SelectedIntKind(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, int32, ReturnVar); + auto number = declare("num", arg_types[0], Local); + body.push_back(al, b.Assignment(number, args[0])); + body.push_back(al, b.If(b.iLtE(number, b.i(2, arg_types[0])), { + b.Assignment(result, b.i(1, int32)) + }, { + b.If(b.iLtE(number, b.i(4, arg_types[0])), { + b.Assignment(result, b.i(2, int32)) + }, { + b.If(b.iLtE(number, b.i(9, arg_types[0])), { + b.Assignment(result, b.i(4, int32)) + }, { + b.Assignment(result, b.i(8, int32)) + }) + }) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace SelectedIntKind + +namespace SelectedRealKind { + + static inline ASR::expr_t *eval_SelectedRealKind(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t kind; + ASRUtils::ASRBuilder b(al, loc); + int64_t p = ASR::down_cast(args[0])->m_n; + int64_t r = ASR::down_cast(args[1])->m_n; + int64_t radix = ASR::down_cast(args[2])->m_n; + + if (p < 7 && r < 38 && radix == 2) { + kind = 4; + } else if (p < 16 && r < 308 && radix == 2) { + kind = 8; + } else if (radix != 2) { + kind = -5; + } else { + kind = -1; + } + return b.i32(kind); + } + + static inline ASR::expr_t* instantiate_SelectedRealKind(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("x", arg_types[0]); + fill_func_arg("y", arg_types[1]); + fill_func_arg("z", arg_types[2]); + auto result = declare(fn_name, int32, ReturnVar); + auto p = declare("p", arg_types[0], Local); + auto r = declare("r", arg_types[1], Local); + auto radix = declare("radix", arg_types[2], Local); + + body.push_back(al, b.Assignment(p, args[0])); + body.push_back(al, b.Assignment(r, args[1])); + body.push_back(al, b.Assignment(radix, args[2])); + body.push_back(al, b.If(b.And(b.And(b.iLt(p, b.i(7, arg_types[0])), b.iLt(r, b.i(38, arg_types[1]))), b.iEq(radix, b.i(2, arg_types[2]))), { + b.Assignment(result, b.i(4, int32)) + }, { + b.If( b.And(b.And(b.iLt(p, b.i(15, arg_types[0])), b.iLt(r, b.i(308, arg_types[1]))), b.iEq(radix, b.i(2, arg_types[2]))), { + b.Assignment(result, b.i(8, int32)) + }, { + b.If(b.iNotEq(radix, b.i(2, arg_types[2])), { + b.Assignment(result, b.i(-5, int32)) + }, { + b.Assignment(result, b.i(-1, int32)) + }) + }) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace SelectedRealKind + +namespace SelectedCharKind { + + static inline ASR::expr_t *eval_SelectedCharKind(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t kind; + ASRUtils::ASRBuilder b(al, loc); + char* name = ASR::down_cast(args[0])->m_s; + std::string lowercase_name = to_lower(name); + if (lowercase_name == "ascii" || lowercase_name == "default") { + kind = 1; + } else if (lowercase_name == "iso_10646") { + kind = 4; + } else { + kind = -1; + } + return b.i32(kind); + } + + static inline ASR::expr_t* instantiate_SelectedCharKind(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_selected_char_kind_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + + ASR::expr_t* func_call_lowercase = b.CallIntrinsic(scope, {arg_types[0]}, + {args[0]}, arg_types[0], 0, ToLowerCase::instantiate_ToLowerCase); + body.push_back(al, b.If(b.Or(b.sEq(func_call_lowercase, b.StringConstant("ascii", arg_types[0])), + b.sEq(func_call_lowercase, b.StringConstant("default", arg_types[0]))), { + b.Assignment(result, b.i(1, return_type)) + }, { + b.If(b.sEq(func_call_lowercase, b.StringConstant("iso_10646", arg_types[0])), { + b.Assignment(result, b.i(4, return_type)) + }, { + b.Assignment(result, b.i(-1, return_type)) + }) + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace SelectedCharKind + +namespace Kind { + + static ASR::expr_t *eval_Kind(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + int result = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(args[0])); + return make_ConstantWithType(make_IntegerConstant_t, result, int32, loc); + } + + static inline ASR::expr_t* instantiate_Kind(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_kind_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, int32, ReturnVar); + body.push_back(al, b.Assignment(result, b.i32(ASRUtils::extract_kind_from_ttype_t(arg_types[0])))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Kind + +namespace Rank { + + static ASR::expr_t *eval_Rank(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + ASRUtils::ASRBuilder b(al, loc); + return b.i32(extract_n_dims_from_ttype(expr_type(args[0]))); + } + +} // namespace Rank + +namespace Adjustl { + + static ASR::expr_t *eval_Adjustl(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* str = ASR::down_cast(args[0])->m_s; + size_t len = std::strlen(str); + size_t first_non_space = 0; + while (first_non_space < len && std::isspace(str[first_non_space])) { + first_non_space++; + } + std::string res(len, ' '); + char* result = s2c(al, res); + std::strncpy(result, str + first_non_space, len - first_non_space); + return make_ConstantWithType(make_StringConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Adjustl(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_adjustl_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, args[0], int32, nullptr)))); + auto result = declare("result", return_type, ReturnVar); + auto itr = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto tmp = declare("tmp", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + + /* + function adjustl_(s) result(r) + character(len=*), intent(in) :: s + character(len=len(s)) :: r + integer :: i, tmp + i = 1 + do while (i <= len(s)) + if (isspace(s(i:i))) then + i = i + 1 + else + exit + end if + end do + if i <= len(s) then + tmp = len(s) - i + 1 + r(1:tmp) = s(i:len(s)) + end if + end function + */ + + body.push_back(al, b.Assignment(itr, b.i32(1))); + body.push_back(al, b.While(b.iLtE(itr, b.StringLen(args[0])), { + b.If(b.iEq(ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, + ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr)), nullptr)), int32, nullptr)), + b.Ichar(" ", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, 1, nullptr)), int32)), { + b.Assignment(itr, b.i_tAdd(itr, b.i32(1), int32)) + }, { + b.Exit(nullptr) + }), + })); + + body.push_back(al, b.If(b.iLtE(itr, b.StringLen(args[0])), { + b.Assignment(tmp, b.iAdd(b.iSub(b.StringLen(args[0]), itr), b.i32(1))), + b.Assignment(b.StringSection(result, b.i32(0), tmp), b.StringSection(args[0], b.i_tSub(itr, b.i32(1), int32), b.StringLen(args[0]))) + }, {})); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, new_args[0].m_value, int32, nullptr)))); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace AdjustL + +namespace Adjustr { + + static ASR::expr_t *eval_Adjustr(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* str = ASR::down_cast(args[0])->m_s; + size_t len = std::strlen(str); + int last_non_space = len - 1; + while (last_non_space >= 0 && std::isspace(str[last_non_space])) { + last_non_space--; + } + std::string res(len, ' '); + char* result = s2c(al, res); + if (last_non_space != -1) { + int tmp = len - 1 - last_non_space; + for (int i = 0; i <= last_non_space; i++) { + result[i + tmp] = str[i]; + } + } + return make_ConstantWithType(make_StringConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Adjustr(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_adjustr_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, args[0], int32, nullptr)))); + auto result = declare("result", return_type, ReturnVar); + auto itr = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto tmp = declare("tmp", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + + /* + function adjustr_(s) result(r) + character(len=*), intent(in) :: s + character(len=len(s)) :: r + integer :: i, tmp + i = len(s) + do while (i >= 1) + if isspace(s(i:i)) then + i = i - 1 + else + exit + end if + end do + if i /= 0 then + tmp = len(s) - i + 1 + r(tmp:len(s)) = s(1:i) + end if + end function + */ + + body.push_back(al, b.Assignment(itr, b.StringLen(args[0]))); + body.push_back(al, b.While(b.iGtE(itr, b.i32(1)), { + b.If(b.iEq(ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, + ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr)), nullptr)), int32, nullptr)), + b.Ichar(" ", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, 1, nullptr)), int32)), { + b.Assignment(itr, b.i_tSub(itr, b.i32(1), int32)) + }, { + b.Exit(nullptr) + }), + })); + + body.push_back(al, b.If(b.iNotEq(itr, b.i32(0)), { + b.Assignment(tmp, b.iAdd(b.iSub(b.StringLen(args[0]), itr), b.i32(1))), + b.Assignment(b.StringSection(result, b.iSub(tmp, b.i32(1)), b.StringLen(args[0])), + b.StringSection(args[0], b.i32(0), itr)) + }, {})); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, new_args[0].m_value, int32, nullptr)))); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Adjustr + + +namespace Ichar { + + static ASR::expr_t *eval_Ichar(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* str = ASR::down_cast(args[0])->m_s; + char first_char = str[0]; + int result = (int)first_char; + return make_ConstantWithType(make_IntegerConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Ichar(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_ichar_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + auto result = declare("result", return_type, ReturnVar); + auto itr = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + body.push_back(al, b.Assignment(itr, b.i32(1))); + body.push_back(al, b.Assignment(result, b.i2i( + ASRUtils::EXPR(ASR::make_Ichar_t(al, loc, ASRUtils::EXPR(ASR::make_StringItem_t(al, loc, args[0], itr, + ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr)), nullptr)), int32, nullptr)), + return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Ichar + +namespace Char { + + static ASR::expr_t *eval_Char(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + int64_t i = ASR::down_cast(args[0])->m_n; + char str = i; + std::string svalue; + svalue += str; + Str s; + s.from_str_view(svalue); + char *result = s.c_str(al); + return make_ConstantWithType(make_StringConstant_t, result, t1, loc); + } + + static inline ASR::expr_t* instantiate_Char(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables(""); + fill_func_arg("i", arg_types[0]); + auto result = declare("result", return_type, ReturnVar); + + body.push_back(al, b.Assignment(result, ASRUtils::EXPR(ASR::make_StringChr_t(al, loc, b.i2i(args[0], int32), return_type, nullptr)))); + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Char + +namespace Digits { + + static ASR::expr_t *eval_Digits(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& diag) { + ASR::ttype_t *type1 = ASRUtils::expr_type(args[0]); + int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(args[0])); + if (is_integer(*type1)) { + if (kind == 4) { + return make_ConstantWithType(make_IntegerConstant_t, 31, int32, loc); + } else if (kind == 8) { + return make_ConstantWithType(make_IntegerConstant_t, 63, int32, loc); + } else { + append_error(diag, "Kind "+ std::to_string(kind) + " not supported for type Integer", loc); + } + } else if (is_real(*type1)) { + if (kind == 4) { + return make_ConstantWithType(make_IntegerConstant_t, 24, int32, loc); + } else if (kind == 8) { + return make_ConstantWithType(make_IntegerConstant_t, 53, int32, loc); + } else { + append_error(diag, "Kind "+ std::to_string(kind) + " not supported for type Real", loc); + } + } else { + append_error(diag, "Argument to `digits` intrinsic must be real or integer", loc); + } + return nullptr; + } + + static inline ASR::expr_t* instantiate_Digits(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_digits_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, int32, ReturnVar); + int kind = ASRUtils::extract_kind_from_ttype_t(arg_types[0]); + if (is_integer(*arg_types[0])) { + if (kind == 4) { + body.push_back(al, b.Assignment(result, b.i32(31))); + } else if (kind == 8) { + body.push_back(al, b.Assignment(result, b.i32(63))); + } + } else if (is_real(*arg_types[0])) { + if (kind == 4) { + body.push_back(al, b.Assignment(result, b.i32(24))); + } else if (kind == 8) { + body.push_back(al, b.Assignment(result, b.i32(53))); + } + } + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Digits + +namespace Rrspacing { + + static ASR::expr_t *eval_Rrspacing(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + int kind = ASRUtils::extract_kind_from_ttype_t(ASRUtils::expr_type(args[0])); + double digits = 0.0; + double fraction = 0.0; + digits = (kind == 4) ? 24.00 : 53.00; + if (kind == 4) { + float x = ASR::down_cast(args[0])->m_r; + int32_t exponent; + if (x == 0.0) { + exponent = 0; + fraction = x * std::pow((2), (-1*(exponent))); + } + else{ + int32_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 23) & 0xff) - 126; + fraction = x * std::pow((2), (-1*(exponent))); + } + } + else if (kind == 8) { + double x = ASR::down_cast(args[0])->m_r; + int64_t exponent; + if (x == 0.0) { + exponent = 0; + fraction = x * std::pow((2), (-1*(exponent))); + } + else{ + int64_t ix; + std::memcpy(&ix, &x, sizeof(ix)); + exponent = ((ix >> 52) & 0x7ff) - 1022; + fraction = x * std::pow((2), (-1*(exponent))); + } + } + fraction = std::abs(fraction); + double radix = 2.00; + double result = fraction * std::pow(radix, digits); + return make_ConstantWithType(make_RealConstant_t, result, arg_type, loc); + + } + + static inline ASR::expr_t* instantiate_Rrspacing(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_rrspacing_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, return_type, ReturnVar); + /* + * r = rrspacing(X) + * r = abs(fraction(X)) * (radix(X)**digits(X)) + */ + body.push_back(al, b.Assignment(result, b.r_tMul(b.CallIntrinsic(scope, {arg_types[0]}, { + b.CallIntrinsic(scope, {arg_types[0]}, {args[0]}, return_type, 0, Fraction::instantiate_Fraction)}, + return_type, 0, Abs::instantiate_Abs), b.rPow(b.i2r(b.i32(2),return_type), + b.i2r(b.CallIntrinsic(scope, {arg_types[0]}, {args[0]}, int32, 0, Digits::instantiate_Digits), + return_type), return_type), return_type))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + + } + +} // namespace Rrspacing + +namespace Repeat { + + static ASR::expr_t *eval_Repeat(Allocator &al, const Location &loc, + ASR::ttype_t* t1, Vec &args, diag::Diagnostics& /*diag*/) { + char* str = ASR::down_cast(args[0])->m_s; + int64_t n = ASR::down_cast(args[1])->m_n; + size_t len = std::strlen(str); + size_t new_len = len*n; + char* result = new char[new_len+1]; + for (size_t i=0; i& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + auto func_name = "_lcompilers_optimization_repeat_" + type_to_str_python(arg_types[0]) + + type_to_str_python(arg_types[1]); + declare_basic_variables(func_name); + if (scope->get_symbol(func_name)) { + ASR::symbol_t *s = scope->get_symbol(func_name); + return b.Call(s, new_args, return_type, nullptr); + } + fill_func_arg("x", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -10, nullptr))); + fill_func_arg("y", arg_types[1]); + auto result = declare(fn_name, ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -3, + ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, + ASRUtils::EXPR(ASR::make_StringLen_t(al, loc, args[0], ASRUtils::expr_type(args[1]), nullptr)), + ASR::binopType::Mul, args[1], ASRUtils::expr_type(args[1]), nullptr)))), ReturnVar); + auto i = declare("i", int32, Local); + auto j = declare("j", int32, Local); + auto m = declare("m", int32, Local); + auto cnt = declare("cnt", int32, Local); + /* + function repeat_(s, n) result(r) + character(len=*), intent(in) :: s + integer, intent(in) :: n + character(len=n*len(s)) :: r + integer :: i, j, m, cnt + m = len(s) + i = 1 + j = m + cnt = 0 + do while (cnt < n) + r(i:j) = s(1:len(s)) + i = j + 1 + j = i + m - 1 + cnt = cnt + 1 + end do + end function + */ + + body.push_back(al, b.Assignment(m, b.StringLen(args[0]))); + body.push_back(al, b.Assignment(i, b.i32(1))); + body.push_back(al, b.Assignment(j, m)); + body.push_back(al, b.Assignment(cnt, b.i32(0))); + body.push_back(al, b.While(b.iLt(cnt, CastingUtil::perform_casting(args[1], int32, al, loc)), { + b.Assignment(b.StringSection(result, b.iSub(i, b.i32(1)), j), + b.StringSection(args[0], b.i32(0), b.StringLen(args[0]))), + b.Assignment(i, b.iAdd(j, b.i32(1))), + b.Assignment(j, b.iSub(b.iAdd(i, m), b.i32(1))), + b.Assignment(cnt, b.iAdd(cnt, b.i32(1))), + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Repeat + +namespace StringContainsSet { + + static ASR::expr_t *eval_StringContainsSet(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + char* string = ASR::down_cast(args[0])->m_s; + char* set = ASR::down_cast(args[1])->m_s; + bool back = ASR::down_cast(args[2])->m_value; + int64_t kind = ASR::down_cast(args[3])->m_n; + size_t len = std::strlen(string); + int64_t result = 0; + if (back) { + for (size_t i=0; i& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_verify_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("set", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("back", ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))); + fill_func_arg("kind", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4))); + auto result = declare(fn_name, return_type, ReturnVar); + auto matched = declare("matched", arg_types[2], Local); + auto i = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto j = declare("j", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + /* + function StringContainsSet_(string, set, back, kind) result(result) + character(len=*) :: string + character(len=*) :: set + logical, optional :: back + integer(kind) :: result = 0 + integer :: i, j + logical :: matched + if (back) then + i = len(string) + do while (i >= 1) + matched = .false. + j = 1 + do while (j <= len(set)) + if (string(i:i) == set(j:j)) then + matched = .true. + end if + j = j + 1 + end do + if (.not. matched) then + result = i + exit + end if + i = i - 1 + end do + else + i = 1 + do while (i <= len(string)) + matched = .false. + j = 1 + do while (j <= len(set)) + if (string(i:i) == set(j:j)) then + matched = .true. + end if + j = j + 1 + end do + if (.not. matched) then + result = i + exit + end if + i = i + 1 + end do + end if + end function + */ + body.push_back(al, b.Assignment(result, b.i(0, return_type))); + body.push_back(al, b.If(b.boolEq(args[2], b.bool32(1)), { + b.Assignment(i, b.StringLen(args[0])), + b.While(b.iGtE(i, b.i(1, return_type)), { + b.Assignment(matched, b.bool32(0)), + b.Assignment(j, b.i(1, return_type)), + b.While(b.iLtE(j, b.StringLen(args[1])), { + b.If(b.sEq(b.StringSection(args[0], b.i_tSub(i, b.i(1, return_type), return_type), i), + b.StringSection(args[1], b.i_tSub(j, b.i(1, return_type), return_type), j)), { + b.Assignment(matched, b.bool32(1)) + }, {}), + b.Assignment(j, b.i_tAdd(j, b.i(1, return_type), return_type)), + }), + b.If(b.boolEq(matched, b.bool32(0)), { + b.Assignment(result, i), + b.Exit(nullptr) + }, {}), + b.Assignment(i, b.i_tSub(i, b.i(1, return_type), return_type)), + }), + }, { + b.Assignment(i, b.i(1, return_type)), + b.While(b.iLtE(i, b.StringLen(args[0])), { + b.Assignment(matched, b.bool32(0)), + b.Assignment(j, b.i(1, return_type)), + b.While(b.iLtE(j, b.StringLen(args[1])), { + b.If(b.sEq(b.StringSection(args[0], b.i_tSub(i, b.i(1, return_type), return_type), i), + b.StringSection(args[1], b.i_tSub(j, b.i(1, return_type), return_type), j)), { + b.Assignment(matched, b.bool32(1)) + }, {}), + b.Assignment(j, b.i_tAdd(j, b.i(1, return_type), return_type)), + }), + b.If(b.boolEq(matched, b.bool32(0)), { + b.Assignment(result, i), + b.Exit(nullptr) + }, {}), + b.Assignment(i, b.i_tAdd(i, b.i(1, return_type), return_type)) + }), + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace StringContainsSet + +namespace StringFindSet { + + static ASR::expr_t *eval_StringFindSet(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + char* string = ASR::down_cast(args[0])->m_s; + char* set = ASR::down_cast(args[1])->m_s; + bool back = ASR::down_cast(args[2])->m_value; + int64_t kind = ASR::down_cast(args[3])->m_n; + size_t len = std::strlen(string); + int64_t result = 0; + if (back) { + for (size_t i=0; i& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_scan_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("set", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("back", ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))); + fill_func_arg("kind", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4))); + auto result = declare(fn_name, return_type, ReturnVar); + auto i = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto j = declare("j", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + /* + function StringFindSet_(string, set, back, kind) result(r) + character(len=*) :: string + character(len=*) :: set + logical, optional :: back + integer(kind) :: r = 0 + integer :: i, j + if (back) then + i = len(string) + do while (i >= 1) + j = 1 + do while (j <= len(set)) + if (string(i:i) == set(j:j)) then + r = i + exit + end if + j = j + 1 + end do + if (r /= 0) exit + i = i - 1 + end do + else + i = 1 + do while (i <= len(string)) + j = 1 + do while (j <= len(set)) + if (string(i:i) == set(j:j)) then + r = i + exit + end if + j = j + 1 + end do + if (r /= 0) exit + i = i + 1 + end do + end if + end function + */ + + body.push_back(al, b.Assignment(result, b.i(0, return_type))); + body.push_back(al, b.If(b.boolEq(args[2], b.bool32(1)), { + b.Assignment(i, b.StringLen(args[0])), + b.While(b.iGtE(i, b.i(1, return_type)), { + b.Assignment(j, b.i(1, return_type)), + b.While(b.iLtE(j, b.StringLen(args[1])), { + b.If(b.sEq(b.StringSection(args[0], b.i_tSub(i, b.i(1, return_type), return_type), i), + b.StringSection(args[1], b.i_tSub(j, b.i(1, return_type), return_type), j)), { + b.Assignment(result, i), + b.Exit(nullptr) + }, {}), + b.Assignment(j, b.i_tAdd(j, b.i(1, return_type), return_type)), + }), + b.If(b.iNotEq(result, b.i(0, return_type)), { + b.Exit(nullptr) + }, {}), + b.Assignment(i, b.i_tSub(i, b.i(1, return_type), return_type)) + }), + }, { + b.Assignment(i, b.i(1, return_type)), + b.While(b.iLtE(i, b.StringLen(args[0])), { + b.Assignment(j, b.i(1, return_type)), + b.While(b.iLtE(j, b.StringLen(args[1])), { + b.If(b.sEq(b.StringSection(args[0], b.i_tSub(i, b.i(1, return_type), return_type), i), + b.StringSection(args[1], b.i_tSub(j, b.i(1, return_type), return_type), j)), { + b.Assignment(result, i), + b.Exit(nullptr) + }, {}), + b.Assignment(j, b.i_tAdd(j, b.i(1, return_type), return_type)), + }), + b.If(b.iNotEq(result, b.i(0, return_type)), { + b.Exit(nullptr) + }, {}), + b.Assignment(i, b.i_tAdd(i, b.i(1, return_type), return_type)) + }), + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace StringFindSet + +namespace SubstrIndex { + + static ASR::expr_t *eval_SubstrIndex(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + char* string = ASR::down_cast(args[0])->m_s; + char* substring = ASR::down_cast(args[1])->m_s; + bool back = ASR::down_cast(args[2])->m_value; + int64_t kind = ASR::down_cast(args[3])->m_n; + size_t len = std::strlen(string); + int64_t result = 0; + if (back) { + for (size_t i=0; i& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_index_" + type_to_str_python(arg_types[0])); + fill_func_arg("str", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("substr", ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + fill_func_arg("back", ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4))); + fill_func_arg("kind", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4))); + auto idx = declare(fn_name, return_type, ReturnVar); + auto found = declare("found", arg_types[2], Local); + auto i = declare("i", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto j = declare("j", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto k = declare("k", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + auto pos = declare("pos", ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)), Local); + + /* + function SubstrIndex_(string, substring, back, kind) result(r) + character(len=*) :: string + character(len=*) :: substring + logical, optional :: back + integer(kind) :: idx = 0 + integer :: i, j, k, pos, len_str, len_sub, idx + logical :: found = .true. + i = 1 + len_str = len(string) + len_sub = len(substring) + + if (len_str < len_sub) then + found = .false. + end if + + do while (i < len_str .and. found) + k = 0 + j = 1 + do while (j <= len_sub .and. found) + pos = i + k + if( string(pos:pos) /= substring(j:j) ) then + found = .false. + end if + k = k + 1 + j = j + 1 + end do + if (found) then + idx = i + if (back .eqv. .true.) then + found = .true. + else + found = .false. + end if + else + found = .true. + end if + i = i + 1 + end do + end function + */ + body.push_back(al, b.Assignment(idx, b.i(0, return_type))); + body.push_back(al, b.Assignment(i, b.i(1, return_type))); + body.push_back(al, b.Assignment(found, b.bool32(1))); + body.push_back(al, b.If(b.iLt(b.StringLen(args[0]), b.StringLen(args[1])), { + b.Assignment(found, b.bool32(0)) + }, {})); + + body.push_back(al, b.While(b.And(b.iLt(i, b.StringLen(args[0])), b.boolEq(found, b.bool32(1))), { + b.Assignment(k, b.i(0, return_type)), + b.Assignment(j, b.i(1, return_type)), + b.While(b.And(b.iLtE(j, b.StringLen(args[1])), b.boolEq(found, b.bool32(1))), { + b.Assignment(pos, b.i_tAdd(i, k, return_type)), + b.If(b.sNotEq( + b.StringSection(args[0], b.i_tSub(pos, b.i(1, return_type), return_type), pos), + b.StringSection(args[1], b.i_tSub(j, b.i(1, return_type), return_type), j)), { + b.Assignment(found, b.bool32(0)) + }, {}), + b.Assignment(j, b.i_tAdd(j, b.i(1, return_type), return_type)), + b.Assignment(k, b.i_tAdd(k, b.i(1, return_type), return_type)), + }), + b.If(b.boolEq(found, b.bool32(1)), { + b.Assignment(idx, i), + b.Assignment(found, args[2]) + }, { + b.Assignment(found, b.bool32(1)) + }), + b.Assignment(i, b.i_tAdd(i, b.i(1, return_type), return_type)), + })); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, idx, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace SubstrIndex + +namespace MinExponent { + + static ASR::expr_t *eval_MinExponent(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + ASR::RealConstant_t* a = ASR::down_cast(args[0]); + int m_kind = ASRUtils::extract_kind_from_ttype_t(a->m_type); + int result; + if (m_kind == 4) { + result = std::numeric_limits::min_exponent; + } else { + result = std::numeric_limits::min_exponent; + } + return make_ConstantWithType(make_IntegerConstant_t, result, int32, loc); + + } + + static inline ASR::expr_t* instantiate_MinExponent(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_minexponent_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, int32, ReturnVar); + + int m_kind = ASRUtils::extract_kind_from_ttype_t(arg_types[0]); + if (m_kind == 4) { + body.push_back(al, b.Assignment(result, b.i32(-125))); + } else { + body.push_back(al, b.Assignment(result, b.i32(-1021))); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace MinExponent + +namespace MaxExponent { + + static ASR::expr_t *eval_MaxExponent(Allocator &al, const Location &loc, + ASR::ttype_t* /*t1*/, Vec &args, diag::Diagnostics& /*diag*/) { + ASR::RealConstant_t* a = ASR::down_cast(args[0]); + int m_kind = ASRUtils::extract_kind_from_ttype_t(a->m_type); + int result; + if (m_kind == 4) { + result = std::numeric_limits::max_exponent; + } else { + result = std::numeric_limits::max_exponent; + } + return make_ConstantWithType(make_IntegerConstant_t, result, int32, loc); + + } + + static inline ASR::expr_t* instantiate_MaxExponent(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_optimization_maxexponent_" + type_to_str_python(arg_types[0])); + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, int32, ReturnVar); + + int m_kind = ASRUtils::extract_kind_from_ttype_t(arg_types[0]); + if (m_kind == 4) { + body.push_back(al, b.Assignment(result, b.i32(128))); + } else { + body.push_back(al, b.Assignment(result, b.i32(1024))); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace MaxExponent + +#define create_exp_macro(X, stdeval) \ +namespace X { \ + static inline ASR::expr_t* eval_##X(Allocator &al, const Location &loc, \ + ASR::ttype_t *t, Vec &args, diag::Diagnostics& /*diag*/) { \ + LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); \ + double rv = -1; \ + if( ASRUtils::extract_value(args[0], rv) ) { \ + double val = std::stdeval(rv); \ + return ASRUtils::EXPR(ASR::make_RealConstant_t(al, loc, val, t)); \ + } \ + return nullptr; \ + } \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) { \ + if (args.size() != 1) { \ + append_error(diag, "Intrinsic function `"#X"` accepts exactly 1 argument", \ + loc); \ + return nullptr; \ + } \ + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); \ + if (!ASRUtils::is_real(*type)) { \ + append_error(diag, "Argument of the `"#X"` function must be either Real", \ + args[0]->base.loc); \ + return nullptr; \ + } \ + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ + static_cast(IntrinsicElementalFunctions::X), 0, type, diag); \ + } \ +} // namespace X + +create_exp_macro(Exp2, exp2) +create_exp_macro(Expm1, expm1) + +namespace Exp { + + static inline ASR::expr_t* eval_Exp(Allocator &al, const Location &loc, + ASR::ttype_t *t, Vec &args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); + double rv = -1; + if( ASRUtils::extract_value(args[0], rv) ) { + double val = std::exp(rv); + return ASRUtils::EXPR(ASR::make_RealConstant_t(al, loc, val, t)); + } else { + std::complex crv; + if( ASRUtils::extract_value(args[0], crv) ) { + std::complex val = std::exp(crv); + return ASRUtils::EXPR(ASR::make_ComplexConstant_t( + al, loc, val.real(), val.imag(), t)); + } + } + return nullptr; + } + + static inline ASR::asr_t* create_Exp(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "Intrinsic function `exp` accepts exactly 1 argument", loc); + return nullptr; + } + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); + if (!ASRUtils::is_real(*type) && !is_complex(*type)) { + append_error(diag, "Argument of the `exp` function must be either Real or Complex", + args[0]->base.loc); + return nullptr; + } + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, + eval_Exp, static_cast(IntrinsicElementalFunctions::Exp), + 0, type, diag); + } + + static inline ASR::expr_t* instantiate_Exp(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t overload_id) { + if (is_real(*arg_types[0])) { + Vec args; args.reserve(al, 1); + args.push_back(al, new_args[0].m_value); + return EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::Exp), + args.p, 1, overload_id, return_type, nullptr)); + } else { + return UnaryIntrinsicFunction::instantiate_functions(al, loc, scope, + "exp", arg_types[0], return_type, new_args, overload_id); + } + } + +} // namespace Exp + +namespace ListIndex { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args <= 4, "Call to list.index must have at most four arguments", + x.base.base.loc, diagnostics); + ASR::ttype_t* arg0_type = ASRUtils::type_get_past_const(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl(ASR::is_a(*arg0_type) && + ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), ASRUtils::get_contained_type(arg0_type)), + "First argument to list.index must be of list type and " + "second argument must be of same type as list elemental type", + x.base.base.loc, diagnostics); + if(x.n_args >= 3) { + ASRUtils::require_impl( + ASR::is_a(*ASRUtils::expr_type(x.m_args[2])), + "Third argument to list.index must be an integer", + x.base.base.loc, diagnostics); + } + if(x.n_args == 4) { + ASRUtils::require_impl( + ASR::is_a(*ASRUtils::expr_type(x.m_args[3])), + "Fourth argument to list.index must be an integer", + x.base.base.loc, diagnostics); + } + ASRUtils::require_impl(ASR::is_a(*x.m_type), + "Return type of list.index must be an integer", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_list_index(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for ListConstant expression + return nullptr; +} + + +static inline ASR::asr_t* create_ListIndex(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + int64_t overload_id = 0; + ASR::expr_t* list_expr = args[0]; + ASR::ttype_t *type = ASRUtils::expr_type(list_expr); + ASR::ttype_t *list_type = ASR::down_cast(ASRUtils::type_get_past_const(type))->m_type; + ASR::ttype_t *ele_type = ASRUtils::expr_type(args[1]); + if (!ASRUtils::check_equal_type(ele_type, list_type)) { + std::string fnd = ASRUtils::get_type_code(ele_type); + std::string org = ASRUtils::get_type_code(list_type); + append_error(diag, + "Type mismatch in 'index', the types must be compatible " + "(found: '" + fnd + "', expected: '" + org + "')", loc); + return nullptr; + } + if (args.size() >= 3) { + overload_id = 1; + if(!ASR::is_a(*ASRUtils::expr_type(args[2]))) { + append_error(diag, "Third argument to list.index must be an integer", loc); + return nullptr; + } + } + if (args.size() == 4) { + overload_id = 2; + if(!ASR::is_a(*ASRUtils::expr_type(args[3]))) { + append_error(diag, "Fourth argument to list.index must be an integer", loc); + return nullptr; + } + } + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::ttype_t *to_type = int32; + ASR::expr_t* compile_time_value = eval_list_index(al, loc, to_type, arg_values, diag); + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::ListIndex), + args.p, args.size(), overload_id, to_type, compile_time_value); +} + +} // namespace ListIndex + +namespace ListReverse { + +static inline ASR::expr_t *eval_ListReverse(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for ListConstant expression + return nullptr; +} + +} // namespace ListReverse + +namespace ListPop { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args <= 2, "Call to list.pop must have at most one argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "Argument to list.pop must be of list type", + x.base.base.loc, diagnostics); + switch(x.m_overload_id) { + case 0: + break; + case 1: + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[1])), + "Argument to list.pop must be an integer", + x.base.base.loc, diagnostics); + break; + } + ASRUtils::require_impl(ASRUtils::check_equal_type(x.m_type, + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), + "Return type of list.pop must be of same type as list's element type", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_list_pop(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t */*t*/, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for ListConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_ListPop(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() > 2) { + append_error(diag, "Call to list.pop must have at most one argument", loc); + return nullptr; + } + if (args.size() == 2 && + !ASR::is_a(*ASRUtils::expr_type(args[1]))) { + append_error(diag, "Argument to list.pop must be an integer", loc); + return nullptr; + } + + ASR::expr_t* list_expr = args[0]; + ASR::ttype_t *type = ASRUtils::expr_type(list_expr); + ASR::ttype_t *list_type = ASR::down_cast(type)->m_type; + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::ttype_t *to_type = list_type; + ASR::expr_t* compile_time_value = eval_list_pop(al, loc, to_type, arg_values, diag); + int64_t overload_id = (args.size() == 2); + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::ListPop), + args.p, args.size(), overload_id, to_type, compile_time_value); +} + +} // namespace ListPop + +namespace ListReserve { + +static inline ASR::expr_t *eval_ListReserve(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for ListConstant expression + return nullptr; +} + +} // namespace ListReserve + +namespace DictKeys { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 1, "Call to dict.keys must have no argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "Argument to dict.keys must be of dict type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*x.m_type) && + ASRUtils::check_equal_type(ASRUtils::get_contained_type(x.m_type), + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]), 0)), + "Return type of dict.keys must be of list of dict key element type", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_dict_keys(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for DictConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_DictKeys(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "Call to dict.keys must have no argument", loc); + return nullptr; + } + + ASR::expr_t* dict_expr = args[0]; + ASR::ttype_t *type = ASRUtils::expr_type(dict_expr); + ASR::ttype_t *dict_keys_type = ASR::down_cast(type)->m_key_type; + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::ttype_t *to_type = List(dict_keys_type); + ASR::expr_t* compile_time_value = eval_dict_keys(al, loc, to_type, arg_values, diag); + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::DictKeys), + args.p, args.size(), 0, to_type, compile_time_value); +} + +} // namespace DictKeys + +namespace DictValues { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 1, "Call to dict.values must have no argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "Argument to dict.values must be of dict type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*x.m_type) && + ASRUtils::check_equal_type(ASRUtils::get_contained_type(x.m_type), + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]), 1)), + "Return type of dict.values must be of list of dict value element type", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_dict_values(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for DictConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_DictValues(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "Call to dict.values must have no argument", loc); + return nullptr; + } + + ASR::expr_t* dict_expr = args[0]; + ASR::ttype_t *type = ASRUtils::expr_type(dict_expr); + ASR::ttype_t *dict_values_type = ASR::down_cast(type)->m_value_type; + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::ttype_t *to_type = List(dict_values_type); + ASR::expr_t* compile_time_value = eval_dict_values(al, loc, to_type, arg_values, diag); + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::DictValues), + args.p, args.size(), 0, to_type, compile_time_value); +} + +} // namespace DictValues + +namespace SetAdd { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 2, "Call to set.add must have exactly one argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "First argument to set.add must be of set type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), + "Second argument to set.add must be of same type as set's element type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(x.m_type == nullptr, + "Return type of set.add must be empty", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_set_add(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for SetConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_SetAdd(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 2) { + append_error(diag, "Call to set.add must have exactly one argument", loc); + return nullptr; + } + if (!ASRUtils::check_equal_type(ASRUtils::expr_type(args[1]), + ASRUtils::get_contained_type(ASRUtils::expr_type(args[0])))) { + append_error(diag, "Argument to set.add must be of same type as set's " + "element type", loc); + return nullptr; + } + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::expr_t* compile_time_value = eval_set_add(al, loc, nullptr, arg_values, diag); + return ASR::make_Expr_t(al, loc, + ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::SetAdd), + args.p, args.size(), 0, nullptr, compile_time_value))); +} + +} // namespace SetAdd + +namespace SetRemove { + +static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 2, "Call to set.remove must have exactly one argument", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*ASRUtils::expr_type(x.m_args[0])), + "First argument to set.remove must be of set type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASRUtils::check_equal_type(ASRUtils::expr_type(x.m_args[1]), + ASRUtils::get_contained_type(ASRUtils::expr_type(x.m_args[0]))), + "Second argument to set.remove must be of same type as set's element type", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(x.m_type == nullptr, + "Return type of set.remove must be empty", + x.base.base.loc, diagnostics); +} + +static inline ASR::expr_t *eval_set_remove(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO: To be implemented for SetConstant expression + return nullptr; +} + +static inline ASR::asr_t* create_SetRemove(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 2) { + append_error(diag, "Call to set.remove must have exactly one argument", loc); + return nullptr; + } + if (!ASRUtils::check_equal_type(ASRUtils::expr_type(args[1]), + ASRUtils::get_contained_type(ASRUtils::expr_type(args[0])))) { + append_error(diag, "Argument to set.remove must be of same type as set's " + "element type", loc); + return nullptr; + } + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + ASR::expr_t* compile_time_value = eval_set_remove(al, loc, nullptr, arg_values, diag); + return ASR::make_Expr_t(al, loc, + ASRUtils::EXPR(ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::SetRemove), + args.p, args.size(), 0, nullptr, compile_time_value))); +} + +} // namespace SetRemove + +namespace Max { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args > 1, "Call to max0 must have at least two arguments", + x.base.base.loc, diagnostics); + ASR::ttype_t* arg0_type = ASRUtils::type_get_past_array(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl(ASR::is_a(*arg0_type) || + ASR::is_a(*arg0_type) || ASR::is_a(*arg0_type), + "Arguments to max0 must be of real, integer or character type", + x.base.base.loc, diagnostics); + for(size_t i=0;i(*ASRUtils::expr_type(x.m_args[i])) && + ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))) || + (ASR::is_a(*ASRUtils::expr_type(x.m_args[i])) && + ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))) || + (ASR::is_a(*ASRUtils::expr_type(x.m_args[i])) && + ASR::is_a(*ASRUtils::expr_type(x.m_args[0]))), + "All arguments must be of the same type", + x.base.base.loc, diagnostics); + } + } + + static ASR::expr_t *eval_Max(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); + if (ASR::is_a(*arg_type)) { + double max_val = ASR::down_cast(args[0])->m_r; + for (size_t i = 1; i < args.size(); i++) { + double val = ASR::down_cast(args[i])->m_r; + max_val = std::fmax(max_val, val); + } + return ASR::down_cast(ASR::make_RealConstant_t(al, loc, max_val, arg_type)); + } else if (ASR::is_a(*arg_type)) { + int64_t max_val = ASR::down_cast(args[0])->m_n; + for (size_t i = 1; i < args.size(); i++) { + int64_t val = ASR::down_cast(args[i])->m_n; + max_val = std::fmax(max_val, val); + } + return ASR::down_cast(ASR::make_IntegerConstant_t(al, loc, max_val, arg_type)); + } else if (ASR::is_a(*arg_type)) { + char* max_val = ASR::down_cast(args[0])->m_s; + for (size_t i = 1; i < args.size(); i++) { + char* val = ASR::down_cast(args[i])->m_s; + if (strcmp(val, max_val) > 0) { + max_val = val; + } + } + return ASR::down_cast(ASR::make_StringConstant_t(al, loc, max_val, arg_type)); + } else { + return nullptr; + } + } + + static inline ASR::asr_t* create_Max( + Allocator& al, const Location& loc, Vec& args, + diag::Diagnostics& diag) { + bool is_compile_time = true; + for(size_t i=0; i<100;i++){ + args.erase(nullptr); + } + if (args.size() < 2) { + append_error(diag, "Intrinsic max0 must have 2 arguments", loc); + return nullptr; + } + ASR::ttype_t *arg_type = ASRUtils::expr_type(args[0]); + for(size_t i=0;i arg_values; + arg_values.reserve(al, args.size()); + ASR::expr_t *arg_value; + for(size_t i=0;i(IntrinsicElementalFunctions::Max), + args.p, args.n, 0, ASRUtils::expr_type(args[0]), value); + } else { + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::Max), + args.p, args.n, 0, ASRUtils::expr_type(args[0]), nullptr); + } + } + + static inline ASR::expr_t* instantiate_Max(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_max0_" + type_to_str_python(arg_types[0])); + int64_t kind = extract_kind_from_ttype_t(arg_types[0]); + if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + } + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, args[0], int32, nullptr)))); + } else if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Real_t(al, loc, kind))); + } + } else if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Integer_t(al, loc, kind))); + } + } else { + throw LCompilersException("Arguments to max0 must be of real, integer or character type"); + } + + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, args[0])); + if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.iGt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + } else if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.fGt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + } else if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.sGt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, new_args[0].m_value, int32, nullptr)))); + } else { + throw LCompilersException("Arguments to max0 must be of real, integer or character type"); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Max + +namespace Min { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args > 1, "Call to min0 must have at least two arguments", + x.base.base.loc, diagnostics); + ASR::ttype_t* arg0_type = ASRUtils::type_get_past_array(ASRUtils::expr_type(x.m_args[0])); + ASRUtils::require_impl(ASR::is_a(*arg0_type) || + ASR::is_a(*arg0_type) || ASR::is_a(*arg0_type), + "Arguments to min0 must be of real, integer or character type", + x.base.base.loc, diagnostics); + for(size_t i=0;i(*arg_type) && ASR::is_a(*arg0_type)) || + (ASR::is_a(*arg_type) && ASR::is_a(*arg0_type)) || + (ASR::is_a(*arg_type) && ASR::is_a(*arg0_type) ), + "All arguments must be of the same type", + x.base.base.loc, diagnostics); + } + } + + static ASR::expr_t *eval_Min(Allocator &al, const Location &loc, + ASR::ttype_t *arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + LCOMPILERS_ASSERT(ASRUtils::all_args_evaluated(args)); + if (ASR::is_a(*arg_type)) { + double min_val = ASR::down_cast(args[0])->m_r; + for (size_t i = 1; i < args.size(); i++) { + double val = ASR::down_cast(args[i])->m_r; + min_val = std::fmin(min_val, val); + } + return ASR::down_cast(ASR::make_RealConstant_t(al, loc, min_val, arg_type)); + } else if (ASR::is_a(*arg_type)) { + int64_t min_val = ASR::down_cast(args[0])->m_n; + for (size_t i = 1; i < args.size(); i++) { + int64_t val = ASR::down_cast(args[i])->m_n; + min_val = std::fmin(min_val, val); + } + return ASR::down_cast(ASR::make_IntegerConstant_t(al, loc, min_val, arg_type)); + } else if (ASR::is_a(*arg_type)) { + char* min_val = ASR::down_cast(args[0])->m_s; + for (size_t i = 1; i < args.size(); i++) { + char* val = ASR::down_cast(args[i])->m_s; + if (strcmp(val, min_val) < 0) { + min_val = val; + } + } + return ASR::down_cast(ASR::make_StringConstant_t(al, loc, min_val, arg_type)); + } else { + return nullptr; + } + } + + static inline ASR::asr_t* create_Min( + Allocator& al, const Location& loc, Vec& args, + diag::Diagnostics& diag) { + bool is_compile_time = true; + for(size_t i=0; i<100;i++){ + args.erase(nullptr); + } + if (args.size() < 2) { + append_error(diag, "Intrinsic min0 must have 2 arguments", loc); + return nullptr; + } + ASR::ttype_t *arg_type = ASRUtils::expr_type(args[0]); + for(size_t i=0;i arg_values; + arg_values.reserve(al, args.size()); + ASR::expr_t *arg_value; + for(size_t i=0;i(IntrinsicElementalFunctions::Min), + args.p, args.n, 0, ASRUtils::expr_type(args[0]), value); + } else { + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::Min), + args.p, args.n, 0, ASRUtils::expr_type(args[0]), nullptr); + } + } + + static inline ASR::expr_t* instantiate_Min(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + declare_basic_variables("_lcompilers_min0_" + type_to_str_python(arg_types[0])); + int64_t kind = extract_kind_from_ttype_t(arg_types[0]); + if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Character_t(al, loc, 1, -1, nullptr))); + } + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, args[0], int32, nullptr)))); + } else if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Real_t(al, loc, kind))); + } + } else if (ASR::is_a(*arg_types[0])) { + for (size_t i = 0; i < new_args.size(); i++) { + fill_func_arg("x" + std::to_string(i), ASRUtils::TYPE(ASR::make_Integer_t(al, loc, kind))); + } + } else { + throw LCompilersException("Arguments to min0 must be of real, integer or character type"); + } + + auto result = declare(fn_name, return_type, ReturnVar); + body.push_back(al, b.Assignment(result, args[0])); + if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.iLt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + } else if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.fLt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + } else if (ASR::is_a(*return_type)) { + for (size_t i = 1; i < args.size(); i++) { + body.push_back(al, b.If(b.sLt(args[i], result), { + b.Assignment(result, args[i]) + }, {})); + } + return_type = TYPE(ASR::make_Character_t(al, loc, 1, -3, EXPR(ASR::make_StringLen_t(al, loc, new_args[0].m_value, int32, nullptr)))); + } else { + throw LCompilersException("Arguments to min0 must be of real, integer or character type"); + } + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, return_type, nullptr); + } + +} // namespace Min + +namespace Partition { + + static inline ASR::expr_t* eval_Partition(Allocator &al, const Location &loc, + std::string &s_var, std::string &sep) { + /* + using KMP algorithm to find separator inside string + res_tuple: stores the resulting 3-tuple expression ---> + (if separator exist) tuple: (left of separator, separator, right of separator) + (if separator does not exist) tuple: (string, "", "") + res_tuple_type: stores the type of each expression present in resulting 3-tuple + */ + ASRBuilder b(al, loc); + int sep_pos = ASRUtils::KMP_string_match(s_var, sep); + std::string first_res, second_res, third_res; + if(sep_pos == -1) { + /* seperator does not exist */ + first_res = s_var; + second_res = ""; + third_res = ""; + } else { + first_res = s_var.substr(0, sep_pos); + second_res = sep; + third_res = s_var.substr(sep_pos + sep.size()); + } + + Vec res_tuple; res_tuple.reserve(al, 3); + ASR::ttype_t *first_res_type = character(first_res.size()); + ASR::ttype_t *second_res_type = character(second_res.size()); + ASR::ttype_t *third_res_type = character(third_res.size()); + return b.TupleConstant({ b.StringConstant(first_res, first_res_type), + b.StringConstant(second_res, second_res_type), + b.StringConstant(third_res, third_res_type) }, + b.Tuple({first_res_type, second_res_type, third_res_type})); + } + + static inline ASR::asr_t *create_partition(Allocator &al, const Location &loc, + Vec &args, ASR::expr_t *s_var, + diag::Diagnostics& diag) { + ASRBuilder b(al, loc); + if (args.size() != 1) { + append_error(diag, "str.partition() takes exactly one argument", loc); + return nullptr; + } + ASR::expr_t *arg = args[0]; + if (!ASRUtils::is_character(*expr_type(arg))) { + append_error(diag, "str.partition() takes one arguments of type: str", arg->base.loc); + return nullptr; + } + + Vec e_args; e_args.reserve(al, 2); + e_args.push_back(al, s_var); + e_args.push_back(al, arg); + + ASR::ttype_t *return_type = b.Tuple({character(-2), character(-2), character(-2)}); + ASR::expr_t *value = nullptr; + if (ASR::is_a(*s_var) + && ASR::is_a(*arg)) { + std::string s_sep = ASR::down_cast(arg)->m_s; + std::string s_str = ASR::down_cast(s_var)->m_s; + if (s_sep.size() == 0) { + append_error(diag, "Separator cannot be an empty string", arg->base.loc); + return nullptr; + } + value = eval_Partition(al, loc, s_str, s_sep); + } + + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::Partition), + e_args.p, e_args.n, 0, return_type, value); + } + + static inline ASR::expr_t *instantiate_Partition(Allocator &al, + const Location &loc, SymbolTable *scope, + Vec& /*arg_types*/, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + // TODO: show runtime error for empty separator or pattern + declare_basic_variables("_lpython_str_partition"); + fill_func_arg("target_string", character(-2)); + fill_func_arg("pattern", character(-2)); + + auto result = declare("result", return_type, ReturnVar); + auto index = declare("index", int32, Local); + body.push_back(al, b.Assignment(index, b.Call(UnaryIntrinsicFunction:: + create_KMP_function(al, loc, scope), args, int32))); + body.push_back(al, b.If(b.iEq(index, b.i32_n(-1)), { + b.Assignment(result, b.TupleConstant({ args[0], + b.StringConstant("", character(0)), + b.StringConstant("", character(0)) }, + b.Tuple({character(-2), character(0), character(0)}))) + }, { + b.Assignment(result, b.TupleConstant({ + b.StringSection(args[0], b.i32(0), index), args[1], + b.StringSection(args[0], b.iAdd(index, b.StringLen(args[1])), + b.StringLen(args[0]))}, return_type)) + })); + body.push_back(al, Return()); + ASR::symbol_t *fn_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, fn_sym); + return b.Call(fn_sym, new_args, return_type, nullptr); + } + +} // namespace Partition + +namespace Epsilon { + + static ASR::expr_t *eval_Epsilon(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + double epsilon_val = -1; + ASRUtils::ASRBuilder b(al, loc); + int32_t kind = extract_kind_from_ttype_t(arg_type); + switch ( kind ) { + case 4: { + epsilon_val = std::numeric_limits::epsilon(); break; + } case 8: { + epsilon_val = std::numeric_limits::epsilon(); break; + } default: { + break; + } + } + return b.f(epsilon_val, arg_type); + } + +} // namespace Epsilon + +namespace Precision { + + static ASR::expr_t *eval_Precision(Allocator &al, const Location &loc, + ASR::ttype_t* /*return_type*/, Vec &args, diag::Diagnostics& diag) { + int64_t precision_val = -1; + ASRUtils::ASRBuilder b(al, loc); + ASR::ttype_t *arg_type = expr_type(args[0]); + int32_t kind = extract_kind_from_ttype_t(arg_type); + switch ( kind ) { + case 4: { + precision_val = 6; break; + } case 8: { + precision_val = 15; break; + } default: { + append_error(diag, "Kind " + std::to_string(kind) + " is not supported yet", loc); + return nullptr; + } + } + return b.i32(precision_val); + } + +} // namespace Precision + +namespace Tiny { + + static ASR::expr_t *eval_Tiny(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &/*args*/, diag::Diagnostics& diag) { + double tiny_value = -1; + ASRUtils::ASRBuilder b(al, loc); + int32_t kind = extract_kind_from_ttype_t(arg_type); + switch ( kind ) { + case 4: { + tiny_value = std::numeric_limits::min(); break; + } case 8: { + tiny_value = std::numeric_limits::min(); break; + } default: { + append_error(diag, "Kind " + std::to_string(kind) + " is not supported yet", loc); + return nullptr; + } + } + return b.f(tiny_value, arg_type); + } + +} // namespace Tiny + +namespace Conjg { + + static ASR::expr_t *eval_Conjg(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &args, diag::Diagnostics& /*diag*/) { + std::complex crv; + if( extract_value(args[0], crv) ) { + std::complex val = std::conj(crv); + return EXPR(ASR::make_ComplexConstant_t( + al, loc, val.real(), val.imag(), arg_type)); + } else { + return nullptr; + } + } + + static inline ASR::expr_t* instantiate_Conjg(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, ASR::ttype_t *return_type, + Vec& new_args, int64_t /*overload_id*/) { + std::string func_name = "_lcompilers_conjg_" + type_to_str_python(arg_types[0]); + declare_basic_variables(func_name); + if (scope->get_symbol(func_name)) { + ASR::symbol_t *s = scope->get_symbol(func_name); + ASR::Function_t *f = ASR::down_cast(s); + return b.Call(s, new_args, expr_type(f->m_return_var), nullptr); + } + fill_func_arg("x", arg_types[0]); + auto result = declare(fn_name, arg_types[0], ReturnVar); + // * r = real(x) - aimag(x)*(0,1) + + body.push_back(al, b.Assignment(result, b.ElementalSub( + EXPR(ASR::make_Cast_t(al, loc, EXPR(ASR::make_ComplexRe_t(al, loc, + args[0], TYPE(ASR::make_Real_t(al, loc, extract_kind_from_ttype_t(arg_types[0]))), nullptr)), + ASR::cast_kindType::RealToComplex, arg_types[0], nullptr)), + b.ElementalMul(EXPR(ASR::make_Cast_t(al, loc, EXPR(ASR::make_ComplexIm_t(al, loc, + args[0], TYPE(ASR::make_Real_t(al, loc, extract_kind_from_ttype_t(arg_types[0]))), nullptr)), + ASR::cast_kindType::RealToComplex, arg_types[0], nullptr)), EXPR(ASR::make_ComplexConstant_t(al, loc, + 0.0, 1.0, arg_types[0])), loc), loc))); + + ASR::symbol_t *f_sym = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, result, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, f_sym); + return b.Call(f_sym, new_args, ASRUtils::extract_type(return_type), nullptr); + } + +} // namespace Conjg + +namespace Huge { + + static ASR::expr_t *eval_Huge(Allocator &al, const Location &loc, + ASR::ttype_t* arg_type, Vec &/*args*/, diag::Diagnostics& diag) { + ASRUtils::ASRBuilder b(al, loc); + int32_t kind = extract_kind_from_ttype_t(arg_type); + if (ASR::is_a(*arg_type)) { + int64_t huge_value = -1; + switch ( kind ) { + case 1: { + huge_value = std::numeric_limits::max(); break; + } case 2: { + huge_value = std::numeric_limits::max(); break; + } case 4: { + huge_value = std::numeric_limits::max(); break; + } case 8: { + huge_value = std::numeric_limits::max(); break; + } default: { + append_error(diag, "Kind " + std::to_string(kind) + " is not supported yet", loc); + return nullptr; + } + } + return b.i(huge_value, arg_type); + } else { + double huge_value = -1; + switch ( kind ) { + case 4: { + huge_value = std::numeric_limits::max(); break; + } case 8: { + huge_value = std::numeric_limits::max(); break; + } default: { + append_error(diag, "Kind " + std::to_string(kind) + " is not supported yet", loc); + return nullptr; + } + } + return b.f(huge_value, arg_type); + } + } + +} // namespace Huge + +namespace SymbolicSymbol { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + const Location& loc = x.base.base.loc; + ASRUtils::require_impl(x.n_args == 1, + "SymbolicSymbol intrinsic must have exactly 1 input argument", + loc, diagnostics); + + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); + ASRUtils::require_impl(ASR::is_a(*input_type), + "SymbolicSymbol intrinsic expects a character input argument", + loc, diagnostics); + } + + static inline ASR::expr_t *eval_SymbolicSymbol(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO + return nullptr; + } + + static inline ASR::asr_t* create_SymbolicSymbol(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + if (args.size() != 1) { + append_error(diag, "Intrinsic Symbol function accepts exactly 1 argument", loc); + return nullptr; + } + + ASR::ttype_t *type = ASRUtils::expr_type(args[0]); + if (!ASRUtils::is_character(*type)) { + append_error(diag, "Argument of the Symbol function must be a Character", + args[0]->base.loc); + return nullptr; + } + + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicSymbol, + static_cast(IntrinsicElementalFunctions::SymbolicSymbol), 0, to_type, diag); + } + +} // namespace SymbolicSymbol + +#define create_symbolic_binary_macro(X) \ +namespace X{ \ + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, \ + diag::Diagnostics& diagnostics) { \ + ASRUtils::require_impl(x.n_args == 2, "Intrinsic function `"#X"` accepts" \ + "exactly 2 arguments", x.base.base.loc, diagnostics); \ + \ + ASR::ttype_t* left_type = ASRUtils::expr_type(x.m_args[0]); \ + ASR::ttype_t* right_type = ASRUtils::expr_type(x.m_args[1]); \ + \ + ASRUtils::require_impl(ASR::is_a(*left_type) && \ + ASR::is_a(*right_type), \ + "Both arguments of `"#X"` must be of type SymbolicExpression", \ + x.base.base.loc, diagnostics); \ + } \ + \ + static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ + ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { \ + /*TODO*/ \ + return nullptr; \ + } \ + \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) { \ + if (args.size() != 2) { \ + append_error(diag, "Intrinsic function `"#X"` accepts exactly 2 arguments", \ + loc); \ + return nullptr; \ + } \ + \ + for (size_t i = 0; i < args.size(); i++) { \ + ASR::ttype_t* argtype = ASRUtils::expr_type(args[i]); \ + if(!ASR::is_a(*argtype)) { \ + append_error(diag, \ + "Arguments of `"#X"` function must be of type SymbolicExpression", \ + args[i]->base.loc); \ + return nullptr; \ + } \ + } \ + \ + Vec arg_values; \ + arg_values.reserve(al, args.size()); \ + for( size_t i = 0; i < args.size(); i++ ) { \ + arg_values.push_back(al, ASRUtils::expr_value(args[i])); \ + } \ + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ + ASR::expr_t* compile_time_value = eval_##X(al, loc, to_type, arg_values, diag); \ + return ASR::make_IntrinsicElementalFunction_t(al, loc, \ + static_cast(IntrinsicElementalFunctions::X), \ + args.p, args.size(), 0, to_type, compile_time_value); \ + } \ +} // namespace X + +create_symbolic_binary_macro(SymbolicAdd) +create_symbolic_binary_macro(SymbolicSub) +create_symbolic_binary_macro(SymbolicMul) +create_symbolic_binary_macro(SymbolicDiv) +create_symbolic_binary_macro(SymbolicPow) +create_symbolic_binary_macro(SymbolicDiff) + +#define create_symbolic_constants_macro(X) \ +namespace X { \ + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, \ + diag::Diagnostics& diagnostics) { \ + const Location& loc = x.base.base.loc; \ + ASRUtils::require_impl(x.n_args == 0, \ + #X " does not take arguments", loc, diagnostics); \ + } \ + \ + static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ + ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { \ + /*TODO*/ \ + return nullptr; \ + } \ + \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) { \ + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ + ASR::expr_t* compile_time_value = eval_##X(al, loc, to_type, args, diag); \ + return ASR::make_IntrinsicElementalFunction_t(al, loc, \ + static_cast(IntrinsicElementalFunctions::X), \ + nullptr, 0, 0, to_type, compile_time_value); \ + } \ +} // namespace X + +create_symbolic_constants_macro(SymbolicPi) +create_symbolic_constants_macro(SymbolicE) + +namespace SymbolicInteger { + + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 1, + "SymbolicInteger intrinsic must have exactly 1 input argument", + x.base.base.loc, diagnostics); + + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); + ASRUtils::require_impl(ASR::is_a(*input_type), + "SymbolicInteger intrinsic expects an integer input argument", + x.base.base.loc, diagnostics); + } + + static inline ASR::expr_t* eval_SymbolicInteger(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec& /*args*/, diag::Diagnostics& /*diag*/) { + // TODO + return nullptr; + } + + static inline ASR::asr_t* create_SymbolicInteger(Allocator& al, const Location& loc, + Vec& args, + diag::Diagnostics& diag) { + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicInteger, + static_cast(IntrinsicElementalFunctions::SymbolicInteger), 0, to_type, diag); + } + +} // namespace SymbolicInteger + +namespace SymbolicHasSymbolQ { + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, + diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 2, "Intrinsic function SymbolicHasSymbolQ" + "accepts exactly 2 arguments", x.base.base.loc, diagnostics); + + ASR::ttype_t* left_type = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t* right_type = ASRUtils::expr_type(x.m_args[1]); + + ASRUtils::require_impl(ASR::is_a(*left_type) && + ASR::is_a(*right_type), + "Both arguments of SymbolicHasSymbolQ must be of type SymbolicExpression", + x.base.base.loc, diagnostics); + } + + static inline ASR::expr_t* eval_SymbolicHasSymbolQ(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + /*TODO*/ + return nullptr; + } + + static inline ASR::asr_t* create_SymbolicHasSymbolQ(Allocator& al, + const Location& loc, Vec& args, + diag::Diagnostics& diag) { + + if (args.size() != 2) { + append_error(diag, "Intrinsic function SymbolicHasSymbolQ accepts exactly 2 arguments", loc); + return nullptr; + } + + for (size_t i = 0; i < args.size(); i++) { + ASR::ttype_t* argtype = ASRUtils::expr_type(args[i]); + if(!ASR::is_a(*argtype)) { + append_error(diag, "Arguments of SymbolicHasSymbolQ function must be of type SymbolicExpression", + args[i]->base.loc); + return nullptr; + } + } + + Vec arg_values; + arg_values.reserve(al, args.size()); + for( size_t i = 0; i < args.size(); i++ ) { + arg_values.push_back(al, ASRUtils::expr_value(args[i])); + } + + ASR::expr_t* compile_time_value = eval_SymbolicHasSymbolQ(al, loc, logical, arg_values, diag); + return ASR::make_IntrinsicElementalFunction_t(al, loc, + static_cast(IntrinsicElementalFunctions::SymbolicHasSymbolQ), + args.p, args.size(), 0, logical, compile_time_value); + } +} // namespace SymbolicHasSymbolQ + +namespace SymbolicGetArgument { + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, + diag::Diagnostics& diagnostics) { + ASRUtils::require_impl(x.n_args == 2, "Intrinsic function SymbolicGetArgument" + "accepts exactly 2 argument", x.base.base.loc, diagnostics); + + ASR::ttype_t* arg1_type = ASRUtils::expr_type(x.m_args[0]); + ASR::ttype_t* arg2_type = ASRUtils::expr_type(x.m_args[1]); + ASRUtils::require_impl(ASR::is_a(*arg1_type), + "SymbolicGetArgument expects the first argument to be of type SymbolicExpression", + x.base.base.loc, diagnostics); + ASRUtils::require_impl(ASR::is_a(*arg2_type), + "SymbolicGetArgument expects the second argument to be of type Integer", + x.base.base.loc, diagnostics); + } + + static inline ASR::expr_t* eval_SymbolicGetArgument(Allocator &/*al*/, + const Location &/*loc*/, ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { + /*TODO*/ + return nullptr; + } + + static inline ASR::asr_t* create_SymbolicGetArgument(Allocator& al, + const Location& loc, Vec& args, + diag::Diagnostics& diag) { + + if (args.size() != 2) { + append_error(diag, "Intrinsic function SymbolicGetArguments accepts exactly 2 argument", loc); + return nullptr; + } + + ASR::ttype_t* arg1_type = ASRUtils::expr_type(args[0]); + ASR::ttype_t* arg2_type = ASRUtils::expr_type(args[1]); + if (!ASR::is_a(*arg1_type)) { + append_error(diag, "The first argument of SymbolicGetArgument function must be of type SymbolicExpression", + args[0]->base.loc); + return nullptr; + } + if (!ASR::is_a(*arg2_type)) { + append_error(diag, "The second argument of SymbolicGetArgument function must be of type Integer", + args[1]->base.loc); + return nullptr; + } + + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_SymbolicGetArgument, + static_cast(IntrinsicElementalFunctions::SymbolicGetArgument), + 0, to_type, diag); + } +} // namespace SymbolicGetArgument + +#define create_symbolic_query_macro(X) \ +namespace X { \ + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, \ + diag::Diagnostics& diagnostics) { \ + const Location& loc = x.base.base.loc; \ + ASRUtils::require_impl(x.n_args == 1, \ + #X " must have exactly 1 input argument", loc, diagnostics); \ + \ + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); \ + ASRUtils::require_impl(ASR::is_a(*input_type), \ + #X " expects an argument of type SymbolicExpression", loc, diagnostics); \ + } \ + \ + static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ + ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { \ + /*TODO*/ \ + return nullptr; \ + } \ + \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) { \ + if (args.size() != 1) { \ + append_error(diag, "Intrinsic " #X " function accepts exactly 1 argument", \ + loc); \ + return nullptr; \ + } \ + \ + ASR::ttype_t* argtype = ASRUtils::expr_type(args[0]); \ + if (!ASR::is_a(*argtype)) { \ + append_error(diag, \ + "Argument of " #X " function must be of type SymbolicExpression", \ + args[0]->base.loc); \ + return nullptr; \ + } \ + \ + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ + static_cast(IntrinsicElementalFunctions::X), 0, logical, diag); \ + } \ +} // namespace X + +create_symbolic_query_macro(SymbolicAddQ) +create_symbolic_query_macro(SymbolicMulQ) +create_symbolic_query_macro(SymbolicPowQ) +create_symbolic_query_macro(SymbolicLogQ) +create_symbolic_query_macro(SymbolicSinQ) + +#define create_symbolic_unary_macro(X) \ +namespace X { \ + static inline void verify_args(const ASR::IntrinsicElementalFunction_t& x, \ + diag::Diagnostics& diagnostics) { \ + const Location& loc = x.base.base.loc; \ + ASRUtils::require_impl(x.n_args == 1, \ + #X " must have exactly 1 input argument", loc, diagnostics); \ + \ + ASR::ttype_t* input_type = ASRUtils::expr_type(x.m_args[0]); \ + ASRUtils::require_impl(ASR::is_a(*input_type), \ + #X " expects an argument of type SymbolicExpression", loc, diagnostics); \ + } \ + \ + static inline ASR::expr_t* eval_##X(Allocator &/*al*/, const Location &/*loc*/, \ + ASR::ttype_t *, Vec &/*args*/, diag::Diagnostics& /*diag*/) { \ + /*TODO*/ \ + return nullptr; \ + } \ + \ + static inline ASR::asr_t* create_##X(Allocator& al, const Location& loc, \ + Vec& args, \ + diag::Diagnostics& diag) { \ + if (args.size() != 1) { \ + append_error(diag, "Intrinsic " #X " function accepts exactly 1 argument", \ + loc); \ + return nullptr; \ + } \ + \ + ASR::ttype_t* argtype = ASRUtils::expr_type(args[0]); \ + if (!ASR::is_a(*argtype)) { \ + append_error(diag, \ + "Argument of " #X " function must be of type SymbolicExpression", \ + args[0]->base.loc); \ + return nullptr; \ + } \ + \ + ASR::ttype_t *to_type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, loc)); \ + return UnaryIntrinsicFunction::create_UnaryFunction(al, loc, args, eval_##X, \ + static_cast(IntrinsicElementalFunctions::X), 0, to_type, diag); \ + } \ +} // namespace X + +create_symbolic_unary_macro(SymbolicSin) +create_symbolic_unary_macro(SymbolicCos) +create_symbolic_unary_macro(SymbolicLog) +create_symbolic_unary_macro(SymbolicExp) +create_symbolic_unary_macro(SymbolicAbs) +create_symbolic_unary_macro(SymbolicExpand) + +} // namespace LCompilers::ASRUtils + +#endif // LIBASR_PASS_INTRINSIC_FUNCTIONS_H diff --git a/src/libasr/pass/intrinsic_subroutine.cpp b/src/libasr/pass/intrinsic_subroutine.cpp new file mode 100644 index 0000000000..61e9e9d305 --- /dev/null +++ b/src/libasr/pass/intrinsic_subroutine.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace LCompilers { + +/* + +This ASR pass replaces the IntrinsicSubroutine node with a call to an +implementation in ASR that we construct (and cache) on the fly for the actual +arguments. + +Call this pass if you do not want to implement intrinsic subroutines directly +in the backend. + +*/ + +class ReplaceIntrinsicSubroutines : public ASR::CallReplacerOnExpressionsVisitor +{ + private: + + Allocator& al; + SymbolTable* global_scope; + bool remove_original_statement; + Vec pass_result; + Vec* parent_body; + + public: + + ReplaceIntrinsicSubroutines(Allocator& al_) : + al(al_), remove_original_statement(false) { + pass_result.n = 0; + } + + void visit_IntrinsicImpureSubroutine(const ASR::IntrinsicImpureSubroutine_t &x) { + Vec new_args; new_args.reserve(al, x.n_args); + // Replace any IntrinsicImpureSubroutinesin the argument first: + for( size_t i = 0; i < x.n_args; i++ ) { + ASR::call_arg_t arg0; + arg0.loc = x.m_args[i]->base.loc; + arg0.m_value = x.m_args[i]; // Use the converted arg + new_args.push_back(al, arg0); + } + ASRUtils::impl_subroutine instantiate_subroutine = + ASRUtils::IntrinsicImpureSubroutineRegistry::get_instantiate_subroutine(x.m_intrinsic_id); + if( instantiate_subroutine == nullptr ) { + return ; + } + Vec arg_types; + arg_types.reserve(al, x.n_args); + for( size_t i = 0; i < x.n_args; i++ ) { + arg_types.push_back(al, ASRUtils::expr_type(x.m_args[i])); + } + ASR::stmt_t* subroutine_call = instantiate_subroutine(al, x.base.base.loc, + global_scope, arg_types, new_args, x.m_overload_id); + remove_original_statement = true; + pass_result.push_back(al, subroutine_call); + } + + void transform_stmts(ASR::stmt_t **&m_body, size_t &n_body) { + bool remove_original_statement_copy = remove_original_statement; + Vec body; + body.reserve(al, n_body); + if( parent_body ) { + for (size_t j=0; j < pass_result.size(); j++) { + parent_body->push_back(al, pass_result[j]); + } + } + for (size_t i=0; i* parent_body_copy = parent_body; + parent_body = &body; + visit_stmt(*m_body[i]); + parent_body = parent_body_copy; + for (size_t j=0; j < pass_result.size(); j++) { + body.push_back(al, pass_result[j]); + } + if( !remove_original_statement ) { + body.push_back(al, m_body[i]); + } + } + m_body = body.p; + n_body = body.size(); + pass_result.n = 0; + remove_original_statement = remove_original_statement_copy; + } + + // TODO: Only Program and While is processed, we need to process all calls + // to visit_stmt(). + // TODO: Only TranslationUnit's and Program's symbol table is processed + // for transforming function->subroutine if they return arrays + void visit_TranslationUnit(const ASR::TranslationUnit_t &x) { + SymbolTable* current_scope_copy = current_scope; + current_scope = x.m_symtab; + + global_scope = x.m_symtab; + while( global_scope->parent ) { + global_scope = global_scope->parent; + } + + std::vector build_order + = ASRUtils::determine_module_dependencies(x); + for (auto &item : build_order) { + LCOMPILERS_ASSERT(x.m_symtab->get_symbol(item)); + ASR::symbol_t *mod = x.m_symtab->get_symbol(item); + visit_symbol(*mod); + } + + // Now visit everything else + for (auto &item : x.m_symtab->get_scope()) { + if (!ASR::is_a(*item.second)) { + this->visit_symbol(*item.second); + } + } + current_scope = current_scope_copy; + } + + void visit_Module(const ASR::Module_t &x) { + // FIXME: this is a hack, we need to pass in a non-const `x`, + // which requires to generate a TransformVisitor. + SymbolTable* current_scope_copy = current_scope; + current_scope = x.m_symtab; + + global_scope = x.m_symtab; + while( global_scope->parent ) { + global_scope = global_scope->parent; + } + + // Now visit everything else + for (auto &item : x.m_symtab->get_scope()) { + this->visit_symbol(*item.second); + } + current_scope = current_scope_copy; + } + + void visit_Program(const ASR::Program_t &x) { + // FIXME: this is a hack, we need to pass in a non-const `x`, + // which requires to generate a TransformVisitor. + ASR::Program_t& xx = const_cast(x); + SymbolTable* current_scope_copy = current_scope; + current_scope = xx.m_symtab; + global_scope = xx.m_symtab; + + while( global_scope->parent ) { + global_scope = global_scope->parent; + } + + for (auto &item : x.m_symtab->get_scope()) { + if (ASR::is_a(*item.second)) { + ASR::AssociateBlock_t *s = ASR::down_cast(item.second); + visit_AssociateBlock(*s); + } + if (ASR::is_a(*item.second)) { + visit_Function(*ASR::down_cast( + item.second)); + } + } + + transform_stmts(xx.m_body, xx.n_body); + current_scope = current_scope_copy; + } + +}; + +void pass_replace_intrinsic_subroutine(Allocator &al, ASR::TranslationUnit_t &unit, + const LCompilers::PassOptions& /*pass_options*/) { + ReplaceIntrinsicSubroutines v(al); + v.visit_TranslationUnit(unit); + PassUtils::UpdateDependenciesVisitor u(al); + u.visit_TranslationUnit(unit); +} + + +} // namespace LCompilers diff --git a/src/libasr/pass/intrinsic_subroutine_registry.h b/src/libasr/pass/intrinsic_subroutine_registry.h new file mode 100644 index 0000000000..d84105d49d --- /dev/null +++ b/src/libasr/pass/intrinsic_subroutine_registry.h @@ -0,0 +1,88 @@ +#ifndef LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H +#define LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H + +// #include +#include + +#include +#include +#include + +namespace LCompilers { + +namespace ASRUtils { + +#define INTRINSIC_SUBROUTINE_NAME_CASE(X) \ + case (static_cast(ASRUtils::IntrinsicImpureSubroutines::X)) : { \ + return #X; \ + } + +inline std::string get_intrinsic_subroutine_name(int x) { + switch (x) { + INTRINSIC_SUBROUTINE_NAME_CASE(RandomNumber) + default : { + throw LCompilersException("pickle: intrinsic_id not implemented"); + } + } +} + +/************************* Intrinsic Impure Subroutine **************************/ + +namespace IntrinsicImpureSubroutineRegistry { + + static const std::map>& intrinsic_subroutine_by_id_db = { + {static_cast(IntrinsicImpureSubroutines::RandomNumber), + {&RandomNumber::instantiate_RandomNumber, &RandomNumber::verify_args}}, + }; + + static const std::map& intrinsic_subroutine_id_to_name = { + {static_cast(IntrinsicImpureSubroutines::RandomNumber), + "random_number"}, + }; + + + static const std::map& intrinsic_subroutine_by_name_db = { + {"random_number", &RandomNumber::create_RandomNumber}, + }; + + static inline bool is_intrinsic_subroutine(const std::string& name) { + return intrinsic_subroutine_by_name_db.find(name) != intrinsic_subroutine_by_name_db.end(); + } + + static inline bool is_intrinsic_subroutine(int64_t id) { + return intrinsic_subroutine_by_id_db.find(id) != intrinsic_subroutine_by_id_db.end(); + } + + static inline create_intrinsic_subroutine get_create_subroutine(const std::string& name) { + return intrinsic_subroutine_by_name_db.at(name); + } + + static inline verify_subroutine get_verify_subroutine(int64_t id) { + return std::get<1>(intrinsic_subroutine_by_id_db.at(id)); + } + + static inline impl_subroutine get_instantiate_subroutine(int64_t id) { + if( intrinsic_subroutine_by_id_db.find(id) == intrinsic_subroutine_by_id_db.end() ) { + return nullptr; + } + return std::get<0>(intrinsic_subroutine_by_id_db.at(id)); + } + + static inline std::string get_intrinsic_subroutine_name(int64_t id) { + if( intrinsic_subroutine_id_to_name.find(id) == intrinsic_subroutine_id_to_name.end() ) { + throw LCompilersException("IntrinsicSubroutine with ID " + std::to_string(id) + + " has no name registered for it"); + } + return intrinsic_subroutine_id_to_name.at(id); + } + +} // namespace IntrinsicImpureSubroutineRegistry + +} // namespace ASRUtils + +} // namespace LCompilers + +#endif // LFORTRAN_PASS_INTRINSIC_SUBROUTINE_REGISTRY_H diff --git a/src/libasr/pass/intrinsic_subroutines.h b/src/libasr/pass/intrinsic_subroutines.h new file mode 100644 index 0000000000..f4b946b0b2 --- /dev/null +++ b/src/libasr/pass/intrinsic_subroutines.h @@ -0,0 +1,120 @@ +#ifndef LIBASR_PASS_INTRINSIC_SUBROUTINES_H +#define LIBASR_PASS_INTRINSIC_SUBROUTINES_H + + +#include +#include + +namespace LCompilers::ASRUtils { + +/* +To add a new subroutine implementation, + +1. Create a new namespace like, `Sin`, `LogGamma` in this file. +2. In the above created namespace add `eval_*`, `instantiate_*`, and `create_*`. +3. Then register in the maps present in `IntrinsicImpureSubroutineRegistry`. + +You can use helper macros and define your own helper macros to reduce +the code size. +*/ + +enum class IntrinsicImpureSubroutines : int64_t { + RandomNumber, + // ... +}; + +typedef ASR::stmt_t* (*impl_subroutine)( + Allocator&, const Location &, + SymbolTable*, Vec&, + Vec&, int64_t); + +typedef ASR::asr_t* (*create_intrinsic_subroutine)( + Allocator&, const Location&, + Vec&, + diag::Diagnostics&); + +typedef void (*verify_subroutine)( + const ASR::IntrinsicImpureSubroutine_t&, + diag::Diagnostics&); + +typedef ASR::expr_t* (*get_initial_value_sub)(Allocator&, ASR::ttype_t*); + +namespace RandomNumber { + + static inline void verify_args(const ASR::IntrinsicImpureSubroutine_t& x, diag::Diagnostics& diagnostics) { + if (x.n_args == 1) { + ASRUtils::require_impl(x.m_overload_id == 0, "Overload Id for random_number expected to be 0, found " + std::to_string(x.m_overload_id), x.base.base.loc, diagnostics); + } + else { + ASRUtils::require_impl(false, "Unexpected number of args, random_number takes 1 arguments, found " + std::to_string(x.n_args), x.base.base.loc, diagnostics); + } + } + + static inline ASR::asr_t* create_RandomNumber(Allocator& al, const Location& loc, Vec& args, diag::Diagnostics& /*diag*/) { + Vec m_args; m_args.reserve(al, 1); m_args.push_back(al, args[0]); + return ASR::make_IntrinsicImpureSubroutine_t(al, loc, static_cast(IntrinsicImpureSubroutines::RandomNumber), m_args.p, m_args.n, 0); + } + + static inline ASR::stmt_t* instantiate_RandomNumber(Allocator &al, const Location &loc, + SymbolTable *scope, Vec& arg_types, + Vec& new_args, int64_t /*overload_id*/) { + std::string c_func_name; + int kind = ASRUtils::extract_kind_from_ttype_t(arg_types[0]); + if ( kind == 4 ) { + c_func_name = "_lfortran_sp_rand_num"; + } else { + c_func_name = "_lfortran_dp_rand_num"; + } + std::string new_name = "_lcompilers_random_number_"; + + declare_basic_variables(new_name); + fill_func_arg_sub("r", arg_types[0], InOut); + SymbolTable *fn_symtab_1 = al.make_new(fn_symtab); + Vec args_1; args_1.reserve(al, 0); + ASR::expr_t *return_var_1 = b.Variable(fn_symtab_1, c_func_name, + ASRUtils::type_get_past_array(ASRUtils::type_get_past_allocatable(arg_types[0])), + ASRUtils::intent_return_var, ASR::abiType::BindC, false); + SetChar dep_1; dep_1.reserve(al, 1); + Vec body_1; body_1.reserve(al, 1); + ASR::symbol_t *s = make_ASR_Function_t(c_func_name, fn_symtab_1, dep_1, args_1, + body_1, return_var_1, ASR::abiType::BindC, ASR::deftypeType::Interface, s2c(al, c_func_name)); + fn_symtab->add_symbol(c_func_name, s); + dep.push_back(al, s2c(al, c_func_name)); + + if (ASRUtils::is_array(ASRUtils::expr_type(args[0]))) { + /* + real :: b(3) + call random_number(b) + To + real :: b(3) + do i=lbound(b,1),ubound(b,1) + call random_number(b(i)) + end do + */ + ASR::dimension_t* array_dims = nullptr; + int array_rank = extract_dimensions_from_ttype(arg_types[0], array_dims); + std::vector do_loop_variables; + for (int i = 0; i < array_rank; i++) { + do_loop_variables.push_back(declare("i_" + std::to_string(i), int32, Local)); + } + ASR::stmt_t* func_call = b.CallIntrinsicSubroutine(scope, {ASRUtils::type_get_past_array(ASRUtils::type_get_past_allocatable(arg_types[0]))}, + {b.ArrayItem_01(args[0], do_loop_variables)}, 0, RandomNumber::instantiate_RandomNumber); + fn_name = scope->get_unique_name(fn_name, false); + body.push_back(al, PassUtils::create_do_loop_helper_random_number(al, loc, do_loop_variables, s, args[0], + ASRUtils::type_get_past_array(ASRUtils::type_get_past_allocatable(arg_types[0])), + b.ArrayItem_01(args[0], do_loop_variables), func_call, 1)); + } else { + Vec call_args; call_args.reserve(al, 0); + body.push_back(al, b.Assignment(args[0], b.Call(s, call_args, arg_types[0]))); + } + ASR::symbol_t *new_symbol = make_ASR_Function_t(fn_name, fn_symtab, dep, args, + body, nullptr, ASR::abiType::Source, ASR::deftypeType::Implementation, nullptr); + scope->add_symbol(fn_name, new_symbol); + return b.SubroutineCall(new_symbol, new_args); + } + +} // namespace RandomNumber + +} // namespace LCompilers::ASRUtils + +#endif // LIBASR_PASS_INTRINSIC_SUBROUTINES_H diff --git a/src/libasr/pass/loop_unroll.cpp b/src/libasr/pass/loop_unroll.cpp index 9b2e0fb69e..7a9135a706 100644 --- a/src/libasr/pass/loop_unroll.cpp +++ b/src/libasr/pass/loop_unroll.cpp @@ -90,8 +90,7 @@ class LoopUnrollVisitor : public PassUtils::PassVisitor pass_result.push_back(al, init_stmt); ASR::stmt_t* unrolled_whileloop = ASRUtils::STMT(ASR::make_WhileLoop_t(al, x.base.base.loc, - whileloop->m_name, whileloop->m_test, unrolled_loop.p, unrolled_loop.size(), - nullptr, 0)); + whileloop->m_name, whileloop->m_test, unrolled_loop.p, unrolled_loop.size(), x.m_orelse, x.n_orelse)); pass_result.push_back(al, unrolled_whileloop); for( int64_t i = 0; i < remaining_part; i++ ) { for( size_t i = 0; i < whileloop->n_body; i++ ) { diff --git a/src/libasr/pass/nested_vars.cpp b/src/libasr/pass/nested_vars.cpp index e2ec051f60..51b7b4a23e 100644 --- a/src/libasr/pass/nested_vars.cpp +++ b/src/libasr/pass/nested_vars.cpp @@ -420,7 +420,7 @@ class ReplaceNestedVisitor: public ASR::CallReplacerOnExpressionsVisitor(x); ASRUtils::Call_t_body(al, xx.m_name, xx.m_args, xx.n_args, x.m_dt, - nullptr, false); + nullptr, false, false); } void visit_SubroutineCall(const ASR::SubroutineCall_t &x) { @@ -441,7 +441,7 @@ class ReplaceNestedVisitor: public ASR::CallReplacerOnExpressionsVisitor(x); ASRUtils::Call_t_body(al, xx.m_name, xx.m_args, xx.n_args, x.m_dt, - nullptr, false); + nullptr, false, ASRUtils::get_class_proc_nopass_val(x.m_name)); } void visit_Array(const ASR::Array_t& /*x*/) { @@ -506,13 +506,13 @@ class AssignNestedVars: public PassUtils::PassVisitor { std::string sym_name = ASRUtils::symbol_name(sym_); sym_ = current_scope->get_symbol(sym_name); if( !sym_ ) { + ASR::symbol_t *s = ASRUtils::symbol_get_past_external(sym); ASR::asr_t *fn = ASR::make_ExternalSymbol_t( al, t->base.loc, /* a_symtab */ current_scope, /* a_name */ s2c(al, current_scope->get_unique_name(sym_name, false)), - ASRUtils::symbol_get_past_external(sym), - ASRUtils::symbol_name(ASRUtils::get_asr_owner(ASRUtils::symbol_get_past_external(sym))), - nullptr, 0, s2c(al, sym_name), ASR::accessType::Public + s, ASRUtils::symbol_name(ASRUtils::get_asr_owner(s)), + nullptr, 0, ASRUtils::symbol_name(s), ASR::accessType::Public ); sym_ = ASR::down_cast(fn); current_scope->add_symbol(sym_name, sym_); diff --git a/src/libasr/pass/pass_array_by_data.cpp b/src/libasr/pass/pass_array_by_data.cpp index 20f925f17c..453acdc30b 100644 --- a/src/libasr/pass/pass_array_by_data.cpp +++ b/src/libasr/pass/pass_array_by_data.cpp @@ -126,13 +126,13 @@ class PassArrayByDataProcedureVisitor : public PassUtils::PassVisitorm_name); + suffix += "_" + ASRUtils::type_to_str(arg_func->m_function_signature); } else { - suffix += "_" + std::string(arg->m_name); + suffix += "_" + ASRUtils::type_to_str(arg->m_type); } + suffix += "_" + std::to_string(i); } ASR::expr_t* new_arg; if (arg_func) { @@ -151,6 +151,13 @@ class PassArrayByDataProcedureVisitor : public PassUtils::PassVisitor= 'a' && suffix[suffixi] <= 'z') || + (suffix[suffixi] >= '0' && suffix[suffixi] <= '9')) ) { + suffix[suffixi] = '_'; + } + } std::string new_name = std::string(x->m_name) + suffix; if( ASR::is_a( *((ASR::symbol_t*) x) ) ) { ASR::FunctionType_t* x_func_type = ASRUtils::get_FunctionType(x); @@ -373,6 +380,12 @@ class EditProcedureVisitor: public ASR::CallReplacerOnExpressionsVisitor::visit_BlockCall(x); } + void visit_AssociateBlockCall(const ASR::AssociateBlockCall_t& x) { + ASR::AssociateBlockCall_t& xx = const_cast(x); + edit_symbol_reference(m) + ASR::CallReplacerOnExpressionsVisitor::visit_AssociateBlockCall(x); + } + void visit_SubroutineCall(const ASR::SubroutineCall_t& x) { ASR::SubroutineCall_t& xx = const_cast(x); edit_symbol_reference(name) @@ -444,6 +457,25 @@ class EditProcedureCallsVisitor : public ASR::ASRPassBaseWalkVisitor& dims, + Allocator& al) { + ASR::ttype_t* array_type = ASRUtils::expr_type(array); + ASR::dimension_t* compile_time_dims = nullptr; + int n_dims = ASRUtils::extract_dimensions_from_ttype(array_type, compile_time_dims); + for( int i = 0; i < n_dims; i++ ) { + ASR::expr_t* start = compile_time_dims[i].m_start; + if( start == nullptr ) { + start = PassUtils::get_bound(array, i + 1, "lbound", al); + } + ASR::expr_t* length = compile_time_dims[i].m_length; + if( length == nullptr ) { + length = ASRUtils::get_size(array, i + 1, al); + } + dims.push_back(al, start); + dims.push_back(al, length); + } + } + Vec construct_new_args(size_t n_args, ASR::call_arg_t* orig_args, std::vector& indices) { Vec new_args; new_args.reserve(al, n_args); @@ -477,7 +509,7 @@ class EditProcedureCallsVisitor : public ASR::ASRPassBaseWalkVisitor dim_vars; dim_vars.reserve(al, 2); - ASRUtils::get_dimensions(orig_arg_i, dim_vars, al); + get_dimensions(orig_arg_i, dim_vars, al); for( size_t j = 0; j < dim_vars.size(); j++ ) { ASR::call_arg_t dim_var; dim_var.loc = dim_vars[j]->base.loc; @@ -537,12 +569,10 @@ class EditProcedureCallsVisitor : public ASR::ASRPassBaseWalkVisitor #include #include +#include namespace LCompilers { @@ -71,6 +72,15 @@ namespace LCompilers { ASR::ttype_t* x_type = ASR::down_cast(x)->m_type; ASR::dimension_t* m_dims; get_dim_rank(x_type, m_dims, n_dims); + } else if (ASR::is_a(*x)) { + ASR::ComplexConstructor_t* cc = ASR::down_cast(x); + return get_rank(cc->m_re); + } else if (ASR::is_a(*x)) { + ASR::ComplexIm_t* cc = ASR::down_cast(x); + return get_rank(cc->m_arg); + } else if (ASR::is_a(*x)) { + ASR::ComplexRe_t* cc = ASR::down_cast(x); + return get_rank(cc->m_arg); } return n_dims; } @@ -126,6 +136,9 @@ namespace LCompilers { ASR::expr_t* create_array_ref(ASR::expr_t* arr_expr, Vec& idx_vars, Allocator& al, SymbolTable* current_scope, bool perform_cast, ASR::cast_kindType cast_kind, ASR::ttype_t* casted_type) { + if (idx_vars.size() == 0) { + return arr_expr; + } Vec args; args.reserve(al, 1); for( size_t i = 0; i < idx_vars.size(); i++ ) { @@ -493,6 +506,101 @@ namespace LCompilers { return v; } + ASR::stmt_t* create_do_loop_helper_count(Allocator &al, const Location &loc, std::vector do_loop_variables, ASR::expr_t* mask, ASR::expr_t* res, int curr_idx) { + ASRUtils::ASRBuilder b(al, loc); + + if (curr_idx == 1) { + std::vector vars; + for (size_t i = 0; i < do_loop_variables.size(); i++) { + vars.push_back(do_loop_variables[i]); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(mask, curr_idx), UBound(mask, curr_idx), { + b.If(b.ArrayItem_01(mask, vars), { + b.Assignment(res, b.Add(res, b.i(1, ASRUtils::expr_type(res)))) + }, {}), + }, nullptr); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(mask, curr_idx), UBound(mask, curr_idx), { + create_do_loop_helper_count(al, loc, do_loop_variables, mask, res, curr_idx - 1) + }, nullptr); + } + + ASR::stmt_t* create_do_loop_helper_count_dim(Allocator &al, const Location &loc, std::vector do_loop_variables, + std::vector res_idx, ASR::stmt_t* inner_most_do_loop, + ASR::expr_t* c, ASR::expr_t* mask, ASR::expr_t* res, int curr_idx, int dim) { + ASRUtils::ASRBuilder b(al, loc); + + if (curr_idx == (int) do_loop_variables.size() - 1) { + return b.DoLoop(do_loop_variables[curr_idx], LBound(mask, curr_idx + 1), UBound(mask, curr_idx + 1), { + b.Assignment(c, ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 0, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4))))), + inner_most_do_loop, + b.Assignment(b.ArrayItem_01(res, {res_idx}), c) + }); + } + if (curr_idx != dim - 1) { + return b.DoLoop(do_loop_variables[curr_idx], LBound(mask, curr_idx + 1), UBound(mask, curr_idx + 1), { + create_do_loop_helper_count_dim(al, loc, do_loop_variables, res_idx, inner_most_do_loop, c, mask, res, curr_idx + 1, dim) + }); + } else { + return create_do_loop_helper_count_dim(al, loc, do_loop_variables, res_idx, inner_most_do_loop, c, mask, res, curr_idx + 1, dim); + } + } + + ASR::stmt_t* create_do_loop_helper_pack(Allocator &al, const Location &loc, std::vector do_loop_variables, ASR::expr_t* array, ASR::expr_t* mask, ASR::expr_t* res, ASR::expr_t* idx, int curr_idx) { + ASRUtils::ASRBuilder b(al, loc); + + if (curr_idx == 1) { + std::vector vars; + for (size_t i = 0; i < do_loop_variables.size(); i++) { + vars.push_back(do_loop_variables[i]); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(array, curr_idx), UBound(array, curr_idx), { + b.If(b.ArrayItem_01(mask, vars), { + b.Assignment(b.ArrayItem_01(res, {idx}), b.ArrayItem_01(array, vars)), + b.Assignment(idx, b.Add(idx, ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))))) + }, {}), + }, nullptr); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(array, curr_idx), UBound(array, curr_idx), { + create_do_loop_helper_pack(al, loc, do_loop_variables, array, mask, res, idx, curr_idx - 1) + }, nullptr); + } + + ASR::stmt_t* create_do_loop_helper_unpack(Allocator &al, const Location &loc, std::vector do_loop_variables, ASR::expr_t* vector, ASR::expr_t* mask, ASR::expr_t* res, ASR::expr_t* idx, int curr_idx) { + ASRUtils::ASRBuilder b(al, loc); + if (curr_idx == 1) { + std::vector vars; + for (size_t i = 0; i < do_loop_variables.size(); i++) { + vars.push_back(do_loop_variables[i]); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(mask, 1), UBound(mask, 1), { + b.If(b.ArrayItem_01(mask, vars), { + b.Assignment(b.ArrayItem_01(res, vars), b.ArrayItem_01(vector, {idx})), + b.Assignment(idx, b.Add(idx, ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)))))) + }, {}), + }, nullptr); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(mask, curr_idx), UBound(mask, curr_idx), { + create_do_loop_helper_unpack(al, loc, do_loop_variables, vector, mask, res, idx, curr_idx - 1) + }, nullptr); + } + + ASR::stmt_t* create_do_loop_helper_random_number(Allocator &al, const Location &loc, std::vector do_loop_variables, + ASR::symbol_t* s, ASR::expr_t* arr, ASR::ttype_t* return_type, ASR::expr_t* arr_item, ASR::stmt_t* stmt, int curr_idx) { + ASRUtils::ASRBuilder b(al, loc); + if (curr_idx == (int)do_loop_variables.size()) { + // ASR::expr_t* arr_item = b.ArrayItem_01(arr, do_loop_variables); + Vec args; args.reserve(al, 1); args.push_back(al, arr_item); + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(arr, curr_idx), UBound(arr, curr_idx), { + stmt + }, nullptr); + } + return b.DoLoop(do_loop_variables[curr_idx - 1], LBound(arr, curr_idx), UBound(arr, curr_idx), { + create_do_loop_helper_random_number(al, loc, do_loop_variables, s, arr, return_type, arr_item, stmt, curr_idx + 1) + }, nullptr); + + } + // Imports the function from an already loaded ASR module ASR::symbol_t* import_function2(std::string func_name, std::string module_name, Allocator& al, ASR::TranslationUnit_t& unit, @@ -568,8 +676,7 @@ namespace LCompilers { } } - ASR::expr_t* get_bound(ASR::expr_t* arr_expr, int dim, std::string bound, - Allocator& al) { + ASR::expr_t* get_bound(ASR::expr_t* arr_expr, int dim, std::string bound, Allocator& al) { ASR::ttype_t* x_mv_type = ASRUtils::expr_type(arr_expr); ASR::dimension_t* m_dims; int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims); @@ -581,8 +688,12 @@ namespace LCompilers { ASR::expr_t* zero = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 0, int32_type)); ASR::expr_t* one = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, int32_type)); if( bound == "ubound" ) { - return ASRUtils::EXPR(ASR::make_IntegerBinOp_t( - al, arr_expr->base.loc, m_dims[dim - 1].m_length, ASR::binopType::Sub, one, int32_type, nullptr)); + return ASRUtils::EXPR( + ASR::make_IntegerBinOp_t(al, arr_expr->base.loc, + ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_expr->base.loc, + m_dims[dim - 1].m_length, ASR::binopType::Sub, one, int32_type, nullptr)), + ASR::binopType::Add, m_dims[dim - 1].m_start, int32_type, nullptr) + ); } if ( m_dims[dim - 1].m_start != nullptr ) { return m_dims[dim - 1].m_start; @@ -613,18 +724,18 @@ namespace LCompilers { Allocator& al, ASR::TranslationUnit_t& unit, const Location& loc, PassOptions& pass_options) { ASR::ttype_t* type = ASRUtils::expr_type(arg1); - int64_t fp_s = static_cast(ASRUtils::IntrinsicScalarFunctions::FlipSign); + int64_t fp_s = static_cast(ASRUtils::IntrinsicElementalFunctions::FlipSign); if (skip_instantiation(pass_options, fp_s)) { Vec args; args.reserve(al, 2); args.push_back(al, arg0); args.push_back(al, arg1); - return ASRUtils::EXPR(ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, fp_s, + return ASRUtils::EXPR(ASRUtils::make_IntrinsicElementalFunction_t_util(al, loc, fp_s, args.p, args.n, 0, type, nullptr)); } ASRUtils::impl_function instantiate_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_instantiate_function( - static_cast(ASRUtils::IntrinsicScalarFunctions::FlipSign)); + ASRUtils::IntrinsicElementalFunctionRegistry::get_instantiate_function( + static_cast(ASRUtils::IntrinsicElementalFunctions::FlipSign)); Vec arg_types; arg_types.reserve(al, 2); arg_types.push_back(al, ASRUtils::expr_type(arg0)); @@ -669,8 +780,8 @@ namespace LCompilers { Allocator& al, SymbolTable*& current_scope, ASR::stmt_t*& assign_stmt) { ASR::asr_t* expr_sym = ASR::make_Variable_t(al, expr->base.loc, current_scope, s2c(al, name), nullptr, 0, ASR::intentType::Local, nullptr, nullptr, ASR::storage_typeType::Default, - ASRUtils::duplicate_type(al, ASRUtils::expr_type(expr)), nullptr, ASR::abiType::Source, ASR::accessType::Public, - ASR::presenceType::Required, false); + ASRUtils::duplicate_type(al, ASRUtils::extract_type(ASRUtils::expr_type(expr))), + nullptr, ASR::abiType::Source, ASR::accessType::Public, ASR::presenceType::Required, false); if( current_scope->get_symbol(name) == nullptr ) { current_scope->add_symbol(name, ASR::down_cast(expr_sym)); } else { @@ -701,20 +812,20 @@ namespace LCompilers { ASR::expr_t* get_fma(ASR::expr_t* arg0, ASR::expr_t* arg1, ASR::expr_t* arg2, Allocator& al, ASR::TranslationUnit_t& unit, Location& loc, PassOptions& pass_options) { - int64_t fma_id = static_cast(ASRUtils::IntrinsicScalarFunctions::FMA); + int64_t fma_id = static_cast(ASRUtils::IntrinsicElementalFunctions::FMA); ASR::ttype_t* type = ASRUtils::expr_type(arg0); - if (skip_instantiation(pass_options, fma_id)) { + if (skip_instantiation(pass_options, fma_id) || ASRUtils::is_simd_array(arg0)) { Vec args; args.reserve(al, 3); args.push_back(al, arg0); args.push_back(al, arg1); args.push_back(al, arg2); - return ASRUtils::EXPR(ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, fma_id, + return ASRUtils::EXPR(ASRUtils::make_IntrinsicElementalFunction_t_util(al, loc, fma_id, args.p, args.n, 0, type, nullptr)); } ASRUtils::impl_function instantiate_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_instantiate_function( - static_cast(ASRUtils::IntrinsicScalarFunctions::FMA)); + ASRUtils::IntrinsicElementalFunctionRegistry::get_instantiate_function( + static_cast(ASRUtils::IntrinsicElementalFunctions::FMA)); Vec arg_types; arg_types.reserve(al, 3); arg_types.push_back(al, ASRUtils::expr_type(arg0)); @@ -827,25 +938,25 @@ namespace LCompilers { args.push_back(al, arg5_); return ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util(al, loc, v, nullptr, args.p, args.size(), - nullptr, nullptr, false)); + nullptr, nullptr, false, false)); } ASR::expr_t* get_sign_from_value(ASR::expr_t* arg0, ASR::expr_t* arg1, Allocator& al, ASR::TranslationUnit_t& unit, Location& loc, PassOptions& pass_options) { - int64_t sfv_id = static_cast(ASRUtils::IntrinsicScalarFunctions::SignFromValue); + int64_t sfv_id = static_cast(ASRUtils::IntrinsicElementalFunctions::SignFromValue); ASR::ttype_t* type = ASRUtils::expr_type(arg0); if (skip_instantiation(pass_options, sfv_id)) { Vec args; args.reserve(al, 2); args.push_back(al, arg0); args.push_back(al, arg1); - return ASRUtils::EXPR(ASRUtils::make_IntrinsicScalarFunction_t_util(al, loc, sfv_id, + return ASRUtils::EXPR(ASRUtils::make_IntrinsicElementalFunction_t_util(al, loc, sfv_id, args.p, args.n, 0, type, nullptr)); } ASRUtils::impl_function instantiate_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_instantiate_function( - static_cast(ASRUtils::IntrinsicScalarFunctions::FMA)); + ASRUtils::IntrinsicElementalFunctionRegistry::get_instantiate_function( + static_cast(ASRUtils::IntrinsicElementalFunctions::FMA)); Vec arg_types; arg_types.reserve(al, 2); arg_types.push_back(al, ASRUtils::expr_type(arg0)); @@ -862,6 +973,24 @@ namespace LCompilers { unit.m_symtab, arg_types, type, args, 0); } + void cast_util(ASR::expr_t*& left, ASR::expr_t*& right, Allocator& al, bool is_assign=false) { + ASR::ttype_t *src_type = nullptr, *dest_type = nullptr; + ASR::expr_t *src_expr = nullptr, *dest_expr = nullptr; + int casted_expression_signal = LCompilers::CastingUtil::get_src_dest( + left, right, src_expr, dest_expr, src_type, dest_type, is_assign); + if( casted_expression_signal != 2 ) { + src_expr = CastingUtil::perform_casting( + src_expr, dest_type, al, src_expr->base.loc); + if( casted_expression_signal == 0 ) { + left = src_expr; + right = dest_expr; + } else if( casted_expression_signal == 1 ) { + left = dest_expr; + right = src_expr; + } + } + } + Vec replace_doloop(Allocator &al, const ASR::DoLoop_t &loop, int comp, bool use_loop_variable_after_loop) { Location loc = loop.base.base.loc; @@ -872,6 +1001,14 @@ namespace LCompilers { ASR::stmt_t *inc_stmt = nullptr; ASR::stmt_t *loop_init_stmt = nullptr; ASR::stmt_t *stmt_add_c_after_loop = nullptr; + if( loop.m_head.m_v ) { + ASR::expr_t* loop_head = loop.m_head.m_v; + cast_util(loop_head, a, al, true); + cast_util(loop_head, b, al, true); + if( c ) { + cast_util(loop_head, c, al, true); + } + } if( !a && !b && !c ) { int a_kind = 4; if( loop.m_head.m_v ) { @@ -893,8 +1030,7 @@ namespace LCompilers { if( comp == -1 ) { int increment; bool not_constant_inc = false; - if (!ASRUtils::is_integer(*ASRUtils::type_get_past_const( - ASRUtils::expr_type(c)))) { + if (!ASRUtils::is_integer(*ASRUtils::expr_type(c))) { throw LCompilersException("Do loop increment type should be an integer"); } if (c->type == ASR::exprType::IntegerConstant) { @@ -977,9 +1113,11 @@ namespace LCompilers { ASR::binopType::Add, c, type, nullptr)), nullptr)); if (cond == nullptr) { ASR::ttype_t *log_type = ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)); + ASR::expr_t* left = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, target, + ASR::binopType::Add, c, type, nullptr)); + cond = ASRUtils::EXPR(ASR::make_IntegerCompare_t(al, loc, - ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, target, - ASR::binopType::Add, c, type, nullptr)), cmp_op, b, log_type, nullptr)); + left, cmp_op, b, log_type, nullptr)); } } Vec body; @@ -990,12 +1128,8 @@ namespace LCompilers { for (size_t i=0; i orelse; - orelse.reserve(al, loop.n_orelse); - for (size_t i = 0; i < loop.n_orelse; i++) - orelse.push_back(al, loop.m_orelse[i]); ASR::stmt_t *while_loop_stmt = ASRUtils::STMT(ASR::make_WhileLoop_t(al, loc, - loop.m_name, cond, body.p, body.size(), orelse.p, orelse.size())); + loop.m_name, cond, body.p, body.size(), loop.m_orelse, loop.n_orelse)); Vec result; result.reserve(al, 2); if( loop_init_stmt ) { @@ -1009,28 +1143,58 @@ namespace LCompilers { return result; } + #define increment_by_one(var, body) ASR::expr_t* inc_by_one = builder.ElementalAdd(var, \ + make_ConstantWithType(make_IntegerConstant_t, 1, \ + ASRUtils::expr_type(var), loc), loc); \ + ASR::stmt_t* assign_inc = builder.Assignment(var, inc_by_one); \ + body->push_back(al, assign_inc); \ + namespace ReplacerUtils { void visit_ArrayConstant(ASR::ArrayConstant_t* x, Allocator& al, ASR::expr_t* arr_var, Vec* result_vec, ASR::expr_t* idx_var, SymbolTable* current_scope, bool perform_cast, ASR::cast_kindType cast_kind, ASR::ttype_t* casted_type) { - #define increment_by_one(var, body) ASR::expr_t* inc_by_one = builder.ElementalAdd(var, \ - make_ConstantWithType(make_IntegerConstant_t, 1, \ - ASRUtils::expr_type(var), loc), loc); \ - ASR::stmt_t* assign_inc = builder.Assignment(var, inc_by_one); \ - body->push_back(al, assign_inc); \ + const Location& loc = arr_var->base.loc; + ASRUtils::ASRBuilder builder(al, loc); + for( size_t k = 0; k < x->n_args; k++ ) { + ASR::expr_t* curr_init = x->m_args[k]; + ASR::expr_t* res = PassUtils::create_array_ref(arr_var, idx_var, + al, current_scope); + if( perform_cast && !ASRUtils::types_equal(ASRUtils::expr_type(curr_init), casted_type) ) { + curr_init = ASRUtils::EXPR(ASR::make_Cast_t( + al, curr_init->base.loc, curr_init, cast_kind, casted_type, nullptr)); + } + ASR::stmt_t* assign = builder.Assignment(res, curr_init); + result_vec->push_back(al, assign); + increment_by_one(idx_var, result_vec) + } + } + void visit_ArrayConstructor(ASR::ArrayConstructor_t* x, Allocator& al, + ASR::expr_t* arr_var, Vec* result_vec, + ASR::expr_t* idx_var, SymbolTable* current_scope, + bool perform_cast, ASR::cast_kindType cast_kind, ASR::ttype_t* casted_type) { const Location& loc = arr_var->base.loc; ASRUtils::ASRBuilder builder(al, loc); for( size_t k = 0; k < x->n_args; k++ ) { ASR::expr_t* curr_init = x->m_args[k]; + if( ASR::is_a(*curr_init) ) { + perform_cast = true; + cast_kind = ASR::down_cast(curr_init)->m_kind; + casted_type = ASR::down_cast(curr_init)->m_type; + curr_init = ASR::down_cast(curr_init)->m_arg; + } if( ASR::is_a(*curr_init) ) { ASR::ImpliedDoLoop_t* idoloop = ASR::down_cast(curr_init); - create_do_loop(al, idoloop, arr_var, result_vec, idx_var, perform_cast, cast_kind); + create_do_loop(al, idoloop, arr_var, result_vec, idx_var, perform_cast, cast_kind, casted_type); } else if( ASR::is_a(*curr_init) ) { ASR::ArrayConstant_t* array_constant_t = ASR::down_cast(curr_init); visit_ArrayConstant(array_constant_t, al, arr_var, result_vec, - idx_var, current_scope, perform_cast, cast_kind); + idx_var, current_scope, perform_cast, cast_kind, casted_type); + } else if( ASR::is_a(*curr_init) ) { + ASR::ArrayConstructor_t* array_constructor_t = ASR::down_cast(curr_init); + visit_ArrayConstructor(array_constructor_t, al, arr_var, result_vec, + idx_var, current_scope, perform_cast, cast_kind, casted_type); } else if( ASR::is_a(*curr_init) ) { ASR::ttype_t* element_type = ASRUtils::expr_type(curr_init); if( ASRUtils::is_array(element_type) ) { @@ -1048,7 +1212,7 @@ namespace LCompilers { }, current_scope, result_vec); } else { ASR::expr_t* res = PassUtils::create_array_ref(arr_var, idx_var, al, current_scope); - if( perform_cast ) { + if( perform_cast && !ASRUtils::types_equal(ASRUtils::expr_type(curr_init), casted_type) ) { curr_init = ASRUtils::EXPR(ASR::make_Cast_t( al, curr_init->base.loc, curr_init, cast_kind, casted_type, nullptr)); } diff --git a/src/libasr/pass/pass_utils.h b/src/libasr/pass/pass_utils.h index 0713b76806..2260ac51ed 100644 --- a/src/libasr/pass/pass_utils.h +++ b/src/libasr/pass/pass_utils.h @@ -110,6 +110,27 @@ namespace LCompilers { Vec replace_doloop(Allocator &al, const ASR::DoLoop_t &loop, int comp=-1, bool use_loop_variable_after_loop=false); + ASR::stmt_t* create_do_loop_helper_pack(Allocator &al, const Location &loc, + std::vector do_loop_variables, ASR::expr_t* array, ASR::expr_t* mask, + ASR::expr_t* res, ASR::expr_t* idx, int curr_idx); + + ASR::stmt_t* create_do_loop_helper_unpack(Allocator &al, const Location &loc, + std::vector do_loop_variables, ASR::expr_t* vector, ASR::expr_t* mask, + ASR::expr_t* res, ASR::expr_t* idx, int curr_idx); + + ASR::stmt_t* create_do_loop_helper_count(Allocator &al, const Location &loc, + std::vector do_loop_variables, ASR::expr_t* mask, ASR::expr_t* res, + int curr_idx); + + ASR::stmt_t* create_do_loop_helper_count_dim(Allocator &al, const Location &loc, + std::vector do_loop_variables, std::vector res_idx, + ASR::stmt_t* inner_most_do_loop, ASR::expr_t* c, ASR::expr_t* mask, ASR::expr_t* res, + int curr_idx, int dim); + + ASR::stmt_t* create_do_loop_helper_random_number(Allocator &al, const Location &loc, + std::vector do_loop_variables, ASR::symbol_t* s, ASR::expr_t* arr, + ASR::ttype_t* return_type, ASR::expr_t* arr_item, ASR::stmt_t* stmt, int curr_idx); + static inline bool is_aggregate_type(ASR::expr_t* var) { return ASR::is_a(*ASRUtils::expr_type(var)); } @@ -128,6 +149,75 @@ namespace LCompilers { return false; } + static inline void allocate_res_var(Allocator& al, ASR::FunctionCall_t* x, Vec &new_args, + ASR::expr_t* result_var_, Vec& pass_result, std::vector map) { + ASR::expr_t* func_call_merge = nullptr; + ASR::Function_t* sum = ASR::down_cast(ASRUtils::symbol_get_past_external(x->m_name)); + ASR::symbol_t* res = sum->m_symtab->resolve_symbol("result"); + if (res) { + ASR::ttype_t* type = ASRUtils::duplicate_type(al, x->m_type); + ASR::Array_t* res_arr = ASR::down_cast(type); + for (size_t i = 0; i < res_arr->n_dims; i++) { + if (ASR::is_a(*res_arr->m_dims[i].m_length)) { + func_call_merge = res_arr->m_dims[i].m_length; + ASR::FunctionCall_t* func_call = ASR::down_cast(func_call_merge); + if (ASR::is_a(*func_call->m_args[0].m_value)) { + ASR::ArraySize_t *array_size = ASR::down_cast(func_call->m_args[0].m_value); + array_size->m_v = ASR::down_cast(new_args[map[0]].m_value)->m_arg; + func_call->m_args[0].m_value = ASRUtils::EXPR((ASR::asr_t*) array_size); + } + if (ASR::is_a(*func_call->m_args[1].m_value)) { + ASR::ArraySize_t *array_size = ASR::down_cast(func_call->m_args[1].m_value); + array_size->m_v = ASR::down_cast(new_args[map[1]].m_value)->m_arg; + + func_call->m_args[1].m_value = ASRUtils::EXPR((ASR::asr_t*) array_size); + } + if (ASR::is_a(*func_call->m_args[2].m_value)) { + ASR::IntegerCompare_t *integer_compare = ASR::down_cast(func_call->m_args[2].m_value); + integer_compare->m_right = new_args[map[2]].m_value; + + func_call->m_args[2].m_value = ASRUtils::EXPR((ASR::asr_t*) integer_compare); + } + res_arr->m_dims[i].m_length = func_call_merge; + } + } + if (func_call_merge) { + // allocate result array + Vec alloc_args; alloc_args.reserve(al, 1); + ASR::alloc_arg_t alloc_arg; alloc_arg.loc = x->base.base.loc; + alloc_arg.m_a = result_var_; alloc_arg.m_len_expr = nullptr; + alloc_arg.m_type = nullptr; alloc_arg.m_dims = res_arr->m_dims; + alloc_arg.n_dims = res_arr->n_dims; + alloc_args.push_back(al, alloc_arg); + + ASR::stmt_t* allocate_stmt = ASRUtils::STMT(ASR::make_Allocate_t(al, + x->base.base.loc, alloc_args.p, alloc_args.n, nullptr, nullptr, nullptr)); + pass_result.push_back(al, allocate_stmt); + } + } + } + + static inline ASR::expr_t* get_actual_arg_(ASR::expr_t* arg, Vec& func_call_args, Vec actual_args) { + if (!ASR::is_a(*arg)) return arg; + std::string arg_name = ASRUtils::symbol_name(ASR::down_cast(arg)->m_v); + for (size_t i = 0; i < func_call_args.size(); i++) { + ASR::expr_t* func_arg = func_call_args[i].m_value; + if (func_arg == nullptr) { + continue; + } + if (ASR::is_a(*func_arg)) { + func_arg = ASR::down_cast(func_arg)->m_arg; + } + if (ASR::is_a(*func_arg)) { + std::string func_arg_name = ASRUtils::symbol_name(ASR::down_cast(func_arg)->m_v); + if (arg_name == func_arg_name) { + return actual_args[i]; + } + } + } + return arg; + } + template class PassVisitor: public ASR::ASRPassBaseWalkVisitor { @@ -271,6 +361,7 @@ namespace LCompilers { bool fill_function_dependencies; bool fill_module_dependencies; bool fill_variable_dependencies; + bool _return_var_or_intent_out = false; SymbolTable* current_scope; public: @@ -331,7 +422,11 @@ namespace LCompilers { variable_dependencies.reserve(al, 1); bool fill_variable_dependencies_copy = fill_variable_dependencies; fill_variable_dependencies = true; + _return_var_or_intent_out = (x.m_intent == ASR::intentType::Out || + x.m_intent == ASR::intentType::ReturnVar || + x.m_intent == ASR::intentType::InOut); BaseWalkVisitor::visit_Variable(x); + _return_var_or_intent_out = false; xx.n_dependencies = variable_dependencies.size(); xx.m_dependencies = variable_dependencies.p; fill_variable_dependencies = fill_variable_dependencies_copy; @@ -344,7 +439,7 @@ namespace LCompilers { } void visit_FunctionCall(const ASR::FunctionCall_t& x) { - if (fill_function_dependencies) { + if (fill_function_dependencies) { ASR::symbol_t* asr_owner_sym = nullptr; if (current_scope->asr_owner && ASR::is_a(*current_scope->asr_owner)) { asr_owner_sym = ASR::down_cast(current_scope->asr_owner); @@ -361,7 +456,12 @@ namespace LCompilers { } } else { function_dependencies.push_back(al, ASRUtils::symbol_name(x.m_name)); - } + } + } + + if (_return_var_or_intent_out && temp_scope->get_counter() != ASRUtils::symbol_parent_symtab(x.m_name)->get_counter() && + !ASR::is_a(*x.m_name)) { + function_dependencies.push_back(al, ASRUtils::symbol_name(x.m_name)); } } if( ASR::is_a(*x.m_name) && @@ -382,7 +482,7 @@ namespace LCompilers { } SymbolTable* temp_scope = current_scope; - + if (asr_owner_sym && temp_scope->get_counter() != ASRUtils::symbol_parent_symtab(x.m_name)->get_counter() && !ASR::is_a(*x.m_name) && !ASR::is_a(*x.m_name)) { if (ASR::is_a(*asr_owner_sym) || ASR::is_a(*asr_owner_sym)) { @@ -392,7 +492,7 @@ namespace LCompilers { } } else { function_dependencies.push_back(al, ASRUtils::symbol_name(x.m_name)); - } + } } } @@ -592,11 +692,12 @@ namespace LCompilers { idoloop_m_values_i, cast_kind, casted_type, nullptr)); } ASR::stmt_t* doloop_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.loc, - array_ref, idoloop->m_values[i], nullptr)); + array_ref, idoloop_m_values_i, nullptr)); doloop_body.push_back(al, doloop_stmt); if( arr_idx != nullptr ) { + ASR::expr_t* one = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, arr_var->base.loc, 1, ASRUtils::TYPE(ASR::make_Integer_t(al, arr_var->base.loc, 4)))); ASR::expr_t* increment = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, arr_var->base.loc, - arr_idx, ASR::binopType::Add, const_1, ASRUtils::expr_type(arr_idx), nullptr)); + arr_idx, ASR::binopType::Add, one, ASRUtils::expr_type(arr_idx), nullptr)); ASR::stmt_t* assign_stmt = ASRUtils::STMT(ASR::make_Assignment_t(al, arr_var->base.loc, arr_idx, increment, nullptr)); doloop_body.push_back(al, assign_stmt); @@ -604,7 +705,7 @@ namespace LCompilers { } } ASR::stmt_t* doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, arr_var->base.loc, - nullptr, head, doloop_body.p, doloop_body.size(), nullptr, 0)); + nullptr, head, doloop_body.p, doloop_body.size(), nullptr, 0)); result_vec->push_back(al, doloop); } @@ -633,7 +734,7 @@ namespace LCompilers { doloop_body.push_back(al, doloop); } doloop = ASRUtils::STMT(ASR::make_DoLoop_t(al, loc, nullptr, head, - doloop_body.p, doloop_body.size(), nullptr, 0)); + doloop_body.p, doloop_body.size(), nullptr, 0)); } result_vec->push_back(al, doloop); } @@ -677,6 +778,12 @@ namespace LCompilers { bool perform_cast=false, ASR::cast_kindType cast_kind=ASR::cast_kindType::IntegerToInteger, ASR::ttype_t* casted_type=nullptr); + void visit_ArrayConstructor(ASR::ArrayConstructor_t* x, Allocator& al, + ASR::expr_t* arr_var, Vec* result_vec, + ASR::expr_t* idx_var, SymbolTable* current_scope, + bool perform_cast=false, ASR::cast_kindType cast_kind=ASR::cast_kindType::IntegerToInteger, + ASR::ttype_t* casted_type=nullptr); + template static inline void replace_ArrayConstant(ASR::ArrayConstant_t* x, T* replacer, bool& remove_original_statement, Vec* result_vec, @@ -723,6 +830,106 @@ namespace LCompilers { "dimension sliced are supported for now."); } + Vec idx_vars; + PassUtils::create_idx_vars(idx_vars, 1, loc, replacer->al, replacer->current_scope); + ASR::expr_t* idx_var = idx_vars[0]; + ASR::expr_t* lb = PassUtils::get_bound(target_section->m_v, sliced_dim_index, "lbound", replacer->al); + ASR::expr_t* const_1 = ASRUtils::EXPR(ASR::make_IntegerConstant_t(replacer->al, loc, 1, + ASRUtils::expr_type(idx_var))); + ASR::stmt_t* assign_stmt = ASRUtils::STMT(ASR::make_Assignment_t(replacer->al, + target_section->base.base.loc, idx_var, lb, nullptr)); + result_vec->push_back(replacer->al, assign_stmt); + for( size_t k = 0; k < x->n_args; k++ ) { + Vec args; + args.reserve(replacer->al, target_section->n_args); + for( size_t i = 0; i < target_section->n_args; i++ ) { + if( i + 1 == sliced_dim_index ) { + ASR::array_index_t ai; + ai.loc = target_section->base.base.loc; + ai.m_left = nullptr; + ai.m_step = nullptr; + ai.m_right = idx_var; + args.push_back(replacer->al, ai); + } else { + args.push_back(replacer->al, target_section->m_args[i]); + } + } + + ASR::ttype_t* array_ref_type = ASRUtils::expr_type(replacer->result_var); + Vec empty_dims; + empty_dims.reserve(replacer->al, 1); + array_ref_type = ASRUtils::duplicate_type(replacer->al, array_ref_type, &empty_dims); + + ASR::expr_t* array_ref = ASRUtils::EXPR(ASRUtils::make_ArrayItem_t_util(replacer->al, + target_section->base.base.loc, + target_section->m_v, + args.p, args.size(), + ASRUtils::type_get_past_pointer( + ASRUtils::type_get_past_allocatable(array_ref_type)), + ASR::arraystorageType::RowMajor, nullptr)); + ASR::expr_t* x_m_args_k = x->m_args[k]; + if( perform_cast ) { + LCOMPILERS_ASSERT(casted_type != nullptr); + x_m_args_k = ASRUtils::EXPR(ASR::make_Cast_t(replacer->al, array_ref->base.loc, + x_m_args_k, cast_kind, casted_type, nullptr)); + } + ASR::stmt_t* assign_stmt = ASRUtils::STMT(ASR::make_Assignment_t(replacer->al, target_section->base.base.loc, + array_ref, x_m_args_k, nullptr)); + result_vec->push_back(replacer->al, assign_stmt); + ASR::expr_t* increment = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(replacer->al, target_section->base.base.loc, + idx_var, ASR::binopType::Add, const_1, ASRUtils::expr_type(idx_var), nullptr)); + assign_stmt = ASRUtils::STMT(ASR::make_Assignment_t(replacer->al, target_section->base.base.loc, idx_var, increment, nullptr)); + result_vec->push_back(replacer->al, assign_stmt); + } + } + } + + template + static inline void replace_ArrayConstructor(ASR::ArrayConstructor_t* x, T* replacer, + bool& remove_original_statement, Vec* result_vec, + bool perform_cast=false, + ASR::cast_kindType cast_kind=ASR::cast_kindType::IntegerToInteger, + ASR::ttype_t* casted_type=nullptr) { + LCOMPILERS_ASSERT(replacer->result_var != nullptr); + if( x->n_args == 0 ) { + remove_original_statement = true; + return ; + } + + const Location& loc = x->base.base.loc; + if( ASR::is_a(*replacer->result_var) ) { + [[maybe_unused]] ASR::ttype_t* result_var_type = ASRUtils::expr_type(replacer->result_var); + LCOMPILERS_ASSERT_MSG(ASRUtils::extract_n_dims_from_ttype(result_var_type) == 1, + "Initialisation using ArrayConstructor is " + "supported only for single dimensional arrays, found: " + + std::to_string(ASRUtils::extract_n_dims_from_ttype(result_var_type))) + Vec idx_vars; + PassUtils::create_idx_vars(idx_vars, 1, loc, replacer->al, replacer->current_scope); + ASR::expr_t* idx_var = idx_vars[0]; + ASR::expr_t* lb = PassUtils::get_bound(replacer->result_var, 1, "lbound", replacer->al); + ASR::stmt_t* assign_stmt = ASRUtils::STMT(ASR::make_Assignment_t(replacer->al, + loc, idx_var, lb, nullptr)); + result_vec->push_back(replacer->al, assign_stmt); + visit_ArrayConstructor(x, replacer->al, replacer->result_var, result_vec, + idx_var, replacer->current_scope, + perform_cast, cast_kind, casted_type); + } else if( ASR::is_a(*replacer->result_var) ) { + ASR::ArraySection_t* target_section = ASR::down_cast(replacer->result_var); + int sliced_dims_count = 0; + size_t sliced_dim_index = 0; + for( size_t i = 0; i < target_section->n_args; i++ ) { + if( !(target_section->m_args[i].m_left == nullptr && + target_section->m_args[i].m_right != nullptr && + target_section->m_args[i].m_step == nullptr) ) { + sliced_dims_count += 1; + sliced_dim_index = i + 1; + } + } + if( sliced_dims_count != 1 ) { + throw LCompilersException("Target expressions only having one " + "dimension sliced are supported for now."); + } + Vec idx_vars; PassUtils::create_idx_vars(idx_vars, 1, loc, replacer->al, replacer->current_scope); ASR::expr_t* idx_var = idx_vars[0]; diff --git a/src/libasr/pass/print_arr.cpp b/src/libasr/pass/print_arr.cpp index 73226e5a66..ea5416e25e 100644 --- a/src/libasr/pass/print_arr.cpp +++ b/src/libasr/pass/print_arr.cpp @@ -59,7 +59,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor PassUtils::create_idx_vars(idx_vars, n_dims, loc, al, current_scope); ASR::stmt_t* doloop = nullptr; ASR::stmt_t* empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, loc, - nullptr, 0, nullptr, nullptr)); + nullptr, 0, nullptr, nullptr)); ASR::ttype_t *str_type_len_1 = ASRUtils::TYPE(ASR::make_Character_t( al, loc, 1, 1, nullptr)); ASR::ttype_t *str_type_len_2 = ASRUtils::TYPE(ASR::make_Character_t( @@ -84,7 +84,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor print_args.push_back(al, ref); ASR::stmt_t* print_stmt = nullptr; if (format != nullptr) { - ASR::expr_t* string_format = ASRUtils::EXPR(ASR::make_StringFormat_t(al, format->base.base.loc, + ASR::expr_t* string_format = ASRUtils::EXPR(ASRUtils::make_StringFormat_t_util(al, format->base.base.loc, format->m_fmt, print_args.p, print_args.size(), ASR::string_format_kindType::FormatFortran, format->m_type, format->m_value)); Vec format_args; @@ -92,6 +92,9 @@ class PrintArrVisitor : public PassUtils::PassVisitor format_args.push_back(al, string_format); print_stmt = ASRUtils::STMT(ASR::make_Print_t(al, loc, format_args.p, format_args.size(), nullptr, empty_space)); + } else if (ASR::is_a(*ASRUtils::type_get_past_allocatable(ASRUtils::type_get_past_array(ASRUtils::expr_type(print_args[0]))))) { + print_stmt = ASRUtils::STMT(ASR::make_Print_t(al, loc, + print_args.p, print_args.size(), nullptr, empty_space)); } else { print_stmt = ASRUtils::STMT(ASR::make_Print_t(al, loc, print_args.p, print_args.size(), nullptr, space)); @@ -106,13 +109,34 @@ class PrintArrVisitor : public PassUtils::PassVisitor return doloop; } - ASR::stmt_t* create_formatstmt(std::vector &print_body, ASR::StringFormat_t* format, const Location &loc, ASR::stmtType _type) { + void print_fixed_sized_array(ASR::expr_t *arr_expr,std::vector& print_body, const Location &loc) { + ASR::dimension_t* m_dims; + int n_dims = ASRUtils::extract_dimensions_from_ttype(ASRUtils::expr_type(arr_expr), m_dims); + int m_dim_length = ASR::down_cast(m_dims->m_length)->m_n; + Vec idx_vars; + PassUtils::create_idx_vars(idx_vars, n_dims, loc, al, current_scope); + ASR::ttype_t *int32_type = ASRUtils::TYPE(ASR::make_Integer_t(al, loc, 4)); + ASR::expr_t* one = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, 1, int32_type)); + for (int n = 0; n < n_dims; n++) { + ASR::expr_t* idx_var = idx_vars[n]; + idx_var = one; + for (int m = 0; m < m_dim_length; m++) { + ASR::expr_t* ref = PassUtils::create_array_ref(arr_expr, idx_var, al, current_scope); + print_body.push_back(ref); + idx_var = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, idx_var, + ASR::binopType::Add, one, int32_type, nullptr)); + } + } + } + + ASR::stmt_t* create_formatstmt(std::vector &print_body, ASR::StringFormat_t* format, const Location &loc, ASR::stmtType _type, + ASR::expr_t* unit = nullptr, ASR::expr_t* separator = nullptr, ASR::expr_t* end = nullptr, ASR::stmt_t* overloaded = nullptr) { Vec body; body.reserve(al, print_body.size()); for (size_t j=0; jbase.base.loc, + ASR::expr_t* string_format = ASRUtils::EXPR(ASRUtils::make_StringFormat_t_util(al, format->base.base.loc, format->m_fmt, body.p, body.size(), ASR::string_format_kindType::FormatFortran, format->m_type, nullptr)); Vec print_args; @@ -121,10 +145,10 @@ class PrintArrVisitor : public PassUtils::PassVisitor ASR::stmt_t* statement = nullptr; if (_type == ASR::stmtType::Print) { statement = ASRUtils::STMT(ASR::make_Print_t(al, loc, - print_args.p, print_args.size(), nullptr, nullptr)); + print_args.p, print_args.size(), nullptr, nullptr)); } else if (_type == ASR::stmtType::FileWrite) { - statement = ASRUtils::STMT(ASR::make_FileWrite_t(al, loc, 0, nullptr, - nullptr, nullptr, nullptr, print_args.p, print_args.size(), nullptr, nullptr)); + statement = ASRUtils::STMT(ASR::make_FileWrite_t(al, loc, 0, unit, + nullptr, nullptr, nullptr, print_args.p, print_args.size(), separator, end, overloaded)); } print_body.clear(); return statement; @@ -136,17 +160,21 @@ class PrintArrVisitor : public PassUtils::PassVisitor ASR::stmt_t* print_stmt; if (x.n_values > 0 && ASR::is_a(*x.m_values[0])) { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, nullptr)); + nullptr, 0, nullptr, nullptr)); ASR::StringFormat_t* format = ASR::down_cast(x.m_values[0]); for (size_t i=0; in_args; i++) { if (PassUtils::is_array(format->m_args[i])) { - if (print_body.size() > 0) { - print_stmt = create_formatstmt(print_body, format, x.base.base.loc, ASR::stmtType::Print); + if (ASRUtils::is_fixed_size_array(ASRUtils::expr_type(format->m_args[i]))) { + print_fixed_sized_array(format->m_args[i], print_body, x.base.base.loc); + } else { + if (print_body.size() > 0) { + print_stmt = create_formatstmt(print_body, format, x.base.base.loc, ASR::stmtType::Print); + pass_result.push_back(al, print_stmt); + } + print_stmt = print_array_using_doloop(format->m_args[i],format, x.base.base.loc); pass_result.push_back(al, print_stmt); + pass_result.push_back(al, empty_print_endl); } - print_stmt = print_array_using_doloop(format->m_args[i],format, x.base.base.loc); - pass_result.push_back(al, print_stmt); - pass_result.push_back(al, empty_print_endl); } else { print_body.push_back(format->m_args[i]); } @@ -164,15 +192,11 @@ class PrintArrVisitor : public PassUtils::PassVisitor ASR::expr_t *backspace = ASRUtils::EXPR(ASR::make_StringConstant_t( al, x.base.base.loc, s2c(al, "\b"), str_type_len_1)); ASR::stmt_t* back = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, backspace)); + nullptr, 0, nullptr, backspace)); for (size_t i=0; i(*ASRUtils::expr_type(x.m_values[i])) && PassUtils::is_array(x.m_values[i])) { if (print_body.size() > 0) { @@ -199,18 +223,18 @@ class PrintArrVisitor : public PassUtils::PassVisitor if (x.m_separator) { if (i == x.n_values - 1) { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, x.m_end)); + nullptr, 0, nullptr, x.m_end)); } else { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, x.m_separator)); + nullptr, 0, nullptr, x.m_separator)); } } else { if (i == x.n_values - 1) { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, x.m_end)); + nullptr, 0, nullptr, x.m_end)); } else { empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc, - nullptr, 0, nullptr, nullptr)); + nullptr, 0, nullptr, nullptr)); } } pass_result.push_back(al, empty_print_endl); @@ -232,7 +256,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor } } - ASR::stmt_t* write_array_using_doloop(ASR::expr_t *arr_expr, ASR::StringFormat_t* format, const Location &loc) { + ASR::stmt_t* write_array_using_doloop(ASR::expr_t *arr_expr, ASR::StringFormat_t* format, ASR::expr_t* unit, const Location &loc) { int n_dims = PassUtils::get_rank(arr_expr); Vec idx_vars; PassUtils::create_idx_vars(idx_vars, n_dims, loc, al, current_scope); @@ -242,7 +266,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor ASR::expr_t *empty_space = ASRUtils::EXPR(ASR::make_StringConstant_t( al, loc, s2c(al, ""), str_type_len)); ASR::stmt_t* empty_file_write_endl = ASRUtils::STMT(ASR::make_FileWrite_t(al, loc, - 0, nullptr, nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr)); + 0, unit, nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr)); for( int i = n_dims - 1; i >= 0; i-- ) { ASR::do_loop_head_t head; head.m_v = idx_vars[i]; @@ -259,19 +283,19 @@ class PrintArrVisitor : public PassUtils::PassVisitor print_args.push_back(al, ref); ASR::stmt_t* write_stmt = nullptr; if (format != nullptr) { - ASR::expr_t* string_format = ASRUtils::EXPR(ASR::make_StringFormat_t(al, format->base.base.loc, + ASR::expr_t* string_format = ASRUtils::EXPR(ASRUtils::make_StringFormat_t_util(al, format->base.base.loc, format->m_fmt, print_args.p, print_args.size(), ASR::string_format_kindType::FormatFortran, format->m_type, format->m_value)); Vec format_args; format_args.reserve(al, 1); format_args.push_back(al, string_format); write_stmt = ASRUtils::STMT(ASR::make_FileWrite_t( - al, loc, i, nullptr, nullptr, nullptr, nullptr, - format_args.p, format_args.size(), nullptr, empty_space)); + al, loc, i, unit, nullptr, nullptr, nullptr, + format_args.p, format_args.size(), nullptr, empty_space, nullptr)); } else { write_stmt = ASRUtils::STMT(ASR::make_FileWrite_t( - al, loc, i, nullptr, nullptr, nullptr, nullptr, - print_args.p, print_args.size(), nullptr, nullptr)); + al, loc, i, unit, nullptr, nullptr, nullptr, + print_args.p, print_args.size(), nullptr, nullptr, nullptr)); } doloop_body.push_back(al, write_stmt); } else { @@ -287,54 +311,60 @@ class PrintArrVisitor : public PassUtils::PassVisitor Vec body; body.from_pointer_n_copy(al, write_body.data(), write_body.size()); ASR::stmt_t* write_stmt = ASRUtils::STMT(ASR::make_FileWrite_t( - al, x.base.base.loc, x.m_label, x.m_unit, x.m_iomsg, x.m_iostat, - x.m_id, body.p, body.size(), x.m_separator, x.m_end)); + al, x.base.base.loc, x.m_label, x.m_unit, x.m_iomsg, + x.m_iostat, x.m_id, body.p, body.size(), x.m_separator, x.m_end, x.m_overloaded)); pass_result.push_back(al, write_stmt); write_body.clear(); } void visit_FileWrite(const ASR::FileWrite_t& x) { + if (x.m_unit && ASRUtils::is_character(*ASRUtils::expr_type(x.m_unit))) { + // Skip for character write + return; + } std::vector write_body; ASR::stmt_t* write_stmt; ASR::stmt_t* empty_file_write_endl = ASRUtils::STMT(ASR::make_FileWrite_t(al, x.base.base.loc, - x.m_label, nullptr, nullptr, nullptr, nullptr, - nullptr, 0, nullptr, nullptr)); + x.m_label, x.m_unit, nullptr, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr)); if(x.m_values && x.m_values[0] != nullptr && ASR::is_a(*x.m_values[0])){ ASR::StringFormat_t* format = ASR::down_cast(x.m_values[0]); for (size_t i=0; in_args; i++) { if (PassUtils::is_array(format->m_args[i])) { - if (write_body.size() > 0) { - write_stmt = create_formatstmt(write_body, format, x.base.base.loc, ASR::stmtType::FileWrite); + if (ASRUtils::is_fixed_size_array(ASRUtils::expr_type(format->m_args[i]))) { + print_fixed_sized_array(format->m_args[i], write_body, x.base.base.loc); + } else { + if (write_body.size() > 0) { + write_stmt = create_formatstmt(write_body, format, + x.base.base.loc, ASR::stmtType::FileWrite, x.m_unit, x.m_separator, + x.m_end, x.m_overloaded); + pass_result.push_back(al, write_stmt); + } + write_stmt = write_array_using_doloop(format->m_args[i], format, x.m_unit, x.base.base.loc); pass_result.push_back(al, write_stmt); + pass_result.push_back(al, empty_file_write_endl); } - write_stmt = write_array_using_doloop(format->m_args[i],format, x.base.base.loc); - pass_result.push_back(al, write_stmt); - pass_result.push_back(al, empty_file_write_endl); } else { write_body.push_back(format->m_args[i]); } } if (write_body.size() > 0) { - write_stmt = create_formatstmt(write_body, format, x.base.base.loc, ASR::stmtType::FileWrite); + write_stmt = create_formatstmt(write_body, format, x.base.base.loc, + ASR::stmtType::FileWrite, x.m_unit, x.m_separator, + x.m_end, x.m_overloaded); pass_result.push_back(al, write_stmt); } return; } for (size_t i=0; i(*ASRUtils::expr_type(x.m_values[i])) && - PassUtils::is_array(x.m_values[i])) { + // DIVERGENCE between LFortran and LPython + // If a pointer array variable is provided + // then it will be printed as a normal array. + if (PassUtils::is_array(x.m_values[i])) { if (write_body.size() > 0) { print_args_apart_from_arrays(write_body, x); pass_result.push_back(al, empty_file_write_endl); } - write_stmt = write_array_using_doloop(x.m_values[i], nullptr, x.base.base.loc); + write_stmt = write_array_using_doloop(x.m_values[i], nullptr, x.m_unit, x.base.base.loc); pass_result.push_back(al, write_stmt); pass_result.push_back(al, empty_file_write_endl); } else { diff --git a/src/libasr/pass/promote_allocatable_to_nonallocatable.cpp b/src/libasr/pass/promote_allocatable_to_nonallocatable.cpp new file mode 100644 index 0000000000..740bf0ae74 --- /dev/null +++ b/src/libasr/pass/promote_allocatable_to_nonallocatable.cpp @@ -0,0 +1,257 @@ +#include +#include +#include +#include +#include +#include + +#include + +namespace LCompilers { + +class IsAllocatedCalled: public ASR::CallReplacerOnExpressionsVisitor { + public: + + std::map>& scope2var; + + IsAllocatedCalled(std::map>& scope2var_): + scope2var(scope2var_) {} + + void visit_IntrinsicImpureFunction(const ASR::IntrinsicImpureFunction_t& x) { + if( x.m_impure_intrinsic_id == static_cast( + ASRUtils::IntrinsicImpureFunctions::Allocated) ) { + LCOMPILERS_ASSERT(x.n_args == 1); + if( ASR::is_a(*x.m_args[0]) ) { + scope2var[current_scope].push_back( + ASR::down_cast(x.m_args[0])->m_v); + } + } + } + + void visit_FunctionCall(const ASR::FunctionCall_t& x) { + ASR::FunctionType_t* func_type = ASRUtils::get_FunctionType(x.m_name); + for( size_t i = 0; i < x.n_args; i++ ) { + if( ASR::is_a(*func_type->m_arg_types[i]) || + ASR::is_a(*func_type->m_arg_types[i]) ) { + if( ASR::is_a(*x.m_args[i].m_value) ) { + scope2var[current_scope].push_back( + ASR::down_cast(x.m_args[i].m_value)->m_v); + } + } + } + } + + void visit_SubroutineCall(const ASR::SubroutineCall_t& x) { + ASR::FunctionType_t* func_type = ASRUtils::get_FunctionType(x.m_name); + for( size_t i = 0; i < x.n_args; i++ ) { + if( ASR::is_a(*func_type->m_arg_types[i]) || + ASR::is_a(*func_type->m_arg_types[i]) ) { + if( ASR::is_a(*x.m_args[i].m_value) ) { + scope2var[current_scope].push_back( + ASR::down_cast(x.m_args[i].m_value)->m_v); + } + } + } + } + + void visit_ReAlloc(const ASR::ReAlloc_t& x) { + for( size_t i = 0; i < x.n_args; i++ ) { + if( ASR::is_a(*ASRUtils::expr_type(x.m_args[i].m_a)) || + ASR::is_a(*ASRUtils::expr_type(x.m_args[i].m_a)) ) { + if( ASR::is_a(*x.m_args[i].m_a) ) { + scope2var[current_scope].push_back( + ASR::down_cast(x.m_args[i].m_a)->m_v); + } + } + } + } + + void visit_Allocate(const ASR::Allocate_t& x) { + for( size_t i = 0; i < x.n_args; i++ ) { + ASR::alloc_arg_t alloc_arg = x.m_args[i]; + if( !ASRUtils::is_dimension_dependent_only_on_arguments( + alloc_arg.m_dims, alloc_arg.n_dims) ) { + if( ASR::is_a(*alloc_arg.m_a) ) { + scope2var[current_scope].push_back( + ASR::down_cast(alloc_arg.m_a)->m_v); + } + } + } + } + +}; + +class PromoteAllocatableToNonAllocatable: + public ASR::CallReplacerOnExpressionsVisitor +{ + private: + + Allocator& al; + bool remove_original_statement; + + public: + + std::map>& scope2var; + + PromoteAllocatableToNonAllocatable(Allocator& al_, + std::map>& scope2var_): + al(al_), remove_original_statement(false), scope2var(scope2var_) {} + + void visit_Allocate(const ASR::Allocate_t& x) { + ASR::Allocate_t& xx = const_cast(x); + Vec x_args; + x_args.reserve(al, x.n_args); + for( size_t i = 0; i < x.n_args; i++ ) { + ASR::alloc_arg_t alloc_arg = x.m_args[i]; + if( ASR::is_a(*alloc_arg.m_a) && + ASR::is_a(*ASRUtils::expr_type(alloc_arg.m_a)) && + ASRUtils::is_array(ASRUtils::expr_type(alloc_arg.m_a)) && + ASR::is_a( + *ASR::down_cast(alloc_arg.m_a)->m_v) && + ASRUtils::expr_intent(alloc_arg.m_a) == ASRUtils::intent_local && + ASRUtils::is_dimension_dependent_only_on_arguments( + alloc_arg.m_dims, alloc_arg.n_dims) && + std::find(scope2var[current_scope].begin(), + scope2var[current_scope].end(), + ASR::down_cast(alloc_arg.m_a)->m_v) == + scope2var[current_scope].end() ) { + ASR::Variable_t* alloc_variable = ASR::down_cast( + ASR::down_cast(alloc_arg.m_a)->m_v); + alloc_variable->m_type = ASRUtils::make_Array_t_util(al, x.base.base.loc, + ASRUtils::type_get_past_array( + ASRUtils::type_get_past_allocatable(alloc_variable->m_type)), + alloc_arg.m_dims, alloc_arg.n_dims); + } else if( ASR::is_a(*ASRUtils::expr_type(alloc_arg.m_a)) || + ASR::is_a(*ASRUtils::expr_type(alloc_arg.m_a)) ) { + x_args.push_back(al, alloc_arg); + } + } + if( x_args.size() > 0 ) { + xx.m_args = x_args.p; + xx.n_args = x_args.size(); + } else { + remove_original_statement = true; + } + } + + template + void visit_Deallocate(const T& x) { + T& xx = const_cast(x); + Vec x_args; + x_args.reserve(al, x.n_vars); + for( size_t i = 0; i < x.n_vars; i++ ) { + if( ASR::is_a( + *ASRUtils::expr_type(x.m_vars[i])) || + ASR::is_a( + *ASRUtils::expr_type(x.m_vars[i])) ) { + x_args.push_back(al, x.m_vars[i]); + } + } + if( x_args.size() > 0 ) { + xx.m_vars = x_args.p; + xx.n_vars = x_args.size(); + } else { + remove_original_statement = true; + } + } + + void visit_ExplicitDeallocate(const ASR::ExplicitDeallocate_t& x) { + visit_Deallocate(x); + } + + void visit_ImplicitDeallocate(const ASR::ImplicitDeallocate_t& x) { + visit_Deallocate(x); + } + + void transform_stmts(ASR::stmt_t **&m_body, size_t &n_body) { + bool remove_original_statement_copy = remove_original_statement; + Vec body; + body.reserve(al, n_body); + for (size_t i = 0; i < n_body; i++) { + remove_original_statement = false; + visit_stmt(*m_body[i]); + if( !remove_original_statement ) { + body.push_back(al, m_body[i]); + } + } + m_body = body.p; + n_body = body.size(); + remove_original_statement = remove_original_statement_copy; + } + +}; + +class FixArrayPhysicalCast: public ASR::BaseExprReplacer { + private: + Allocator& al; + + public: + + FixArrayPhysicalCast(Allocator& al_): al(al_) {} + + void replace_ArrayPhysicalCast(ASR::ArrayPhysicalCast_t* x) { + ASR::BaseExprReplacer::replace_ArrayPhysicalCast(x); + if( x->m_old != ASRUtils::extract_physical_type(ASRUtils::expr_type(x->m_arg)) ) { + x->m_old = ASRUtils::extract_physical_type(ASRUtils::expr_type(x->m_arg)); + } + if( (x->m_old == x->m_new && + x->m_old != ASR::array_physical_typeType::DescriptorArray) || + (x->m_old == x->m_new && x->m_old == ASR::array_physical_typeType::DescriptorArray && + (ASR::is_a(*ASRUtils::expr_type(x->m_arg)) || + ASR::is_a(*ASRUtils::expr_type(x->m_arg))) ) ) { + *current_expr = x->m_arg; + } + } + + void replace_FunctionCall(ASR::FunctionCall_t* x) { + ASR::BaseExprReplacer::replace_FunctionCall(x); + ASR::expr_t* call = ASRUtils::EXPR(ASRUtils::make_FunctionCall_t_util( + al, x->base.base.loc, x->m_name, x->m_original_name, x->m_args, + x->n_args, x->m_type, x->m_value, x->m_dt)); + ASR::FunctionCall_t* function_call = ASR::down_cast(call); + x->m_args = function_call->m_args; + x->n_args = function_call->n_args; + } +}; + +class FixArrayPhysicalCastVisitor: public ASR::CallReplacerOnExpressionsVisitor { + public: + + Allocator& al; + FixArrayPhysicalCast replacer; + + FixArrayPhysicalCastVisitor(Allocator& al_): al(al_), replacer(al_) {} + + void call_replacer() { + replacer.current_expr = current_expr; + replacer.replace_expr(*current_expr); + } + + void visit_SubroutineCall(const ASR::SubroutineCall_t& x) { + ASR::CallReplacerOnExpressionsVisitor::visit_SubroutineCall(x); + ASR::stmt_t* call = ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util( + al, x.base.base.loc, x.m_name, x.m_original_name, x.m_args, + x.n_args, x.m_dt, nullptr, false, ASRUtils::get_class_proc_nopass_val(x.m_name))); + ASR::SubroutineCall_t* subrout_call = ASR::down_cast(call); + ASR::SubroutineCall_t& xx = const_cast(x); + xx.m_args = subrout_call->m_args; + xx.n_args = subrout_call->n_args; + } +}; + +void pass_promote_allocatable_to_nonallocatable( + Allocator &al, ASR::TranslationUnit_t &unit, + const PassOptions &/*pass_options*/) { + std::map> scope2var; + IsAllocatedCalled is_allocated_called(scope2var); + is_allocated_called.visit_TranslationUnit(unit); + PromoteAllocatableToNonAllocatable promoter(al, scope2var); + promoter.visit_TranslationUnit(unit); + promoter.visit_TranslationUnit(unit); + FixArrayPhysicalCastVisitor fix_array_physical_cast(al); + fix_array_physical_cast.visit_TranslationUnit(unit); + PassUtils::UpdateDependenciesVisitor u(al); + u.visit_TranslationUnit(unit); +} + +} // namespace LCompilers diff --git a/src/libasr/pass/promote_allocatable_to_nonallocatable.h b/src/libasr/pass/promote_allocatable_to_nonallocatable.h new file mode 100644 index 0000000000..e15dc7047f --- /dev/null +++ b/src/libasr/pass/promote_allocatable_to_nonallocatable.h @@ -0,0 +1,14 @@ +#ifndef LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H +#define LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H + +#include +#include + +namespace LCompilers { + + void pass_promote_allocatable_to_nonallocatable(Allocator &al, ASR::TranslationUnit_t &unit, + const PassOptions &pass_options); + +} // namespace LCompilers + +#endif // LIBASR_PASS_PROMOTE_ALLOCATABLE_TO_NONALLOCATABLE_H diff --git a/src/libasr/pass/replace_function_call_in_declaration.h b/src/libasr/pass/replace_function_call_in_declaration.h new file mode 100644 index 0000000000..2b5be55efd --- /dev/null +++ b/src/libasr/pass/replace_function_call_in_declaration.h @@ -0,0 +1,14 @@ +#ifndef LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H +#define LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H + +#include +#include + +namespace LCompilers { + + void pass_replace_function_call_in_declaration(Allocator &al, ASR::TranslationUnit_t &unit, + const PassOptions &pass_options); + +} // namespace LCompilers + +#endif // LIBASR_PASS_REPLACE_FUNCTION_CALL_IN_DECLARATION_H diff --git a/src/libasr/pass/replace_intrinsic_subroutine.h b/src/libasr/pass/replace_intrinsic_subroutine.h new file mode 100644 index 0000000000..7d11dec7ac --- /dev/null +++ b/src/libasr/pass/replace_intrinsic_subroutine.h @@ -0,0 +1,14 @@ +#ifndef LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H +#define LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H + +#include +#include + +namespace LCompilers { + + void pass_replace_intrinsic_subroutine(Allocator &al, ASR::TranslationUnit_t &unit, + const PassOptions &pass_options); + +} // namespace LCompilers + +#endif // LIBASR_PASS_REPLACE_INTRINSIC_SUBROUTINE_H diff --git a/src/libasr/pass/replace_symbolic.cpp b/src/libasr/pass/replace_symbolic.cpp index c263ea444c..6e4aa5a7d2 100644 --- a/src/libasr/pass/replace_symbolic.cpp +++ b/src/libasr/pass/replace_symbolic.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace LCompilers { @@ -51,28 +52,28 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_args[0], x->m_args[1])); \ break; } #define BASIC_UNARYOP(SYM, name) \ - case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + case LCompilers::ASRUtils::IntrinsicElementalFunctions::Symbolic##SYM: { \ pass_result.push_back(al, basic_unaryop(loc, "basic_"#name, \ target, x->m_args[0])); \ break; } #define BASIC_ATTR(SYM, N) \ - case LCompilers::ASRUtils::IntrinsicScalarFunctions::Symbolic##SYM: { \ + case LCompilers::ASRUtils::IntrinsicElementalFunctions::Symbolic##SYM: { \ ASR::expr_t* function_call = basic_get_type(loc, \ intrinsic_func->m_args[0]); \ - return iEq(function_call, i32(N)); } + return b.iEq(function_call, b.i32(N)); } ASR::stmt_t *SubroutineCall(const Location &loc, ASR::symbol_t *sym, std::vector args) { @@ -268,16 +269,16 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*expr)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(expr); + if (ASR::is_a(*expr)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(expr); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; - switch (static_cast(intrinsic_id)) { - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicHasSymbolQ: - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicAddQ: - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicMulQ: - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicPowQ: - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicLogQ: - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSinQ: + switch (static_cast(intrinsic_id)) { + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicHasSymbolQ: + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicAddQ: + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicMulQ: + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicPowQ: + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicLogQ: + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicSinQ: return true; default: return false; @@ -416,8 +417,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*arg)) { return arg; - } else if (ASR::is_a(*arg)) { - this->visit_IntrinsicFunction(*ASR::down_cast(arg)); + } else if (ASR::is_a(*arg)) { + this->visit_IntrinsicFunction(*ASR::down_cast(arg)); } else if (ASR::is_a(*arg)) { this->visit_Cast(*ASR::down_cast(arg)); } else { @@ -428,10 +429,10 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_intrinsic_id; - switch (static_cast(intrinsic_id)) { - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicSymbol: { + switch (static_cast(intrinsic_id)) { + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicSymbol: { pass_result.push_back(al, symbol_set(loc, target, x->m_args[0])); break; } @@ -449,7 +450,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitorm_args[0]); @@ -495,11 +496,12 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*expr)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(expr); + if (ASR::is_a(*expr)) { + ASRUtils::ASRBuilder b(al, loc); + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(expr); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; - switch (static_cast(intrinsic_id)) { - case LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicHasSymbolQ: { + switch (static_cast(intrinsic_id)) { + case LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicHasSymbolQ: { return basic_has_symbol(loc, intrinsic_func->m_args[0], intrinsic_func->m_args[1]); } @@ -528,8 +530,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x.m_value)->m_v; pass_result.push_back(al, basic_assign(x.base.base.loc, x.m_target, ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, var_sym)))); - } else if (ASR::is_a(*x.m_value)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(x.m_value); + } else if (ASR::is_a(*x.m_value)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(x.m_value); if (intrinsic_func->m_type->type == ASR::ttypeType::SymbolicExpression) { process_intrinsic_function(x.base.base.loc, intrinsic_func, x.m_target); } else if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { @@ -549,11 +551,11 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*cast_value)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(cast_value); + } else if (ASR::is_a(*cast_value)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(cast_value); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; - if (static_cast(intrinsic_id) == - LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicInteger) { + if (static_cast(intrinsic_id) == + LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicInteger) { int const_value = 0; if (ASR::is_a(*cast_arg)){ ASR::IntegerConstant_t* const_int = ASR::down_cast(cast_arg); @@ -694,8 +696,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x); transform_stmts(xx.m_body, xx.n_body); transform_stmts(xx.m_orelse, xx.n_orelse); - if (ASR::is_a(*xx.m_test)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(xx.m_test); + if (ASR::is_a(*xx.m_test)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(xx.m_test); if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { if (is_logical_intrinsic_symbolic(xx.m_test)) { ASR::expr_t* function_call = process_attributes(xx.base.base.loc, xx.m_test); @@ -704,8 +706,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*xx.m_test)) { ASR::LogicalNot_t* logical_not = ASR::down_cast(xx.m_test); - if (ASR::is_a(*logical_not->m_arg)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(logical_not->m_arg); + if (ASR::is_a(*logical_not->m_arg)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(logical_not->m_arg); if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { if (is_logical_intrinsic_symbolic(logical_not->m_arg)) { ASR::expr_t* function_call = process_attributes(xx.base.base.loc, logical_not->m_arg); @@ -735,8 +737,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*val) && ASR::is_a(*ASRUtils::expr_type(val))) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(val); + if (val && ASR::is_a(*val) && ASR::is_a(*ASRUtils::expr_type(val))) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(val); ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, x.base.base.loc)); std::string symengine_var = symengine_stack.push(); ASR::symbol_t *arg = ASR::down_cast(ASR::make_Variable_t( @@ -787,8 +789,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*val)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(val); + } else if (ASR::is_a(*val)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(val); if (ASR::is_a(*ASRUtils::expr_type(val))) { ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, x.base.base.loc)); std::string symengine_var = symengine_stack.push(); @@ -863,7 +865,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitortype == ASR::ttypeType::SymbolicExpression) { ASR::ttype_t *type = ASRUtils::TYPE(ASR::make_SymbolicExpression_t(al, x.base.base.loc)); std::string symengine_var = symengine_stack.push(); @@ -879,7 +881,7 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x); + ASR::IntrinsicElementalFunction_t &xx = const_cast(x); ASR::expr_t* target = ASRUtils::EXPR(ASR::make_Var_t(al, x.base.base.loc, arg)); process_intrinsic_function(x.base.base.loc, &xx, target); } @@ -905,11 +907,11 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*cast_value)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(cast_value); + if (ASR::is_a(*cast_value)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(cast_value); int64_t intrinsic_id = intrinsic_func->m_intrinsic_id; - if (static_cast(intrinsic_id) == - LCompilers::ASRUtils::IntrinsicScalarFunctions::SymbolicInteger) { + if (static_cast(intrinsic_id) == + LCompilers::ASRUtils::IntrinsicElementalFunctions::SymbolicInteger) { int const_value = 0; if (ASR::is_a(*cast_arg)){ ASR::IntegerConstant_t* const_int = ASR::down_cast(cast_arg); @@ -934,8 +936,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*expr)) { var_sym = ASR::down_cast(expr)->m_v; - } else if (ASR::is_a(*expr)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(expr); + } else if (ASR::is_a(*expr)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(expr); this->visit_IntrinsicFunction(*intrinsic_func); var_sym = current_scope->get_symbol(symengine_stack.pop()); } else if (ASR::is_a(*expr)) { @@ -977,8 +979,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(*x.m_test)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(x.m_test); + } else if (ASR::is_a(*x.m_test)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(x.m_test); if (intrinsic_func->m_type->type == ASR::ttypeType::Logical) { if (is_logical_intrinsic_symbolic(x.m_test)) { ASR::expr_t* test = process_attributes(x.base.base.loc, x.m_test); @@ -1012,8 +1014,8 @@ class ReplaceSymbolicVisitor : public PassUtils::PassVisitor(x); transform_stmts(xx.m_body, xx.n_body); - if (ASR::is_a(*xx.m_test)) { - ASR::IntrinsicScalarFunction_t* intrinsic_func = ASR::down_cast(xx.m_test); + if (ASR::is_a(*xx.m_test)) { + ASR::IntrinsicElementalFunction_t* intrinsic_func = ASR::down_cast(xx.m_test); if (ASR::is_a(*intrinsic_func->m_type)) { ASR::expr_t* function_call = process_attributes(xx.base.base.loc, xx.m_test); xx.m_test = function_call; diff --git a/src/libasr/pass/select_case.cpp b/src/libasr/pass/select_case.cpp index d5cd5e0b06..0fba2c20e3 100644 --- a/src/libasr/pass/select_case.cpp +++ b/src/libasr/pass/select_case.cpp @@ -150,6 +150,69 @@ Vec replace_selectcase(Allocator &al, const ASR::Select_t &select_ return body; } +void case_to_if_with_fall_through(Allocator& al, const ASR::Select_t& x, + ASR::expr_t* a_test, Vec& body, SymbolTable* scope) { + body.reserve(al, x.n_body + 1); + const Location& loc = x.base.base.loc; + ASR::symbol_t* case_found_sym = ASR::down_cast(ASR::make_Variable_t( + al, loc, scope, s2c(al, scope->get_unique_name("case_found")), nullptr, 0, + ASR::intentType::Local, nullptr, nullptr, ASR::storage_typeType::Default, + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)), nullptr, ASR::abiType::Source, + ASR::accessType::Public, ASR::presenceType::Required, false)); + scope->add_symbol(scope->get_unique_name("case_found"), case_found_sym); + ASR::expr_t* true_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, true, + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)))); + ASR::expr_t* false_asr = ASRUtils::EXPR(ASR::make_LogicalConstant_t(al, loc, false, + ASRUtils::TYPE(ASR::make_Logical_t(al, loc, 4)))); + ASR::expr_t* case_found = ASRUtils::EXPR(ASR::make_Var_t(al, loc, case_found_sym)); + body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t(al, loc, case_found, false_asr, nullptr))); + int label_id = ASRUtils::LabelGenerator::get_instance()->get_unique_label(); + for( size_t idx = 0; idx < x.n_body; idx++ ) { + ASR::case_stmt_t* case_body = x.m_body[idx]; + switch(case_body->type) { + case ASR::case_stmtType::CaseStmt: { + ASR::CaseStmt_t* Case_Stmt = ASR::down_cast(case_body); + ASR::expr_t* test_expr = gen_test_expr_CaseStmt(al, loc, Case_Stmt, a_test); + test_expr = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, loc, test_expr, + ASR::logicalbinopType::Or, case_found, ASRUtils::expr_type(case_found), nullptr)); + Vec case_body; case_body.reserve(al, Case_Stmt->n_body); + case_body.from_pointer_n(Case_Stmt->m_body, Case_Stmt->n_body); + case_body.push_back(al, ASRUtils::STMT(ASR::make_Assignment_t( + al, loc, case_found, true_asr, nullptr))); + if( !Case_Stmt->m_fall_through ) { + case_body.push_back(al, ASRUtils::STMT(ASR::make_GoTo_t(al, loc, + label_id, s2c(al, scope->get_unique_name("switch_case_label"))))); + } + body.push_back(al, ASRUtils::STMT(ASR::make_If_t(al, loc, + test_expr, case_body.p, case_body.size(), nullptr, 0))); + break; + } + case ASR::case_stmtType::CaseStmt_Range: { + LCOMPILERS_ASSERT(false); + break; + } + } + } + for( size_t id = 0; id < x.n_default; id++ ) { + body.push_back(al, x.m_default[id]); + } + SymbolTable* block_symbol_table = al.make_new(scope); + ASR::symbol_t* empty_block = ASR::down_cast(ASR::make_Block_t( + al, loc, block_symbol_table, s2c(al, scope->get_unique_name("switch_case_label")), + nullptr, 0)); + scope->add_symbol(scope->get_unique_name("switch_case_label"), empty_block); + body.push_back(al, ASRUtils::STMT(ASR::make_BlockCall_t(al, loc, label_id, empty_block))); +} + +Vec replace_selectcase_with_fall_through( + Allocator &al, const ASR::Select_t &select_case, + SymbolTable* scope) { + ASR::expr_t *a = select_case.m_test; + Vec body; + case_to_if_with_fall_through(al, select_case, a, body, scope); + return body; +} + class SelectCaseVisitor : public PassUtils::PassVisitor { @@ -165,7 +228,11 @@ class SelectCaseVisitor : public PassUtils::PassVisitor } void visit_Select(const ASR::Select_t &x) { - pass_result = replace_selectcase(al, x); + if( x.m_enable_fall_through ) { + pass_result = replace_selectcase_with_fall_through(al, x, current_scope); + } else { + pass_result = replace_selectcase(al, x); + } } }; diff --git a/src/libasr/pass/subroutine_from_function.cpp b/src/libasr/pass/subroutine_from_function.cpp index d7b4c2d8eb..b815869046 100644 --- a/src/libasr/pass/subroutine_from_function.cpp +++ b/src/libasr/pass/subroutine_from_function.cpp @@ -175,7 +175,7 @@ class ReplaceFunctionCallWithSubroutineCall: is_return_var_handled = fn->m_return_var == nullptr; } if (is_return_var_handled) { - ASR::ttype_t* result_var_type = x->m_type; + ASR::ttype_t* result_var_type = ASRUtils::duplicate_type(al, x->m_type); bool is_allocatable = false; bool is_func_call_allocatable = false; bool is_result_var_allocatable = false; @@ -302,11 +302,25 @@ class ReplaceFunctionCallWithSubroutineCall: s_args.push_back(al, result_arg); ASR::stmt_t* subrout_call = ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util(al, loc, x->m_name, nullptr, s_args.p, s_args.size(), nullptr, - nullptr, false)); + nullptr, false, false)); pass_result.push_back(al, subrout_call); } } + void replace_ArrayPhysicalCast(ASR::ArrayPhysicalCast_t* x) { + ASR::BaseExprReplacer::replace_ArrayPhysicalCast(x); + if( (x->m_old == x->m_new && + x->m_old != ASR::array_physical_typeType::DescriptorArray) || + (x->m_old == x->m_new && x->m_old == ASR::array_physical_typeType::DescriptorArray && + (ASR::is_a(*ASRUtils::expr_type(x->m_arg)) || + ASR::is_a(*ASRUtils::expr_type(x->m_arg)))) || + x->m_old != ASRUtils::extract_physical_type(ASRUtils::expr_type(x->m_arg)) ) { + *current_expr = x->m_arg; + } else { + x->m_old = ASRUtils::extract_physical_type(ASRUtils::expr_type(x->m_arg)); + } + } + }; class ReplaceFunctionCallWithSubroutineCallVisitor: @@ -365,7 +379,8 @@ class ReplaceFunctionCallWithSubroutineCallVisitor: void visit_Assignment(const ASR::Assignment_t &x) { if( (ASR::is_a(*ASRUtils::expr_type(x.m_target)) && ASR::is_a(*x.m_value)) || - (ASR::is_a(*x.m_value))) { + (ASR::is_a(*x.m_value) || + ASR::is_a(*x.m_value)) ) { return ; } diff --git a/src/libasr/pass/transform_optional_argument_functions.cpp b/src/libasr/pass/transform_optional_argument_functions.cpp index 7e379fb6b8..fd33065da2 100644 --- a/src/libasr/pass/transform_optional_argument_functions.cpp +++ b/src/libasr/pass/transform_optional_argument_functions.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,7 @@ class ReplacePresentCalls: public ASR::BaseExprReplacer { public: - ReplacePresentCalls(Allocator& al_, ASR::Function_t* f_) : al(al_), f(f_) + ReplacePresentCalls(Allocator& al_, ASR::Function_t* f_) : al{al_}, f{f_} {} void replace_FunctionCall(ASR::FunctionCall_t* x) { @@ -333,6 +334,17 @@ bool fill_new_args(Vec& new_args, Allocator& al, size_t k; bool k_found = false; for( k = 0; k < owning_function->n_args; k++ ) { + ASR::expr_t* original_expr = nullptr; + if (ASR::is_a(*x.m_args[i].m_value)) { + ASR::ArrayPhysicalCast_t *x_array_cast = ASR::down_cast(x.m_args[i].m_value); + original_expr = x_array_cast->m_arg; + } + if( original_expr && ASR::is_a(*original_expr) && ASR::down_cast(owning_function->m_args[k])->m_v == + ASR::down_cast(original_expr)->m_v ) { + k_found = true; + break ; + } + if( ASR::is_a(*x.m_args[i].m_value) && ASR::down_cast(owning_function->m_args[k])->m_v == ASR::down_cast(x.m_args[i].m_value)->m_v ) { k_found = true; @@ -354,6 +366,15 @@ bool fill_new_args(Vec& new_args, Allocator& al, } ASR::call_arg_t present_arg; present_arg.loc = x.m_args[i].loc; + if( x.m_args[i].m_value && + ASRUtils::is_allocatable(x.m_args[i].m_value) && + !ASRUtils::is_allocatable(func_arg_j->m_type) ) { + ASR::expr_t* is_allocated = ASRUtils::EXPR(ASR::make_IntrinsicImpureFunction_t( + al, x.m_args[i].loc, static_cast(ASRUtils::IntrinsicImpureFunctions::Allocated), + &x.m_args[i].m_value, 1, 0, logical_t, nullptr)); + is_present = ASRUtils::EXPR(ASR::make_LogicalBinOp_t(al, x.m_args[i].loc, + is_allocated, ASR::logicalbinopType::And, is_present, logical_t, nullptr)); + } present_arg.m_value = is_present; new_args.push_back(al, present_arg); j++; @@ -440,7 +461,7 @@ class ReplaceSubroutineCallsWithOptionalArgumentsVisitor : public PassUtils::Pas pass_result.push_back(al, ASRUtils::STMT(ASRUtils::make_SubroutineCall_t_util(al, x.base.base.loc, x.m_name, x.m_original_name, new_args.p, new_args.size(), x.m_dt, - nullptr, false))); + nullptr, false, ASRUtils::get_class_proc_nopass_val(x.m_name)))); } }; diff --git a/src/libasr/pass/unique_symbols.cpp b/src/libasr/pass/unique_symbols.cpp index 1d08cb179a..fdccda31ec 100644 --- a/src/libasr/pass/unique_symbols.cpp +++ b/src/libasr/pass/unique_symbols.cpp @@ -9,6 +9,7 @@ #include #include + extern std::string lcompilers_unique_ID; /* @@ -54,15 +55,20 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { SymbolRenameVisitor(bool mm, bool gm, bool im, bool am, bool bcm, bool fm, bool cm) : module_name_mangling(mm), global_symbols_mangling(gm), intrinsic_symbols_mangling(im), - all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm) , c_mangling(cm){} + all_symbols_mangling(am), bindc_mangling(bcm), fortran_mangling(fm), c_mangling(cm) {} + - const std::unordered_set reserved_keywords_c = { - "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", "break", "case", "char", "_Bool", "const", "continue", "default", "do", "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "signed", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" + "_Alignas", "_Alignof", "_Atomic", "_Bool", "_Complex", "_Generic", + "_Imaginary", "_Noreturn", "_Static_assert", "_Thread_local", "auto", + "break", "case", "char", "_Bool", "const", "continue", "default", "do", + "double", "else", "enum", "extern", "float", "for", "goto", "if", "int", + "long", "register", "return", "short", "signed", "sizeof", "static", + "struct", "switch", "typedef", "union", "unsigned", "void", "volatile", "while" }; -//TODO: Implement other backends mangling when refactoring the pass infrastructure - void mangle_c(ASR::symbol_t* sym, const std::string& name){ + //TODO: Implement other backends mangling when refactoring the pass infrastructure + void mangle_c(ASR::symbol_t* sym, const std::string& name){ if (reserved_keywords_c.find(name) != reserved_keywords_c.end()) { sym_to_renamed[sym] = "_xx_"+std::string(name)+"_xx_"; } @@ -115,8 +121,7 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { if (all_symbols_mangling || module_name_mangling || should_mangle) { sym_to_renamed[sym] = update_name(x.m_name); } - if ((x.m_intrinsic && intrinsic_symbols_mangling) || - (global_symbols_mangling && startswith(x.m_name, "_global_symbols"))) { + if ((global_symbols_mangling && startswith(x.m_name, "_global_symbols"))) { should_mangle = true; } for (auto &a : x.m_symtab->get_scope()) { @@ -160,11 +165,15 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { sym_to_renamed[sym] = current_scope->parent->get_unique_name( "f" + std::string(x.m_name)); } - } + } + if ( c_mangling ) { + ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); + mangle_c(sym , std::string(x.m_name)); + } } - if ( c_mangling ) { + if (intrinsic_symbols_mangling && startswith(x.m_name, "_lcompilers_")) { ASR::symbol_t *sym = ASR::down_cast((ASR::asr_t*)&x); - mangle_c(sym , std::string(x.m_name)); + sym_to_renamed[sym] = update_name(x.m_name); } for (auto &a : x.m_symtab->get_scope()) { bool nested_function = is_nested_function(a.second); @@ -195,7 +204,6 @@ class SymbolRenameVisitor: public ASR::BaseWalkVisitor { std::string(x.m_name)); } } - if ( c_mangling ) { mangle_c(sym , std::string(x.m_name)); } diff --git a/src/libasr/pass/unused_functions.cpp b/src/libasr/pass/unused_functions.cpp index f17fee6816..d91796707d 100644 --- a/src/libasr/pass/unused_functions.cpp +++ b/src/libasr/pass/unused_functions.cpp @@ -45,6 +45,7 @@ class CollectUnusedFunctionsVisitor : for (size_t i=0; im_name; uint64_t h = get_hash((ASR::asr_t*)f); fn_used[h] = name; + h = get_hash((ASR::asr_t*)x.m_v); + fn_used[h] = name; } if (ASR::is_a(*s)) { ASR::GenericProcedure_t *g = ASR::down_cast(s); std::string name = g->m_name; uint64_t h = get_hash((ASR::asr_t*)g); fn_used[h] = name; + h = get_hash((ASR::asr_t*)x.m_v); + fn_used[h] = name; } } @@ -231,7 +236,8 @@ class UnusedFunctionsVisitor : public ASR::BaseWalkVisitor to_be_erased; for (auto it = symtab->get_scope().begin(); it != symtab->get_scope().end(); ++it) { uint64_t h = get_hash((ASR::asr_t*)it->second); - if (symtab->parent && fn_unused.find(h) != fn_unused.end()) { + if ((symtab->parent || (!symtab->parent && startswith(it->first, "_lcompilers_"))) + && fn_unused.find(h) != fn_unused.end()) { to_be_erased.push_back(it->first); } else { this->visit_symbol(*it->second); diff --git a/src/libasr/pass/update_array_dim_intrinsic_calls.cpp b/src/libasr/pass/update_array_dim_intrinsic_calls.cpp index bdacde4bcc..845667aa08 100644 --- a/src/libasr/pass/update_array_dim_intrinsic_calls.cpp +++ b/src/libasr/pass/update_array_dim_intrinsic_calls.cpp @@ -81,8 +81,11 @@ class ReplaceArrayDimIntrinsicCalls: public ASR::BaseExprReplacerbase.base.loc, 1, x->m_type)); for( int i = 0; i < n; i++ ) { + ASR::expr_t* dim_length = ASRUtils::EXPR(ASR::make_Cast_t( + al, x->base.base.loc, dims[i].m_length, ASR::cast_kindType::IntegerToInteger, x->m_type, nullptr)); + array_size = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, x->base.base.loc, - array_size, ASR::binopType::Mul, dims[i].m_length, x->m_type, + array_size, ASR::binopType::Mul, dim_length, x->m_type, nullptr)); } *current_expr = array_size; diff --git a/src/libasr/pass/where.cpp b/src/libasr/pass/where.cpp index b5e5ba5d4a..d893d69582 100644 --- a/src/libasr/pass/where.cpp +++ b/src/libasr/pass/where.cpp @@ -96,7 +96,7 @@ class ReplaceVar : public ASR::BaseExprReplacer BinOpReplacement(make_RealBinOp_t) } - void replace_IntrinsicScalarFunction(ASR::IntrinsicScalarFunction_t* x) { + void replace_IntrinsicElementalFunction(ASR::IntrinsicElementalFunction_t* x) { Vec args; args.reserve(al, x->n_args); for (size_t i=0; in_args; i++) { @@ -107,7 +107,7 @@ class ReplaceVar : public ASR::BaseExprReplacer } ASR::ttype_t* type = ASRUtils::expr_type(args[0]); ASR::expr_t* new_expr = ASRUtils::EXPR( - ASRUtils::make_IntrinsicScalarFunction_t_util(al, x->base.base.loc, + ASRUtils::make_IntrinsicElementalFunction_t_util(al, x->base.base.loc, x->m_intrinsic_id, args.p, x->n_args, x->m_overload_id, type, x->m_value)); *current_expr = new_expr; } @@ -279,7 +279,7 @@ class WhereVisitor : public PassUtils::PassVisitor real_cmp = ASR::down_cast(test); left = real_cmp->m_left; } else { - throw LCompilersException("Unsupported type"); + throw LCompilersException("Unsupported type, " + std::to_string(test->type)); } // Construct a do loop diff --git a/src/libasr/runtime/lfortran_intrinsics.c b/src/libasr/runtime/lfortran_intrinsics.c index 06f7bc20f1..1381e97022 100644 --- a/src/libasr/runtime/lfortran_intrinsics.c +++ b/src/libasr/runtime/lfortran_intrinsics.c @@ -10,7 +10,7 @@ #include #include -#if defined(_MSC_VER) +#if defined(_WIN32) # include # include # define ftruncate _chsize_s @@ -116,7 +116,7 @@ LFORTRAN_API void _lfortran_init_random_seed(unsigned seed) LFORTRAN_API void _lfortran_init_random_clock() { unsigned int count; -#if defined(_MSC_VER) +#if defined(_WIN32) count = (unsigned int)clock(); #else struct timespec ts; @@ -171,10 +171,10 @@ char* append_to_string(char* str, const char* append) { return str; } -void handle_integer(char* format, int val, char** result) { +void handle_integer(char* format, int64_t val, char** result) { int width = 0, min_width = 0; char* dot_pos = strchr(format, '.'); - int len = (val == 0) ? 1 : (int)log10(abs(val)) + 1; + int len = (val == 0) ? 1 : (int)log10(llabs(val)) + 1; int sign_width = (val < 0) ? 1 : 0; if (dot_pos != NULL) { dot_pos++; @@ -207,8 +207,7 @@ void handle_integer(char* format, int val, char** result) { for (int i = 0; i < (min_width - len - sign_width); i++) { *result = append_to_string(*result, "0"); } - } - else { + } else { for (int i = 0; i < (width - len - sign_width); i++) { *result = append_to_string(*result, " "); } @@ -217,7 +216,7 @@ void handle_integer(char* format, int val, char** result) { } } char str[20]; - sprintf(str, "%d", abs(val)); + sprintf(str, "%lld", llabs(val)); *result = append_to_string(*result, str); } else { for (int i = 0; i < width; i++) { @@ -226,6 +225,18 @@ void handle_integer(char* format, int val, char** result) { } } +void handle_logical(char* format, bool val, char** result) { + int width = atoi(format + 1); + for (int i = 0; i < width - 1; i++) { + *result = append_to_string(*result, " "); + } + if (val) { + *result = append_to_string(*result, "T"); + } else { + *result = append_to_string(*result, "F"); + } +} + void handle_float(char* format, double val, char** result) { int width = 0, decimal_digits = 0; long integer_part = (long)fabs(val); @@ -297,44 +308,64 @@ void handle_float(char* format, double val, char** result) { } void handle_decimal(char* format, double val, int scale, char** result, char* c) { + // Consider an example: write(*, "(es10.2)") 1.123e+10 + // format = "es10.2", val = 11230000128.00, scale = 0, c = "E" int width = 0, decimal_digits = 0; - int64_t integer_part = (int64_t)val; int sign_width = (val < 0) ? 1 : 0; - int integer_length = (integer_part == 0) ? 1 : (int)log10(llabs(integer_part)) + 1; + // sign_width = 0 + double integer_part = trunc(val); + int integer_length = (integer_part == 0) ? 1 : (int)log10(fabs(integer_part)) + 1; + // integer_part = 11230000128, integer_length = 11 char *num_pos = format ,*dot_pos = strchr(format, '.'); decimal_digits = atoi(++dot_pos); while(!isdigit(*num_pos)) num_pos++; width = atoi(num_pos); + // width = 10, decimal_digits = 2 - char val_str[64]; + char val_str[128]; // TODO: This will work for up to `E65.60` but will fail for: // print "(E67.62)", 1.23456789101112e-62_8 sprintf(val_str, "%.*lf", (60-integer_length), val); + // val_str = "11230000128.00..." int i = strlen(val_str) - 1; while (val_str[i] == '0') { val_str[i] = '\0'; i--; } + // val_str = "11230000128." + + int exp = 2; + char* exp_loc = strchr(num_pos, 'e'); + if (exp_loc != NULL) { + exp = atoi(++exp_loc); + } + // exp = 2; char* ptr = strchr(val_str, '.'); if (ptr != NULL) { memmove(ptr, ptr + 1, strlen(ptr)); } + // val_str = "11230000128" if (val < 0) { + // removes `-` (negative) sign memmove(val_str, val_str + 1, strlen(val_str)); } int decimal = 1; while (val_str[0] == '0') { + // Used for the case: 1.123e-10 memmove(val_str, val_str + 1, strlen(val_str)); decimal--; + // loop end: decimal = -9 } - if (format[1] == 'S') { + if (tolower(format[1]) == 's') { scale = 1; decimal--; + // decimal = 0, case: 1.123e+10 + // decimal = -10, case: 1.123e-10 } if (dot_pos != NULL) { @@ -361,6 +392,7 @@ void handle_decimal(char* format, double val, int scale, char** result, char* c) char formatted_value[64] = ""; int spaces = width - sign_width - decimal_digits - 6; + // spaces = 2 if (scale > 1) { decimal_digits -= scale - 1; } @@ -369,6 +401,7 @@ void handle_decimal(char* format, double val, int scale, char** result, char* c) } if (sign_width == 1) { + // adds `-` (negative) sign strcat(formatted_value, "-"); } if (scale <= 0) { @@ -391,13 +424,16 @@ void handle_decimal(char* format, double val, int scale, char** result, char* c) char* temp = substring(val_str, 0, scale); strcat(formatted_value, temp); strcat(formatted_value, "."); + // formatted_value = " 1." char* new_str = substring(val_str, scale, strlen(val_str)); + // new_str = "1230000128" case: 1.123e+10 int zeros = 0; if (decimal_digits < strlen(new_str) && decimal_digits + scale <= 15) { new_str[15] = '\0'; zeros = strspn(new_str, "0"); long long t = (long long)round((long double)atoll(new_str) / (long long) pow(10, (strlen(new_str) - decimal_digits))); sprintf(new_str, "%lld", t); + // new_str = 12 int index = zeros; while(index--) { memmove(new_str + 1, new_str, strlen(new_str)+1); @@ -406,20 +442,24 @@ void handle_decimal(char* format, double val, int scale, char** result, char* c) } new_str[decimal_digits] = '\0'; strcat(formatted_value, new_str); + // formatted_value = " 1.12" free(new_str); free(temp); } strcat(formatted_value, c); + // formatted_value = " 1.12E" char exponent[12]; if (atoi(num_pos) == 0) { sprintf(exponent, "%+02d", (integer_length > 0 && integer_part != 0 ? integer_length - scale : decimal)); } else { - sprintf(exponent, "%+03d", (integer_length > 0 && integer_part != 0 ? integer_length - scale : decimal)); + sprintf(exponent, "%+0*d", exp+1, (integer_length > 0 && integer_part != 0 ? integer_length - scale : decimal)); + // exponent = "+10" } strcat(formatted_value, exponent); + // formatted_value = " 1.12E+10" if (strlen(formatted_value) == width + 1 && scale <= 0) { char* ptr = strchr(formatted_value, '0'); @@ -434,6 +474,7 @@ void handle_decimal(char* format, double val, int scale, char** result, char* c) } } else { *result = append_to_string(*result, formatted_value); + // result = " 1.12E+10" } } @@ -455,6 +496,9 @@ char** parse_fortran_format(char* format, int *count, int *item_start) { case '/' : format_values_2[format_values_count++] = substring(format, index, index+1); break; + case '*' : + format_values_2[format_values_count++] = substring(format, index, index+1); + break; case '"' : start = index++; while (format[index] != '"') { @@ -482,11 +526,20 @@ char** parse_fortran_format(char* format, int *count, int *item_start) { case 'd' : case 'e' : case 'f' : + case 'l' : start = index++; + bool dot = false; if(tolower(format[index]) == 's') index++; while (isdigit(format[index])) index++; - if (format[index] == '.') index++; + if (format[index] == '.') { + dot = true; + index++; + } while (isdigit(format[index])) index++; + if (dot && tolower(format[index]) == 'e') { + index++; + while (isdigit(format[index])) index++; + } format_values_2[format_values_count++] = substring(format, start, index); index--; break; @@ -497,12 +550,11 @@ char** parse_fortran_format(char* format, int *count, int *item_start) { *item_start = format_values_count; break; default : - if (isdigit(format[index]) && tolower(format[index+1]) == 'p') { + if ( + (format[index] == '-' && isdigit(format[index + 1]) && tolower(format[index + 2]) == 'p') + || ((isdigit(format[index])) && tolower(format[index + 1]) == 'p')) { start = index; - if (index > 0 && format[index-1] == '-') { - start = index - 1; - } - index = index + 1; + index = index + 1 + (format[index] == '-'); format_values_2[format_values_count++] = substring(format, start, index + 1); } else if (isdigit(format[index])) { start = index; @@ -530,6 +582,9 @@ char** parse_fortran_format(char* format, int *count, int *item_start) { } index--; } + } else if (format[index] != ' ') { + fprintf(stderr, "Unsupported or unrecognized `%c` in format string\n", format[index]); + exit(1); } } index++; @@ -548,13 +603,14 @@ LFORTRAN_API char* _lcompilers_string_format_fortran(int count, const char* form modified_input_string[len] = '\0'; if (format[0] == '(' && format[len-1] == ')') { memmove(modified_input_string, modified_input_string + 1, strlen(modified_input_string)); - modified_input_string[len-1] = '\0'; + modified_input_string[len-2] = '\0'; } int format_values_count = 0,item_start_idx=0; char** format_values = parse_fortran_format(modified_input_string,&format_values_count,&item_start_idx); char* result = (char*)malloc(sizeof(char)); result[0] = '\0'; int item_start = 0; + bool array = false; while (1) { int scale = 0; for (int i = item_start; i < format_values_count; i++) { @@ -588,6 +644,8 @@ LFORTRAN_API char* _lcompilers_string_format_fortran(int count, const char* form if (value[0] == '/') { result = append_to_string(result, "\n"); + } else if (value[0] == '*') { + array = true; } else if (isdigit(value[0]) && tolower(value[1]) == 'p') { // Scale Factor nP scale = atoi(&value[0]); @@ -627,7 +685,7 @@ LFORTRAN_API char* _lcompilers_string_format_fortran(int count, const char* form // Integer Editing ( I[w[.m]] ) if ( count == 0 ) break; count--; - int val = va_arg(args, int); + int64_t val = va_arg(args, int64_t); handle_integer(value, val, &result); } else if (tolower(value[0]) == 'd') { // D Editing (D[w[.d]]) @@ -647,13 +705,23 @@ LFORTRAN_API char* _lcompilers_string_format_fortran(int count, const char* form count--; double val = va_arg(args, double); handle_float(value, val, &result); + } else if (tolower(value[0]) == 'l') { + if ( count == 0 ) break; + count--; + char* val_str = va_arg(args, char*); + bool val = (strcmp(val_str, "True") == 0); + handle_logical(value, val, &result); } else if (strlen(value) != 0) { + if ( count == 0 ) break; + count--; printf("Printing support is not available for %s format.\n",value); } } if ( count > 0 ) { - result = append_to_string(result, "\n"); + if (!array) { + result = append_to_string(result, "\n"); + } item_start = item_start_idx; } else { break; @@ -805,16 +873,6 @@ LFORTRAN_API double_complex_t _lfortran_zsqrt(double_complex_t x) // aimag ----------------------------------------------------------------------- -LFORTRAN_API float _lfortran_caimag(float_complex_t x) -{ - return cimagf(x); -} - -LFORTRAN_API double _lfortran_zaimag(double_complex_t x) -{ - return cimag(x); -} - LFORTRAN_API void _lfortran_complex_aimag_32(struct _lfortran_complex_32 *x, float *res) { *res = x->im; @@ -859,6 +917,14 @@ LFORTRAN_API double _lfortran_dlog(double x) return log(x); } +LFORTRAN_API bool _lfortran_rsp_is_nan(float x) { + return isnan(x); +} + +LFORTRAN_API bool _lfortran_rdp_is_nan(double x) { + return isnan(x); +} + LFORTRAN_API float_complex_t _lfortran_clog(float_complex_t x) { return clogf(x); @@ -929,6 +995,622 @@ LFORTRAN_API double _lfortran_dlog_gamma(double x) return lgamma(x); } +// besselj0 -------------------------------------------------------------------- + +/** +* Ported from implementation done at: +* https://github.com/stdlib-js/stdlib/blob/develop/lib/node_modules/%40stdlib/math/base/special/besselj0/lib/main.js +* +* All credits to the original authors of the implementation. +*/ + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj0_rational_p1q1( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.17291506903064494; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -412986685009.9087 + (x * (27282507878.60594 + (x * (-621407004.2354012 + (x * (6630299.79048338 + (x * (-36629.81465510709 + (x * (103.44222815443189 + (x * -0.12117036164593528))))))))))); + s2 = 2388378799633.229 + (x * (26328198300.85965 + (x * (139850973.72263435 + (x * (456126.9622421994 + (x * (936.1402239233771 + (x * (1.0 + (x * 0.0))))))))))); + } else { + ix = 1.0 / x; + s1 = -0.12117036164593528 + (ix * (103.44222815443189 + (ix * (-36629.81465510709 + (ix * (6630299.79048338 + (ix * (-621407004.2354012 + (ix * (27282507878.60594 + (ix * -412986685009.9087))))))))))); + s2 = 0.0 + (ix * (1.0 + (ix * (936.1402239233771 + (ix * (456126.9622421994 + (ix * (139850973.72263435 + (ix * (26328198300.85965 + (ix * 2388378799633.229))))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj0_rational_p2q2( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return 0.005119512965174424; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -1831.9397969392085 + (x * (-12254.07816137899 + (x * (-7287.970246446462 + (x * (10341.910641583727 + (x * (11725.046279757104 + (x * (4417.670702532509 + (x * (743.2119668062425 + (x * 48.5917033559165))))))))))))); + s2 = -357834.78026152303 + (x * (245991.0226258631 + (x * (-84055.06259116957 + (x * (18680.99000835919 + (x * (-2945.876654550934 + (x * (333.07310774649073 + (x * (-25.258076240801554 + (x * 1.0))))))))))))); + } else { + ix = 1.0 / x; + s1 = 48.5917033559165 + (ix * (743.2119668062425 + (ix * (4417.670702532509 + (ix * (11725.046279757104 + (ix * (10341.910641583727 + (ix * (-7287.970246446462 + (ix * (-12254.07816137899 + (ix * -1831.9397969392085))))))))))))); + s2 = 1.0 + (ix * (-25.258076240801554 + (ix * (333.07310774649073 + (ix * (-2945.876654550934 + (ix * (18680.99000835919 + (ix * (-84055.06259116957 + (ix * (245991.0226258631 + (ix * -357834.78026152303))))))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj0_rational_pcqc( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return 1.0; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = 22779.090197304686 + (x * (41345.38663958076 + (x * (21170.523380864943 + (x * (3480.648644324927 + (x * (153.76201909008356 + (x * 0.8896154842421046))))))))); + s2 = 22779.090197304686 + (x * (41370.41249551042 + (x * (21215.350561880117 + (x * (3502.8735138235606 + (x * (157.11159858080893 + (x * 1.0))))))))); + } else { + ix = 1.0 / x; + s1 = 0.8896154842421046 + (ix * (153.76201909008356 + (ix * (3480.648644324927 + (ix * (21170.523380864943 + (ix * (41345.38663958076 + (ix * 22779.090197304686))))))))); + s2 = 1.0 + (ix * (157.11159858080893 + (ix * (3502.8735138235606 + (ix * (21215.350561880117 + (ix * (41370.41249551042 + (ix * 22779.090197304686))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj0_rational_psqs( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.015625; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -89.22660020080009 + (x * (-185.91953644342993 + (x * (-111.83429920482737 + (x * (-22.300261666214197 + (x * (-1.244102674583564 + (x * -0.008803330304868075))))))))); + s2 = 5710.502412851206 + (x * (11951.131543434614 + (x * (7264.278016921102 + (x * (1488.7231232283757 + (x * (90.59376959499312 + (x * 1.0))))))))); + } else { + ix = 1.0 / x; + s1 = -0.008803330304868075 + (ix * (-1.244102674583564 + (ix * (-22.300261666214197 + (ix * (-111.83429920482737 + (ix * (-185.91953644342993 + (ix * -89.22660020080009))))))))); + s2 = 1.0 + (ix * (90.59376959499312 + (ix * (1488.7231232283757 + (ix * (7264.278016921102 + (ix * (11951.131543434614 + (ix * 5710.502412851206))))))))); + } + return s1 / s2; +} + +LFORTRAN_API double _lfortran_dbesselj0( double x ) { + double rc; + double rs; + double si; + double co; + double y2; + double r; + double y; + double f; + + double ONE_DIV_SQRT_PI = 0.5641895835477563; + double x1 = 2.4048255576957727686e+00; + double x2 = 5.5200781102863106496e+00; + double x11 = 6.160e+02; + double x12 = -1.42444230422723137837e-03; + double x21 = 1.4130e+03; + double x22 = 5.46860286310649596604e-04; + + if ( x < 0 ) { + x = -x; + } + if ( x == HUGE_VAL ) { + return 0.0; + } + if ( x == 0 ) { + return 1.0; + } + if ( x <= 4.0 ) { + y = x * x; + r = besselj0_rational_p1q1( y ); + f = ( x+x1 ) * ( (x - (x11/256.0)) - x12 ); + return f * r; + } + if ( x <= 8.0 ) { + y = 1.0 - ( ( x*x )/64.0 ); + r = besselj0_rational_p2q2( y ); + f = ( x+x2 ) * ( (x - (x21/256.0)) - x22 ); + return f * r; + } + y = 8.0 / x; + y2 = y * y; + rc = besselj0_rational_pcqc( y2 ); + rs = besselj0_rational_psqs( y2 ); + f = ONE_DIV_SQRT_PI / sqrt(x); + + // __sincos(x, &si, &co); + si = sin(x); + co = cos(x); + return f * ( ( rc * (co+si) ) - ( (y*rs) * (si-co) ) ); +} + +LFORTRAN_API float _lfortran_sbesselj0( float x ) { + return (float)_lfortran_dbesselj0((double)x); +} + +// besselj1 -------------------------------------------------------------------- + +/** +* Ported from implementation done at: +* https://github.com/stdlib-js/stdlib/blob/develop/lib/node_modules/%40stdlib/math/base/special/besselj1/lib/main.js +* +* All credits to the original authors of the implementation. +*/ + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj1_rational_p1q1( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.03405537391318949; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -142585098013.66644 + (x * (6678104126.14924 + (x * (-115486967.64841276 + (x * (980629.0409895825 + (x * (-4461.579298277507 + (x * (10.650724020080236 + (x * -0.010767857011487301))))))))))); + s2 = 4186860446082.0176 + (x * (42091902282.58013 + (x * (202283751.40097034 + (x * (591176.1449417479 + (x * (1074.227223951738 + (x * (1.0 + (x * 0.0))))))))))); + } else { + ix = 1.0 / x; + s1 = -0.010767857011487301 + (ix * (10.650724020080236 + (ix * (-4461.579298277507 + (ix * (980629.0409895825 + (ix * (-115486967.64841276 + (ix * (6678104126.14924 + (ix * -142585098013.66644))))))))))); + s2 = 0.0 + (ix * (1.0 + (ix * (1074.227223951738 + (ix * (591176.1449417479 + (ix * (202283751.40097034 + (ix * (42091902282.58013 + (ix * 4186860446082.0176))))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj1_rational_p2q2( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.010158790774176108; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -17527881995806512.0 + (x * (1660853173129901.8 + (x * (-36658018905416.664 + (x * (355806656709.1062 + (x * (-1811393126.9860668 + (x * (5079326.614801118 + (x * (-7502.334222078161 + (x * 4.6179191852758255))))))))))))); + s2 = 1725390588844768000.0 + (x * (17128800897135812.0 + (x * (84899346165481.42 + (x * (276227772862.44086 + (x * (648725028.9959639 + (x * (1126712.5065029138 + (x * (1388.6978985861358 + (x * 1.0))))))))))))); + } else { + ix = 1.0 / x; + s1 = 4.6179191852758255 + (ix * (-7502.334222078161 + (ix * (5079326.614801118 + (ix * (-1811393126.9860668 + (ix * (355806656709.1062 + (ix * (-36658018905416.664 + (ix * (1660853173129901.8 + (ix * -17527881995806512.0))))))))))))); + s2 = 1.0 + (ix * (1388.6978985861358 + (ix * (1126712.5065029138 + (ix * (648725028.9959639 + (ix * (276227772862.44086 + (ix * (84899346165481.42 + (ix * (17128800897135812.0 + (ix * 1725390588844768000.0))))))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj1_rational_pcqc( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return 1.0; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -4435757.816794128 + (x * (-9942246.505077641 + (x * (-6603373.248364939 + (x * (-1523529.3511811374 + (x * (-109824.05543459347 + (x * (-1611.6166443246102 + (x * 0.0))))))))))); + s2 = -4435757.816794128 + (x * (-9934124.389934586 + (x * (-6585339.4797230875 + (x * (-1511809.5066341609 + (x * (-107263.8599110382 + (x * (-1455.0094401904962 + (x * 1.0))))))))))); + } else { + ix = 1.0 / x; + s1 = 0.0 + (ix * (-1611.6166443246102 + (ix * (-109824.05543459347 + (ix * (-1523529.3511811374 + (ix * (-6603373.248364939 + (ix * (-9942246.505077641 + (ix * -4435757.816794128))))))))))); + s2 = 1.0 + (ix * (-1455.0094401904962 + (ix * (-107263.8599110382 + (ix * (-1511809.5066341609 + (ix * (-6585339.4797230875 + (ix * (-9934124.389934586 + (ix * -4435757.816794128))))))))))); + } + return s1 / s2; +} + +/** +* Evaluates a rational function (i.e., the ratio of two polynomials described by the coefficients stored in \\(P\\) and \\(Q\\)). +* +* ## Notes +* +* - Coefficients should be sorted in ascending degree. +* - The implementation uses [Horner's rule][horners-method] for efficient computation. +* +* [horners-method]: https://en.wikipedia.org/wiki/Horner%27s_method +* +* @param x value at which to evaluate the rational function +* @return evaluated rational function +*/ +static double besselj1_rational_psqs( const double x ) { + double ax; + double ix; + double s1; + double s2; + if ( x == 0.0 ) { + return 0.046875; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = 33220.913409857225 + (x * (85145.1606753357 + (x * (66178.83658127084 + (x * (18494.262873223866 + (x * (1706.375429020768 + (x * (35.26513384663603 + (x * 0.0))))))))))); + s2 = 708712.8194102874 + (x * (1819458.0422439973 + (x * (1419460.669603721 + (x * (400294.43582266977 + (x * (37890.2297457722 + (x * (863.8367769604992 + (x * 1.0))))))))))); + } else { + ix = 1.0 / x; + s1 = 0.0 + (ix * (35.26513384663603 + (ix * (1706.375429020768 + (ix * (18494.262873223866 + (ix * (66178.83658127084 + (ix * (85145.1606753357 + (ix * 33220.913409857225))))))))))); + s2 = 1.0 + (ix * (863.8367769604992 + (ix * (37890.2297457722 + (ix * (400294.43582266977 + (ix * (1419460.669603721 + (ix * (1819458.0422439973 + (ix * 708712.8194102874))))))))))); + } + return s1 / s2; +} + +LFORTRAN_API double _lfortran_dbesselj1( double x ) { + double value; + double rc; + double rs; + double si; + double co; + double y2; + double r; + double y; + double f; + double w; + + double SQRT_PI = 1.7724538509055160; + double x1 = 3.8317059702075123156e+00; + double x2 = 7.0155866698156187535e+00; + double x11 = 9.810e+02; + double x12 = -3.2527979248768438556e-04; + double x21 = 1.7960e+03; + double x22 = -3.8330184381246462950e-05; + + w = fabs( x ); + if ( x == 0.0 ) { + return 0.0; + } + if ( w == HUGE_VAL ) { + return 0.0; + } + if ( w <= 4.0 ) { + y = x * x; + r = besselj1_rational_p1q1( y ); + f = w * ( w+x1 ) * ( ( w - (x11/256.0) ) - x12 ); + value = f * r; + } else if ( w <= 8.0 ) { + y = x * x; + r = besselj1_rational_p2q2( y ); + f = w * ( w+x2 ) * ( ( w - (x21/256.0) ) - x22 ); + value = f * r; + } else { + y = 8.0 / w; + y2 = y * y; + rc = besselj1_rational_pcqc( y2 ); + rs = besselj1_rational_psqs( y2 ); + f = 1.0 / ( sqrt(w) * SQRT_PI ); + + // __sincos(w, &si, &co); + si = sin(w); + co = cos(w); + value = f * ( ( rc * (si-co) ) + ( (y*rs) * (si+co) ) ); + } + if ( x < 0.0 ) { + value = -1.0 * value; + } + return value; +} + +LFORTRAN_API float _lfortran_sbesselj1( float x ) { + return (float)_lfortran_dbesselj1((double)x); +} + +static double bessely0_rational_p1q1( double x ) { + double ax; + double s1; + double s2; + if ( x == 0.0 ) { + return 0.18214429522164177; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = 107235387820.03177 + (x * (-8371625545.12605 + (x * (204222743.5737662 + (x * (-2128754.84744018 + (x * (10102.532948020907 + (x * -18.402381979244993))))))))); + s2 = 588738657389.9703 + (x * (8161718777.729036 + (x * (55662956.624278255 + (x * (238893.93209447255 + (x * (664.7598668924019 + (x * 1.0))))))))); + } else { + x = 1.0 / x; + s1 = -18.402381979244993 + (x * (10102.532948020907 + (x * (-2128754.84744018 + (x * (204222743.5737662 + (x * (-8371625545.12605 + (x * 107235387820.03177))))))))); + s2 = 1.0 + (x * (664.7598668924019 + (x * (238893.93209447255 + (x * (55662956.624278255 + (x * (8161718777.729036 + (x * 588738657389.9703))))))))); + } + return s1 / s2; +} + +static double bessely0_rational_p2q2( double x ) { + double ax; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.051200622130023854; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -22213976967566.19 + (x * (-551074352067.2264 + (x * (43600098638.60306 + (x * (-695904393.9461962 + (x * (4690528.861167863 + (x * (-14566.865832663636 + (x * 17.427031242901595))))))))))); + s2 = 433861465807072.6 + (x * (5426682441941.234 + (x * (34015103849.97124 + (x * (139602027.7098683 + (x * (406699.82352539554 + (x * (830.3085761207029 + (x * 1.0))))))))))); + } else { + x = 1.0 / x; + s1 = 17.427031242901595 + (x * (-14566.865832663636 + (x * (4690528.861167863 + (x * (-695904393.9461962 + (x * (43600098638.60306 + (x * (-551074352067.2264 + (x * -22213976967566.19))))))))))); + s2 = 1.0 + (x * (830.3085761207029 + (x * (406699.82352539554 + (x * (139602027.7098683 + (x * (34015103849.97124 + (x * (5426682441941.234 + (x * 433861465807072.6))))))))))); + } + return s1 / s2; +} + +static double bessely0_rational_p3q3( double x ) { + double ax; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.023356489432789604; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -8072872690515021.0 + (x * (670166418691732.4 + (x * (-128299123640.88687 + (x * (-193630512667.72083 + (x * (2195882717.0518103 + (x * (-10085539.923498211 + (x * (21363.5341693139 + (x * -17.439661319197498))))))))))))); + s2 = 345637246288464600.0 + (x * (3927242556964031.0 + (x * (22598377924042.9 + (x * (86926121104.20982 + (x * (247272194.75672302 + (x * (539247.3920976806 + (x * (879.0336216812844 + (x * 1.0))))))))))))); + } else { + x = 1.0 / x; + s1 = -17.439661319197498 + (x * (21363.5341693139 + (x * (-10085539.923498211 + (x * (2195882717.0518103 + (x * (-193630512667.72083 + (x * (-128299123640.88687 + (x * (670166418691732.4 + (x * -8072872690515021.0))))))))))))); + s2 = 1.0 + (x * (879.0336216812844 + (x * (539247.3920976806 + (x * (247272194.75672302 + (x * (86926121104.20982 + (x * (22598377924042.9 + (x * (3927242556964031.0 + (x * 345637246288464600.0))))))))))))); + } + return s1 / s2; +} + +static double bessely0_rational_pcqc( double x ) { + double ax; + double s1; + double s2; + if ( x == 0.0 ) { + return 1.0; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = 22779.090197304686 + (x * (41345.38663958076 + (x * (21170.523380864943 + (x * (3480.648644324927 + (x * (153.76201909008356 + (x * 0.8896154842421046))))))))); // eslint-disable-line max-len + s2 = 22779.090197304686 + (x * (41370.41249551042 + (x * (21215.350561880117 + (x * (3502.8735138235606 + (x * (157.11159858080893 + (x * 1.0))))))))); // eslint-disable-line max-len + } else { + x = 1.0 / x; + s1 = 0.8896154842421046 + (x * (153.76201909008356 + (x * (3480.648644324927 + (x * (21170.523380864943 + (x * (41345.38663958076 + (x * 22779.090197304686))))))))); // eslint-disable-line max-len + s2 = 1.0 + (x * (157.11159858080893 + (x * (3502.8735138235606 + (x * (21215.350561880117 + (x * (41370.41249551042 + (x * 22779.090197304686))))))))); // eslint-disable-line max-len + } + return s1 / s2; +} + +static double bessely0_rational_psqs( double x ) { + double ax; + double s1; + double s2; + if ( x == 0.0 ) { + return -0.015625; + } + if ( x < 0.0 ) { + ax = -x; + } else { + ax = x; + } + if ( ax <= 1.0 ) { + s1 = -89.22660020080009 + (x * (-185.91953644342993 + (x * (-111.83429920482737 + (x * (-22.300261666214197 + (x * (-1.244102674583564 + (x * -0.008803330304868075))))))))); // eslint-disable-line max-len + s2 = 5710.502412851206 + (x * (11951.131543434614 + (x * (7264.278016921102 + (x * (1488.7231232283757 + (x * (90.59376959499312 + (x * 1.0))))))))); // eslint-disable-line max-len + } else { + x = 1.0 / x; + s1 = -0.008803330304868075 + (x * (-1.244102674583564 + (x * (-22.300261666214197 + (x * (-111.83429920482737 + (x * (-185.91953644342993 + (x * -89.22660020080009))))))))); // eslint-disable-line max-len + s2 = 1.0 + (x * (90.59376959499312 + (x * (1488.7231232283757 + (x * (7264.278016921102 + (x * (11951.131543434614 + (x * 5710.502412851206))))))))); // eslint-disable-line max-len + } + return s1 / s2; +} + +LFORTRAN_API double _lfortran_dbessely0( double x ) { + + double PI = 3.14159265358979323846; + double SQRT_PI = 1.7724538509055160273; + double ONE_DIV_SQRT_PI = 1.0 / SQRT_PI; + double TWO_DIV_PI = 2.0 / PI; + + double x1 = 8.9357696627916752158e-01; + double x2 = 3.9576784193148578684e+00; + double x3 = 7.0860510603017726976e+00; + double x11 = 2.280e+02; + double x12 = 2.9519662791675215849e-03; + double x21 = 1.0130e+03; + double x22 = 6.4716931485786837568e-04; + double x31 = 1.8140e+03; + double x32 = 1.1356030177269762362e-04; + + double rc; + double rs; + double y2; + double r; + double y; + double z; + double f; + double si; + double co; + + if ( x < 0.0 ) { + return nan("1"); + } + if ( x == 0.0 ) { + return -1*HUGE_VAL; + } + if ( x == HUGE_VAL ) { + return 0.0; + } + if ( x <= 3.0 ) { + y = x * x; + z = ( _lfortran_dlog(x/x1) * _lfortran_dbesselj0(x) ) * TWO_DIV_PI; + r = bessely0_rational_p1q1( y ); + f = ( x+x1 ) * ( ( x - (x11/256.0) ) - x12 ); + return z + ( f*r ); + } + if ( x <= 5.5 ) { + y = x * x; + z = ( _lfortran_dlog(x/x1) * _lfortran_dbesselj0(x) ) * TWO_DIV_PI; + r = bessely0_rational_p2q2( y ); + f = ( x+x2 ) * ( (x - (x21/256.0)) - x22 ); + return z + ( f*r ); + } + if ( x <= 8.0 ) { + y = x * x; + z = ( _lfortran_dlog(x/x1) * _lfortran_dbesselj0(x) ) * TWO_DIV_PI; + r = bessely0_rational_p3q3( y ); + f = ( x+x3 ) * ( (x - (x31/256.0)) - x32 ); + return z + ( f*r ); + } + y = 8.0 / x; + y2 = y * y; + rc = bessely0_rational_pcqc( y2 ); + rs = bessely0_rational_psqs( y2 ); + f = ONE_DIV_SQRT_PI / sqrt( x ); + + // __sincos(w, &si, &co); + si = sin(x); + co = cos(x); + return f * ( ( rc * (si-co) ) + ( (y*rs) * (si+co) ) ); +} + +LFORTRAN_API float _lfortran_sbessely0( float x ) { + return (float)_lfortran_dbessely0((double)x); +} + // sin ------------------------------------------------------------------------- LFORTRAN_API float _lfortran_ssin(float x) @@ -1287,9 +1969,13 @@ LFORTRAN_API void _lfortran_strcpy(char** x, char *y, int8_t free_target) if (*x) { free((void *)*x); } + // *x = (char*) malloc((strlen(y) + 1) * sizeof(char)); + // _lfortran_string_init(strlen(y) + 1, *x); } - *x = (char*) malloc((strlen(y) + 1) * sizeof(char)); - _lfortran_string_init(strlen(y) + 1, *x); + // if( *x == NULL ) { + *x = (char*) malloc((strlen(y) + 1) * sizeof(char)); + _lfortran_string_init(strlen(y) + 1, *x); + // } for (size_t i = 0; i < strlen(*x); i++) { if (i < strlen(y)) { x[0][i] = y[i]; @@ -1594,8 +2280,10 @@ LFORTRAN_API char* _lfortran_str_slice_assign(char* s, char *r, int32_t idx1, in } if (idx1 == idx2 || (step > 0 && (idx1 > idx2 || idx1 >= s_len)) || - (step < 0 && (idx1 < idx2 || idx2 >= s_len-1))) - return ""; + (step < 0 && (idx1 < idx2 || idx2 >= s_len-1))) { + return s; + } + char* dest_char = (char*)malloc(s_len); strcpy(dest_char, s); int s_i = idx1, d_i = 0; @@ -1672,82 +2360,6 @@ LFORTRAN_API void _lfortran_string_init(int size_plus_one, char *s) { // bit ------------------------------------------------------------------------ -LFORTRAN_API int32_t _lfortran_iand32(int32_t x, int32_t y) { - return x & y; -} - -LFORTRAN_API int64_t _lfortran_iand64(int64_t x, int64_t y) { - return x & y; -} - -LFORTRAN_API int32_t _lfortran_not32(int32_t x) { - return ~ x; -} - -LFORTRAN_API int64_t _lfortran_not64(int64_t x) { - return ~ x; -} - -LFORTRAN_API int32_t _lfortran_ior32(int32_t x, int32_t y) { - return x | y; -} - -LFORTRAN_API int64_t _lfortran_ior64(int64_t x, int64_t y) { - return x | y; -} - -LFORTRAN_API int32_t _lfortran_ieor32(int32_t x, int32_t y) { - return x ^ y; -} - -LFORTRAN_API int64_t _lfortran_ieor64(int64_t x, int64_t y) { - return x ^ y; -} - -LFORTRAN_API int32_t _lfortran_ibclr32(int32_t i, int pos) { - return i & ~(1 << pos); -} - -LFORTRAN_API int64_t _lfortran_ibclr64(int64_t i, int pos) { - return i & ~(1LL << pos); -} - -LFORTRAN_API int32_t _lfortran_ibset32(int32_t i, int pos) { - return i | (1 << pos); -} - -LFORTRAN_API int64_t _lfortran_ibset64(int64_t i, int pos) { - return i | (1LL << pos); -} - -LFORTRAN_API int32_t _lfortran_btest32(int32_t i, int pos) { - return i & (1 << pos); -} - -LFORTRAN_API int64_t _lfortran_btest64(int64_t i, int pos) { - return i & (1LL << pos); -} - -LFORTRAN_API int32_t _lfortran_ishft32(int32_t i, int32_t shift) { - if(shift > 0) { - return i << shift; - } else if(shift < 0) { - return i >> abs(shift); - } else { - return i; - } -} - -LFORTRAN_API int64_t _lfortran_ishft64(int64_t i, int64_t shift) { - if(shift > 0) { - return i << shift; - } else if(shift < 0) { - return i >> llabs(shift); - } else { - return i; - } -} - LFORTRAN_API int32_t _lfortran_mvbits32(int32_t from, int32_t frompos, int32_t len, int32_t to, int32_t topos) { uint32_t all_ones = ~0; @@ -1776,46 +2388,6 @@ LFORTRAN_API int64_t _lfortran_mvbits64(int64_t from, int32_t frompos, return (~all_ones & uto) | ufrom; } -LFORTRAN_API int32_t _lfortran_bgt32(int32_t i, int32_t j) { - uint32_t ui = i, uj = j; - return ui > uj; -} - -LFORTRAN_API int32_t _lfortran_bgt64(int64_t i, int64_t j) { - uint64_t ui = i, uj = j; - return ui > uj; -} - -LFORTRAN_API int32_t _lfortran_bge32(int32_t i, int32_t j) { - uint32_t ui = i, uj = j; - return ui >= uj; -} - -LFORTRAN_API int32_t _lfortran_bge64(int64_t i, int64_t j) { - uint64_t ui = i, uj = j; - return ui >= uj; -} - -LFORTRAN_API int32_t _lfortran_ble32(int32_t i, int32_t j) { - uint32_t ui = i, uj = j; - return ui <= uj; -} - -LFORTRAN_API int32_t _lfortran_ble64(int64_t i, int64_t j) { - uint64_t ui = i, uj = j; - return ui <= uj; -} - -LFORTRAN_API int32_t _lfortran_blt32(int32_t i, int32_t j) { - uint32_t ui = i, uj = j; - return ui < uj; -} - -LFORTRAN_API int32_t _lfortran_blt64(int64_t i, int64_t j) { - uint64_t ui = i, uj = j; - return ui < uj; -} - LFORTRAN_API int32_t _lfortran_ibits32(int32_t i, int32_t pos, int32_t len) { uint32_t ui = i; return ((ui << (BITS_32 - pos - len)) >> (BITS_32 - len)); @@ -1836,13 +2408,13 @@ LFORTRAN_API void _lfortran_cpu_time(double *t) { LFORTRAN_API void _lfortran_i32sys_clock( int32_t *count, int32_t *rate, int32_t *max) { -#if defined(_MSC_VER) || defined(__MACH__) +#if defined(_WIN32) *count = - INT_MAX; *rate = 0; *max = 0; #else struct timespec ts; - if(clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + if(clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { *count = (int32_t)(ts.tv_nsec / 1000000) + ((int32_t)ts.tv_sec * 1000); *rate = 1e3; // milliseconds *max = INT_MAX; @@ -1856,13 +2428,43 @@ LFORTRAN_API void _lfortran_i32sys_clock( LFORTRAN_API void _lfortran_i64sys_clock( uint64_t *count, int64_t *rate, int64_t *max) { -#if defined(_MSC_VER) || defined(__MACH__) +#if defined(_WIN32) *count = - INT_MAX; *rate = 0; *max = 0; #else struct timespec ts; - if(clock_gettime(CLOCK_MONOTONIC, &ts) == -1) { + if(clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + *count = (uint64_t)(ts.tv_nsec) + ((uint64_t)ts.tv_sec * 1000000000); + // FIXME: Rate can be in microseconds or nanoseconds depending on + // resolution of the underlying platform clock. + *rate = 1e9; // nanoseconds + *max = LLONG_MAX; + } else { + *count = - LLONG_MAX; + *rate = 0; + *max = 0; + } +#endif +} + +LFORTRAN_API void _lfortran_i64r64sys_clock( + uint64_t *count, double *rate, int64_t *max) { +double ratev; +int64_t maxv; +if( rate == NULL ) { + rate = &ratev; +} +if( max == NULL ) { + max = &maxv; +} +#if defined(_WIN32) + *count = - INT_MAX; + *rate = 0; + *max = 0; +#else + struct timespec ts; + if(clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { *count = (uint64_t)(ts.tv_nsec) + ((uint64_t)ts.tv_sec * 1000000000); // FIXME: Rate can be in microseconds or nanoseconds depending on // resolution of the underlying platform clock. @@ -1878,7 +2480,7 @@ LFORTRAN_API void _lfortran_i64sys_clock( LFORTRAN_API double _lfortran_time() { -#if defined(_MSC_VER) +#if defined(_WIN32) FILETIME ft; ULARGE_INTEGER uli; GetSystemTimeAsFileTime(&ft); @@ -1894,12 +2496,12 @@ LFORTRAN_API double _lfortran_time() #endif } -LFORTRAN_API void _lfortran_sp_rand_num(float *x) { - *x = rand() / (float) RAND_MAX; +LFORTRAN_API float _lfortran_sp_rand_num() { + return rand() / (float) RAND_MAX; } -LFORTRAN_API void _lfortran_dp_rand_num(double *x) { - *x = rand() / (double) RAND_MAX; +LFORTRAN_API double _lfortran_dp_rand_num() { + return rand() / (double) RAND_MAX; } LFORTRAN_API int64_t _lpython_open(char *path, char *flags) @@ -2378,7 +2980,7 @@ LFORTRAN_API void _lfortran_read_double(double *p, int32_t unit_num) } } -LFORTRAN_API void _lfortran_formatted_read(int32_t unit_num, int32_t* iostat, char* fmt, int32_t no_of_args, ...) +LFORTRAN_API void _lfortran_formatted_read(int32_t unit_num, int32_t* iostat, int32_t* chunk, char* fmt, int32_t no_of_args, ...) { if (!streql(fmt, "(a)")) { printf("Only (a) supported as fmt currently"); @@ -2411,11 +3013,21 @@ LFORTRAN_API void _lfortran_formatted_read(int32_t unit_num, int32_t* iostat, ch } *iostat = !(fgets(*arg, n+1, filep) == *arg); - (*arg)[strcspn(*arg, "\n")] = 0; + if (streql(*arg, "\n")) { + *iostat = -2; + } + int len = strcspn(*arg, "\n"); + *chunk = len; + (*arg)[len] = 0; va_end(args); } LFORTRAN_API void _lfortran_empty_read(int32_t unit_num, int32_t* iostat) { + if (unit_num == -1) { + // Read from stdin + return; + } + bool unit_file_bin; FILE* fp = get_file_pointer_from_unit(unit_num, &unit_file_bin); if (!fp) { @@ -2453,7 +3065,7 @@ LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n) return c; } -LFORTRAN_API void _lfortran_file_write(int32_t unit_num, const char *format, ...) +LFORTRAN_API void _lfortran_file_write(int32_t unit_num, int32_t* iostat, const char *format, ...) { bool unit_file_bin; FILE* filep = get_file_pointer_from_unit(unit_num, &unit_file_bin); @@ -2470,9 +3082,10 @@ LFORTRAN_API void _lfortran_file_write(int32_t unit_num, const char *format, ... va_end(args); (void)!ftruncate(fileno(filep), ftell(filep)); + *iostat = 0; } -LFORTRAN_API void _lfortran_string_write(char **str, const char *format, ...) { +LFORTRAN_API void _lfortran_string_write(char **str, int32_t* iostat, const char *format, ...) { va_list args; va_start(args, format); char *s = (char *) malloc(strlen(*str)*sizeof(char)); @@ -2480,6 +3093,11 @@ LFORTRAN_API void _lfortran_string_write(char **str, const char *format, ...) { _lfortran_strcpy(str, s, 0); free(s); va_end(args); + *iostat = 0; +} + +LFORTRAN_API void _lfortran_string_read(char *str, char *format, int *i) { + sscanf(str, format, i); } LFORTRAN_API void _lpython_close(int64_t fd) diff --git a/src/libasr/runtime/lfortran_intrinsics.h b/src/libasr/runtime/lfortran_intrinsics.h index 7d25667eab..7215573fde 100644 --- a/src/libasr/runtime/lfortran_intrinsics.h +++ b/src/libasr/runtime/lfortran_intrinsics.h @@ -99,14 +99,14 @@ LFORTRAN_API void _lfortran_complex_aimag_32(struct _lfortran_complex_32 *x, flo LFORTRAN_API void _lfortran_complex_aimag_64(struct _lfortran_complex_64 *x, double *res); LFORTRAN_API float_complex_t _lfortran_csqrt(float_complex_t x); LFORTRAN_API double_complex_t _lfortran_zsqrt(double_complex_t x); -LFORTRAN_API float _lfortran_caimag(float_complex_t x); -LFORTRAN_API double _lfortran_zaimag(double_complex_t x); LFORTRAN_API float _lfortran_sexp(float x); LFORTRAN_API double _lfortran_dexp(double x); LFORTRAN_API float_complex_t _lfortran_cexp(float_complex_t x); LFORTRAN_API double_complex_t _lfortran_zexp(double_complex_t x); LFORTRAN_API float _lfortran_slog(float x); LFORTRAN_API double _lfortran_dlog(double x); +LFORTRAN_API bool _lfortran_rsp_is_nan(float x); +LFORTRAN_API bool _lfortran_rdp_is_nan(double x); LFORTRAN_API float_complex_t _lfortran_clog(float_complex_t x); LFORTRAN_API double_complex_t _lfortran_zlog(double_complex_t x); LFORTRAN_API float _lfortran_serf(float x); @@ -214,34 +214,10 @@ LFORTRAN_API char* _lfortran_str_slice(char* s, int32_t idx1, int32_t idx2, int3 bool idx1_present, bool idx2_present); LFORTRAN_API char* _lfortran_str_slice_assign(char* s, char *r, int32_t idx1, int32_t idx2, int32_t step, bool idx1_present, bool idx2_present); -LFORTRAN_API int32_t _lfortran_iand32(int32_t x, int32_t y); -LFORTRAN_API int64_t _lfortran_iand64(int64_t x, int64_t y); -LFORTRAN_API int32_t _lfortran_not32(int32_t x); -LFORTRAN_API int64_t _lfortran_not64(int64_t x); -LFORTRAN_API int32_t _lfortran_ior32(int32_t x, int32_t y); -LFORTRAN_API int64_t _lfortran_ior64(int64_t x, int64_t y); -LFORTRAN_API int32_t _lfortran_ieor32(int32_t x, int32_t y); -LFORTRAN_API int64_t _lfortran_ieor64(int64_t x, int64_t y); -LFORTRAN_API int32_t _lfortran_ibclr32(int32_t i, int pos); -LFORTRAN_API int64_t _lfortran_ibclr64(int64_t i, int pos); -LFORTRAN_API int32_t _lfortran_ibset32(int32_t i, int pos); -LFORTRAN_API int64_t _lfortran_ibset64(int64_t i, int pos); -LFORTRAN_API int32_t _lfortran_btest32(int32_t i, int pos); -LFORTRAN_API int64_t _lfortran_btest64(int64_t i, int pos); -LFORTRAN_API int32_t _lfortran_ishft32(int32_t i, int32_t shift); -LFORTRAN_API int64_t _lfortran_ishft64(int64_t i, int64_t shift); LFORTRAN_API int32_t _lfortran_mvbits32(int32_t from, int32_t frompos, int32_t len, int32_t to, int32_t topos); LFORTRAN_API int64_t _lfortran_mvbits64(int64_t from, int32_t frompos, int32_t len, int64_t to, int32_t topos); -LFORTRAN_API int32_t _lfortran_bgt32(int32_t i, int32_t j); -LFORTRAN_API int32_t _lfortran_bgt64(int64_t i, int64_t j); -LFORTRAN_API int32_t _lfortran_bge32(int32_t i, int32_t j); -LFORTRAN_API int32_t _lfortran_bge64(int64_t i, int64_t j); -LFORTRAN_API int32_t _lfortran_ble32(int32_t i, int32_t j); -LFORTRAN_API int32_t _lfortran_ble64(int64_t i, int64_t j); -LFORTRAN_API int32_t _lfortran_blt32(int32_t i, int32_t j); -LFORTRAN_API int32_t _lfortran_blt64(int64_t i, int64_t j); LFORTRAN_API int32_t _lfortran_ibits32(int32_t i, int32_t pos, int32_t len); LFORTRAN_API int64_t _lfortran_ibits64(int64_t i, int32_t pos, int32_t len); LFORTRAN_API void _lfortran_cpu_time(double *t); @@ -249,14 +225,16 @@ LFORTRAN_API void _lfortran_i32sys_clock( int32_t *count, int32_t *rate, int32_t *max); LFORTRAN_API void _lfortran_i64sys_clock( uint64_t *count, int64_t *rate, int64_t *max); +LFORTRAN_API void _lfortran_i64r64sys_clock( + uint64_t *count, double *rate, int64_t *max); LFORTRAN_API double _lfortran_time(); -LFORTRAN_API void _lfortran_sp_rand_num(float *x); -LFORTRAN_API void _lfortran_dp_rand_num(double *x); +LFORTRAN_API float _lfortran_sp_rand_num(); +LFORTRAN_API double _lfortran_dp_rand_num(); LFORTRAN_API int64_t _lpython_open(char *path, char *flags); LFORTRAN_API int64_t _lfortran_open(int32_t unit_num, char *f_name, char *status, char* form); LFORTRAN_API void _lfortran_flush(int32_t unit_num); LFORTRAN_API void _lfortran_inquire(char *f_name, bool *exists, int32_t unit_num, bool *opened); -LFORTRAN_API void _lfortran_formatted_read(int32_t unit_num, int32_t* iostat, char* fmt, int32_t no_of_args, ...); +LFORTRAN_API void _lfortran_formatted_read(int32_t unit_num, int32_t* iostat, int32_t* chunk, char* fmt, int32_t no_of_args, ...); LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n); LFORTRAN_API void _lfortran_read_int32(int32_t *p, int32_t unit_num); LFORTRAN_API void _lfortran_read_int64(int64_t *p, int32_t unit_num); @@ -266,8 +244,9 @@ LFORTRAN_API void _lfortran_read_float(float *p, int32_t unit_num); LFORTRAN_API void _lfortran_read_array_float(float *p, int array_size, int32_t unit_num); LFORTRAN_API void _lfortran_read_array_double(double *p, int array_size, int32_t unit_num); LFORTRAN_API void _lfortran_read_char(char **p, int32_t unit_num); -LFORTRAN_API void _lfortran_string_write(char **str, const char *format, ...); -LFORTRAN_API void _lfortran_file_write(int32_t unit_num, const char *format, ...); +LFORTRAN_API void _lfortran_string_write(char **str, int32_t* iostat, const char *format, ...); +LFORTRAN_API void _lfortran_file_write(int32_t unit_num, int32_t* iostat, const char *format, ...); +LFORTRAN_API void _lfortran_string_read(char *str, char *format, int *i); LFORTRAN_API void _lfortran_empty_read(int32_t unit_num, int32_t* iostat); LFORTRAN_API void _lpython_close(int64_t fd); LFORTRAN_API void _lfortran_close(int32_t unit_num); diff --git a/src/libasr/serialization.cpp b/src/libasr/serialization.cpp index 3c0bc96882..12967cda78 100644 --- a/src/libasr/serialization.cpp +++ b/src/libasr/serialization.cpp @@ -243,6 +243,28 @@ class FixParentSymtabVisitor : public BaseWalkVisitor current_symtab = parent_symtab; } + void visit_Requirement(const Requirement_t &x) { + SymbolTable *parent_symtab = current_symtab; + current_symtab = x.m_symtab; + x.m_symtab->parent = parent_symtab; + x.m_symtab->asr_owner = (asr_t*)&x; + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + current_symtab = parent_symtab; + } + + void visit_Template(const Template_t &x) { + SymbolTable *parent_symtab = current_symtab; + current_symtab = x.m_symtab; + x.m_symtab->parent = parent_symtab; + x.m_symtab->asr_owner = (asr_t*)&x; + for (auto &a : x.m_symtab->get_scope()) { + this->visit_symbol(*a.second); + } + current_symtab = parent_symtab; + } + }; class FixExternalSymbolsVisitor : public BaseWalkVisitor @@ -343,6 +365,10 @@ class FixExternalSymbolsVisitor : public BaseWalkVisitor(m_sym); sym = m->m_symtab->find_scoped_symbol(original_name, x.n_scope_names, x.m_scope_names); + } else if( ASR::is_a(*m_sym) ) { + Function_t *m = down_cast(m_sym); + sym = m->m_symtab->find_scoped_symbol(original_name, + x.n_scope_names, x.m_scope_names); } if (sym) { // FIXME: this is a hack, we need to pass in a non-const `x`. diff --git a/src/libasr/stacktrace.cpp b/src/libasr/stacktrace.cpp index 2c730a5ec5..d5cab7445d 100644 --- a/src/libasr/stacktrace.cpp +++ b/src/libasr/stacktrace.cpp @@ -15,11 +15,6 @@ // For registering SIGSEGV callbacks #include -#ifdef __APPLE__ -// For PATH_MAX -# include -#endif - // The following C headers are needed for some specific C functionality (see // the comments), which is not available in C++: @@ -41,6 +36,7 @@ #ifdef HAVE_LFORTRAN_MACHO # include +# include // PATH_MAX #endif #ifdef HAVE_LFORTRAN_BFD diff --git a/src/libasr/utils.h b/src/libasr/utils.h index e65f1ce76f..4a51127987 100644 --- a/src/libasr/utils.h +++ b/src/libasr/utils.h @@ -28,6 +28,8 @@ struct PassOptions { std::filesystem::path mod_files_dir; std::vector include_dirs; + int default_integer_kind = 4; + std::string run_fun; // for global_stmts pass // TODO: Convert to std::filesystem::path (also change find_and_load_module()) std::string runtime_library_dir; @@ -69,10 +71,15 @@ struct CompilerOptions { bool c_preprocessor = false; std::vector c_preprocessor_defines; bool prescan = true; + bool disable_main = false; bool symtab_only = false; bool show_stacktrace = false; bool use_colors = true; bool indent = true; + bool json = false; + bool tree = false; + bool visualize = false; + bool fast = false; bool openmp = false; bool generate_object_code = false; bool no_warnings = false; diff --git a/src/lpython/semantics/python_ast_to_asr.cpp b/src/lpython/semantics/python_ast_to_asr.cpp index c5a4554281..8ca37a7c1c 100644 --- a/src/lpython/semantics/python_ast_to_asr.cpp +++ b/src/lpython/semantics/python_ast_to_asr.cpp @@ -304,7 +304,7 @@ void get_calls_to_global_init_and_stmts(Allocator &al, const Location &loc, Symb ASR::accessType::Public)); scope->add_symbol(g_func_name, es); tmp_vec.push_back(ASRUtils::make_SubroutineCall_t_util(al, loc, - es, g_func, nullptr, 0, nullptr, nullptr, false)); + es, g_func, nullptr, 0, nullptr, nullptr, false, false)); } g_func_name = mod_name + "global_stmts"; @@ -317,7 +317,7 @@ void get_calls_to_global_init_and_stmts(Allocator &al, const Location &loc, Symb ASR::accessType::Public)); scope->add_symbol(g_func_name, es); tmp_vec.push_back(ASRUtils::make_SubroutineCall_t_util(al, loc, - es, g_func, nullptr, 0, nullptr, nullptr, false)); + es, g_func, nullptr, 0, nullptr, nullptr, false, false)); } } @@ -1038,6 +1038,7 @@ class CommonVisitor : public AST::BaseVisitor { ASR::asr_t* make_dummy_assignment(ASR::expr_t* expr) { ASR::ttype_t* type = ASRUtils::expr_type(expr); + LCOMPILERS_ASSERT(type != nullptr); std::string dummy_ret_name = current_scope->get_unique_name("__lcompilers_dummy", false); SetChar variable_dependencies_vec; variable_dependencies_vec.reserve(al, 1); @@ -1233,7 +1234,7 @@ class CommonVisitor : public AST::BaseVisitor { } return ASRUtils::make_SubroutineCall_t_util(al, loc, stemp, - s_generic, args_new.p, args_new.size(), nullptr, nullptr, false); + s_generic, args_new.p, args_new.size(), nullptr, nullptr, false, false); } } else if(ASR::is_a(*s)) { ASR::StructType_t* StructType = ASR::down_cast(s); @@ -1903,8 +1904,8 @@ class CommonVisitor : public AST::BaseVisitor { // See integration_tests/test_bool_binop.py for its significance. if(!is_assign && ASRUtils::is_logical(*left_type) && ASRUtils::is_logical(*right_type) ) { ASR::ttype_t* dest_type = ASRUtils::TYPE(ASR::make_Integer_t(al, left_type->base.loc, 4)); - left = CastingUtil::perform_casting(left, left_type, dest_type, al, left->base.loc); - right = CastingUtil::perform_casting(right, right_type, dest_type, al, right->base.loc); + left = CastingUtil::perform_casting(left, dest_type, al, left->base.loc); + right = CastingUtil::perform_casting(right, dest_type, al, right->base.loc); return ; } @@ -1915,8 +1916,7 @@ class CommonVisitor : public AST::BaseVisitor { if( casted_expression_signal == 2 ) { return ; } - src_expr = CastingUtil::perform_casting(src_expr, src_type, - dest_type, al, src_expr->base.loc); + src_expr = CastingUtil::perform_casting(src_expr, dest_type, al, src_expr->base.loc); if( casted_expression_signal == 0 ) { left = src_expr; right = dest_expr; @@ -1938,8 +1938,7 @@ class CommonVisitor : public AST::BaseVisitor { if( ASRUtils::check_equal_type(src_type, dest_type) ) { return ; } - src_expr = CastingUtil::perform_casting(src_expr, src_type, - dest_type, al, loc); + src_expr = CastingUtil::perform_casting(src_expr, dest_type, al, loc); } void make_BinOp_helper(ASR::expr_t *left, ASR::expr_t *right, @@ -2186,23 +2185,23 @@ class CommonVisitor : public AST::BaseVisitor { ASRUtils::create_intrinsic_function create_function; switch (op) { case (ASR::binopType::Add): { - create_function = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicAdd"); + create_function = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicAdd"); break; } case (ASR::binopType::Sub): { - create_function = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicSub"); + create_function = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicSub"); break; } case (ASR::binopType::Mul): { - create_function = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicMul"); + create_function = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicMul"); break; } case (ASR::binopType::Div): { - create_function = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicDiv"); + create_function = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicDiv"); break; } case (ASR::binopType::Pow): { - create_function = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SymbolicPow"); + create_function = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SymbolicPow"); break; } default: { @@ -2210,9 +2209,7 @@ class CommonVisitor : public AST::BaseVisitor { break; } } - tmp = create_function(al, loc, args_with_symbolic, [&](const std::string& msg, const Location& loc) { - throw SemanticError(msg, loc); - }); + tmp = create_function(al, loc, args_with_symbolic, diag); return; } else { std::string ltype = ASRUtils::type_to_str_python(ASRUtils::expr_type(left)); @@ -3234,14 +3231,13 @@ class CommonVisitor : public AST::BaseVisitor { ASR::symbol_t *s = current_scope->resolve_symbol(name); LCOMPILERS_ASSERT(s); tmp = ASR::make_Var_t(al, x.base.base.loc, s); - } else if (ASRUtils::IntrinsicScalarFunctionRegistry::is_intrinsic_function(name) && + } else if (ASRUtils::IntrinsicElementalFunctionRegistry::is_intrinsic_function(name) && (not_cpython_builtin.find(name) == not_cpython_builtin.end() || imported_functions.find(name) != imported_functions.end() )) { ASRUtils::create_intrinsic_function create_func = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function(name); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function(name); Vec args_; - tmp = create_func(al, x.base.base.loc, args_, [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = create_func(al, x.base.base.loc, args_, diag); } else { throw SemanticError("Variable '" + name + "' not declared", x.base.base.loc); @@ -3333,8 +3329,8 @@ class CommonVisitor : public AST::BaseVisitor { ASR::ttype_t *dest_type = left_operand_type; if (!ASRUtils::check_equal_type(left_operand_type, right_operand_type)) { - throw SemanticError("Type mismatch: '" + ASRUtils::type_to_str_python(left_operand_type) - + "' and '" + ASRUtils::type_to_str_python(right_operand_type) + throw SemanticError("Type mismatch: '" + ASRUtils::type_to_str_python(left_operand_type) + + "' and '" + ASRUtils::type_to_str_python(right_operand_type) + "'. Both operands must be of the same type.", x.base.base.loc); } // Reference: https://docs.python.org/3/reference/expressions.html#boolean-operations @@ -3474,10 +3470,8 @@ class CommonVisitor : public AST::BaseVisitor { args.push_back(al, left); args.push_back(al, right); ASRUtils::create_intrinsic_function create_func = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function(op_name); - tmp = create_func(al, x.base.base.loc, args, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function(op_name); + tmp = create_func(al, x.base.base.loc, args, diag); return; } @@ -3911,7 +3905,7 @@ class CommonVisitor : public AST::BaseVisitor { ASR::expr_t *dim_size = ASR::down_cast(type)->m_dims[idx].m_length; ASR::expr_t *idx_expr = ASRUtils::EXPR(ASR::make_IntegerConstant_t(al, loc, idx + 1, int_type)); ASR::expr_t *size_expr = ASRUtils::EXPR(ASRUtils::make_ArraySize_t_util(al, loc, value, idx_expr, int_type, dim_size, false)); - index = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, + index = ASRUtils::EXPR(ASR::make_IntegerBinOp_t(al, loc, size_expr, ASR::binopType::Add, neg_idx, int_type, nullptr)); } } @@ -6853,9 +6847,7 @@ class BodyVisitor : public CommonVisitor { */ Vec args_; args_.reserve(al, args.n); ASRUtils::visit_expr_list(al, args, args_); - tmp = ASRUtils::Partition::create_partition(al, loc, args_, s_var, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = ASRUtils::Partition::create_partition(al, loc, args_, s_var, diag); return; } else if(attr_name == "count") { if(args.size() != 1) { @@ -7230,9 +7222,7 @@ class BodyVisitor : public CommonVisitor { loc, 1, s_var.size(), nullptr)); ASR::expr_t *str = ASRUtils::EXPR(ASR::make_StringConstant_t(al, loc, s2c(al, s_var), char_type)); - tmp = ASRUtils::Partition::create_partition(al, loc, args_, str, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = ASRUtils::Partition::create_partition(al, loc, args_, str, diag); return; } else if (attr_name.size() > 2 && attr_name[0] == 'i' && attr_name[1] == 's') { /* @@ -7345,7 +7335,7 @@ we will have to use something else. } else if (attr_name == "isalpha") { /* * Specification - - Return True if all characters in the string are alphabets, + Return True if all characters in the string are alphabets, and there is at least one character in the string. */ bool is_alpha = (s_var.size() != 0); @@ -7361,7 +7351,7 @@ we will have to use something else. } else if (attr_name == "isalnum") { /* * Specification - - Return True if all characters in the string are alphabets or numbers, + Return True if all characters in the string are alphabets or numbers, and there is at least one character in the string. */ bool is_alnum = (s_var.size() != 0); @@ -7377,7 +7367,7 @@ we will have to use something else. } else if (attr_name == "isnumeric") { /* * Specification - - Return True if all characters in the string are numbers, + Return True if all characters in the string are numbers, and there is at least one character in the string. */ bool is_numeric = (s_var.size() != 0); @@ -7393,7 +7383,7 @@ we will have to use something else. } else if (attr_name == "istitle") { /* * Specification - - Returns True if all words in the string are in title case, + Returns True if all words in the string are in title case, and there is at least one character in the string. */ bool is_title = (s_var.size() != 0); @@ -7457,15 +7447,13 @@ we will have to use something else. if (symbolic_attributes.find(call_name) != symbolic_attributes.end() && symbolic_constants.find(mod_name) != symbolic_constants.end()){ ASRUtils::create_intrinsic_function create_func; - create_func = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function(mod_name); + create_func = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function(mod_name); Vec eles; eles.reserve(al, args.size()); Vec args_; args_.reserve(al, 1); for (size_t i=0; ibase.base.loc, args_, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = create_func(al, at->base.base.loc, args_, diag); handle_symbolic_attribute(ASRUtils::EXPR(tmp), call_name, loc, eles); return; } @@ -7687,13 +7675,13 @@ we will have to use something else. imported_functions[call_name] == "sympy"){ intrinsic_name = "Symbolic" + std::string(1, std::toupper(call_name[0])) + call_name.substr(1); } - if ((ASRUtils::IntrinsicScalarFunctionRegistry::is_intrinsic_function(intrinsic_name) || + if ((ASRUtils::IntrinsicElementalFunctionRegistry::is_intrinsic_function(intrinsic_name) || ASRUtils::IntrinsicArrayFunctionRegistry::is_intrinsic_function(intrinsic_name)) && (not_cpython_builtin.find(call_name) == not_cpython_builtin.end() || imported_functions.find(call_name) != imported_functions.end() )) { ASRUtils::create_intrinsic_function create_func; - if (ASRUtils::IntrinsicScalarFunctionRegistry::is_intrinsic_function(intrinsic_name)) { - create_func = ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function(intrinsic_name); + if (ASRUtils::IntrinsicElementalFunctionRegistry::is_intrinsic_function(intrinsic_name)) { + create_func = ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function(intrinsic_name); } else { create_func = ASRUtils::IntrinsicArrayFunctionRegistry::get_create_function(intrinsic_name); } @@ -7704,9 +7692,7 @@ we will have to use something else. throw SemanticError("Function '" + call_name + "' does not accept vector values", x.base.base.loc); } - tmp = create_func(al, x.base.base.loc, args_, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = create_func(al, x.base.base.loc, args_, diag); return ; } else if (intrinsic_procedures.is_intrinsic(call_name)) { s = resolve_intrinsic_function(x.base.base.loc, call_name); @@ -7789,11 +7775,9 @@ we will have to use something else. } else if( call_name == "reserve" ) { parse_args(x, args); ASRUtils::create_intrinsic_function create_func = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("reserve"); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("list.reserve"); Vec args_exprs = ASRUtils::call_arg2expr(al, args); - tmp = create_func(al, x.base.base.loc, args_exprs, - [&](const std::string &msg, const Location &loc) { - throw SemanticError(msg, loc); }); + tmp = create_func(al, x.base.base.loc, args_exprs, diag); return ; } else if (call_name == "size") { parse_args(x, args); @@ -7866,7 +7850,7 @@ we will have to use something else. } else { Vec arr_args; arr_args.reserve(al, 0); - tmp = ASRUtils::make_ArrayConstant_t_util(al, x.base.base.loc, + tmp = ASRUtils::make_ArrayConstructor_t_util(al, x.base.base.loc, arr_args.p, arr_args.size(), type, ASR::arraystorageType::RowMajor); } return; @@ -8025,10 +8009,10 @@ we will have to use something else. type = ASRUtils::make_Array_t_util(al, x.base.base.loc, type, dims.p, dims.size(), ASR::abiType::Source, false, ASR::array_physical_typeType::PointerToDataArray, true); for( size_t i = 0; i < n_args; i++ ) { - m_args[i] = CastingUtil::perform_casting(m_args[i], ASRUtils::expr_type(m_args[i]), - ASRUtils::type_get_past_array(type), al, x.base.base.loc); + m_args[i] = CastingUtil::perform_casting(m_args[i], ASRUtils::type_get_past_array(type), + al, x.base.base.loc); } - tmp = ASR::make_ArrayConstant_t(al, x.base.base.loc, m_args, n_args, type, ASR::arraystorageType::RowMajor); + tmp = ASRUtils::make_ArrayConstructor_t_util(al, x.base.base.loc, m_args, n_args, type, ASR::arraystorageType::RowMajor); } else { throw SemanticError("array accepts only list for now, got " + ASRUtils::type_to_str(type) + " type.", x.base.base.loc); diff --git a/src/lpython/semantics/python_attribute_eval.h b/src/lpython/semantics/python_attribute_eval.h index 5c80074e01..5e5aceb613 100644 --- a/src/lpython/semantics/python_attribute_eval.h +++ b/src/lpython/semantics/python_attribute_eval.h @@ -202,7 +202,7 @@ struct AttributeHandler { } static ASR::asr_t* eval_list_index(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -210,13 +210,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("list.index"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("list.index"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_list_reverse(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { if (ASR::is_a(*ASRUtils::expr_type(s))) { throw SemanticError("cannot reverse a const list", loc); } @@ -227,13 +226,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("list.reverse"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("list.reverse"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_list_pop(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { if (ASR::is_a(*ASRUtils::expr_type(s))) { throw SemanticError("cannot pop element from a const list", loc); } @@ -244,16 +242,15 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("list.pop"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("list.pop"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_list_insert(ASR::expr_t *s, Allocator &al, const Location &loc, Vec &args, diag::Diagnostics &diag) { if (ASR::is_a(*ASRUtils::expr_type(s))) { throw SemanticError("cannot insert element in a const list", loc); - } + } if (args.size() != 2) { throw SemanticError("insert() takes exactly two arguments", loc); @@ -315,7 +312,7 @@ struct AttributeHandler { } static ASR::asr_t* eval_set_add(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_set; args_with_set.reserve(al, args.size() + 1); args_with_set.push_back(al, s); @@ -323,13 +320,12 @@ struct AttributeHandler { args_with_set.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("set.add"); - return create_function(al, loc, args_with_set, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("set.add"); + return create_function(al, loc, args_with_set, diag); } static ASR::asr_t* eval_set_remove(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_set; args_with_set.reserve(al, args.size() + 1); args_with_set.push_back(al, s); @@ -337,9 +333,8 @@ struct AttributeHandler { args_with_set.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("set.remove"); - return create_function(al, loc, args_with_set, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("set.remove"); + return create_function(al, loc, args_with_set, diag); } static ASR::asr_t* eval_dict_get(ASR::expr_t *s, Allocator &al, const Location &loc, @@ -406,7 +401,7 @@ struct AttributeHandler { } static ASR::asr_t* eval_dict_keys(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_dict; args_with_dict.reserve(al, args.size() + 1); args_with_dict.push_back(al, s); @@ -414,13 +409,12 @@ struct AttributeHandler { args_with_dict.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("dict.keys"); - return create_function(al, loc, args_with_dict, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("dict.keys"); + return create_function(al, loc, args_with_dict, diag); } static ASR::asr_t* eval_dict_values(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_dict; args_with_dict.reserve(al, args.size() + 1); args_with_dict.push_back(al, s); @@ -428,13 +422,12 @@ struct AttributeHandler { args_with_dict.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("dict.values"); - return create_function(al, loc, args_with_dict, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("dict.values"); + return create_function(al, loc, args_with_dict, diag); } static ASR::asr_t* eval_symbolic_diff(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -442,13 +435,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("diff"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("diff"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_expand(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -456,13 +448,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("expand"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("expand"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_has_symbol(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -470,13 +461,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("has"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("has"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_is_Add(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -484,13 +474,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("AddQ"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("AddQ"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_is_Mul(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -498,13 +487,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("MulQ"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("MulQ"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_is_Pow(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -512,13 +500,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("PowQ"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("PowQ"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_is_log(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -526,13 +513,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("LogQ"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("LogQ"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_is_sin(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -540,13 +526,12 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("SinQ"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("SinQ"); + return create_function(al, loc, args_with_list, diag); } static ASR::asr_t* eval_symbolic_get_argument(ASR::expr_t *s, Allocator &al, const Location &loc, - Vec &args, diag::Diagnostics &/*diag*/) { + Vec &args, diag::Diagnostics &diag) { Vec args_with_list; args_with_list.reserve(al, args.size() + 1); args_with_list.push_back(al, s); @@ -554,9 +539,8 @@ struct AttributeHandler { args_with_list.push_back(al, args[i]); } ASRUtils::create_intrinsic_function create_function = - ASRUtils::IntrinsicScalarFunctionRegistry::get_create_function("GetArgument"); - return create_function(al, loc, args_with_list, [&](const std::string &msg, const Location &loc) - { throw SemanticError(msg, loc); }); + ASRUtils::IntrinsicElementalFunctionRegistry::get_create_function("GetArgument"); + return create_function(al, loc, args_with_list, diag); } }; // AttributeHandler diff --git a/tests/reference/asr-array_01_decl-39cf894.json b/tests/reference/asr-array_01_decl-39cf894.json index 1095e876ae..6d47b6ce49 100644 --- a/tests/reference/asr-array_01_decl-39cf894.json +++ b/tests/reference/asr-array_01_decl-39cf894.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-array_01_decl-39cf894.stdout", - "stdout_hash": "f14010ffcf7d42b89e54c88ebecc7ca51d67b204825e07f4f708875e", + "stdout_hash": "34c5f9983e43e6b5c65f021792e415f0c2e4fe5135c6435eb5322719", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-array_01_decl-39cf894.stdout b/tests/reference/asr-array_01_decl-39cf894.stdout index 3d8b06bb51..144c02d35c 100644 --- a/tests/reference/asr-array_01_decl-39cf894.stdout +++ b/tests/reference/asr-array_01_decl-39cf894.stdout @@ -156,7 +156,7 @@ ) [] [(Var 224 xf32)] - [(= + [(Assignment (ArrayItem (Var 224 xf32) [(() @@ -180,7 +180,7 @@ ) () ) - (= + (Assignment (Var 224 _lpython_return_variable) (ArrayItem (Var 224 xf32) @@ -265,7 +265,7 @@ ) [] [(Var 225 xf64)] - [(= + [(Assignment (ArrayItem (Var 225 xf64) [(() @@ -281,7 +281,7 @@ ) () ) - (= + (Assignment (Var 225 _lpython_return_variable) (ArrayItem (Var 225 xf64) @@ -366,7 +366,7 @@ ) [] [(Var 221 xi16)] - [(= + [(Assignment (ArrayItem (Var 221 xi16) [(() @@ -384,7 +384,7 @@ ) () ) - (= + (Assignment (Var 221 _lpython_return_variable) (ArrayItem (Var 221 xi16) @@ -469,7 +469,7 @@ ) [] [(Var 222 xi32)] - [(= + [(Assignment (ArrayItem (Var 222 xi32) [(() @@ -482,7 +482,7 @@ (IntegerConstant 32 (Integer 4)) () ) - (= + (Assignment (Var 222 _lpython_return_variable) (ArrayItem (Var 222 xi32) @@ -567,7 +567,7 @@ ) [] [(Var 223 xi64)] - [(= + [(Assignment (ArrayItem (Var 223 xi64) [(() @@ -585,7 +585,7 @@ ) () ) - (= + (Assignment (Var 223 _lpython_return_variable) (ArrayItem (Var 223 xi64) @@ -779,9 +779,9 @@ accept_f32_array accept_f64_array] [] - [(= + [(Assignment (Var 226 ai16) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 2) @@ -789,13 +789,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 ai32) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -803,13 +804,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 ai64) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 8) @@ -817,13 +819,14 @@ (IntegerConstant 10 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 af32) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -831,13 +834,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 af64) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -845,13 +849,14 @@ (IntegerConstant 10 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 ac32) - (ArrayConstant + (ArrayConstructor [] (Array (Complex 4) @@ -859,13 +864,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 ac64) - (ArrayConstant + (ArrayConstructor [] (Array (Complex 8) @@ -873,6 +879,7 @@ (IntegerConstant 10 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () diff --git a/tests/reference/asr-array_02_decl-e8f6874.json b/tests/reference/asr-array_02_decl-e8f6874.json index 1f7a2804a5..21996b79ed 100644 --- a/tests/reference/asr-array_02_decl-e8f6874.json +++ b/tests/reference/asr-array_02_decl-e8f6874.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-array_02_decl-e8f6874.stdout", - "stdout_hash": "5279aef41f63f0cd241fff1b853b3186a3d83a32905264b64b66705c", + "stdout_hash": "16f1a4388b7117f7ce6886ac48749fe533265ee12949b513a9317eba", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-array_02_decl-e8f6874.stdout b/tests/reference/asr-array_02_decl-e8f6874.stdout index e8eda385d8..3858f3f07c 100644 --- a/tests/reference/asr-array_02_decl-e8f6874.stdout +++ b/tests/reference/asr-array_02_decl-e8f6874.stdout @@ -108,7 +108,7 @@ ) [] [(Var 222 xf32)] - [(= + [(Assignment (Var 222 _lpython_return_variable) (ArrayItem (Var 222 xf32) @@ -197,7 +197,7 @@ ) [] [(Var 223 xf64)] - [(= + [(Assignment (Var 223 _lpython_return_variable) (ArrayItem (Var 223 xf64) @@ -289,7 +289,7 @@ ) [] [(Var 220 xi32)] - [(= + [(Assignment (Var 220 _lpython_return_variable) (ArrayItem (Var 220 xi32) @@ -385,7 +385,7 @@ ) [] [(Var 221 xi64)] - [(= + [(Assignment (Var 221 _lpython_return_variable) (ArrayItem (Var 221 xi64) @@ -581,9 +581,9 @@ accept_multidim_f32_array accept_multidim_f64_array] [] - [(= + [(Assignment (Var 224 ai32) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -593,13 +593,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 224 ai64) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 8) @@ -611,13 +612,14 @@ (IntegerConstant 10 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 224 af32) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -625,13 +627,14 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 224 af64) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -641,13 +644,14 @@ (IntegerConstant 4 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 224 ac32) - (ArrayConstant + (ArrayConstructor [] (Array (Complex 4) @@ -659,13 +663,14 @@ (IntegerConstant 99 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 224 ac64) - (ArrayConstant + (ArrayConstructor [] (Array (Complex 8) @@ -679,6 +684,7 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () diff --git a/tests/reference/asr-arrays_01-a617b64.json b/tests/reference/asr-arrays_01-a617b64.json index 45a1b7310d..ac13b25984 100644 --- a/tests/reference/asr-arrays_01-a617b64.json +++ b/tests/reference/asr-arrays_01-a617b64.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_01-a617b64.stderr", - "stderr_hash": "b8317c7306f747ceefa8557c06f2a0b4a8a4bd7ae805bb494fca6ef2", + "stderr_hash": "69f8656cd4ab2b5cc8b1555c5b089c764a36a817023697e5314a7815", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_01-a617b64.stderr b/tests/reference/asr-arrays_01-a617b64.stderr index 4fa39a8c3c..7fc7e250e5 100644 --- a/tests/reference/asr-arrays_01-a617b64.stderr +++ b/tests/reference/asr-arrays_01-a617b64.stderr @@ -6,3 +6,7 @@ semantic error: Type mismatch in procedure call; the types must be compatible | 9 | a : i8[4] = empty(4, dtype=int8) | ^^^^^ type mismatch (passed argument type is list[i8] but required type is i8[4]) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_02-da94458.json b/tests/reference/asr-arrays_02-da94458.json index 37de52ba40..9424e995da 100644 --- a/tests/reference/asr-arrays_02-da94458.json +++ b/tests/reference/asr-arrays_02-da94458.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_02-da94458.stderr", - "stderr_hash": "dc0e5be7cd6de7395421aedf1ce11977206f3e35bb7cba271aed8992", + "stderr_hash": "15fc716bf5d58791fd20510131f51127e7e99d1e8fab7a8d01e3b008", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_02-da94458.stderr b/tests/reference/asr-arrays_02-da94458.stderr index 295e0c9b28..2a1a008b78 100644 --- a/tests/reference/asr-arrays_02-da94458.stderr +++ b/tests/reference/asr-arrays_02-da94458.stderr @@ -3,3 +3,7 @@ semantic error: The truth value of an array with more than one element is ambigu | 28 | assert r1.a == t1.a | ^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_03-de2e952.json b/tests/reference/asr-arrays_03-de2e952.json index 1583b11b63..3c1e18549b 100644 --- a/tests/reference/asr-arrays_03-de2e952.json +++ b/tests/reference/asr-arrays_03-de2e952.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_03-de2e952.stderr", - "stderr_hash": "4c932f31bbb10c9ba8d8d75be226ba9c33553be3bcb367c8112e31af", + "stderr_hash": "42cba9a2472dd0b8fd0d081f97bfb17615c8efbe56fdb3f4ff709e48", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_03-de2e952.stderr b/tests/reference/asr-arrays_03-de2e952.stderr index 1fb5635502..eb6dd9b6d0 100644 --- a/tests/reference/asr-arrays_03-de2e952.stderr +++ b/tests/reference/asr-arrays_03-de2e952.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 6 | x: i16[4] = empty([5], dtype=int16) | ^ ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[4]' and 'i16[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_04-880407c.json b/tests/reference/asr-arrays_04-880407c.json index 1c5077a22c..7e26d05113 100644 --- a/tests/reference/asr-arrays_04-880407c.json +++ b/tests/reference/asr-arrays_04-880407c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_04-880407c.stderr", - "stderr_hash": "10ef155b0236096d5de8157e38b3989d99343b016a8153b68a36aa54", + "stderr_hash": "40354354f9ae2e3eae5163f41ff6ce0298b5005bf4d13fd3e89cf48b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_04-880407c.stderr b/tests/reference/asr-arrays_04-880407c.stderr index 5cb27a1cb7..f416808d0f 100644 --- a/tests/reference/asr-arrays_04-880407c.stderr +++ b/tests/reference/asr-arrays_04-880407c.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 6 | x: i16[5] = empty([5], dtype=int32) | ^ ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[5]' and 'i32[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_05-ec8fbd5.json b/tests/reference/asr-arrays_05-ec8fbd5.json index a4302b38e0..c548921f11 100644 --- a/tests/reference/asr-arrays_05-ec8fbd5.json +++ b/tests/reference/asr-arrays_05-ec8fbd5.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_05-ec8fbd5.stderr", - "stderr_hash": "4e5d42a186b8d82b484ec66ccc5a3b90da7e4be8a32bac26ea906198", + "stderr_hash": "14eef4151e9c559cdcc637a009a39a4a965049d22f5393af3e83c5e1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_05-ec8fbd5.stderr b/tests/reference/asr-arrays_05-ec8fbd5.stderr index 165aee29a8..671e75e1cc 100644 --- a/tests/reference/asr-arrays_05-ec8fbd5.stderr +++ b/tests/reference/asr-arrays_05-ec8fbd5.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 6 | x: i16[5, 4] = empty([5, 3], dtype=int16) | ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[5,4]' and 'i16[5,3]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_06-fbb09a3.json b/tests/reference/asr-arrays_06-fbb09a3.json index 863eeebf1e..7b63fdaf6b 100644 --- a/tests/reference/asr-arrays_06-fbb09a3.json +++ b/tests/reference/asr-arrays_06-fbb09a3.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_06-fbb09a3.stderr", - "stderr_hash": "1fa3f5061a72f03c0678806c0460b9ec5caf01cbbd2f07a606f1057e", + "stderr_hash": "0da1a817c8625225561019e08f1e47247998ed20bf3ab53e01c1963a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_06-fbb09a3.stderr b/tests/reference/asr-arrays_06-fbb09a3.stderr index 9bbcde8ee8..a3c6f9d6d1 100644 --- a/tests/reference/asr-arrays_06-fbb09a3.stderr +++ b/tests/reference/asr-arrays_06-fbb09a3.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 6 | x: i16[5, 4] = empty([5, 4], dtype=int32) | ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[5,4]' and 'i32[5,4]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_07-de430fd.json b/tests/reference/asr-arrays_07-de430fd.json index 19a44750cc..e6784da01f 100644 --- a/tests/reference/asr-arrays_07-de430fd.json +++ b/tests/reference/asr-arrays_07-de430fd.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_07-de430fd.stderr", - "stderr_hash": "7fadea44b4ad8f383e0cadbd27a53eb3ab75f0edef98d27639527723", + "stderr_hash": "6774eef8f3ca19c2ac8347014012d6daa8fd8d5382a22b29fb843a9f", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_07-de430fd.stderr b/tests/reference/asr-arrays_07-de430fd.stderr index 7624d1fe92..ef8973c0b4 100644 --- a/tests/reference/asr-arrays_07-de430fd.stderr +++ b/tests/reference/asr-arrays_07-de430fd.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 6 | x: f32[5, 4] = empty([5, 4], dtype=complex64) | ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('f32[5,4]' and 'c32[5,4]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_08-ba317a3.json b/tests/reference/asr-arrays_08-ba317a3.json index 56982fe195..7dc9343199 100644 --- a/tests/reference/asr-arrays_08-ba317a3.json +++ b/tests/reference/asr-arrays_08-ba317a3.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_08-ba317a3.stderr", - "stderr_hash": "bedb87b219b7c49a18cced170e4ffcac780d242f70c3ae8bbfb27a26", + "stderr_hash": "05ceaebc761f9c6981c8a418395b46ac7f0d7ee1f349b51b68accecb", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_08-ba317a3.stderr b/tests/reference/asr-arrays_08-ba317a3.stderr index e8f8eb441e..cbd0fd5112 100644 --- a/tests/reference/asr-arrays_08-ba317a3.stderr +++ b/tests/reference/asr-arrays_08-ba317a3.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 9 | x: i64[p, q, r] = empty([q, p, r], dtype=int64) | ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i64[100,120,200]' and 'i64[120,100,200]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_09-50ee586.json b/tests/reference/asr-arrays_09-50ee586.json index 2f86b11cfb..5f534fac24 100644 --- a/tests/reference/asr-arrays_09-50ee586.json +++ b/tests/reference/asr-arrays_09-50ee586.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_09-50ee586.stderr", - "stderr_hash": "0169175ca66ace6110382408ed4506313e311d560e9b8c16bdd997b3", + "stderr_hash": "2a118c1202a5c3336eda7159c9d999acff05b5702f95564147e38b48", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_09-50ee586.stderr b/tests/reference/asr-arrays_09-50ee586.stderr index e485f02cbb..18b0391b70 100644 --- a/tests/reference/asr-arrays_09-50ee586.stderr +++ b/tests/reference/asr-arrays_09-50ee586.stderr @@ -3,3 +3,7 @@ semantic error: Only those local variables that can be reduced to compile-time c | 9 | x: i64[p, q, r] = empty([q, p, r], dtype=int64) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_10-bc82d75.json b/tests/reference/asr-arrays_10-bc82d75.json index e1b3693872..10c9268bd1 100644 --- a/tests/reference/asr-arrays_10-bc82d75.json +++ b/tests/reference/asr-arrays_10-bc82d75.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_10-bc82d75.stderr", - "stderr_hash": "1c45f4b45b48ceb3de4567413bff847b67df2750fcc68d6a358df096", + "stderr_hash": "0072f417616b40366ab4718be0e354d3ce1d0e9a76a2699a11c3274b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_10-bc82d75.stderr b/tests/reference/asr-arrays_10-bc82d75.stderr index e7b0047ea1..4a1a0e76d9 100644 --- a/tests/reference/asr-arrays_10-bc82d75.stderr +++ b/tests/reference/asr-arrays_10-bc82d75.stderr @@ -3,3 +3,7 @@ semantic error: Only those local variables that can be reduced to compile-time c | 9 | x: i64[100, 120, 200] = empty([q, p, r], dtype=int64) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_11-fc505b4.json b/tests/reference/asr-arrays_11-fc505b4.json index 22700cace0..28bde3d803 100644 --- a/tests/reference/asr-arrays_11-fc505b4.json +++ b/tests/reference/asr-arrays_11-fc505b4.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_11-fc505b4.stderr", - "stderr_hash": "ef5e89392b20ad345ba9bcf862ab71b19e56c85d9838db742be117a1", + "stderr_hash": "bc288ede8eb7bad0ba460ec8fa86fd970a362bd2fd42b59ae8245f21", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_11-fc505b4.stderr b/tests/reference/asr-arrays_11-fc505b4.stderr index 09cb02b625..01a76b4357 100644 --- a/tests/reference/asr-arrays_11-fc505b4.stderr +++ b/tests/reference/asr-arrays_11-fc505b4.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 5 | x: i16[4] = empty([5], dtype=int16) | ^ ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[4]' and 'i16[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_12-63d6f25.json b/tests/reference/asr-arrays_12-63d6f25.json index a032a5fad1..12b6b3089a 100644 --- a/tests/reference/asr-arrays_12-63d6f25.json +++ b/tests/reference/asr-arrays_12-63d6f25.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_12-63d6f25.stderr", - "stderr_hash": "b6fa626301868bd5cbbef6d914f5b4f38b1d896b951753122969e74a", + "stderr_hash": "a278181ad1227b3371e16b43a19ae6bb9326f5be6a3abd1180fffbab", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_12-63d6f25.stderr b/tests/reference/asr-arrays_12-63d6f25.stderr index 8000ae521d..53e6a5703b 100644 --- a/tests/reference/asr-arrays_12-63d6f25.stderr +++ b/tests/reference/asr-arrays_12-63d6f25.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 5 | x: i16[5] = empty([5], dtype=int32) | ^ ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[5]' and 'i32[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_13-b5fcc7e.json b/tests/reference/asr-arrays_13-b5fcc7e.json index 3a17697702..bca5250fef 100644 --- a/tests/reference/asr-arrays_13-b5fcc7e.json +++ b/tests/reference/asr-arrays_13-b5fcc7e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_13-b5fcc7e.stderr", - "stderr_hash": "6bde2f7fc14d5a461a58d694e44e19dd79ef5bee47c88b4022daf5d6", + "stderr_hash": "92e3dc9e94bf8aecba8229504351dc861f0a6dfdef8cb21f85fa4305", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_13-b5fcc7e.stderr b/tests/reference/asr-arrays_13-b5fcc7e.stderr index 14f0dbe414..37ff19b627 100644 --- a/tests/reference/asr-arrays_13-b5fcc7e.stderr +++ b/tests/reference/asr-arrays_13-b5fcc7e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 7 | x: i16[4] = empty(5, dtype=int16) | ^ ^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[4]' and 'i16[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-arrays_14-78be00e.json b/tests/reference/asr-arrays_14-78be00e.json index b41704e4d0..fb28ddf4e6 100644 --- a/tests/reference/asr-arrays_14-78be00e.json +++ b/tests/reference/asr-arrays_14-78be00e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-arrays_14-78be00e.stderr", - "stderr_hash": "267aea8e48708230a9b2bc61c37c849a0b75cb45294ca25ee11fe632", + "stderr_hash": "be4da7730affe7f477cb84d11a75b7087ee9dbd0c51ccfa592641e81", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-arrays_14-78be00e.stderr b/tests/reference/asr-arrays_14-78be00e.stderr index ed7f661811..47dc8349c9 100644 --- a/tests/reference/asr-arrays_14-78be00e.stderr +++ b/tests/reference/asr-arrays_14-78be00e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 7 | x: i16[4] = empty((5), dtype=int16) | ^ ^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('i16[4]' and 'i16[5]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-assert1-1ce92ea.json b/tests/reference/asr-assert1-1ce92ea.json index 5e5858a464..007e5553d2 100644 --- a/tests/reference/asr-assert1-1ce92ea.json +++ b/tests/reference/asr-assert1-1ce92ea.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-assert1-1ce92ea.stdout", - "stdout_hash": "ce8797c74c843e69622a590671ed85a981a9261278f1f83878327414", + "stdout_hash": "f29b167c4a6cb05221c4ba8ec8322488adc1597b77d0bc08e5088f48", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-assert1-1ce92ea.stdout b/tests/reference/asr-assert1-1ce92ea.stdout index 6f1053a992..e1dc626d16 100644 --- a/tests/reference/asr-assert1-1ce92ea.stdout +++ b/tests/reference/asr-assert1-1ce92ea.stdout @@ -46,7 +46,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 5 (Integer 4)) () diff --git a/tests/reference/asr-assign1-886f049.json b/tests/reference/asr-assign1-886f049.json index 6e23997392..d5fb6d577a 100644 --- a/tests/reference/asr-assign1-886f049.json +++ b/tests/reference/asr-assign1-886f049.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-assign1-886f049.stdout", - "stdout_hash": "c2ffd64d63b0780c568d6f28ec8306cade4e74588adc6f7db056603f", + "stdout_hash": "e0fabd01607cc19e598b4ed2ffcb88f13cc17aa37887664176e2ac0b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-assign1-886f049.stdout b/tests/reference/asr-assign1-886f049.stdout index eff4af54bc..bbdff9de60 100644 --- a/tests/reference/asr-assign1-886f049.stdout +++ b/tests/reference/asr-assign1-886f049.stdout @@ -78,12 +78,12 @@ ) [] [] - [(= + [(Assignment (Var 3 r) (IntegerConstant 0 (Integer 4)) () ) - (= + (Assignment (Var 3 r) (IntegerBinOp (Var 3 r) @@ -94,12 +94,12 @@ ) () ) - (= + (Assignment (Var 3 s) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 3 r) (IntegerBinOp (Var 3 r) @@ -110,7 +110,7 @@ ) () ) - (= + (Assignment (Var 3 r) (IntegerBinOp (Var 3 r) @@ -121,12 +121,12 @@ ) () ) - (= + (Assignment (Var 3 s) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 3 r) (RealBinOp (Cast @@ -147,7 +147,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringConstant "" @@ -155,7 +155,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringConcat (Var 3 a) diff --git a/tests/reference/asr-bindc_01-6d521a9.json b/tests/reference/asr-bindc_01-6d521a9.json index 288b847447..0e7d5c5061 100644 --- a/tests/reference/asr-bindc_01-6d521a9.json +++ b/tests/reference/asr-bindc_01-6d521a9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-bindc_01-6d521a9.stdout", - "stdout_hash": "2a346b7a00bd685bde6e5c686bda4012fa442eac78bf03bad9d846aa", + "stdout_hash": "ef60e71b9f8d29c6c9788d7a614fda516a74a38d7a7423e7e39bbf7f", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-bindc_01-6d521a9.stdout b/tests/reference/asr-bindc_01-6d521a9.stdout index 2600c7c43d..d2ea3f7022 100644 --- a/tests/reference/asr-bindc_01-6d521a9.stdout +++ b/tests/reference/asr-bindc_01-6d521a9.stdout @@ -114,7 +114,7 @@ ) [] [] - [(= + [(Assignment (Var 3 p) (PointerNullConstant (CPtr) diff --git a/tests/reference/asr-bindc_01-f761165.json b/tests/reference/asr-bindc_01-f761165.json index 24d385098d..173839e771 100644 --- a/tests/reference/asr-bindc_01-f761165.json +++ b/tests/reference/asr-bindc_01-f761165.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-bindc_01-f761165.stderr", - "stderr_hash": "b2d416fa6afa00923a130cb76dbd580798a9ee0841e34980c531b050", + "stderr_hash": "5171127abfe429f4fd3b02095634e99e83408c53d1ae57568ee1cafc", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-bindc_01-f761165.stderr b/tests/reference/asr-bindc_01-f761165.stderr index 7fe85cd32b..11452c2dbc 100644 --- a/tests/reference/asr-bindc_01-f761165.stderr +++ b/tests/reference/asr-bindc_01-f761165.stderr @@ -6,3 +6,7 @@ semantic error: Type mismatch in procedure call; the types must be compatible | 4 | def cptr_arg(arg1: CPtr): | ^^^^ type mismatch (passed argument type is i32 but required type is CPtr) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-bindc_02-5092d8e.json b/tests/reference/asr-bindc_02-5092d8e.json index 6b3c472b5c..506d047b87 100644 --- a/tests/reference/asr-bindc_02-5092d8e.json +++ b/tests/reference/asr-bindc_02-5092d8e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-bindc_02-5092d8e.stderr", - "stderr_hash": "315076027d80c91db75f4ec44ea5cf8d5fd37a499a367f627b6f6553", + "stderr_hash": "daeb0d3e1c14acbdcd6e78566d1ebb34ef56ff4487c962a34fa7c65d", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-bindc_02-5092d8e.stderr b/tests/reference/asr-bindc_02-5092d8e.stderr index 4ac4183597..2489cde4e8 100644 --- a/tests/reference/asr-bindc_02-5092d8e.stderr +++ b/tests/reference/asr-bindc_02-5092d8e.stderr @@ -6,3 +6,7 @@ semantic error: Type mismatch in procedure call; the types must be compatible | 5 | cptr_member: CPtr | ^^^^ type mismatch (passed argument type is i32 but required type is CPtr) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-bindc_02-bc1a7ea.json b/tests/reference/asr-bindc_02-bc1a7ea.json index a34e4bfebe..a68240c8dc 100644 --- a/tests/reference/asr-bindc_02-bc1a7ea.json +++ b/tests/reference/asr-bindc_02-bc1a7ea.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-bindc_02-bc1a7ea.stdout", - "stdout_hash": "9d951f8b167e7db51dc5bb48205856e4d9fd6294a2a580d2dcb5306f", + "stdout_hash": "6d897e8e403d0bf95f62fcbf19436ccc70f908d6b9181cd0ce8ed660", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-bindc_02-bc1a7ea.stdout b/tests/reference/asr-bindc_02-bc1a7ea.stdout index d4a740316e..27416513da 100644 --- a/tests/reference/asr-bindc_02-bc1a7ea.stdout +++ b/tests/reference/asr-bindc_02-bc1a7ea.stdout @@ -156,16 +156,16 @@ ) [] [] - [(= + [(Assignment (Var 220 yq) (PointerNullConstant (CPtr) ) () ) - (= + (Assignment (Var 220 y) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 2) @@ -173,11 +173,12 @@ (IntegerConstant 2 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 220 y) [(() @@ -195,7 +196,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 220 y) [(() @@ -213,7 +214,7 @@ ) () ) - (= + (Assignment (Var 220 yptr1) (GetPointer (Var 220 y) diff --git a/tests/reference/asr-bindc_03-95dbba7.json b/tests/reference/asr-bindc_03-95dbba7.json index 7ea004cc34..a9e638509d 100644 --- a/tests/reference/asr-bindc_03-95dbba7.json +++ b/tests/reference/asr-bindc_03-95dbba7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-bindc_03-95dbba7.stderr", - "stderr_hash": "371c3fc384c0e72448648d5a3734a373fe96ba258b261f0695ccb518", + "stderr_hash": "945230d4a2ff6c48f1c4c4ec9825a13bd73ae9cca2b906edf9b4d99a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-bindc_03-95dbba7.stderr b/tests/reference/asr-bindc_03-95dbba7.stderr index ae2b810b6c..a250d3608c 100644 --- a/tests/reference/asr-bindc_03-95dbba7.stderr +++ b/tests/reference/asr-bindc_03-95dbba7.stderr @@ -3,3 +3,7 @@ semantic error: Target type specified in c_p_pointer must have deferred shape. | 6 | A: Pointer[i16[:]] = c_p_pointer(b, i16[n * k], array([k * n])) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-bindc_04-06bd800.json b/tests/reference/asr-bindc_04-06bd800.json index 7f9fcea30c..9d2b82611a 100644 --- a/tests/reference/asr-bindc_04-06bd800.json +++ b/tests/reference/asr-bindc_04-06bd800.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-bindc_04-06bd800.stderr", - "stderr_hash": "85d50c491c17976f21e6263e164a6ce5dbeda95dae2635f589a02d86", + "stderr_hash": "dc356297d86d9f52dae60bcd783906b020e39f1cb259577991e453f9", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-bindc_04-06bd800.stderr b/tests/reference/asr-bindc_04-06bd800.stderr index a84e785818..6daa31b7cb 100644 --- a/tests/reference/asr-bindc_04-06bd800.stderr +++ b/tests/reference/asr-bindc_04-06bd800.stderr @@ -3,3 +3,7 @@ semantic error: Only those local variables that can be reduced to compile-time c | 20 | C: i16[nk] = empty(nk, dtype=int16) | ^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-bindc_10e-8b10394.json b/tests/reference/asr-bindc_10e-8b10394.json index 38439231b2..f48e8c155b 100644 --- a/tests/reference/asr-bindc_10e-8b10394.json +++ b/tests/reference/asr-bindc_10e-8b10394.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-bindc_10e-8b10394.stderr", - "stderr_hash": "9ea4ff2c8a8789057456196deb5772e4b3a2dffadbd10ecfe5f15f29", + "stderr_hash": "28afae50a8bd5624384618aef6dc0a959bdb533579f8f897790ea473", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-bindc_10e-8b10394.stderr b/tests/reference/asr-bindc_10e-8b10394.stderr index cc7c1cd0aa..3b3b72f8f9 100644 --- a/tests/reference/asr-bindc_10e-8b10394.stderr +++ b/tests/reference/asr-bindc_10e-8b10394.stderr @@ -12,3 +12,7 @@ semantic error: The struct in c_p_pointer must be C interoperable | 7 | b: i64 | ...~~~~~~~~~~ help: add the @ccallable decorator to this struct to make it C interoperable + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-c_interop1-cf2e9b4.json b/tests/reference/asr-c_interop1-cf2e9b4.json index d595b8426b..7e3a3571c3 100644 --- a/tests/reference/asr-c_interop1-cf2e9b4.json +++ b/tests/reference/asr-c_interop1-cf2e9b4.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-c_interop1-cf2e9b4.stdout", - "stdout_hash": "f63eac62a8e739f07a2ecd8acf5d872843e4721733736acf1cbff922", + "stdout_hash": "bd48af35b456f30937131736ae9872387bf174cdf46a2fa0d80c48c3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-c_interop1-cf2e9b4.stdout b/tests/reference/asr-c_interop1-cf2e9b4.stdout index 3fd5f6a776..dc2d460b82 100644 --- a/tests/reference/asr-c_interop1-cf2e9b4.stdout +++ b/tests/reference/asr-c_interop1-cf2e9b4.stdout @@ -224,7 +224,7 @@ ) [] [(Var 5 x)] - [(= + [(Assignment (Var 5 _lpython_return_variable) (RealBinOp (Var 5 x) @@ -458,7 +458,7 @@ h l] [] - [(= + [(Assignment (Var 7 x) (RealConstant 5.000000 @@ -466,7 +466,7 @@ ) () ) - (= + (Assignment (Var 7 i) (FunctionCall 2 f @@ -478,7 +478,7 @@ ) () ) - (= + (Assignment (Var 7 y) (Cast (RealConstant @@ -494,7 +494,7 @@ ) () ) - (= + (Assignment (Var 7 z) (Cast (IntegerConstant 3 (Integer 4)) @@ -504,7 +504,7 @@ ) () ) - (= + (Assignment (Var 7 zz) (IntegerConstant 2 (Integer 4)) () @@ -518,7 +518,7 @@ ((Var 7 zz))] () ) - (= + (Assignment (Var 7 i) (FunctionCall 2 h diff --git a/tests/reference/asr-callback_01-df40fd5.json b/tests/reference/asr-callback_01-df40fd5.json index cfd5db0657..b228c00a7e 100644 --- a/tests/reference/asr-callback_01-df40fd5.json +++ b/tests/reference/asr-callback_01-df40fd5.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-callback_01-df40fd5.stdout", - "stdout_hash": "d8283ff4af45372de119998a592b0995335f8d6ada869664e3306a22", + "stdout_hash": "a8fbb30389ff308781e5cc08c41bee122eb1f40c9707b86000d81a39", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-callback_01-df40fd5.stdout b/tests/reference/asr-callback_01-df40fd5.stdout index 85ec941f5a..d43454d701 100644 --- a/tests/reference/asr-callback_01-df40fd5.stdout +++ b/tests/reference/asr-callback_01-df40fd5.stdout @@ -182,7 +182,7 @@ ) [] [(Var 3 x)] - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) @@ -255,7 +255,7 @@ ) [] [(Var 4 x)] - [(= + [(Assignment (Var 4 _lpython_return_variable) (IntegerBinOp (Var 4 x) @@ -329,7 +329,7 @@ [f f2] [(Var 5 x)] - [(= + [(Assignment (Var 5 _lpython_return_variable) (IntegerBinOp (FunctionCall @@ -509,7 +509,7 @@ [] [(Var 6 func) (Var 6 arg)] - [(= + [(Assignment (Var 6 ret) (FunctionCall 6 func @@ -521,7 +521,7 @@ ) () ) - (= + (Assignment (Var 6 _lpython_return_variable) (Var 6 ret) () diff --git a/tests/reference/asr-cast-435c233.json b/tests/reference/asr-cast-435c233.json index 3dd33fc6fa..fbfb94cb39 100644 --- a/tests/reference/asr-cast-435c233.json +++ b/tests/reference/asr-cast-435c233.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-cast-435c233.stdout", - "stdout_hash": "beea7e3be87c6bb603024071129f88f96a9f7729af4aec43df537f68", + "stdout_hash": "976d59f05dfd318c8315b0e71415f5e0905bf1ed203be1eb7f342e70", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-cast-435c233.stdout b/tests/reference/asr-cast-435c233.stdout index 29b65cf890..406cb861fb 100644 --- a/tests/reference/asr-cast-435c233.stdout +++ b/tests/reference/asr-cast-435c233.stdout @@ -128,7 +128,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringConstant "lpython" @@ -136,7 +136,7 @@ ) () ) - (= + (Assignment (Var 3 x) (FunctionCall 3 list @@ -150,7 +150,7 @@ ) () ) - (= + (Assignment (Var 3 y) (ListConstant [(StringConstant @@ -171,7 +171,7 @@ ) () ) - (= + (Assignment (Var 3 x) (FunctionCall 3 list @@ -185,7 +185,7 @@ ) () ) - (= + (Assignment (Var 3 x) (ListConstant [] @@ -195,7 +195,7 @@ ) () ) - (= + (Assignment (Var 3 x) (FunctionCall 3 list @@ -219,7 +219,7 @@ ) () ) - (= + (Assignment (Var 3 x) (FunctionCall 3 list diff --git a/tests/reference/asr-complex1-f26c460.json b/tests/reference/asr-complex1-f26c460.json index f76a12ebca..276410d715 100644 --- a/tests/reference/asr-complex1-f26c460.json +++ b/tests/reference/asr-complex1-f26c460.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-complex1-f26c460.stdout", - "stdout_hash": "f4e6f84bffb93e20f3a8092d52e27786b0104ef0514adf01a0fbf27b", + "stdout_hash": "092781fe1c5fd2eeb2902d423fa191dc0409999380ad894f4deba5f8", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-complex1-f26c460.stdout b/tests/reference/asr-complex1-f26c460.stdout index 20b2339c17..02ae61e801 100644 --- a/tests/reference/asr-complex1-f26c460.stdout +++ b/tests/reference/asr-complex1-f26c460.stdout @@ -78,7 +78,7 @@ ) [] [] - [(= + [(Assignment (Var 4 x) (ComplexBinOp (Cast @@ -106,7 +106,7 @@ ) () ) - (= + (Assignment (Var 4 y) (ComplexBinOp (Cast @@ -134,7 +134,7 @@ ) () ) - (= + (Assignment (Var 4 z) (Cast (ComplexBinOp @@ -150,7 +150,7 @@ ) () ) - (= + (Assignment (Var 4 z) (Cast (ComplexBinOp @@ -166,7 +166,7 @@ ) () ) - (= + (Assignment (Var 4 z) (Cast (ComplexBinOp @@ -370,7 +370,7 @@ ) [] [] - [(= + [(Assignment (Var 3 c) (Cast (FunctionCall @@ -395,7 +395,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (FunctionCall @@ -423,7 +423,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (FunctionCall @@ -455,7 +455,7 @@ ) () ) - (= + (Assignment (Var 3 c) (FunctionCall 3 complex@__lpython_overloaded_2__complex @@ -471,7 +471,7 @@ ) () ) - (= + (Assignment (Var 3 c1) (Cast (FunctionCall @@ -497,7 +497,7 @@ ) () ) - (= + (Assignment (Var 3 c2) (Cast (FunctionCall @@ -526,7 +526,7 @@ ) () ) - (= + (Assignment (Var 3 c3) (FunctionCall 3 complex@__lpython_overloaded_5__complex @@ -549,7 +549,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ComplexCompare (Var 3 c1) @@ -560,7 +560,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ComplexCompare (Cast @@ -576,7 +576,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ComplexBinOp (Var 3 c1) @@ -587,7 +587,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ComplexBinOp (Var 3 c2) @@ -598,7 +598,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ComplexBinOp (Var 3 c1) @@ -609,7 +609,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (ComplexBinOp @@ -663,7 +663,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (ComplexBinOp @@ -711,7 +711,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (ComplexBinOp diff --git a/tests/reference/asr-const_01-af8289b.json b/tests/reference/asr-const_01-af8289b.json index c54ff59cdd..cffe50ea1d 100644 --- a/tests/reference/asr-const_01-af8289b.json +++ b/tests/reference/asr-const_01-af8289b.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-const_01-af8289b.stderr", - "stderr_hash": "f47e74e916315ec82f38680f66c9cf5ef3c958bcdfa87b9efe09b264", + "stderr_hash": "ee5a12da5ff69e8dd9689fa38e5689558cc022ce5b39072bca22a498", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-const_01-af8289b.stderr b/tests/reference/asr-const_01-af8289b.stderr index 47034b6158..5c6d3560c3 100644 --- a/tests/reference/asr-const_01-af8289b.stderr +++ b/tests/reference/asr-const_01-af8289b.stderr @@ -3,3 +3,7 @@ semantic error: Constant variable x is not initialised at declaration. | 4 | x: Const[i32] | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-const_02-fce29b7.json b/tests/reference/asr-const_02-fce29b7.json index af31951d5b..6c2d8bc567 100644 --- a/tests/reference/asr-const_02-fce29b7.json +++ b/tests/reference/asr-const_02-fce29b7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-const_02-fce29b7.stderr", - "stderr_hash": "b8b90da28518edbe487dbe6f52f1f25f004042fe463e8fba7b96d174", + "stderr_hash": "7bcbd3356f93816ef45275fb9e2b7ed5bf684bdb7f824d1744ea1ec6", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-const_02-fce29b7.stderr b/tests/reference/asr-const_02-fce29b7.stderr index 3bdb12c237..213fea1a79 100644 --- a/tests/reference/asr-const_02-fce29b7.stderr +++ b/tests/reference/asr-const_02-fce29b7.stderr @@ -3,3 +3,7 @@ semantic error: Targets with Const[i32] type cannot be re-assigned. | 5 | x = 5 | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-constants1-5828e8a.json b/tests/reference/asr-constants1-5828e8a.json index 0dcd9c57fa..c34e7af68d 100644 --- a/tests/reference/asr-constants1-5828e8a.json +++ b/tests/reference/asr-constants1-5828e8a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-constants1-5828e8a.stdout", - "stdout_hash": "1b3194a6cd7f73d860c5c90062d03235b25d1efc585b4bb82bd1a059", + "stdout_hash": "ee37a85f3fdd5a79da83bc269ca3a72982703657f76af23824786213", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-constants1-5828e8a.stdout b/tests/reference/asr-constants1-5828e8a.stdout index 34707cf979..67fdc7899e 100644 --- a/tests/reference/asr-constants1-5828e8a.stdout +++ b/tests/reference/asr-constants1-5828e8a.stdout @@ -82,9 +82,9 @@ ) [] [] - [(= + [(Assignment (Var 5 a) - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerConstant 5 (Integer 4))] 0 @@ -93,9 +93,9 @@ ) () ) - (= + (Assignment (Var 5 a) - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerUnaryMinus (IntegerConstant 500 (Integer 4)) @@ -108,9 +108,9 @@ ) () ) - (= + (Assignment (Var 5 a) - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Cast (LogicalConstant @@ -127,9 +127,9 @@ ) () ) - (= + (Assignment (Var 5 a) - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Cast (LogicalConstant @@ -146,10 +146,10 @@ ) () ) - (= + (Assignment (Var 5 b) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealConstant 3.450000 @@ -171,10 +171,10 @@ ) () ) - (= + (Assignment (Var 5 b) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealUnaryMinus (RealConstant @@ -203,10 +203,10 @@ ) () ) - (= + (Assignment (Var 5 b) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(FunctionCall 5 complex@__lpython_overloaded_5__complex @@ -308,7 +308,7 @@ ) [] [] - [(= + [(Assignment (Var 7 a) (Cast (IntegerConstant 0 (Integer 4)) @@ -321,7 +321,7 @@ ) () ) - (= + (Assignment (Var 7 a) (Cast (IntegerUnaryMinus @@ -338,7 +338,7 @@ ) () ) - (= + (Assignment (Var 7 a) (Cast (StringConstant @@ -354,7 +354,7 @@ ) () ) - (= + (Assignment (Var 7 a) (Cast (FunctionCall @@ -392,7 +392,7 @@ ) () ) - (= + (Assignment (Var 7 a) (Cast (StringConstant @@ -408,7 +408,7 @@ ) () ) - (= + (Assignment (Var 7 a) (Cast (RealConstant @@ -512,7 +512,7 @@ ) [] [] - [(= + [(Assignment (Var 3 b) (FunctionCall 3 bin @@ -527,7 +527,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 bin @@ -542,7 +542,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 bin @@ -561,7 +561,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 oct @@ -576,7 +576,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 oct @@ -591,7 +591,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 oct @@ -610,7 +610,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 hex @@ -625,7 +625,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 hex @@ -640,7 +640,7 @@ ) () ) - (= + (Assignment (Var 3 b) (FunctionCall 3 hex @@ -720,12 +720,12 @@ ) [] [] - [(= + [(Assignment (Var 9 b) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 9 a) (LogicalConstant .true. @@ -746,7 +746,7 @@ ) () ) - (= + (Assignment (Var 9 a) (LogicalConstant .false. @@ -767,7 +767,7 @@ ) () ) - (= + (Assignment (Var 9 a) (LogicalConstant .false. @@ -846,7 +846,7 @@ ) [] [] - [(= + [(Assignment (Var 12 a) (FunctionCall 12 divmod @@ -869,7 +869,7 @@ ) () ) - (= + (Assignment (Var 12 a) (FunctionCall 12 divmod @@ -896,7 +896,7 @@ ) () ) - (= + (Assignment (Var 12 a) (FunctionCall 12 divmod @@ -919,7 +919,7 @@ ) () ) - (= + (Assignment (Var 12 a) (FunctionCall 12 divmod @@ -942,7 +942,7 @@ ) () ) - (= + (Assignment (Var 12 a) (FunctionCall 12 divmod @@ -1010,7 +1010,7 @@ ) [] [] - [(= + [(Assignment (Var 11 a) (RealConstant 0.000000 @@ -1018,7 +1018,7 @@ ) () ) - (= + (Assignment (Var 11 a) (RealConstant 4.560000 @@ -1026,7 +1026,7 @@ ) () ) - (= + (Assignment (Var 11 a) (Cast (IntegerConstant 5 (Integer 4)) @@ -1039,7 +1039,7 @@ ) () ) - (= + (Assignment (Var 11 a) (Cast (IntegerUnaryMinus @@ -1056,7 +1056,7 @@ ) () ) - (= + (Assignment (Var 11 a) (Cast (LogicalConstant @@ -1072,7 +1072,7 @@ ) () ) - (= + (Assignment (Var 11 a) (Cast (LogicalConstant @@ -1133,12 +1133,12 @@ ) [] [] - [(= + [(Assignment (Var 10 a) (IntegerConstant 0 (Integer 8)) () ) - (= + (Assignment (Var 10 a) (Cast (RealConstant @@ -1151,7 +1151,7 @@ ) () ) - (= + (Assignment (Var 10 a) (Cast (IntegerConstant 5 (Integer 4)) @@ -1161,7 +1161,7 @@ ) () ) - (= + (Assignment (Var 10 a) (Cast (RealUnaryMinus @@ -1181,7 +1181,7 @@ ) () ) - (= + (Assignment (Var 10 a) (Cast (LogicalConstant @@ -1194,7 +1194,7 @@ ) () ) - (= + (Assignment (Var 10 a) (Cast (LogicalConstant @@ -1207,7 +1207,7 @@ ) () ) - (= + (Assignment (Var 10 a) (IntegerConstant 5346 (Integer 8)) () @@ -1275,7 +1275,7 @@ ) [] [] - [(= + [(Assignment (Var 6 a) (StringLen (StringConstant @@ -1287,7 +1287,7 @@ ) () ) - (= + (Assignment (Var 6 a) (StringLen (StringConstant @@ -1299,7 +1299,7 @@ ) () ) - (= + (Assignment (Var 6 a) (StringLen (StringConstant @@ -1311,7 +1311,7 @@ ) () ) - (= + (Assignment (Var 6 a) (TupleLen (TupleConstant @@ -1329,7 +1329,7 @@ ) () ) - (= + (Assignment (Var 6 a) (TupleLen (TupleConstant @@ -1386,7 +1386,7 @@ ) () ) - (= + (Assignment (Var 6 a) (ListLen (ListConstant @@ -1402,7 +1402,7 @@ ) () ) - (= + (Assignment (Var 6 a) (ListLen (ListConstant @@ -1457,7 +1457,7 @@ ) () ) - (= + (Assignment (Var 6 a) (SetLen (SetConstant @@ -1473,7 +1473,7 @@ ) () ) - (= + (Assignment (Var 6 a) (DictLen (DictConstant @@ -1502,7 +1502,7 @@ ) () ) - (= + (Assignment (Var 6 l) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -1515,7 +1515,7 @@ ) () ) - (= + (Assignment (Var 6 a) (ListLen (Var 6 l) @@ -1528,7 +1528,7 @@ (Var 6 l) (IntegerConstant 5 (Integer 4)) ) - (= + (Assignment (Var 6 a) (ListLen (Var 6 l) @@ -1598,7 +1598,7 @@ ) [] [] - [(= + [(Assignment (Var 4 a) (StringOrd (StringConstant @@ -1610,7 +1610,7 @@ ) () ) - (= + (Assignment (Var 4 s) (StringChr (IntegerConstant 43 (Integer 4)) @@ -1667,7 +1667,7 @@ ) [] [] - [(= + [(Assignment (Var 8 s) (StringConstant "" @@ -1675,7 +1675,7 @@ ) () ) - (= + (Assignment (Var 8 s) (Cast (IntegerConstant 5 (Integer 4)) @@ -1688,7 +1688,7 @@ ) () ) - (= + (Assignment (Var 8 s) (Cast (IntegerUnaryMinus @@ -1705,7 +1705,7 @@ ) () ) - (= + (Assignment (Var 8 s) (Cast (RealConstant @@ -1721,7 +1721,7 @@ ) () ) - (= + (Assignment (Var 8 s) (Cast (LogicalConstant @@ -1737,7 +1737,7 @@ ) () ) - (= + (Assignment (Var 8 s) (Cast (LogicalConstant @@ -1753,7 +1753,7 @@ ) () ) - (= + (Assignment (Var 8 s) (StringConstant "5346" diff --git a/tests/reference/asr-cptr_01-4e660f1.json b/tests/reference/asr-cptr_01-4e660f1.json index c554aa6d5b..e5ef59dc7d 100644 --- a/tests/reference/asr-cptr_01-4e660f1.json +++ b/tests/reference/asr-cptr_01-4e660f1.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-cptr_01-4e660f1.stderr", - "stderr_hash": "0477f93b29ff4932b3471a59731a173fb19d6e44273236829eeaffbe", + "stderr_hash": "8242c95361704d7cd6822c6e71e553700fb2efc45394ffe3e9995b79", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-cptr_01-4e660f1.stderr b/tests/reference/asr-cptr_01-4e660f1.stderr index 510fd3ad0c..2a1440bd89 100644 --- a/tests/reference/asr-cptr_01-4e660f1.stderr +++ b/tests/reference/asr-cptr_01-4e660f1.stderr @@ -3,3 +3,7 @@ semantic error: Indexing CPtr typed expressions is not supported yet | 5 | print(x[0]) | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-dictionary1-a105a36.json b/tests/reference/asr-dictionary1-a105a36.json index 3bc6f3bfd1..991461787d 100644 --- a/tests/reference/asr-dictionary1-a105a36.json +++ b/tests/reference/asr-dictionary1-a105a36.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-dictionary1-a105a36.stdout", - "stdout_hash": "ac9f74e24e585a3382e6615e4f197e6ebda5ba099def0664967fbcc0", + "stdout_hash": "3ea42309cc8f2201f43bb2fdeb28a85feea890fe49db4063af5c46f8", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-dictionary1-a105a36.stdout b/tests/reference/asr-dictionary1-a105a36.stdout index b434f5addf..8ae305005f 100644 --- a/tests/reference/asr-dictionary1-a105a36.stdout +++ b/tests/reference/asr-dictionary1-a105a36.stdout @@ -140,7 +140,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (DictConstant [(IntegerConstant 1 (Integer 4)) @@ -154,7 +154,7 @@ ) () ) - (= + (Assignment (Var 3 y) (DictConstant [(StringConstant @@ -182,7 +182,7 @@ ) () ) - (= + (Assignment (Var 3 z) (DictItem (Var 3 y) @@ -196,7 +196,7 @@ ) () ) - (= + (Assignment (Var 3 z) (DictItem (Var 3 y) @@ -210,7 +210,7 @@ ) () ) - (= + (Assignment (Var 3 z) (DictItem (Var 3 x) @@ -285,7 +285,7 @@ ) [] [] - [(= + [(Assignment (Var 5 y) (DictConstant [(StringConstant @@ -313,7 +313,7 @@ ) () ) - (= + (Assignment (Var 5 x) (DictItem (Var 5 y) @@ -327,7 +327,7 @@ ) () ) - (= + (Assignment (Var 5 x) (DictItem (Var 5 y) @@ -389,7 +389,7 @@ ) [] [] - [(= + [(Assignment (Var 4 y) (DictConstant [(StringConstant @@ -493,7 +493,7 @@ ) [] [] - [(= + [(Assignment (Var 6 y) (DictConstant [(StringConstant @@ -513,7 +513,7 @@ ) () ) - (= + (Assignment (Var 6 x) (DictPop (Var 6 y) diff --git a/tests/reference/asr-doconcurrentloop_01-3fdc189.json b/tests/reference/asr-doconcurrentloop_01-3fdc189.json index 74736504bc..d6ab359efa 100644 --- a/tests/reference/asr-doconcurrentloop_01-3fdc189.json +++ b/tests/reference/asr-doconcurrentloop_01-3fdc189.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-doconcurrentloop_01-3fdc189.stdout", - "stdout_hash": "b87f31e0e98b1ec330df01b0f8eafa390b61858a9e559e149e27c2a6", + "stdout_hash": "413974a16ffc353be79c5bba8842ef9190e2c5c845d605c96b15e55b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-doconcurrentloop_01-3fdc189.stdout b/tests/reference/asr-doconcurrentloop_01-3fdc189.stdout index c865fbcc89..4146667eaf 100644 --- a/tests/reference/asr-doconcurrentloop_01-3fdc189.stdout +++ b/tests/reference/asr-doconcurrentloop_01-3fdc189.stdout @@ -177,7 +177,7 @@ ) [triad] [] - [(= + [(Assignment (Var 4 scalar) (Cast (RealConstant @@ -193,7 +193,7 @@ ) () ) - (= + (Assignment (Var 4 nsize) (ArraySize (Var 4 a) @@ -214,7 +214,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 4 a) [(() @@ -238,7 +238,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 4 b) [(() @@ -474,7 +474,7 @@ (Var 3 b) (Var 3 scalar) (Var 3 c)] - [(= + [(Assignment (Var 3 N) (ArraySize (Var 3 a) @@ -495,7 +495,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 3 c) [(() diff --git a/tests/reference/asr-elemental_01-b58df26.json b/tests/reference/asr-elemental_01-b58df26.json index 3dee5bd747..b35d8f853b 100644 --- a/tests/reference/asr-elemental_01-b58df26.json +++ b/tests/reference/asr-elemental_01-b58df26.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-elemental_01-b58df26.stdout", - "stdout_hash": "a2a599171f233c4ffa976a40eefe89a518f74be52611595abbe82f71", + "stdout_hash": "3053b7358f72cd731a9fb1625231938c2f59a0df49473856482457be", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-elemental_01-b58df26.stdout b/tests/reference/asr-elemental_01-b58df26.stdout index 7029d7eff4..d97fd28cab 100644 --- a/tests/reference/asr-elemental_01-b58df26.stdout +++ b/tests/reference/asr-elemental_01-b58df26.stdout @@ -192,9 +192,9 @@ ) [verify2d] [] - [(= + [(Assignment (Var 228 array2d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -204,13 +204,14 @@ (IntegerConstant 64 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 228 cos2d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -220,6 +221,7 @@ (IntegerConstant 64 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -248,7 +250,7 @@ (IntegerConstant 63 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 228 array2d) [(() @@ -279,7 +281,7 @@ )] [] ) - (= + (Assignment (Var 228 cos2d) (RealBinOp (FunctionCall @@ -489,9 +491,9 @@ ) [verify1d_mul] [] - [(= + [(Assignment (Var 226 array_a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -499,13 +501,14 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 array_b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -513,13 +516,14 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 226 array_c) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -527,6 +531,7 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -543,7 +548,7 @@ (IntegerConstant 99 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 226 array_a) [(() @@ -575,7 +580,7 @@ (IntegerConstant 99 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 226 array_b) [(() @@ -601,7 +606,7 @@ )] [] ) - (= + (Assignment (Var 226 array_c) (RealBinOp (RealBinOp @@ -891,9 +896,9 @@ [verify1d verifynd] [] - [(= + [(Assignment (Var 227 array1d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -901,13 +906,14 @@ (IntegerConstant 256 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 227 sin1d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -915,6 +921,7 @@ (IntegerConstant 256 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -931,7 +938,7 @@ (IntegerConstant 255 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 227 array1d) [(() @@ -951,7 +958,7 @@ )] [] ) - (= + (Assignment (Var 227 sin1d) (FunctionCall 227 sin@__lpython_overloaded_1__sin @@ -1010,9 +1017,9 @@ ((IntegerConstant 256 (Integer 4)))] () ) - (= + (Assignment (Var 227 arraynd) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1024,13 +1031,14 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 227 sinnd) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1042,6 +1050,7 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1082,7 +1091,7 @@ (IntegerConstant 15 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 227 arraynd) [(() @@ -1124,7 +1133,7 @@ )] [] ) - (= + (Assignment (Var 227 sinnd) (RealBinOp (FunctionCall @@ -1343,9 +1352,9 @@ ) [verify1d_sum] [] - [(= + [(Assignment (Var 225 array_a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1353,13 +1362,14 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 225 array_b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1367,13 +1377,14 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 225 array_c) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1381,6 +1392,7 @@ (IntegerConstant 100 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1397,7 +1409,7 @@ (IntegerConstant 99 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 225 array_a) [(() @@ -1429,7 +1441,7 @@ (IntegerConstant 99 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 225 array_b) [(() @@ -1455,7 +1467,7 @@ )] [] ) - (= + (Assignment (Var 225 array_c) (RealBinOp (RealBinOp @@ -1780,7 +1792,7 @@ ) [] [] - [(= + [(Assignment (Var 229 eps) (Cast (RealConstant @@ -1796,9 +1808,9 @@ ) () ) - (= + (Assignment (Var 229 arraynd) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1812,13 +1824,14 @@ (IntegerConstant 4 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 229 observed) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1832,13 +1845,14 @@ (IntegerConstant 4 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 229 observed1d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1846,6 +1860,7 @@ (IntegerConstant 65536 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1898,7 +1913,7 @@ (IntegerConstant 3 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 229 arraynd) [(() @@ -1951,7 +1966,7 @@ )] [] ) - (= + (Assignment (Var 229 observed) (RealBinOp (RealBinOp @@ -2059,9 +2074,9 @@ ) () ) - (= + (Assignment (Var 229 newshape) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -2069,11 +2084,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 229 newshape) [(() @@ -2086,7 +2102,7 @@ (IntegerConstant 65536 (Integer 4)) () ) - (= + (Assignment (Var 229 observed1d) (ArrayReshape (Var 229 observed) @@ -2126,7 +2142,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ArrayItem @@ -2228,7 +2244,7 @@ block [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -2380,7 +2396,7 @@ [(Var 220 array) (Var 220 result) (Var 220 size)] - [(= + [(Assignment (Var 220 eps) (Cast (RealConstant @@ -2575,7 +2591,7 @@ (Var 224 array_b) (Var 224 result) (Var 224 size)] - [(= + [(Assignment (Var 224 eps) (RealConstant 0.000010 @@ -2597,7 +2613,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -2837,7 +2853,7 @@ (Var 223 array_b) (Var 223 result) (Var 223 size)] - [(= + [(Assignment (Var 223 eps) (RealConstant 0.000000 @@ -2859,7 +2875,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -2996,7 +3012,7 @@ block [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -3217,7 +3233,7 @@ (Var 222 result) (Var 222 size1) (Var 222 size2)] - [(= + [(Assignment (Var 222 eps) (RealConstant 0.000000 @@ -3308,7 +3324,7 @@ block [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -3596,7 +3612,7 @@ (Var 221 size1) (Var 221 size2) (Var 221 size3)] - [(= + [(Assignment (Var 221 eps) (RealConstant 0.000000 diff --git a/tests/reference/asr-enum_01-30e1b4a.json b/tests/reference/asr-enum_01-30e1b4a.json index f21587576e..6ddadb47ab 100644 --- a/tests/reference/asr-enum_01-30e1b4a.json +++ b/tests/reference/asr-enum_01-30e1b4a.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-enum_01-30e1b4a.stderr", - "stderr_hash": "ee3775d6e144fa8c18d4beeae5a5790e317f7c4d26212100d03f29d4", + "stderr_hash": "ffe4d855c9b53ad57a7d2c709c9279f1a49b97e6e5c1c88c15b0a578", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-enum_01-30e1b4a.stderr b/tests/reference/asr-enum_01-30e1b4a.stderr index 0947a787ea..adac72391c 100644 --- a/tests/reference/asr-enum_01-30e1b4a.stderr +++ b/tests/reference/asr-enum_01-30e1b4a.stderr @@ -7,3 +7,7 @@ semantic error: Enumerations with non-integer or non-unique integer values canno | 8 | BLUE: f64 = 0.7 | ...^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-enum_02-54656c5.json b/tests/reference/asr-enum_02-54656c5.json index a989cef176..db3f67f755 100644 --- a/tests/reference/asr-enum_02-54656c5.json +++ b/tests/reference/asr-enum_02-54656c5.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-enum_02-54656c5.stderr", - "stderr_hash": "88c95223e82c39f9d40d9f62923d1bffdf3a9f0a47565bad19b37dee", + "stderr_hash": "3b452b5d2b62f231751fd906f2105235733c122d37b6780b8fc72ab3", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-enum_02-54656c5.stderr b/tests/reference/asr-enum_02-54656c5.stderr index 39fb6429e6..1beec7b08c 100644 --- a/tests/reference/asr-enum_02-54656c5.stderr +++ b/tests/reference/asr-enum_02-54656c5.stderr @@ -7,3 +7,7 @@ semantic error: Enumerations with non-integer or non-unique integer values canno | 8 | BLUE: i32 = 2 | ...^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-expr1-8df2d66.json b/tests/reference/asr-expr1-8df2d66.json index c8405e85b6..14586c7302 100644 --- a/tests/reference/asr-expr1-8df2d66.json +++ b/tests/reference/asr-expr1-8df2d66.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr1-8df2d66.stdout", - "stdout_hash": "55544ca6dbfc171a34a0018673cdfada1938540123d89da76150a372", + "stdout_hash": "f80b1b22cac2640f90a800ced131163389d7bc2c821daa9f28618c73", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr1-8df2d66.stdout b/tests/reference/asr-expr1-8df2d66.stdout index f84e24042d..60e468b1c4 100644 --- a/tests/reference/asr-expr1-8df2d66.stdout +++ b/tests/reference/asr-expr1-8df2d66.stdout @@ -78,7 +78,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (NamedExpr (Var 3 y) @@ -100,7 +100,7 @@ ) (Integer 4) ) - [(= + [(Assignment (Var 3 x) (IntegerConstant 1 (Integer 4)) () @@ -114,7 +114,7 @@ (IntegerConstant 1 (Integer 4)) (Integer 4) ) - [(= + [(Assignment (Var 3 y) (IntegerConstant 1 (Integer 4)) () diff --git a/tests/reference/asr-expr10-efcbb1b.json b/tests/reference/asr-expr10-efcbb1b.json index be5a49cf81..3767bde058 100644 --- a/tests/reference/asr-expr10-efcbb1b.json +++ b/tests/reference/asr-expr10-efcbb1b.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr10-efcbb1b.stdout", - "stdout_hash": "7ab3ed61f6e7e3c3af821e2d954e321eaf49af5bd80886dcb03f7562", + "stdout_hash": "4ac6fe05a2094e4deb737d529206b7393ee37e0abf0223b92d124850", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr10-efcbb1b.stdout b/tests/reference/asr-expr10-efcbb1b.stdout index 7941ddc404..eb6a363358 100644 --- a/tests/reference/asr-expr10-efcbb1b.stdout +++ b/tests/reference/asr-expr10-efcbb1b.stdout @@ -172,12 +172,12 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 4 (Integer 4)) () ) - (= + (Assignment (Var 3 a) (IntegerUnaryMinus (IntegerConstant 500 (Integer 4)) @@ -186,7 +186,7 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerBitNot (IntegerConstant 5 (Integer 4)) @@ -195,7 +195,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalNot (Cast @@ -215,7 +215,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalNot (Cast @@ -239,7 +239,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalNot (Cast @@ -259,7 +259,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 1.000000 @@ -267,7 +267,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealUnaryMinus (Cast @@ -290,7 +290,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (LogicalConstant .true. @@ -298,7 +298,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (LogicalNot (LogicalConstant @@ -313,7 +313,7 @@ ) () ) - (= + (Assignment (Var 3 b3) (LogicalNot (Var 3 b2) @@ -322,12 +322,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 3 a) (IntegerUnaryMinus (Cast @@ -344,7 +344,7 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerBitNot (Cast @@ -361,7 +361,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ComplexConstant 1.000000 @@ -370,7 +370,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ComplexUnaryMinus (Cast @@ -407,7 +407,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (LogicalConstant .false. @@ -415,7 +415,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (LogicalConstant .true. diff --git a/tests/reference/asr-expr11-9b91d35.json b/tests/reference/asr-expr11-9b91d35.json index 27fc53c56a..6eb7924f0b 100644 --- a/tests/reference/asr-expr11-9b91d35.json +++ b/tests/reference/asr-expr11-9b91d35.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr11-9b91d35.stdout", - "stdout_hash": "119588e11efc6683fe77260a150cf2622aad182814252c73dbc0b2e1", + "stdout_hash": "e1b95463b42d9a086ed796331d18b6feafb16d8b82b6e14dcf6576ad", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr11-9b91d35.stdout b/tests/reference/asr-expr11-9b91d35.stdout index 499a59590c..943df6c92d 100644 --- a/tests/reference/asr-expr11-9b91d35.stdout +++ b/tests/reference/asr-expr11-9b91d35.stdout @@ -46,7 +46,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringRepeat (StringConstant @@ -62,7 +62,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringRepeat (StringConstant @@ -82,7 +82,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringRepeat (StringConstant @@ -98,7 +98,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringRepeat (StringConstant @@ -114,7 +114,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringRepeat (StringConstant @@ -134,7 +134,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringRepeat (StringRepeat diff --git a/tests/reference/asr-expr12-5c5b71e.json b/tests/reference/asr-expr12-5c5b71e.json index f191d58517..576db11660 100644 --- a/tests/reference/asr-expr12-5c5b71e.json +++ b/tests/reference/asr-expr12-5c5b71e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr12-5c5b71e.stdout", - "stdout_hash": "68b01cfc65c60b82cb2ba5017c95cb10e05d130d085674593975310e", + "stdout_hash": "cc7faf4b191f80b30f9ba8ba5dc649e69a276ee40352403a890a7ecb", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr12-5c5b71e.stdout b/tests/reference/asr-expr12-5c5b71e.stdout index 4b91ecc679..466b7f88f6 100644 --- a/tests/reference/asr-expr12-5c5b71e.stdout +++ b/tests/reference/asr-expr12-5c5b71e.stdout @@ -98,7 +98,7 @@ ) [test] [] - [(= + [(Assignment (Var 4 a) (FunctionCall 2 test @@ -111,7 +111,7 @@ ) () ) - (= + (Assignment (Var 4 _lpython_return_variable) (Var 4 a) () @@ -162,7 +162,7 @@ ) [check] [] - [(= + [(Assignment (Var 5 x) (FunctionCall 2 check @@ -253,7 +253,7 @@ [] [(Var 3 a) (Var 3 b)] - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 a) diff --git a/tests/reference/asr-expr13-81bdb5a.json b/tests/reference/asr-expr13-81bdb5a.json index 4ed78ba723..26e00b8b8d 100644 --- a/tests/reference/asr-expr13-81bdb5a.json +++ b/tests/reference/asr-expr13-81bdb5a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr13-81bdb5a.stdout", - "stdout_hash": "49263833f1645d67ff5a809022f16c6437f9175a35ab7341f13c580f", + "stdout_hash": "7ded7f762f74bec6cd0fb3b413abf192b9b19e80a10280ea0125d442", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr13-81bdb5a.stdout b/tests/reference/asr-expr13-81bdb5a.stdout index 2b9a961d02..e25b37e2e6 100644 --- a/tests/reference/asr-expr13-81bdb5a.stdout +++ b/tests/reference/asr-expr13-81bdb5a.stdout @@ -76,7 +76,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerCompare (IntegerConstant 5 (Integer 4)) @@ -90,7 +90,7 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerCompare (IntegerConstant 5 (Integer 4)) @@ -104,7 +104,7 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerCompare (IntegerConstant 5 (Integer 4)) @@ -118,7 +118,7 @@ ) () ) - (= + (Assignment (Var 3 a) (RealCompare (RealConstant @@ -138,7 +138,7 @@ ) () ) - (= + (Assignment (Var 3 a) (RealCompare (RealConstant @@ -158,7 +158,7 @@ ) () ) - (= + (Assignment (Var 3 a) (RealCompare (RealConstant @@ -178,7 +178,7 @@ ) () ) - (= + (Assignment (Var 3 a) (ComplexCompare (FunctionCall @@ -222,7 +222,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -242,7 +242,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -262,7 +262,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -282,7 +282,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -302,7 +302,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -322,7 +322,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -342,7 +342,7 @@ ) () ) - (= + (Assignment (Var 3 a) (StringCompare (StringConstant @@ -362,7 +362,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalCompare (LogicalConstant @@ -382,7 +382,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalCompare (LogicalConstant @@ -402,7 +402,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalCompare (LogicalConstant @@ -422,7 +422,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalCompare (LogicalConstant diff --git a/tests/reference/asr-expr16-a3dc453.json b/tests/reference/asr-expr16-a3dc453.json index 14ce11462e..a40427a856 100644 --- a/tests/reference/asr-expr16-a3dc453.json +++ b/tests/reference/asr-expr16-a3dc453.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-expr16-a3dc453.stderr", - "stderr_hash": "67cb0d8b08c9910cfdf81faffe003dec601823ff0fd07990a478baf4", + "stderr_hash": "5e2be92ee502526a6c5f1aa78d0165103f5f066c76918ee8fcd3bcb1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-expr16-a3dc453.stderr b/tests/reference/asr-expr16-a3dc453.stderr index 7b8ae5a07d..e13f8400ac 100644 --- a/tests/reference/asr-expr16-a3dc453.stderr +++ b/tests/reference/asr-expr16-a3dc453.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in shorthand operator, the types must be compatibl | 6 | sum += data[i] | ^^^ ^^^^^^^ type mismatch ('f64' and 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-expr2-2e78a12.json b/tests/reference/asr-expr2-2e78a12.json index fb9017f692..127c79cee3 100644 --- a/tests/reference/asr-expr2-2e78a12.json +++ b/tests/reference/asr-expr2-2e78a12.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr2-2e78a12.stdout", - "stdout_hash": "2ff834685a67310d1ac788a1882209a5179ab17c41e4be40773a53a6", + "stdout_hash": "bc0b95ce4ed46823cc16626129a52ee2c7e5318903cbeb7e65b91ce5", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr2-2e78a12.stdout b/tests/reference/asr-expr2-2e78a12.stdout index 510df79e02..50167eff6e 100644 --- a/tests/reference/asr-expr2-2e78a12.stdout +++ b/tests/reference/asr-expr2-2e78a12.stdout @@ -62,7 +62,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (LogicalConstant .false. @@ -70,7 +70,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .true. @@ -78,7 +78,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalBinOp (Var 3 a) @@ -89,7 +89,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalBinOp (Var 3 a) @@ -103,7 +103,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalBinOp (Var 3 a) @@ -114,7 +114,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalBinOp (Var 3 a) @@ -131,7 +131,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalBinOp (Var 3 a) @@ -148,7 +148,7 @@ ) () ) - (= + (Assignment (Var 3 a) (LogicalBinOp (Var 3 b) diff --git a/tests/reference/asr-expr4-cef6743.json b/tests/reference/asr-expr4-cef6743.json index 76521609ad..12d1845f1b 100644 --- a/tests/reference/asr-expr4-cef6743.json +++ b/tests/reference/asr-expr4-cef6743.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr4-cef6743.stdout", - "stdout_hash": "666ba33cd5ae1e6c79478d456ed9d2ad73bf5497f8a541debadd4738", + "stdout_hash": "e50df4848f48a885a035b018d0575749af5192d1ebd257d45fa1a491", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr4-cef6743.stdout b/tests/reference/asr-expr4-cef6743.stdout index 30d1e989c5..880e622806 100644 --- a/tests/reference/asr-expr4-cef6743.stdout +++ b/tests/reference/asr-expr4-cef6743.stdout @@ -62,12 +62,12 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 4 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerConstant 20 (Integer 4)) () diff --git a/tests/reference/asr-expr5-645ffcc.json b/tests/reference/asr-expr5-645ffcc.json index 890d1b68c6..d90b7ef596 100644 --- a/tests/reference/asr-expr5-645ffcc.json +++ b/tests/reference/asr-expr5-645ffcc.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr5-645ffcc.stdout", - "stdout_hash": "c7893c51dec391aa10b49e7839e0b95eff9b93332273faad253f758f", + "stdout_hash": "808a813f58fb818b9d2187476517134f2ec87199cfc9c348d7657ea9", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr5-645ffcc.stdout b/tests/reference/asr-expr5-645ffcc.stdout index 52dd2fcc4b..e17eddc53c 100644 --- a/tests/reference/asr-expr5-645ffcc.stdout +++ b/tests/reference/asr-expr5-645ffcc.stdout @@ -46,7 +46,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringConcat (StringConstant @@ -65,7 +65,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConcat (StringConstant @@ -84,7 +84,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConcat (StringConcat diff --git a/tests/reference/asr-expr6-368e5ed.json b/tests/reference/asr-expr6-368e5ed.json index 3255a6bb27..7fbad5a8ac 100644 --- a/tests/reference/asr-expr6-368e5ed.json +++ b/tests/reference/asr-expr6-368e5ed.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr6-368e5ed.stdout", - "stdout_hash": "eb681d9c5f81c0d94cd1f175bfb84ec29803a153327f1c7a5a17b7d4", + "stdout_hash": "38c2f55590dfedacd997ee117434700aa0d2df34e698820c1b5e2792", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr6-368e5ed.stdout b/tests/reference/asr-expr6-368e5ed.stdout index bb68ad16a9..9e709fabf4 100644 --- a/tests/reference/asr-expr6-368e5ed.stdout +++ b/tests/reference/asr-expr6-368e5ed.stdout @@ -78,12 +78,12 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IfExp (IntegerCompare @@ -100,7 +100,7 @@ ) () ) - (= + (Assignment (Var 3 c) (IfExp (IntegerCompare diff --git a/tests/reference/asr-expr7-480ba2f.json b/tests/reference/asr-expr7-480ba2f.json index e92547c7d6..04a686a609 100644 --- a/tests/reference/asr-expr7-480ba2f.json +++ b/tests/reference/asr-expr7-480ba2f.json @@ -6,8 +6,8 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr7-480ba2f.stdout", - "stdout_hash": "05afdf3289ac02304cef8b61bc6e67c5a1e45f5c58bf7ad7c08fa5d8", + "stdout_hash": "6c5581a5fbdf201e4bd0f17e0fd6f8a154cf2d823784e09e77b0d1dd", "stderr": "asr-expr7-480ba2f.stderr", - "stderr_hash": "6e9790ac88db1a9ead8f64a91ba8a6605de67167037908a74b77be0c", + "stderr_hash": "14266d9eecb4272a8102f9495568abd799c50f1741a894f56101ddd8", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-expr7-480ba2f.stderr b/tests/reference/asr-expr7-480ba2f.stderr index a4fad29beb..3658b5c161 100644 --- a/tests/reference/asr-expr7-480ba2f.stderr +++ b/tests/reference/asr-expr7-480ba2f.stderr @@ -9,3 +9,7 @@ style suggestion: Could have used '**' instead of 'pow' | 8 | res = i32(pow(a, b)) | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-expr7-480ba2f.stdout b/tests/reference/asr-expr7-480ba2f.stdout index 6b3fa7f178..1892879fa2 100644 --- a/tests/reference/asr-expr7-480ba2f.stdout +++ b/tests/reference/asr-expr7-480ba2f.stdout @@ -89,7 +89,7 @@ [] () ) - (= + (Assignment (Var 5 c) (FunctionCall 2 test_pow_1 @@ -167,7 +167,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (Cast (FunctionCall @@ -303,7 +303,7 @@ [] [(Var 4 a) (Var 4 b)] - [(= + [(Assignment (Var 4 res) (Cast (FunctionCall @@ -321,7 +321,7 @@ ) () ) - (= + (Assignment (Var 4 _lpython_return_variable) (Var 4 res) () diff --git a/tests/reference/asr-expr8-6beda60.json b/tests/reference/asr-expr8-6beda60.json index 9fb8c510ab..f9b7643677 100644 --- a/tests/reference/asr-expr8-6beda60.json +++ b/tests/reference/asr-expr8-6beda60.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr8-6beda60.stdout", - "stdout_hash": "b79ac7dd790182c720f71316cdcedbd0a6b3b1bd56ef5cb800fab8dd", + "stdout_hash": "d3ed75b48a59cad2bab8967200596c560fb86809d16147c2d9b9e5d9", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr8-6beda60.stdout b/tests/reference/asr-expr8-6beda60.stdout index cda03a79a5..fb6c354247 100644 --- a/tests/reference/asr-expr8-6beda60.stdout +++ b/tests/reference/asr-expr8-6beda60.stdout @@ -94,7 +94,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (IntegerBinOp (IntegerConstant 2 (Integer 4)) @@ -105,7 +105,7 @@ ) () ) - (= + (Assignment (Var 3 x2) (Cast (RealBinOp @@ -133,7 +133,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (IntegerConstant 54 (Integer 4)) @@ -144,7 +144,7 @@ ) () ) - (= + (Assignment (Var 3 x2) (Cast (RealBinOp @@ -184,7 +184,7 @@ ) () ) - (= + (Assignment (Var 3 x2) (Cast (RealBinOp @@ -212,7 +212,7 @@ ) () ) - (= + (Assignment (Var 3 x2) (Cast (RealBinOp @@ -240,7 +240,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Cast @@ -267,7 +267,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Cast @@ -294,7 +294,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Cast @@ -321,7 +321,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Cast @@ -348,7 +348,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (LogicalConstant .true. @@ -356,7 +356,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (LogicalConstant .false. @@ -364,10 +364,10 @@ ) () ) - (= + (Assignment (Var 3 x) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(Var 3 b1) (Var 3 b1)] @@ -381,7 +381,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Cast diff --git a/tests/reference/asr-expr9-814e4bc.json b/tests/reference/asr-expr9-814e4bc.json index 5e5e4e24e7..e6b8a6023c 100644 --- a/tests/reference/asr-expr9-814e4bc.json +++ b/tests/reference/asr-expr9-814e4bc.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr9-814e4bc.stdout", - "stdout_hash": "a8334d45029aef40c38c8014b64aa2520c38fdc0186ae85869d72c36", + "stdout_hash": "922dc300e7301fe54ac9c1bd22b4cda2551dcaa4ea76fb131db41882", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr9-814e4bc.stdout b/tests/reference/asr-expr9-814e4bc.stdout index 70042e2dcd..0313c83f89 100644 --- a/tests/reference/asr-expr9-814e4bc.stdout +++ b/tests/reference/asr-expr9-814e4bc.stdout @@ -100,7 +100,7 @@ test_return_2 test_return_3] [] - [(= + [(Assignment (Var 6 i) (FunctionCall 2 test_return_1 @@ -112,7 +112,7 @@ ) () ) - (= + (Assignment (Var 6 s) (FunctionCall 2 test_return_2 @@ -124,7 +124,7 @@ ) () ) - (= + (Assignment (Var 6 i) (FunctionCall 2 test_return_3 @@ -213,12 +213,12 @@ ) [] [(Var 3 a)] - [(= + [(Assignment (Var 3 x) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 3 _lpython_return_variable) (Var 3 x) () @@ -301,7 +301,7 @@ ) [] [(Var 4 a)] - [(= + [(Assignment (Var 4 x) (StringConstant "test" @@ -309,7 +309,7 @@ ) () ) - (= + (Assignment (Var 4 _lpython_return_variable) (Var 4 x) () @@ -376,7 +376,7 @@ ) [] [(Var 5 a)] - [(= + [(Assignment (Var 5 _lpython_return_variable) (Var 5 a) () diff --git a/tests/reference/asr-expr_01-211000e.json b/tests/reference/asr-expr_01-211000e.json index 2f242ea977..f164bfc97c 100644 --- a/tests/reference/asr-expr_01-211000e.json +++ b/tests/reference/asr-expr_01-211000e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_01-211000e.stdout", - "stdout_hash": "55ef3fa5588fa753b58860ce4178bd454bce8e1c5c26842bcfe15bbd", + "stdout_hash": "1e770e5983d3028716293596137effa14c8ff482aff2f0f1d1efc3c4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_01-211000e.stdout b/tests/reference/asr-expr_01-211000e.stdout index 2ba434fe81..b76d1a9c36 100644 --- a/tests/reference/asr-expr_01-211000e.stdout +++ b/tests/reference/asr-expr_01-211000e.stdout @@ -130,7 +130,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (IntegerBinOp (IntegerBinOp diff --git a/tests/reference/asr-expr_01-a0d4829.json b/tests/reference/asr-expr_01-a0d4829.json index 23075b510d..46521dcd31 100644 --- a/tests/reference/asr-expr_01-a0d4829.json +++ b/tests/reference/asr-expr_01-a0d4829.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_01-a0d4829.stdout", - "stdout_hash": "22c544446be0bf9235672437a74b58e230def3217713441058c35b49", + "stdout_hash": "81e8dec77a5c7bda11b512e25b14698a02c7923cacfd5d491a86e0b6", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_01-a0d4829.stdout b/tests/reference/asr-expr_01-a0d4829.stdout index 2f80c815e4..3e27c5fd64 100644 --- a/tests/reference/asr-expr_01-a0d4829.stdout +++ b/tests/reference/asr-expr_01-a0d4829.stdout @@ -116,7 +116,7 @@ [] [(Var 3 x) (Var 3 y)] - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 x) @@ -207,7 +207,7 @@ [] [(Var 4 x) (Var 4 y)] - [(= + [(Assignment (Var 4 _lpython_return_variable) (IntegerBinOp (Var 4 x) @@ -297,7 +297,7 @@ [add and_op] [] - [(= + [(Assignment (Var 5 x) (IntegerBinOp (IntegerBinOp @@ -314,7 +314,7 @@ ) () ) - (= + (Assignment (Var 5 y) (IntegerBinOp (FunctionCall @@ -353,7 +353,7 @@ ) () ) - (= + (Assignment (Var 5 z) (FunctionCall 2 and_op diff --git a/tests/reference/asr-expr_05-3a37324.json b/tests/reference/asr-expr_05-3a37324.json index fd18bef00a..3aa8100a33 100644 --- a/tests/reference/asr-expr_05-3a37324.json +++ b/tests/reference/asr-expr_05-3a37324.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_05-3a37324.stdout", - "stdout_hash": "10748750b5ee8a95cb883f0d3248ef706a24bea040d2ab9702595f5a", + "stdout_hash": "495870ee10e0790fb0f932f2c3f460241e5fd0a4203d237a5bd12820", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_05-3a37324.stdout b/tests/reference/asr-expr_05-3a37324.stdout index 09f1032d95..b5b500626f 100644 --- a/tests/reference/asr-expr_05-3a37324.stdout +++ b/tests/reference/asr-expr_05-3a37324.stdout @@ -289,12 +289,12 @@ [test_multiply test_mod] [] - [(= + [(Assignment (Var 5 a) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 5 b) (IntegerUnaryMinus (IntegerConstant 5 (Integer 4)) @@ -303,7 +303,7 @@ ) () ) - (= + (Assignment (Var 5 eps) (RealConstant 0.000000 @@ -333,7 +333,7 @@ ) () ) - (= + (Assignment (Var 5 i) (Cast (IntegerConstant 1 (Integer 4)) @@ -343,7 +343,7 @@ ) () ) - (= + (Assignment (Var 5 i) (IntegerBinOp (Var 5 i) @@ -374,12 +374,12 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 5 (Integer 4)) () @@ -420,12 +420,12 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerConstant 123282374 (Integer 4)) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 32771 (Integer 4)) () @@ -448,7 +448,7 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerUnaryMinus (IntegerConstant 5345 (Integer 4)) @@ -457,7 +457,7 @@ ) () ) - (= + (Assignment (Var 5 b) (IntegerUnaryMinus (IntegerConstant 534 (Integer 4)) @@ -488,7 +488,7 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerUnaryMinus (IntegerConstant 123282374 (Integer 4)) @@ -497,7 +497,7 @@ ) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 32771 (Integer 4)) () @@ -704,12 +704,12 @@ ) () ) - (= + (Assignment (Var 5 i1) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 5 i2) (IntegerConstant 4 (Integer 4)) () @@ -818,12 +818,12 @@ ) () ) - (= + (Assignment (Var 5 i3) (IntegerConstant 432534534 (Integer 4)) () ) - (= + (Assignment (Var 5 i4) (IntegerUnaryMinus (IntegerConstant 4325 (Integer 4)) @@ -916,12 +916,12 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 5 a) (IntegerBinOp (Var 5 a) @@ -942,7 +942,7 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerBinOp (Var 5 a) @@ -963,12 +963,12 @@ ) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 5 a) (FunctionCall 5 _mod@__lpython_overloaded_2___mod @@ -991,12 +991,12 @@ ) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 4 (Integer 4)) () ) - (= + (Assignment (Var 5 a) (IntegerBinOp (Var 5 a) @@ -1017,7 +1017,7 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerBinOp (Var 5 a) @@ -1038,7 +1038,7 @@ ) () ) - (= + (Assignment (Var 5 a) (IntegerBinOp (Var 5 a) @@ -1059,7 +1059,7 @@ ) () ) - (= + (Assignment (Var 5 b) (IntegerBinOp (Var 5 b) @@ -1169,7 +1169,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1231,7 +1231,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1284,7 +1284,7 @@ ) () ) - (= + (Assignment (Var 5 a1) (Cast (IntegerConstant 10 (Integer 4)) @@ -1301,7 +1301,7 @@ ) () ) - (= + (Assignment (Var 5 b1) (Cast (IntegerConstant 3 (Integer 4)) @@ -1318,7 +1318,7 @@ ) () ) - (= + (Assignment (Var 5 c1) (FunctionCall 5 _mod@__lpython_overloaded_4___mod @@ -1355,9 +1355,9 @@ ) () ) - (= + (Assignment (Var 5 c1) - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(Var 5 a1) (Var 5 b1)] @@ -1490,7 +1490,7 @@ [] [(Var 4 a) (Var 4 b)] - [(= + [(Assignment (Var 4 _lpython_return_variable) (FunctionCall 4 _mod@__lpython_overloaded_2___mod @@ -1583,7 +1583,7 @@ [] [(Var 3 a) (Var 3 b)] - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (Var 3 a) diff --git a/tests/reference/asr-expr_07-7742668.json b/tests/reference/asr-expr_07-7742668.json index f22e910c6a..bb5c99c5d7 100644 --- a/tests/reference/asr-expr_07-7742668.json +++ b/tests/reference/asr-expr_07-7742668.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_07-7742668.stdout", - "stdout_hash": "3d6f2e6a2f297f77eb89fa3169ada477efb4806398d84d425db7ee4b", + "stdout_hash": "15b03241d340d1abbeb06e4540d37bcd9307d085f7c484ed822f8555", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_07-7742668.stdout b/tests/reference/asr-expr_07-7742668.stdout index ca96184588..a9537e6938 100644 --- a/tests/reference/asr-expr_07-7742668.stdout +++ b/tests/reference/asr-expr_07-7742668.stdout @@ -89,7 +89,7 @@ ) [] [] - [(= + [(Assignment (Var 5 var) (LogicalConstant .true. @@ -131,7 +131,7 @@ ) () ) - (= + (Assignment (Var 5 var) (LogicalConstant .false. @@ -261,22 +261,22 @@ ) [g] [] - [(= + [(Assignment (Var 4 a) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 4 x) (IntegerConstant 3 (Integer 4)) () ) - (= + (Assignment (Var 4 x) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Var 4 x) diff --git a/tests/reference/asr-expr_09-f3e89c8.json b/tests/reference/asr-expr_09-f3e89c8.json index 0aec74e973..f64d2816af 100644 --- a/tests/reference/asr-expr_09-f3e89c8.json +++ b/tests/reference/asr-expr_09-f3e89c8.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_09-f3e89c8.stdout", - "stdout_hash": "1324aa048cd781878bc51344fea846730c0a0c860930ee839bbc5284", + "stdout_hash": "6e8a419784bc7e466429ca4f3f3b0d6a1883b2dd0c5718fe71361765", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_09-f3e89c8.stdout b/tests/reference/asr-expr_09-f3e89c8.stdout index 43e964d53b..7d736d1d8c 100644 --- a/tests/reference/asr-expr_09-f3e89c8.stdout +++ b/tests/reference/asr-expr_09-f3e89c8.stdout @@ -112,22 +112,22 @@ ) [] [] - [(= + [(Assignment (Var 3 i1) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 3 i2) (IntegerConstant 4 (Integer 4)) () ) - (= + (Assignment (Var 3 i1) (IntegerConstant 3 (Integer 4)) () ) - (= + (Assignment (Var 3 i2) (IntegerConstant 5 (Integer 4)) () @@ -255,7 +255,7 @@ ) [] [] - [(= + [(Assignment (TupleConstant [(Var 5 a) (Var 5 b)] @@ -274,7 +274,7 @@ ) () ) - (= + (Assignment (Var 5 c) (TupleConstant [(IntegerConstant 2 (Integer 4)) @@ -549,12 +549,12 @@ ) [] [] - [(= + [(Assignment (Var 4 g) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 4 d) (RealBinOp (Cast @@ -573,7 +573,7 @@ ) () ) - (= + (Assignment (Var 4 e) (RealBinOp (Cast @@ -592,17 +592,17 @@ ) () ) - (= + (Assignment (Var 4 a) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 4 b) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 4 c) (IntegerConstant 10 (Integer 4)) () @@ -637,7 +637,7 @@ ) () ) - (= + (Assignment (Var 4 x) (RealConstant 23.000000 @@ -645,7 +645,7 @@ ) () ) - (= + (Assignment (Var 4 y) (RealConstant 23.000000 @@ -655,7 +655,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 4 x) @@ -683,7 +683,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 4 y) @@ -711,7 +711,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 4 e) @@ -739,7 +739,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 4 d) @@ -765,7 +765,7 @@ ) () ) - (= + (Assignment (Var 4 k) (ListConstant [] @@ -775,7 +775,7 @@ ) () ) - (= + (Assignment (Var 4 g) (IntegerConstant 0 (Integer 4)) () @@ -821,12 +821,12 @@ )] [] ) - (= + (Assignment (Var 4 i) (Var 4 k) () ) - (= + (Assignment (Var 4 j) (Var 4 k) () @@ -845,7 +845,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ListItem @@ -880,7 +880,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ListItem @@ -915,7 +915,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp diff --git a/tests/reference/asr-expr_10-d39708c.json b/tests/reference/asr-expr_10-d39708c.json index 19558e3c36..5d87486d4c 100644 --- a/tests/reference/asr-expr_10-d39708c.json +++ b/tests/reference/asr-expr_10-d39708c.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_10-d39708c.stdout", - "stdout_hash": "97c3e89ccc963a093255f2df997a14962c244d4ed454ebb3942c39a5", + "stdout_hash": "937ab19f6b8e31442a9a1b0c6bd4fa931e4d10aae2e80a351256227f", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_10-d39708c.stdout b/tests/reference/asr-expr_10-d39708c.stdout index 7daf5f8c8b..1ff47856c9 100644 --- a/tests/reference/asr-expr_10-d39708c.stdout +++ b/tests/reference/asr-expr_10-d39708c.stdout @@ -82,7 +82,7 @@ ) [] [] - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerConstant 5 (Integer 4)) () @@ -216,7 +216,7 @@ [g gsubrout] [] - [(= + [(Assignment (Var 5 i) (FunctionCall 2 g @@ -228,7 +228,7 @@ ) () ) - (= + (Assignment (Var 5 j) (FunctionCall 2 g @@ -240,7 +240,7 @@ ) () ) - (= + (Assignment (Var 5 __lcompilers_dummy) (FunctionCall 2 g diff --git a/tests/reference/asr-expr_12-6769be0.json b/tests/reference/asr-expr_12-6769be0.json index b8830172cd..c9e1e1704e 100644 --- a/tests/reference/asr-expr_12-6769be0.json +++ b/tests/reference/asr-expr_12-6769be0.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_12-6769be0.stdout", - "stdout_hash": "0f537c49f019d14a0240da9280de2e6d05afee0ad5dbdb4b3646e730", + "stdout_hash": "2d85d51b025a58090c9848f23b6bfc7e236771cbeb8b6257e33256b5", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_12-6769be0.stdout b/tests/reference/asr-expr_12-6769be0.stdout index 8b111ab1e3..ad61bc5b2f 100644 --- a/tests/reference/asr-expr_12-6769be0.stdout +++ b/tests/reference/asr-expr_12-6769be0.stdout @@ -327,7 +327,7 @@ [] [(Var 3 x) (Var 3 y)] - [(= + [(Assignment (ArrayItem (Var 3 y) [(() @@ -345,7 +345,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 3 y) [(() @@ -363,7 +363,7 @@ ) () ) - (= + (Assignment (Var 3 x) (GetPointer (Var 3 y) diff --git a/tests/reference/asr-expr_14-f2bd343.json b/tests/reference/asr-expr_14-f2bd343.json index 59cc62002a..2710093259 100644 --- a/tests/reference/asr-expr_14-f2bd343.json +++ b/tests/reference/asr-expr_14-f2bd343.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-expr_14-f2bd343.stdout", - "stdout_hash": "b03cf9660c69a5bd18468550cc176ffd6f219869f5b9a198c2b23e71", + "stdout_hash": "d0556c7ad91fa6f49b4dc82b49e50843ffc424a9289b800e1bceb863", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-expr_14-f2bd343.stdout b/tests/reference/asr-expr_14-f2bd343.stdout index 004396081b..44d81d07ce 100644 --- a/tests/reference/asr-expr_14-f2bd343.stdout +++ b/tests/reference/asr-expr_14-f2bd343.stdout @@ -354,17 +354,17 @@ ) [] [] - [(= + [(Assignment (Var 3 a1) (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 3 a2) (IntegerConstant 9 (Integer 4)) () ) - (= + (Assignment (Var 3 a3) (RealBinOp (Cast @@ -387,7 +387,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 a3) @@ -413,7 +413,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (Cast (IntegerConstant 2 (Integer 4)) @@ -423,7 +423,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (Cast (IntegerConstant 10 (Integer 4)) @@ -433,7 +433,7 @@ ) () ) - (= + (Assignment (Var 3 b3) (RealBinOp (Cast @@ -456,7 +456,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 b3) @@ -482,7 +482,7 @@ ) () ) - (= + (Assignment (Var 3 c1) (Cast (RealConstant @@ -498,7 +498,7 @@ ) () ) - (= + (Assignment (Var 3 c2) (Cast (RealConstant @@ -514,7 +514,7 @@ ) () ) - (= + (Assignment (Var 3 c3) (RealBinOp (Var 3 c2) @@ -527,7 +527,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 c3) @@ -569,7 +569,7 @@ ) () ) - (= + (Assignment (Var 3 d1) (RealConstant 4.000000 @@ -577,7 +577,7 @@ ) () ) - (= + (Assignment (Var 3 d2) (RealConstant 12.000000 @@ -585,7 +585,7 @@ ) () ) - (= + (Assignment (Var 3 d3) (RealBinOp (Var 3 d2) @@ -598,7 +598,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 d3) @@ -624,7 +624,7 @@ ) () ) - (= + (Assignment (Var 3 e1) (ComplexBinOp (Cast @@ -661,7 +661,7 @@ ) () ) - (= + (Assignment (Var 3 e2) (ComplexBinOp (Cast @@ -698,7 +698,7 @@ ) () ) - (= + (Assignment (Var 3 e3) (ComplexBinOp (Var 3 e2) @@ -711,7 +711,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(ComplexBinOp (ComplexBinOp @@ -773,7 +773,7 @@ ) () ) - (= + (Assignment (Var 3 f1) (ComplexBinOp (Cast @@ -801,7 +801,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (ComplexBinOp (Cast @@ -829,7 +829,7 @@ ) () ) - (= + (Assignment (Var 3 f3) (ComplexBinOp (Var 3 f2) @@ -842,7 +842,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(ComplexBinOp (ComplexBinOp diff --git a/tests/reference/asr-func_01-d87aa4a.json b/tests/reference/asr-func_01-d87aa4a.json index 2ac3164ce4..f75ad9b3f9 100644 --- a/tests/reference/asr-func_01-d87aa4a.json +++ b/tests/reference/asr-func_01-d87aa4a.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_01-d87aa4a.stderr", - "stderr_hash": "2a773033fab41aadd3ddf3732cfb473ba5da6c9649453516286dacf1", + "stderr_hash": "a2c1046cadbd9dcca3eb4c55832c99d958d01eb31a75ccc9e768693b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_01-d87aa4a.stderr b/tests/reference/asr-func_01-d87aa4a.stderr index 3963b1e1d5..d1bead0c59 100644 --- a/tests/reference/asr-func_01-d87aa4a.stderr +++ b/tests/reference/asr-func_01-d87aa4a.stderr @@ -7,3 +7,7 @@ semantic error: Function f is already defined | 10 | print(i + 2) | ...^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_02-b439474.json b/tests/reference/asr-func_02-b439474.json index bc648e06af..b600daf84f 100644 --- a/tests/reference/asr-func_02-b439474.json +++ b/tests/reference/asr-func_02-b439474.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_02-b439474.stderr", - "stderr_hash": "855967bc8c46a46b93c348de6e3004107861b10fad24496866c8a197", + "stderr_hash": "49d57f0649497df70b4f2ea87e00000278d40f151aafc2a9802bc6e0", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_02-b439474.stderr b/tests/reference/asr-func_02-b439474.stderr index e4d6ca0563..cfef5657a7 100644 --- a/tests/reference/asr-func_02-b439474.stderr +++ b/tests/reference/asr-func_02-b439474.stderr @@ -3,3 +3,7 @@ semantic error: Assignment to an input function parameter `n` is not allowed | 4 | n = 5 | ^ Hint: create a new local variable with a different name + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_03-cd744a0.json b/tests/reference/asr-func_03-cd744a0.json index e0e191485d..9fa71ba4c0 100644 --- a/tests/reference/asr-func_03-cd744a0.json +++ b/tests/reference/asr-func_03-cd744a0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_03-cd744a0.stderr", - "stderr_hash": "d1201fe81d9eeb213996a3f316f463ee4071c9192fb20d7bf327a898", + "stderr_hash": "57441cbbd75c2fd973a3287f4766a0cfdec20aaa7c53099c2496e06c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_03-cd744a0.stderr b/tests/reference/asr-func_03-cd744a0.stderr index 74251ce6c7..58435b7310 100644 --- a/tests/reference/asr-func_03-cd744a0.stderr +++ b/tests/reference/asr-func_03-cd744a0.stderr @@ -3,3 +3,7 @@ semantic error: Assignment to an input function parameter `l` is not allowed | 4 | l[5] = 5 | ^ Use InOut[list[i32]] to allow assignment + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_04-eef2656.json b/tests/reference/asr-func_04-eef2656.json index 6fa82a6009..92f45dc272 100644 --- a/tests/reference/asr-func_04-eef2656.json +++ b/tests/reference/asr-func_04-eef2656.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_04-eef2656.stderr", - "stderr_hash": "d1e5bb4b5356e57124ff34eea9e5b96ecc44d3bc8a1da4b0a7db5b4a", + "stderr_hash": "e825889cde0d7fc3a1063aa39cb83348ac45de675aac96bdee345922", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_04-eef2656.stderr b/tests/reference/asr-func_04-eef2656.stderr index 744b9460d2..98e45a08a6 100644 --- a/tests/reference/asr-func_04-eef2656.stderr +++ b/tests/reference/asr-func_04-eef2656.stderr @@ -3,3 +3,7 @@ semantic error: Modifying input function parameter `l` is not allowed | 4 | l.append(5) | ^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_05-c22b921.json b/tests/reference/asr-func_05-c22b921.json index 46cec1c7b4..c94d4aa57b 100644 --- a/tests/reference/asr-func_05-c22b921.json +++ b/tests/reference/asr-func_05-c22b921.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_05-c22b921.stderr", - "stderr_hash": "9611beb75ae308f86e573592164c5aca50c4e1acec2e91e48687ba96", + "stderr_hash": "fbd965b2751f10ff6030d018c89ad3dc973eb78ec48eeb7e25691783", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_05-c22b921.stderr b/tests/reference/asr-func_05-c22b921.stderr index fc959f032f..387238b81e 100644 --- a/tests/reference/asr-func_05-c22b921.stderr +++ b/tests/reference/asr-func_05-c22b921.stderr @@ -3,3 +3,7 @@ semantic error: Simple Type i32 cannot be intent InOut/Out | 3 | def f(n: InOut[i32]): | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_06-62e738c.json b/tests/reference/asr-func_06-62e738c.json index 00d0a1051b..c3070c8f4b 100644 --- a/tests/reference/asr-func_06-62e738c.json +++ b/tests/reference/asr-func_06-62e738c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_06-62e738c.stderr", - "stderr_hash": "a97e6d8f812ec9e81cb4b0565dc2fd30f3bd194ccab41770962f6e32", + "stderr_hash": "c722c52c0fe4d3c5bfd12cdf3e06b06e680625f4419fd9b436938b46", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_06-62e738c.stderr b/tests/reference/asr-func_06-62e738c.stderr index 5e5827b226..6c7a5d3e51 100644 --- a/tests/reference/asr-func_06-62e738c.stderr +++ b/tests/reference/asr-func_06-62e738c.stderr @@ -6,3 +6,7 @@ semantic error: Parameter is already declared | 1 | def init_X(m:i32, n: i32, b: CPtr, m: i32) -> None: | ^^^^^^ redeclaration + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_07-4a8c076.json b/tests/reference/asr-func_07-4a8c076.json index 23a3ff6d21..2ca81c01c6 100644 --- a/tests/reference/asr-func_07-4a8c076.json +++ b/tests/reference/asr-func_07-4a8c076.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_07-4a8c076.stderr", - "stderr_hash": "7ed110581f050d55b95ace1c09b3dc30176b30213c125e3ec19f5c68", + "stderr_hash": "749dd900726424e74f4f02048024407e61cc77bda589298e23f8857a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_07-4a8c076.stderr b/tests/reference/asr-func_07-4a8c076.stderr index d876637cc3..bf62b009a1 100644 --- a/tests/reference/asr-func_07-4a8c076.stderr +++ b/tests/reference/asr-func_07-4a8c076.stderr @@ -3,3 +3,7 @@ semantic error: Assignment to an input function parameter `this` is not allowed | 12 | this._len = len(this._buf) | ^^^^ Use InOut[struct StringIO] to allow assignment + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_08-c137415.json b/tests/reference/asr-func_08-c137415.json index e8987fe7e0..eba162c0c3 100644 --- a/tests/reference/asr-func_08-c137415.json +++ b/tests/reference/asr-func_08-c137415.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-func_08-c137415.stderr", - "stderr_hash": "5fe28460d4f28e79ced8c17e75ba6da4cdfccd36e20d1c3a85d07cf1", + "stderr_hash": "cec3ab3b772b374fbc85494ed18310b04bd75ebe14390bf7f0071792", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-func_08-c137415.stderr b/tests/reference/asr-func_08-c137415.stderr index c372ea27dd..4408cbbeac 100644 --- a/tests/reference/asr-func_08-c137415.stderr +++ b/tests/reference/asr-func_08-c137415.stderr @@ -3,3 +3,7 @@ semantic error: Intent annotation 'In' cannot be used here | 3 | def main0(x: In[In[i32]]): | ^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-func_inline_01-56af272.json b/tests/reference/asr-func_inline_01-56af272.json index 7c32b6b371..45c753a0ae 100644 --- a/tests/reference/asr-func_inline_01-56af272.json +++ b/tests/reference/asr-func_inline_01-56af272.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-func_inline_01-56af272.stdout", - "stdout_hash": "dbb86e1cbe4e62cc86aefee1b8654130b8025e892913d824628ca7e8", + "stdout_hash": "7f68a8f56a9391784af374552ec602e3f935f99e20257ea3dd08ec8e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-func_inline_01-56af272.stdout b/tests/reference/asr-func_inline_01-56af272.stdout index be6554a7ec..d39cede0f2 100644 --- a/tests/reference/asr-func_inline_01-56af272.stdout +++ b/tests/reference/asr-func_inline_01-56af272.stdout @@ -111,7 +111,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 3 _lpython_return_variable) (Var 3 n) () @@ -119,7 +119,7 @@ (Return)] [] ) - (= + (Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (FunctionCall @@ -228,7 +228,7 @@ ) [fib] [] - [(= + [(Assignment (Var 4 x) (Cast (IntegerConstant 40 (Integer 4)) @@ -238,7 +238,7 @@ ) () ) - (= + (Assignment (Var 4 ans) (FunctionCall 2 fib diff --git a/tests/reference/asr-generics_01-d616074.json b/tests/reference/asr-generics_01-d616074.json index 33a28845c8..54d83bd302 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": "a7de6a75a240c17b33268eadb9f7f7002885ea8d3c3351723e97ef95", + "stdout_hash": "105b00adca1fb9bd10c1202f83bf20e649aecab7577b30eeecc643b5", "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 cf6b3b0e85..36a7950e12 100644 --- a/tests/reference/asr-generics_01-d616074.stdout +++ b/tests/reference/asr-generics_01-d616074.stdout @@ -98,7 +98,7 @@ [add_integer] [(Var 7 x) (Var 7 y)] - [(= + [(Assignment (Var 7 _lpython_return_variable) (FunctionCall 2 add_integer @@ -191,7 +191,7 @@ [add_string] [(Var 8 x) (Var 8 y)] - [(= + [(Assignment (Var 8 _lpython_return_variable) (FunctionCall 2 add_string @@ -458,7 +458,7 @@ [] [(Var 4 x) (Var 4 y)] - [(= + [(Assignment (Var 4 _lpython_return_variable) (IntegerBinOp (Var 4 x) @@ -549,7 +549,7 @@ [] [(Var 5 x) (Var 5 y)] - [(= + [(Assignment (Var 5 _lpython_return_variable) (StringConcat (Var 5 x) @@ -651,7 +651,7 @@ [add] [(Var 6 x) (Var 6 y)] - [(= + [(Assignment (Var 6 _lpython_return_variable) (FunctionCall 2 add diff --git a/tests/reference/asr-generics_02-e2ea5c9.json b/tests/reference/asr-generics_02-e2ea5c9.json index 06369427a0..57525f45bf 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": "3168e61664d93355b614ece3ef8eb3f1c128bb225dccb77b163d3ddb", + "stdout_hash": "47fea2d8fe6009063e7bbe136cadfaa875168cab41c3e99fbdbe6ba6", "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 d319d880f6..8969af86bb 100644 --- a/tests/reference/asr-generics_02-e2ea5c9.stdout +++ b/tests/reference/asr-generics_02-e2ea5c9.stdout @@ -98,17 +98,17 @@ [] [(Var 5 x) (Var 5 y)] - [(= + [(Assignment (Var 5 temp) (Var 5 x) () ) - (= + (Assignment (Var 5 x) (Var 5 y) () ) - (= + (Assignment (Var 5 y) (Var 5 temp) () @@ -220,12 +220,12 @@ ) [__asr_generic_swap_0] [] - [(= + [(Assignment (Var 4 a) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 4 b) (IntegerConstant 10 (Integer 4)) () @@ -338,17 +338,17 @@ [] [(Var 3 x) (Var 3 y)] - [(= + [(Assignment (Var 3 temp) (Var 3 x) () ) - (= + (Assignment (Var 3 x) (Var 3 y) () ) - (= + (Assignment (Var 3 y) (Var 3 temp) () diff --git a/tests/reference/asr-generics_array_01-682b1b2.json b/tests/reference/asr-generics_array_01-682b1b2.json index dd75932fa9..143c21ac42 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": "cb6353bc8d69e50ce353ad96c48aa4c0b04e0f2b0f7a259160d370f8", + "stdout_hash": "4a3ccd6b08988a8cf0ec5a84b0751a3381456741a39a642e4a4d0645", "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 b63d570847..6ed081bac3 100644 --- a/tests/reference/asr-generics_array_01-682b1b2.stdout +++ b/tests/reference/asr-generics_array_01-682b1b2.stdout @@ -108,7 +108,7 @@ [] [(Var 222 lst) (Var 222 i)] - [(= + [(Assignment (ArrayItem (Var 222 lst) [(() @@ -121,7 +121,7 @@ (Var 222 i) () ) - (= + (Assignment (Var 222 _lpython_return_variable) (ArrayItem (Var 222 lst) @@ -272,7 +272,7 @@ [] [(Var 220 lst) (Var 220 i)] - [(= + [(Assignment (ArrayItem (Var 220 lst) [(() @@ -287,7 +287,7 @@ (Var 220 i) () ) - (= + (Assignment (Var 220 _lpython_return_variable) (ArrayItem (Var 220 lst) @@ -369,9 +369,9 @@ ) [__asr_generic_f_0] [] - [(= + [(Assignment (Var 221 array) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -379,11 +379,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 221 x) (IntegerConstant 69 (Integer 4)) () diff --git a/tests/reference/asr-generics_array_02-22c8dc1.json b/tests/reference/asr-generics_array_02-22c8dc1.json index 3d87a9c0a6..9e60e7d64b 100644 --- a/tests/reference/asr-generics_array_02-22c8dc1.json +++ b/tests/reference/asr-generics_array_02-22c8dc1.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_array_02-22c8dc1.stdout", - "stdout_hash": "368e1725fa7f7c556d4767ee22d84eaf77d63f5c31382a4c888d923f", + "stdout_hash": "a00c87e82f49c6d7141cf1e466dee45855104d910032dca7108a0800", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_array_02-22c8dc1.stdout b/tests/reference/asr-generics_array_02-22c8dc1.stdout index e60fd70580..7369ba5e04 100644 --- a/tests/reference/asr-generics_array_02-22c8dc1.stdout +++ b/tests/reference/asr-generics_array_02-22c8dc1.stdout @@ -165,9 +165,9 @@ [(Var 226 n) (Var 226 a) (Var 226 b)] - [(= + [(Assignment (Var 226 r) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -175,6 +175,7 @@ (Var 226 n))] PointerToDataArray ) + () RowMajor ) () @@ -191,7 +192,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 226 r) [(() @@ -389,9 +390,9 @@ [(Var 227 n) (Var 227 a) (Var 227 b)] - [(= + [(Assignment (Var 227 r) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -399,6 +400,7 @@ (Var 227 n))] PointerToDataArray ) + () RowMajor ) () @@ -415,7 +417,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 227 r) [(() @@ -674,7 +676,7 @@ [] [(Var 222 x) (Var 222 y)] - [(= + [(Assignment (Var 222 _lpython_return_variable) (RealBinOp (Var 222 x) @@ -765,7 +767,7 @@ [] [(Var 221 x) (Var 221 y)] - [(= + [(Assignment (Var 221 _lpython_return_variable) (IntegerBinOp (Var 221 x) @@ -933,9 +935,9 @@ [(Var 223 n) (Var 223 a) (Var 223 b)] - [(= + [(Assignment (Var 223 r) - (ArrayConstant + (ArrayConstructor [] (Array (TypeParameter @@ -945,6 +947,7 @@ (Var 223 n))] PointerToDataArray ) + () RowMajor ) () @@ -961,7 +964,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 223 r) [(() @@ -1137,9 +1140,9 @@ [__asr_generic_g_0 __asr_generic_g_1] [] - [(= + [(Assignment (Var 224 a_int) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1147,11 +1150,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 a_int) [(() @@ -1164,9 +1168,9 @@ (IntegerConstant 400 (Integer 4)) () ) - (= + (Assignment (Var 224 b_int) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1174,11 +1178,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 b_int) [(() @@ -1221,9 +1226,9 @@ ))] () ) - (= + (Assignment (Var 224 a_float) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1231,11 +1236,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 a_float) [(() @@ -1259,9 +1265,9 @@ ) () ) - (= + (Assignment (Var 224 b_float) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1269,11 +1275,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 b_float) [(() diff --git a/tests/reference/asr-generics_array_03-fb3706c.json b/tests/reference/asr-generics_array_03-fb3706c.json index 738e27a51e..bcfb7bd094 100644 --- a/tests/reference/asr-generics_array_03-fb3706c.json +++ b/tests/reference/asr-generics_array_03-fb3706c.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_array_03-fb3706c.stdout", - "stdout_hash": "245442c04682e1c18cde44dcc443461526e3ab6ea77983d1f83b275d", + "stdout_hash": "486681f34a4ead2b21b8cfd7b048a4e22325a05bddce5167fa40ecd4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_array_03-fb3706c.stdout b/tests/reference/asr-generics_array_03-fb3706c.stdout index e3875a867f..be5def1c26 100644 --- a/tests/reference/asr-generics_array_03-fb3706c.stdout +++ b/tests/reference/asr-generics_array_03-fb3706c.stdout @@ -259,9 +259,9 @@ (Var 227 m) (Var 227 a) (Var 227 b)] - [(= + [(Assignment (Var 227 r) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -271,6 +271,7 @@ (Var 227 m))] PointerToDataArray ) + () RowMajor ) () @@ -299,7 +300,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 227 r) [(() @@ -605,9 +606,9 @@ (Var 228 m) (Var 228 a) (Var 228 b)] - [(= + [(Assignment (Var 228 r) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -617,6 +618,7 @@ (Var 228 m))] PointerToDataArray ) + () RowMajor ) () @@ -645,7 +647,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 228 r) [(() @@ -918,7 +920,7 @@ [] [(Var 222 x) (Var 222 y)] - [(= + [(Assignment (Var 222 _lpython_return_variable) (RealBinOp (Var 222 x) @@ -1009,7 +1011,7 @@ [] [(Var 221 x) (Var 221 y)] - [(= + [(Assignment (Var 221 _lpython_return_variable) (IntegerBinOp (Var 221 x) @@ -1275,9 +1277,9 @@ (Var 223 m) (Var 223 a) (Var 223 b)] - [(= + [(Assignment (Var 223 r) - (ArrayConstant + (ArrayConstructor [] (Array (TypeParameter @@ -1289,6 +1291,7 @@ (Var 223 m))] PointerToDataArray ) + () RowMajor ) () @@ -1317,7 +1320,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 223 r) [(() @@ -1579,9 +1582,9 @@ [__asr_generic_g_0 __asr_generic_g_1] [] - [(= + [(Assignment (Var 224 a_int) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1591,11 +1594,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 a_int) [(() @@ -1611,9 +1615,9 @@ (IntegerConstant 400 (Integer 4)) () ) - (= + (Assignment (Var 224 b_int) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1623,11 +1627,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 b_int) [(() @@ -1643,7 +1648,7 @@ (IntegerConstant 20 (Integer 4)) () ) - (= + (Assignment (Var 224 __lcompilers_dummy) (FunctionCall 2 __asr_generic_g_0 @@ -1691,9 +1696,9 @@ ) () ) - (= + (Assignment (Var 224 a_float) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1703,11 +1708,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 a_float) [(() @@ -1731,9 +1737,9 @@ ) () ) - (= + (Assignment (Var 224 b_float) - (ArrayConstant + (ArrayConstructor [] (Array (Real 4) @@ -1743,11 +1749,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 b_float) [(() @@ -1771,7 +1778,7 @@ ) () ) - (= + (Assignment (Var 224 __lcompilers_dummy1) (FunctionCall 2 __asr_generic_g_1 diff --git a/tests/reference/asr-generics_error_01-1e05cd6.json b/tests/reference/asr-generics_error_01-1e05cd6.json index 80dcd03351..172fa7ff92 100644 --- a/tests/reference/asr-generics_error_01-1e05cd6.json +++ b/tests/reference/asr-generics_error_01-1e05cd6.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-generics_error_01-1e05cd6.stderr", - "stderr_hash": "45a4d8fba734f967b36ed69d703fe503111c67dc6c8887013477c791", + "stderr_hash": "7b07678e99da206b5b281821c1d69a5af5eee281e2a4125e77bb04a0", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-generics_error_01-1e05cd6.stderr b/tests/reference/asr-generics_error_01-1e05cd6.stderr index 9d7abb86ef..63eaa2873b 100644 --- a/tests/reference/asr-generics_error_01-1e05cd6.stderr +++ b/tests/reference/asr-generics_error_01-1e05cd6.stderr @@ -3,3 +3,7 @@ semantic error: Inconsistent type variable for the function call | 12 | print(f(1,"a")) | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-generics_error_02-d614928.json b/tests/reference/asr-generics_error_02-d614928.json index 950f37b435..3442d625c1 100644 --- a/tests/reference/asr-generics_error_02-d614928.json +++ b/tests/reference/asr-generics_error_02-d614928.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-generics_error_02-d614928.stderr", - "stderr_hash": "2b82c797067dc1c722d416f8f13d837cfec47a0d4adb11c64f5b7e02", + "stderr_hash": "e51d4a53e5f2faa62221e0a4e0b2641664f0b00928f3b0cf60fe2431", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-generics_error_02-d614928.stderr b/tests/reference/asr-generics_error_02-d614928.stderr index 22668c4d18..fba61ad28d 100644 --- a/tests/reference/asr-generics_error_02-d614928.stderr +++ b/tests/reference/asr-generics_error_02-d614928.stderr @@ -3,3 +3,7 @@ semantic error: No applicable argument to the restriction zero | 37 | print(mean(["a","b","c"], add=add_string, div=div_string)) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-generics_error_03-208d10d.json b/tests/reference/asr-generics_error_03-208d10d.json index a5e6b0f007..8d4e968e7d 100644 --- a/tests/reference/asr-generics_error_03-208d10d.json +++ b/tests/reference/asr-generics_error_03-208d10d.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-generics_error_03-208d10d.stderr", - "stderr_hash": "e4803340775b153d9eafeae36cff39a9469260a0e139f0fc41e9317d", + "stderr_hash": "464fbe6f04df56d0e265ce80ca71c90266ca655041ba697aac9e8281", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-generics_error_03-208d10d.stderr b/tests/reference/asr-generics_error_03-208d10d.stderr index ef155d1bb4..c8ecc0b4bf 100644 --- a/tests/reference/asr-generics_error_03-208d10d.stderr +++ b/tests/reference/asr-generics_error_03-208d10d.stderr @@ -7,3 +7,7 @@ semantic error: Restriction mismatch with provided arguments | 21 | return x + y | ...^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-generics_list_01-39c4044.json b/tests/reference/asr-generics_list_01-39c4044.json index e187c1938a..e03f65ee82 100644 --- a/tests/reference/asr-generics_list_01-39c4044.json +++ b/tests/reference/asr-generics_list_01-39c4044.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-generics_list_01-39c4044.stdout", - "stdout_hash": "8eef1611590df5c815fdf07bf609785edf432da67fce5ff83eded2da", + "stdout_hash": "698e7beddad7e18fe72d49fe6f92233771055f842ca1657cfbf49a26", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-generics_list_01-39c4044.stdout b/tests/reference/asr-generics_list_01-39c4044.stdout index 17a91fe662..abb4c13e85 100644 --- a/tests/reference/asr-generics_list_01-39c4044.stdout +++ b/tests/reference/asr-generics_list_01-39c4044.stdout @@ -136,7 +136,7 @@ add_integer div_integer] [(Var 17 x)] - [(= + [(Assignment (Var 17 k) (ListLen (Var 17 x) @@ -153,7 +153,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 17 _lpython_return_variable) (RealConstant 0.000000 @@ -164,7 +164,7 @@ (Return)] [] ) - (= + (Assignment (Var 17 res) (FunctionCall 2 empty_integer @@ -193,7 +193,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 17 res) (FunctionCall 2 add_integer @@ -213,7 +213,7 @@ )] [] ) - (= + (Assignment (Var 17 _lpython_return_variable) (FunctionCall 2 div_integer @@ -344,7 +344,7 @@ add_float div_float] [(Var 18 x)] - [(= + [(Assignment (Var 18 k) (ListLen (Var 18 x) @@ -361,7 +361,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 18 _lpython_return_variable) (RealConstant 0.000000 @@ -372,7 +372,7 @@ (Return)] [] ) - (= + (Assignment (Var 18 res) (FunctionCall 2 empty_float @@ -401,7 +401,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 18 res) (FunctionCall 2 add_float @@ -421,7 +421,7 @@ )] [] ) - (= + (Assignment (Var 18 _lpython_return_variable) (FunctionCall 2 div_float @@ -552,7 +552,7 @@ add_string div_string] [(Var 19 x)] - [(= + [(Assignment (Var 19 k) (ListLen (Var 19 x) @@ -569,7 +569,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 19 _lpython_return_variable) (RealConstant 0.000000 @@ -580,7 +580,7 @@ (Return)] [] ) - (= + (Assignment (Var 19 res) (FunctionCall 2 empty_string @@ -609,7 +609,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 19 res) (FunctionCall 2 add_string @@ -629,7 +629,7 @@ )] [] ) - (= + (Assignment (Var 19 _lpython_return_variable) (FunctionCall 2 div_string @@ -921,7 +921,7 @@ [] [(Var 10 x) (Var 10 y)] - [(= + [(Assignment (Var 10 _lpython_return_variable) (RealBinOp (Var 10 x) @@ -1012,7 +1012,7 @@ [] [(Var 7 x) (Var 7 y)] - [(= + [(Assignment (Var 7 _lpython_return_variable) (IntegerBinOp (Var 7 x) @@ -1103,7 +1103,7 @@ [] [(Var 13 x) (Var 13 y)] - [(= + [(Assignment (Var 13 _lpython_return_variable) (StringConcat (Var 13 x) @@ -1277,7 +1277,7 @@ [] [(Var 11 x) (Var 11 k)] - [(= + [(Assignment (Var 11 _lpython_return_variable) (RealBinOp (Var 11 x) @@ -1373,7 +1373,7 @@ [] [(Var 8 x) (Var 8 k)] - [(= + [(Assignment (Var 8 _lpython_return_variable) (RealBinOp (Cast @@ -1474,7 +1474,7 @@ [] [(Var 14 x) (Var 14 k)] - [(= + [(Assignment (Var 14 _lpython_return_variable) (RealConstant 0.000000 @@ -1544,7 +1544,7 @@ ) [] [(Var 9 x)] - [(= + [(Assignment (Var 9 _lpython_return_variable) (RealConstant 0.000000 @@ -1614,7 +1614,7 @@ ) [] [(Var 6 x)] - [(= + [(Assignment (Var 6 _lpython_return_variable) (IntegerConstant 0 (Integer 4)) () @@ -1681,7 +1681,7 @@ ) [] [(Var 12 x)] - [(= + [(Assignment (Var 12 _lpython_return_variable) (StringConstant "" @@ -1813,7 +1813,7 @@ add div] [(Var 15 x)] - [(= + [(Assignment (Var 15 k) (ListLen (Var 15 x) @@ -1830,7 +1830,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 15 _lpython_return_variable) (RealConstant 0.000000 @@ -1841,7 +1841,7 @@ (Return)] [] ) - (= + (Assignment (Var 15 res) (FunctionCall 2 zero @@ -1874,7 +1874,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 15 res) (FunctionCall 2 add @@ -1898,7 +1898,7 @@ )] [] ) - (= + (Assignment (Var 15 _lpython_return_variable) (FunctionCall 2 div diff --git a/tests/reference/asr-global_scope1-354e217.json b/tests/reference/asr-global_scope1-354e217.json index 2f52991153..73d652907e 100644 --- a/tests/reference/asr-global_scope1-354e217.json +++ b/tests/reference/asr-global_scope1-354e217.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-global_scope1-354e217.stdout", - "stdout_hash": "a8135cc1724a7d8f68c2d2136484125b8962b707c21873560dbaa04b", + "stdout_hash": "3f8b50cb585b10beb104f627d5b326f8c32669eb57225faf8802d42d", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-global_scope1-354e217.stdout b/tests/reference/asr-global_scope1-354e217.stdout index 350c3d4b39..32acaf34a5 100644 --- a/tests/reference/asr-global_scope1-354e217.stdout +++ b/tests/reference/asr-global_scope1-354e217.stdout @@ -31,7 +31,7 @@ ) [] [] - [(= + [(Assignment (Var 2 i) (IntegerConstant 5 (Integer 4)) () diff --git a/tests/reference/asr-global_syms_01-273906f.json b/tests/reference/asr-global_syms_01-273906f.json index 223ea28a2c..7b494e40d0 100644 --- a/tests/reference/asr-global_syms_01-273906f.json +++ b/tests/reference/asr-global_syms_01-273906f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-global_syms_01-273906f.stdout", - "stdout_hash": "8a038638305efddca192d6bdb758eb4f5c4e701efc7a21e1cdd14a06", + "stdout_hash": "43a562bdeaaa407b58e2176609a1c98428b323edf8e098296307f17d", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-global_syms_01-273906f.stdout b/tests/reference/asr-global_syms_01-273906f.stdout index 317e736a9c..6f23bbcfb8 100644 --- a/tests/reference/asr-global_syms_01-273906f.stdout +++ b/tests/reference/asr-global_syms_01-273906f.stdout @@ -31,7 +31,7 @@ ) [test_global_symbols] [] - [(= + [(Assignment (Var 2 x) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -42,7 +42,7 @@ ) () ) - (= + (Assignment (Var 2 i) (ListItem (Var 2 x) diff --git a/tests/reference/asr-kwargs_01_error-ab9530d.json b/tests/reference/asr-kwargs_01_error-ab9530d.json index 6f05aa772d..c698577c40 100644 --- a/tests/reference/asr-kwargs_01_error-ab9530d.json +++ b/tests/reference/asr-kwargs_01_error-ab9530d.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-kwargs_01_error-ab9530d.stderr", - "stderr_hash": "9acb6dea7d63917291858cf2cac49e5270e11ea1dd547f66303224c1", + "stderr_hash": "24867b4db379dfa578d709e387d946e3f903e7a0a853ace226ad0b65", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-kwargs_01_error-ab9530d.stderr b/tests/reference/asr-kwargs_01_error-ab9530d.stderr index dbdf5c98eb..c2dfe3046c 100644 --- a/tests/reference/asr-kwargs_01_error-ab9530d.stderr +++ b/tests/reference/asr-kwargs_01_error-ab9530d.stderr @@ -3,3 +3,7 @@ semantic error: func01() got multiple values for argument 'a' | 11 | func01(arg1, a=int(8)) | ^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-kwargs_02_error-7c91f8f.json b/tests/reference/asr-kwargs_02_error-7c91f8f.json index 228d941171..3ea771dd85 100644 --- a/tests/reference/asr-kwargs_02_error-7c91f8f.json +++ b/tests/reference/asr-kwargs_02_error-7c91f8f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-kwargs_02_error-7c91f8f.stderr", - "stderr_hash": "120e6e6838e464af15ff96aa99dcdda21923a3bb5f0c3d6d7cc8348b", + "stderr_hash": "8f22215eb75e71e7d96316df25ebd521c049b99d5d2aa6dd002190bb", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-kwargs_02_error-7c91f8f.stderr b/tests/reference/asr-kwargs_02_error-7c91f8f.stderr index 9e13b4f43d..0cc30469a5 100644 --- a/tests/reference/asr-kwargs_02_error-7c91f8f.stderr +++ b/tests/reference/asr-kwargs_02_error-7c91f8f.stderr @@ -3,3 +3,7 @@ semantic error: func02() got multiple values for argument 'b' | 13 | func02(arg3, arg4, c=arg5, b=arg4) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-kwargs_03_error-a68cc46.json b/tests/reference/asr-kwargs_03_error-a68cc46.json index 2b3ac444fa..2481218ff4 100644 --- a/tests/reference/asr-kwargs_03_error-a68cc46.json +++ b/tests/reference/asr-kwargs_03_error-a68cc46.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-kwargs_03_error-a68cc46.stderr", - "stderr_hash": "83b858c0d4e17fe2f03b1e47652414c4478d709def5d3fbaa71aad71", + "stderr_hash": "561db20270f66b4c16ea6f48d37074b7b9c28b2066fe7b16e01de2f5", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-kwargs_03_error-a68cc46.stderr b/tests/reference/asr-kwargs_03_error-a68cc46.stderr index 1a811894e0..f10177c1d1 100644 --- a/tests/reference/asr-kwargs_03_error-a68cc46.stderr +++ b/tests/reference/asr-kwargs_03_error-a68cc46.stderr @@ -3,3 +3,7 @@ semantic error: Function func01 doesn't have an argument named 'd' | 11 | func01(arg1, d=int(8)) | ^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-lambda_01-1ec3e01.json b/tests/reference/asr-lambda_01-1ec3e01.json index 31b51267b2..8a6131f63f 100644 --- a/tests/reference/asr-lambda_01-1ec3e01.json +++ b/tests/reference/asr-lambda_01-1ec3e01.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-lambda_01-1ec3e01.stderr", - "stderr_hash": "99ca916bd82540da6812ad3149c0026c812efdbc777dbb5fb465e868", + "stderr_hash": "975faa45b76a2b037f8a1ef5447cab7c66cb91c372264c9e659d1b1b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-lambda_01-1ec3e01.stderr b/tests/reference/asr-lambda_01-1ec3e01.stderr index 482e01b32e..6c30feadd7 100644 --- a/tests/reference/asr-lambda_01-1ec3e01.stderr +++ b/tests/reference/asr-lambda_01-1ec3e01.stderr @@ -3,3 +3,7 @@ semantic error: The number of args to lambda function much match the number of a | 5 | x: Callable[[i32, i32, i32], i32] = lambda p, q, r, s: p + q + r + s | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-list1-770ba33.json b/tests/reference/asr-list1-770ba33.json index 9a3720e721..d8d5a2c116 100644 --- a/tests/reference/asr-list1-770ba33.json +++ b/tests/reference/asr-list1-770ba33.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-list1-770ba33.stdout", - "stdout_hash": "6b6e9737c184719a7d269490a7fcdfe22f3c1e69d34e20502528f1ac", + "stdout_hash": "dc3a2d020a65ea5e96f79b7d8f375f038fd58db7476c9ae8945a6f0a", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-list1-770ba33.stdout b/tests/reference/asr-list1-770ba33.stdout index 5042167566..69504140d4 100644 --- a/tests/reference/asr-list1-770ba33.stdout +++ b/tests/reference/asr-list1-770ba33.stdout @@ -158,7 +158,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -170,7 +170,7 @@ ) () ) - (= + (Assignment (Var 3 a) (ListConstant [(IntegerUnaryMinus @@ -194,7 +194,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ListConstant [(StringConstant @@ -215,7 +215,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ListConstant [(ListConstant @@ -242,7 +242,7 @@ ) () ) - (= + (Assignment (Var 3 d) (ListItem (Var 3 a) @@ -252,7 +252,7 @@ ) () ) - (= + (Assignment (Var 3 e) (ListConstant [(ListConstant @@ -306,7 +306,7 @@ (IntegerConstant 2 (Integer 4)) (IntegerConstant 13 (Integer 4)) ) - (= + (Assignment (Var 3 a) (ListSection (Var 3 a) @@ -320,9 +320,9 @@ ) () ) - (= + (Assignment (Var 3 d) - (IntrinsicScalarFunction + (IntrinsicElementalFunction ListPop [(Var 3 a)] 0 @@ -331,9 +331,9 @@ ) () ) - (= + (Assignment (Var 3 d) - (IntrinsicScalarFunction + (IntrinsicElementalFunction ListPop [(Var 3 a) (IntegerConstant 2 (Integer 4))] @@ -343,7 +343,7 @@ ) () ) - (= + (Assignment (Var 3 a) (ListConcat (Var 3 a) @@ -361,7 +361,7 @@ ) () ) - (= + (Assignment (Var 3 a) (ListConcat (ListConstant @@ -379,7 +379,7 @@ ) () ) - (= + (Assignment (Var 3 a11) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -390,7 +390,7 @@ ) () ) - (= + (Assignment (Var 3 b11) (ListConstant [(IntegerConstant 3 (Integer 4)) diff --git a/tests/reference/asr-loop1-10d3109.json b/tests/reference/asr-loop1-10d3109.json index fb3b22f4fc..97921cd58f 100644 --- a/tests/reference/asr-loop1-10d3109.json +++ b/tests/reference/asr-loop1-10d3109.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-loop1-10d3109.stdout", - "stdout_hash": "35644e13c81c285ced8a8c6c659d9b0ca0f28979414090e71a5a10b3", + "stdout_hash": "47d9a15a1f8dc76c5ed5dcb2b417d7b574d766eb2f1611f33e20d17c", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-loop1-10d3109.stdout b/tests/reference/asr-loop1-10d3109.stdout index 6ca065b60f..5656399eb4 100644 --- a/tests/reference/asr-loop1-10d3109.stdout +++ b/tests/reference/asr-loop1-10d3109.stdout @@ -100,7 +100,7 @@ test_factorial_2 test_factorial_3] [] - [(= + [(Assignment (Var 6 i) (FunctionCall 2 test_factorial_1 @@ -112,7 +112,7 @@ ) () ) - (= + (Assignment (Var 6 i) (FunctionCall 2 test_factorial_2 @@ -124,7 +124,7 @@ ) () ) - (= + (Assignment (Var 6 j) (FunctionCall 2 test_factorial_3 @@ -221,7 +221,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 3 _lpython_return_variable) (IntegerConstant 0 (Integer 4)) () @@ -229,7 +229,7 @@ (Return)] [] ) - (= + (Assignment (Var 3 result) (IntegerConstant 1 (Integer 4)) () @@ -243,7 +243,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 3 result) (IntegerBinOp (Var 3 result) @@ -254,7 +254,7 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerBinOp (Var 3 x) @@ -267,7 +267,7 @@ )] [] ) - (= + (Assignment (Var 3 _lpython_return_variable) (Var 3 result) () @@ -366,7 +366,7 @@ ) [] [(Var 4 x)] - [(= + [(Assignment (Var 4 result) (IntegerConstant 1 (Integer 4)) () @@ -389,7 +389,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 4 result) (IntegerBinOp (Var 4 result) @@ -402,7 +402,7 @@ )] [] ) - (= + (Assignment (Var 4 _lpython_return_variable) (Var 4 result) () @@ -485,7 +485,7 @@ ) [] [(Var 5 x)] - [(= + [(Assignment (Var 5 result) (Cast (IntegerConstant 0 (Integer 4)) @@ -503,7 +503,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 5 _lpython_return_variable) (Var 5 result) () @@ -511,7 +511,7 @@ (Return)] [] ) - (= + (Assignment (Var 5 result) (Cast (IntegerConstant 1 (Integer 4)) @@ -530,7 +530,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 5 result) (IntegerBinOp (Var 5 result) @@ -546,7 +546,7 @@ ) () ) - (= + (Assignment (Var 5 x) (IntegerBinOp (Var 5 x) @@ -559,7 +559,7 @@ )] [] ) - (= + (Assignment (Var 5 _lpython_return_variable) (Var 5 result) () diff --git a/tests/reference/asr-loop3-a579196.json b/tests/reference/asr-loop3-a579196.json index f97f2f7797..fa0e5972c6 100644 --- a/tests/reference/asr-loop3-a579196.json +++ b/tests/reference/asr-loop3-a579196.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-loop3-a579196.stdout", - "stdout_hash": "33a2b0834fe0ddc68aafecd408b03d67520d2c694a91dd3a3dca6190", + "stdout_hash": "15bb8e784ee7d3f408f358dd4a2ad83f3c47a20bd4eea63e3e6a5a0a", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-loop3-a579196.stdout b/tests/reference/asr-loop3-a579196.stdout index a3461b5206..1b93eba0d1 100644 --- a/tests/reference/asr-loop3-a579196.stdout +++ b/tests/reference/asr-loop3-a579196.stdout @@ -46,7 +46,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 1 (Integer 4)) () diff --git a/tests/reference/asr-loop_01-e7aa06a.json b/tests/reference/asr-loop_01-e7aa06a.json index 943ce68e64..e7de49253f 100644 --- a/tests/reference/asr-loop_01-e7aa06a.json +++ b/tests/reference/asr-loop_01-e7aa06a.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-loop_01-e7aa06a.stderr", - "stderr_hash": "256fe74af3480ca97b87c1b6f770cee10753e5f097d5a2d79135e736", + "stderr_hash": "f3f662b249a6120f972d246d17d4d23641d86864550fdc9aca18815b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-loop_01-e7aa06a.stderr b/tests/reference/asr-loop_01-e7aa06a.stderr index 1b50246d4c..2a69e33162 100644 --- a/tests/reference/asr-loop_01-e7aa06a.stderr +++ b/tests/reference/asr-loop_01-e7aa06a.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in loop start and loop end values, the types must | 5 | for i in range(15, i16(-1), i16(-1)): | ^^ ^^^^^^^ type mismatch ('i32' and 'i16') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-loop_02-5741651.json b/tests/reference/asr-loop_02-5741651.json index 236ad8ba7a..9a0ecca15c 100644 --- a/tests/reference/asr-loop_02-5741651.json +++ b/tests/reference/asr-loop_02-5741651.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-loop_02-5741651.stderr", - "stderr_hash": "a8262496250102a77a9e5718d40aaf1067fb21a18fb047885aa643ac", + "stderr_hash": "fa26965e35820f3b13c07269468e892edf68a711e17c6bafb61a726a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-loop_02-5741651.stderr b/tests/reference/asr-loop_02-5741651.stderr index c9198f2d37..d4f622b890 100644 --- a/tests/reference/asr-loop_02-5741651.stderr +++ b/tests/reference/asr-loop_02-5741651.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in loop start and increment values, the types must | 5 | for i in range(i16(15), i16(-1), -1): | ^^^^^^^ ^^ type mismatch ('i16' and 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-loop_03-401ab45.json b/tests/reference/asr-loop_03-401ab45.json index 16313f16a7..9a78c9e431 100644 --- a/tests/reference/asr-loop_03-401ab45.json +++ b/tests/reference/asr-loop_03-401ab45.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-loop_03-401ab45.stderr", - "stderr_hash": "cc8945240941626554f3ebeecadc96aa4ee6ea80415352dfefce2786", + "stderr_hash": "59d41371ca01bf32c55d25b659c2c8c03947ef8396a96c4c560b9adb", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-loop_03-401ab45.stderr b/tests/reference/asr-loop_03-401ab45.stderr index f558b6c0fd..d6109b0da7 100644 --- a/tests/reference/asr-loop_03-401ab45.stderr +++ b/tests/reference/asr-loop_03-401ab45.stderr @@ -3,3 +3,7 @@ semantic error: Assignment to loop variable `i` is not allowed | 5 | i=i*10 | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-modules_02-ec92e6f.json b/tests/reference/asr-modules_02-ec92e6f.json index 7f73e0678e..8dc35369ec 100644 --- a/tests/reference/asr-modules_02-ec92e6f.json +++ b/tests/reference/asr-modules_02-ec92e6f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-modules_02-ec92e6f.stdout", - "stdout_hash": "35bf9a870b019da27c8c167a499308ae83dba6d9a51c35bebd9aefaf", + "stdout_hash": "afb76ea5fdee50af45a64fe9f7b66dd677bf908b4bed08f726437c1e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-modules_02-ec92e6f.stdout b/tests/reference/asr-modules_02-ec92e6f.stdout index 8efe4339a5..1f682f4f69 100644 --- a/tests/reference/asr-modules_02-ec92e6f.stdout +++ b/tests/reference/asr-modules_02-ec92e6f.stdout @@ -92,7 +92,7 @@ ) [] [] - [(= + [(Assignment (Var 7 x) (IntegerBinOp (IntegerBinOp diff --git a/tests/reference/asr-print_02-afbe092.json b/tests/reference/asr-print_02-afbe092.json index 207c4c7b19..63ff5c7a45 100644 --- a/tests/reference/asr-print_02-afbe092.json +++ b/tests/reference/asr-print_02-afbe092.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-print_02-afbe092.stdout", - "stdout_hash": "87f67f9b4e20e6e73e94cde1e8aa1ac14b2fbfc76dcd539df67d0773", + "stdout_hash": "aae72d26d7d806d7eb476839446f61b55c761da89f69493682c7cd6a", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-print_02-afbe092.stdout b/tests/reference/asr-print_02-afbe092.stdout index 5fdb7de6f9..9e4cb58631 100644 --- a/tests/reference/asr-print_02-afbe092.stdout +++ b/tests/reference/asr-print_02-afbe092.stdout @@ -195,7 +195,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (ListConstant [(StringConstant @@ -216,7 +216,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -229,7 +229,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ListConstant [(RealConstant @@ -258,7 +258,7 @@ ) () ) - (= + (Assignment (Var 3 d) (ListConstant [] @@ -493,7 +493,7 @@ ) [] [] - [(= + [(Assignment (Var 4 w) (ListConstant [(ListConstant @@ -582,7 +582,7 @@ ) () ) - (= + (Assignment (Var 4 x) (ListConstant [(ListConstant @@ -669,7 +669,7 @@ ) () ) - (= + (Assignment (Var 4 y) (ListConstant [(ListConstant @@ -720,7 +720,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ListConstant [(ListConstant @@ -893,7 +893,7 @@ ) [] [] - [(= + [(Assignment (Var 6 p) (ListConstant [(ListConstant @@ -1054,7 +1054,7 @@ ) () ) - (= + (Assignment (Var 6 q) (ListConstant [(ListConstant @@ -1877,7 +1877,7 @@ ) () ) - (= + (Assignment (Var 6 r) (ListConstant [(ListConstant @@ -2698,7 +2698,7 @@ ) [] [] - [(= + [(Assignment (Var 5 a) (ListConstant [(TupleConstant @@ -2734,7 +2734,7 @@ ) () ) - (= + (Assignment (Var 5 c) (ListConstant [(ListConstant @@ -2808,7 +2808,7 @@ ) () ) - (= + (Assignment (Var 5 b1) (ListConstant [(StringConstant @@ -2837,7 +2837,7 @@ ) () ) - (= + (Assignment (Var 5 b2) (ListConstant [(IntegerConstant 10 (Integer 4)) @@ -2850,7 +2850,7 @@ ) () ) - (= + (Assignment (Var 5 b) (TupleConstant [(Var 5 b1) diff --git a/tests/reference/asr-print_list_tuple_03-9de3736.json b/tests/reference/asr-print_list_tuple_03-9de3736.json index 6b3a0197dd..857cf48d38 100644 --- a/tests/reference/asr-print_list_tuple_03-9de3736.json +++ b/tests/reference/asr-print_list_tuple_03-9de3736.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-print_list_tuple_03-9de3736.stdout", - "stdout_hash": "8b0ea951eb9a50ad8f74f09e19c152ab04ce401b7f0a4d00a7b4da65", + "stdout_hash": "8962f3d49727ceb8f899acc2382f5fb6d24b16506a154ccf907400f5", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-print_list_tuple_03-9de3736.stdout b/tests/reference/asr-print_list_tuple_03-9de3736.stdout index 5facd0d100..9e0bc45dec 100644 --- a/tests/reference/asr-print_list_tuple_03-9de3736.stdout +++ b/tests/reference/asr-print_list_tuple_03-9de3736.stdout @@ -109,7 +109,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (DictConstant [(IntegerConstant 1 (Integer 4)) @@ -140,7 +140,7 @@ ) () ) - (= + (Assignment (Var 3 y) (DictConstant [(IntegerConstant 1 (Integer 4)) diff --git a/tests/reference/asr-set1-b7b913a.json b/tests/reference/asr-set1-b7b913a.json index 3f8600d01f..5b961f2c31 100644 --- a/tests/reference/asr-set1-b7b913a.json +++ b/tests/reference/asr-set1-b7b913a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-set1-b7b913a.stdout", - "stdout_hash": "5cedd001b9359adb6bbe66fb49cbbcdb2b13fbc5eae198660c91a996", + "stdout_hash": "009ae3f3b27fd70cd770e43b62bbda6ac19a03082785cba865c3a8da", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-set1-b7b913a.stdout b/tests/reference/asr-set1-b7b913a.stdout index ed54f5debe..6df9463f93 100644 --- a/tests/reference/asr-set1-b7b913a.stdout +++ b/tests/reference/asr-set1-b7b913a.stdout @@ -82,7 +82,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (SetConstant [(IntegerConstant 1 (Integer 4)) @@ -94,7 +94,7 @@ ) () ) - (= + (Assignment (Var 3 a) (SetConstant [(IntegerConstant 2 (Integer 4)) @@ -109,7 +109,7 @@ () ) (Expr - (IntrinsicScalarFunction + (IntrinsicElementalFunction SetAdd [(Var 3 a) (IntegerConstant 9 (Integer 4))] @@ -119,7 +119,7 @@ ) ) (Expr - (IntrinsicScalarFunction + (IntrinsicElementalFunction SetRemove [(Var 3 a) (IntegerConstant 4 (Integer 4))] @@ -128,7 +128,7 @@ () ) ) - (= + (Assignment (Var 3 b) (SetConstant [(StringConstant @@ -149,7 +149,7 @@ ) () ) - (= + (Assignment (Var 3 s) (SetPop (Var 3 b) diff --git a/tests/reference/asr-string_01-78629c4.json b/tests/reference/asr-string_01-78629c4.json index 8cf78f4a79..31cadebb74 100644 --- a/tests/reference/asr-string_01-78629c4.json +++ b/tests/reference/asr-string_01-78629c4.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-string_01-78629c4.stderr", - "stderr_hash": "29aa01d7370a20ada91bdb13c569434f36a0c18309700d946d89fbf0", + "stderr_hash": "e90b6ecc58069e72ce474308537876fb35c88942113141e361ca78ed", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-string_01-78629c4.stderr b/tests/reference/asr-string_01-78629c4.stderr index 4abe3b2eb9..0db273975b 100644 --- a/tests/reference/asr-string_01-78629c4.stderr +++ b/tests/reference/asr-string_01-78629c4.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in index, expected a single integer or slice | 3 | print(x[2, 5]) | ^^^^ type mismatch (found: 'tuple[i32, i32]', expected: 'i32' or slice) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-string_02-499c9ff.json b/tests/reference/asr-string_02-499c9ff.json index ac33dbbf21..6e4936389f 100644 --- a/tests/reference/asr-string_02-499c9ff.json +++ b/tests/reference/asr-string_02-499c9ff.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-string_02-499c9ff.stderr", - "stderr_hash": "368ba74a1e0d6609f71e6f87f95bd0b6151420c81336e48a172cb613", + "stderr_hash": "a00a7d55c016fde4cac60339fd9e8ea14d7b2049ab26366b699dfee7", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-string_02-499c9ff.stderr b/tests/reference/asr-string_02-499c9ff.stderr index 196515476b..f1ca9b7a19 100644 --- a/tests/reference/asr-string_02-499c9ff.stderr +++ b/tests/reference/asr-string_02-499c9ff.stderr @@ -3,3 +3,7 @@ semantic error: str.join() takes type list only | 6 | res:str = x.join(p) | ^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_01-0893e35.json b/tests/reference/asr-structs_01-0893e35.json index b415cd4e5b..1bb3df20bc 100644 --- a/tests/reference/asr-structs_01-0893e35.json +++ b/tests/reference/asr-structs_01-0893e35.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_01-0893e35.stderr", - "stderr_hash": "6f58b337cbc9cb1832e2ecba47fdad4b64e4484b913e29f61c64dbea", + "stderr_hash": "a9e672c827ab451b501313e0b9cdd756a2be77bb1d074c27c4f13e10", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_01-0893e35.stderr b/tests/reference/asr-structs_01-0893e35.stderr index 12892d04eb..be8c5853e6 100644 --- a/tests/reference/asr-structs_01-0893e35.stderr +++ b/tests/reference/asr-structs_01-0893e35.stderr @@ -3,3 +3,7 @@ semantic error: Alignment 5 is not a positive power of 2. | 3 | @packed(aligned=5) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_01-66dc2c9.json b/tests/reference/asr-structs_01-66dc2c9.json index d82e944dc9..ab164948f8 100644 --- a/tests/reference/asr-structs_01-66dc2c9.json +++ b/tests/reference/asr-structs_01-66dc2c9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_01-66dc2c9.stdout", - "stdout_hash": "7996e199fb4e186baf6f87ea3e596a417bcc23ab748eaffa82c89a65", + "stdout_hash": "5a32fdd6e6d78976f4d3effbdf4ab79c614eb664a4fd92967ff5d7d7", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_01-66dc2c9.stdout b/tests/reference/asr-structs_01-66dc2c9.stdout index f93e577681..afebbfd171 100644 --- a/tests/reference/asr-structs_01-66dc2c9.stdout +++ b/tests/reference/asr-structs_01-66dc2c9.stdout @@ -135,7 +135,7 @@ ) [] [] - [(= + [(Assignment (Var 4 s) (StructTypeConstructor 2 S diff --git a/tests/reference/asr-structs_01-be14d49.json b/tests/reference/asr-structs_01-be14d49.json index 1a875592ca..f149ce9e6e 100644 --- a/tests/reference/asr-structs_01-be14d49.json +++ b/tests/reference/asr-structs_01-be14d49.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_01-be14d49.stdout", - "stdout_hash": "fcb3f3d4edc5f2bc5699c29c299c6188a0feab3f4d4663cc4811f873", + "stdout_hash": "6ff17e00a05b231e19396a82ff1a25538d74f39f4df7ccc44abf592c", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_01-be14d49.stdout b/tests/reference/asr-structs_01-be14d49.stdout index aca7141b12..e96c8d99c9 100644 --- a/tests/reference/asr-structs_01-be14d49.stdout +++ b/tests/reference/asr-structs_01-be14d49.stdout @@ -137,7 +137,7 @@ ) [] [(Var 5 a)] - [(= + [(Assignment (StructInstanceMember (Var 5 a) 3 x @@ -158,7 +158,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 5 a) 3 y @@ -304,7 +304,7 @@ [f change_struct] [] - [(= + [(Assignment (Var 6 x) (StructTypeConstructor 2 A @@ -372,7 +372,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 6 x) 3 x @@ -382,7 +382,7 @@ (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (Var 6 x) 3 y diff --git a/tests/reference/asr-structs_02-2ab459a.json b/tests/reference/asr-structs_02-2ab459a.json index bda3203614..298b5bc8a2 100644 --- a/tests/reference/asr-structs_02-2ab459a.json +++ b/tests/reference/asr-structs_02-2ab459a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_02-2ab459a.stdout", - "stdout_hash": "c21d603fb9e1adaa604b93748b074de1c3a37232656a66bf0159427f", + "stdout_hash": "cc9088a5c112c3dd9820ddfb3695cc301e46d853c4f4634fcdb457b6", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_02-2ab459a.stdout b/tests/reference/asr-structs_02-2ab459a.stdout index ad58cd38c9..00933ce63c 100644 --- a/tests/reference/asr-structs_02-2ab459a.stdout +++ b/tests/reference/asr-structs_02-2ab459a.stdout @@ -203,7 +203,7 @@ ) [] [(Var 4 a)] - [(= + [(Assignment (Var 4 a1) (StructTypeConstructor 2 A @@ -227,7 +227,7 @@ ) () ) - (= + (Assignment (Var 4 a2) (GetPointer (Var 4 a1) @@ -254,7 +254,7 @@ () () ) - (= + (Assignment (Var 4 x) (StructInstanceMember (Var 4 a2) @@ -264,7 +264,7 @@ ) () ) - (= + (Assignment (Var 4 y) (StructInstanceMember (Var 4 a2) @@ -347,7 +347,7 @@ ) [f] [] - [(= + [(Assignment (Var 5 b) (PointerNullConstant (CPtr) diff --git a/tests/reference/asr-structs_02-f95782c.json b/tests/reference/asr-structs_02-f95782c.json index c7ea7537c1..7ba6a456f9 100644 --- a/tests/reference/asr-structs_02-f95782c.json +++ b/tests/reference/asr-structs_02-f95782c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_02-f95782c.stderr", - "stderr_hash": "832411f3c9770493283e58b9017703a7d1cd178f42a19da6f8a38571", + "stderr_hash": "23dae0ded4440f61a29fbe60fe03b6ecd04a5fe040965121c58bc521", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_02-f95782c.stderr b/tests/reference/asr-structs_02-f95782c.stderr index e087537e57..828fe60c65 100644 --- a/tests/reference/asr-structs_02-f95782c.stderr +++ b/tests/reference/asr-structs_02-f95782c.stderr @@ -3,3 +3,7 @@ semantic error: `s` must be initialized with an instance of struct S | 8 | s: S | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_03-0cef911.json b/tests/reference/asr-structs_03-0cef911.json index 05df161242..4cff33ed98 100644 --- a/tests/reference/asr-structs_03-0cef911.json +++ b/tests/reference/asr-structs_03-0cef911.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_03-0cef911.stdout", - "stdout_hash": "741fc2b3ec3fd31cba6225af186bd835d5f7d2450868a43835658af7", + "stdout_hash": "86f4e5e4f8a98068919cc24f5e1add31777cbf511dcc6164587c58e3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_03-0cef911.stdout b/tests/reference/asr-structs_03-0cef911.stdout index 94e82fd0a2..5f268f4dde 100644 --- a/tests/reference/asr-structs_03-0cef911.stdout +++ b/tests/reference/asr-structs_03-0cef911.stdout @@ -228,7 +228,7 @@ ) [f] [] - [(= + [(Assignment (Var 5 x) (StructTypeConstructor 2 A @@ -252,7 +252,7 @@ ) () ) - (= + (Assignment (Var 5 xp) (GetPointer (Var 5 x) @@ -303,7 +303,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 5 xp) 3 x @@ -313,7 +313,7 @@ (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (Var 5 xp) 3 y diff --git a/tests/reference/asr-structs_03-754fb64.json b/tests/reference/asr-structs_03-754fb64.json index 7050595260..6977ea00ba 100644 --- a/tests/reference/asr-structs_03-754fb64.json +++ b/tests/reference/asr-structs_03-754fb64.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_03-754fb64.stderr", - "stderr_hash": "c6410f9948863d922cb0a0cd36613c529ad45fdf556d393d36e2df07", + "stderr_hash": "04c922b8860a6cb7a09ee1856898b0e41a509f183970c8fe32d36d3e", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_03-754fb64.stderr b/tests/reference/asr-structs_03-754fb64.stderr index 2a1c1c0d91..0b92ddf3f9 100644 --- a/tests/reference/asr-structs_03-754fb64.stderr +++ b/tests/reference/asr-structs_03-754fb64.stderr @@ -3,3 +3,7 @@ semantic error: Member 'y' not found in struct | 8 | s: S = S(y=2) | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_04-387747b.json b/tests/reference/asr-structs_04-387747b.json index 4a9aaf341a..d0f8cbec18 100644 --- a/tests/reference/asr-structs_04-387747b.json +++ b/tests/reference/asr-structs_04-387747b.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_04-387747b.stdout", - "stdout_hash": "86f2c6449a554bd2357cacda5835425b816e406a81ec89f1d82a30e5", + "stdout_hash": "27f6a0c804ed3cea5368c4bec54cb4ea35c60215f354d0d91bc24e89", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_04-387747b.stdout b/tests/reference/asr-structs_04-387747b.stdout index 7ec23ff0c5..32225f2ccf 100644 --- a/tests/reference/asr-structs_04-387747b.stdout +++ b/tests/reference/asr-structs_04-387747b.stdout @@ -395,7 +395,7 @@ ) [f] [] - [(= + [(Assignment (Var 6 a1) (StructTypeConstructor 2 A @@ -419,7 +419,7 @@ ) () ) - (= + (Assignment (Var 6 a2) (StructTypeConstructor 2 A @@ -443,7 +443,7 @@ ) () ) - (= + (Assignment (Var 6 b) (StructTypeConstructor 2 B @@ -456,7 +456,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 6 b) 4 a @@ -468,7 +468,7 @@ (Var 6 a2) () ) - (= + (Assignment (StructInstanceMember (Var 6 b) 4 z @@ -478,7 +478,7 @@ (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (StructInstanceMember (Var 6 b) @@ -495,7 +495,7 @@ (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (StructInstanceMember (Var 6 b) diff --git a/tests/reference/asr-structs_04-7b864bc.json b/tests/reference/asr-structs_04-7b864bc.json index c188040d2f..c27c14dd54 100644 --- a/tests/reference/asr-structs_04-7b864bc.json +++ b/tests/reference/asr-structs_04-7b864bc.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_04-7b864bc.stderr", - "stderr_hash": "e4e04a1a30ae38b6587c4c3ad12a7e83839c63938c025a3884f62ef8", + "stderr_hash": "4c41571acfa90c551ece87ea4f5bb429349152d0202131c9b82030b1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_04-7b864bc.stderr b/tests/reference/asr-structs_04-7b864bc.stderr index 906b24c606..7fb9e7da35 100644 --- a/tests/reference/asr-structs_04-7b864bc.stderr +++ b/tests/reference/asr-structs_04-7b864bc.stderr @@ -3,3 +3,7 @@ semantic error: S() got multiple values for argument 'x' | 9 | s: S = S(24, x=2) | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_05-fa98307.json b/tests/reference/asr-structs_05-fa98307.json index 28944bba0c..fe7aafaf65 100644 --- a/tests/reference/asr-structs_05-fa98307.json +++ b/tests/reference/asr-structs_05-fa98307.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_05-fa98307.stdout", - "stdout_hash": "f689989b64e70f48af2d09ed0fb1ac3a77050b462d8352ea1f3be08d", + "stdout_hash": "8fcc8e26dba2931043ce6b565fcd1f4a4c0d829a095cdae05b4ea020", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_05-fa98307.stdout b/tests/reference/asr-structs_05-fa98307.stdout index 115c6cf479..89e491d295 100644 --- a/tests/reference/asr-structs_05-fa98307.stdout +++ b/tests/reference/asr-structs_05-fa98307.stdout @@ -232,9 +232,9 @@ update_1 update_2] [] - [(= + [(Assignment (Var 224 y) - (ArrayConstant + (ArrayConstructor [] (Array (Struct @@ -244,11 +244,12 @@ (IntegerConstant 2 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 224 y) [(() @@ -308,7 +309,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 224 y) [(() @@ -510,7 +511,7 @@ ) [] [(Var 222 s)] - [(= + [(Assignment (StructInstanceMember (Var 222 s) 220 x @@ -520,7 +521,7 @@ (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (Var 222 s) 220 y @@ -533,7 +534,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 222 s) 220 z @@ -548,7 +549,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 222 s) 220 a @@ -569,7 +570,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 222 s) 220 b @@ -584,7 +585,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (Var 222 s) 220 c @@ -658,7 +659,7 @@ ) [] [(Var 223 s)] - [(= + [(Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -678,7 +679,7 @@ (IntegerConstant 3 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -701,7 +702,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -726,7 +727,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -757,7 +758,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -782,7 +783,7 @@ ) () ) - (= + (Assignment (StructInstanceMember (ArrayItem (Var 223 s) @@ -990,7 +991,7 @@ (Var 221 y1) (Var 221 x2) (Var 221 y2)] - [(= + [(Assignment (Var 221 eps) (RealConstant 0.000000 @@ -998,7 +999,7 @@ ) () ) - (= + (Assignment (Var 221 s0) (ArrayItem (Var 221 s) @@ -1076,7 +1077,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (StructInstanceMember @@ -1123,7 +1124,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (StructInstanceMember @@ -1213,7 +1214,7 @@ ) () ) - (= + (Assignment (Var 221 s1) (ArrayItem (Var 221 s) @@ -1291,7 +1292,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (StructInstanceMember @@ -1338,7 +1339,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (StructInstanceMember diff --git a/tests/reference/asr-structs_06-6e14537.json b/tests/reference/asr-structs_06-6e14537.json index 7ef7f9dd33..edbdbad484 100644 --- a/tests/reference/asr-structs_06-6e14537.json +++ b/tests/reference/asr-structs_06-6e14537.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_06-6e14537.stderr", - "stderr_hash": "8e0da9c7e84854ce3d6ad79066a9fbb33d82c9fcde3af2a7baeccec8", + "stderr_hash": "1d764cdfc025b24c7e7342924495482196a5e4f701d28728f1e1eb35", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_06-6e14537.stderr b/tests/reference/asr-structs_06-6e14537.stderr index 55d07bfb5e..a1206f141f 100644 --- a/tests/reference/asr-structs_06-6e14537.stderr +++ b/tests/reference/asr-structs_06-6e14537.stderr @@ -3,3 +3,7 @@ semantic error: Struct constructor has more arguments than the number of struct | 9 | s: S = S(2, 3, 4, 5) | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_07-83694b7.json b/tests/reference/asr-structs_07-83694b7.json index 4c07fec19b..c07086dc83 100644 --- a/tests/reference/asr-structs_07-83694b7.json +++ b/tests/reference/asr-structs_07-83694b7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_07-83694b7.stderr", - "stderr_hash": "6b1e1646f11ee384e5dce1ded0d91751f7113eaea7c90da5c1bcf4ff", + "stderr_hash": "59ef2a71632cb112caad8ad64fb801d7ccd8110afa903a4b8e4e231c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_07-83694b7.stderr b/tests/reference/asr-structs_07-83694b7.stderr index 13f0aaf0e1..97f6a0607b 100644 --- a/tests/reference/asr-structs_07-83694b7.stderr +++ b/tests/reference/asr-structs_07-83694b7.stderr @@ -3,3 +3,7 @@ semantic error: Not enough arguments to S(), expected 2 | 9 | s: S = S(y=2) | ^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_08-fa4dbf0.json b/tests/reference/asr-structs_08-fa4dbf0.json index 8f133e95a8..24caa33a12 100644 --- a/tests/reference/asr-structs_08-fa4dbf0.json +++ b/tests/reference/asr-structs_08-fa4dbf0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_08-fa4dbf0.stderr", - "stderr_hash": "cf488d893463c941c43080cebb56591bd17c5bed4cb7acd97353d59a", + "stderr_hash": "a3f0e2bbd04c07f91b68586eed010d51e42443a819b9a25a3a949bbe", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_08-fa4dbf0.stderr b/tests/reference/asr-structs_08-fa4dbf0.stderr index 89af7c314c..be6aea6b15 100644 --- a/tests/reference/asr-structs_08-fa4dbf0.stderr +++ b/tests/reference/asr-structs_08-fa4dbf0.stderr @@ -3,3 +3,7 @@ semantic error: Struct constructor has more arguments than the number of struct | 13 | test_dude3 : StringIO = StringIO(integer_asr, 3, 5, 2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_09-f3ffe08.json b/tests/reference/asr-structs_09-f3ffe08.json index 0af164202d..d5702a74c6 100644 --- a/tests/reference/asr-structs_09-f3ffe08.json +++ b/tests/reference/asr-structs_09-f3ffe08.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_09-f3ffe08.stderr", - "stderr_hash": "f59ab2d213f6423e0a891e43d5a19e83d4405391b1c7bf481b4b939e", + "stderr_hash": "295600c377d777d38b373e302e4a35f5bf19fc7f3ce4690039f10926", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_09-f3ffe08.stderr b/tests/reference/asr-structs_09-f3ffe08.stderr index c7265fdddc..6fc14bbed2 100644 --- a/tests/reference/asr-structs_09-f3ffe08.stderr +++ b/tests/reference/asr-structs_09-f3ffe08.stderr @@ -3,3 +3,7 @@ semantic error: read not present in StringIO dataclass | 13 | bytes_read: i32 = fd.read() | ^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_10-cb8a283.json b/tests/reference/asr-structs_10-cb8a283.json index 6420f7ba94..437839060e 100644 --- a/tests/reference/asr-structs_10-cb8a283.json +++ b/tests/reference/asr-structs_10-cb8a283.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-structs_10-cb8a283.stderr", - "stderr_hash": "2b88127fdbc0c9e3798569cdfa4ef5745d6fce6aeba8fc3f6a1ace9f", + "stderr_hash": "91cddc6a1a589cf46c8fcf65ce9a894fb13906b7000246220b8e73af", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-structs_10-cb8a283.stderr b/tests/reference/asr-structs_10-cb8a283.stderr index 757e06a54e..57d9a031d1 100644 --- a/tests/reference/asr-structs_10-cb8a283.stderr +++ b/tests/reference/asr-structs_10-cb8a283.stderr @@ -7,3 +7,7 @@ semantic error: Struct member functions are not supported | 8 | print(self._len) | ...^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-structs_16-44de89a.json b/tests/reference/asr-structs_16-44de89a.json index 76232fcc54..2710b9ad8a 100644 --- a/tests/reference/asr-structs_16-44de89a.json +++ b/tests/reference/asr-structs_16-44de89a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-structs_16-44de89a.stdout", - "stdout_hash": "9ebf9426938d92178b3a8fdca450859753b0299d3b2b8cb48272469e", + "stdout_hash": "65cfcaf1a3de5bfe7720be9983c0a9ad22d877701f1375eead4ca4b1", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-structs_16-44de89a.stdout b/tests/reference/asr-structs_16-44de89a.stdout index 3e13df611d..b98dbfb8e1 100644 --- a/tests/reference/asr-structs_16-44de89a.stdout +++ b/tests/reference/asr-structs_16-44de89a.stdout @@ -213,7 +213,7 @@ ) [] [] - [(= + [(Assignment (Var 5 bd) (UnionTypeConstructor 5 A_B @@ -225,7 +225,7 @@ ) () ) - (= + (Assignment (UnionInstanceMember (Var 5 bd) 4 x @@ -235,7 +235,7 @@ (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 5 ad) (StructTypeConstructor 2 A diff --git a/tests/reference/asr-subscript1-1acfc19.json b/tests/reference/asr-subscript1-1acfc19.json index acbacd1973..ccd3be8d22 100644 --- a/tests/reference/asr-subscript1-1acfc19.json +++ b/tests/reference/asr-subscript1-1acfc19.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-subscript1-1acfc19.stdout", - "stdout_hash": "cf02a18790b0e93084fa3adbaebdf78297064cc0575c946d00584151", + "stdout_hash": "d7a92e2923edaafb9061c1a2c2739ed3f2b8eaa5bd8bcd8a52e42aec", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-subscript1-1acfc19.stdout b/tests/reference/asr-subscript1-1acfc19.stdout index 9b615dffe7..5dd12f0952 100644 --- a/tests/reference/asr-subscript1-1acfc19.stdout +++ b/tests/reference/asr-subscript1-1acfc19.stdout @@ -104,7 +104,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringConstant "abc" @@ -112,7 +112,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringItem (Var 3 s) @@ -128,7 +128,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -140,7 +140,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -152,7 +152,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -168,7 +168,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -180,7 +180,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -192,7 +192,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -208,7 +208,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -224,7 +224,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -248,7 +248,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringSection (Var 3 s) @@ -260,7 +260,7 @@ ) () ) - (= + (Assignment (Var 3 i) (ArrayItem (Var 3 A) @@ -273,7 +273,7 @@ ) () ) - (= + (Assignment (Var 3 B) (ArraySection (Var 3 A) @@ -290,7 +290,7 @@ ) () ) - (= + (Assignment (Var 3 B) (ArraySection (Var 3 A) diff --git a/tests/reference/asr-test_annassign_01-2f18669.json b/tests/reference/asr-test_annassign_01-2f18669.json index d300379c58..40a31f4745 100644 --- a/tests/reference/asr-test_annassign_01-2f18669.json +++ b/tests/reference/asr-test_annassign_01-2f18669.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_annassign_01-2f18669.stderr", - "stderr_hash": "28c68e6612db1644548768280ac3d35d3735a13cd32c04da44cec570", + "stderr_hash": "1718f84520d91c3fd07fc20164cdc027f1f0a0beeeb2eb034225b7fa", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_annassign_01-2f18669.stderr b/tests/reference/asr-test_annassign_01-2f18669.stderr index 0f08b0d244..bf5f7e1633 100644 --- a/tests/reference/asr-test_annassign_01-2f18669.stderr +++ b/tests/reference/asr-test_annassign_01-2f18669.stderr @@ -3,3 +3,7 @@ semantic error: The type 'Optional' is undeclared. | 2 | a: Optional[i32] = 5 | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_annassign_02-accf6db.json b/tests/reference/asr-test_annassign_02-accf6db.json index 6f7c773278..ddb726d073 100644 --- a/tests/reference/asr-test_annassign_02-accf6db.json +++ b/tests/reference/asr-test_annassign_02-accf6db.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_annassign_02-accf6db.stderr", - "stderr_hash": "1183fbf06e8412166eb5ca96b5b07cec67382752789a96c7c04c1950", + "stderr_hash": "ec335ab50f2f7d0392f13af981bfa42f115e4d9408ab8f06d178e000", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_annassign_02-accf6db.stderr b/tests/reference/asr-test_annassign_02-accf6db.stderr index 90945d34b2..3b5deec24d 100644 --- a/tests/reference/asr-test_annassign_02-accf6db.stderr +++ b/tests/reference/asr-test_annassign_02-accf6db.stderr @@ -3,3 +3,7 @@ semantic error: The type 'Pattern' is undeclared. | 2 | hex_pat : Pattern[str] = r'-?0[xX]+' | ^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_annassign_03-f8c6160.json b/tests/reference/asr-test_annassign_03-f8c6160.json index 43585bc3b4..610e778f21 100644 --- a/tests/reference/asr-test_annassign_03-f8c6160.json +++ b/tests/reference/asr-test_annassign_03-f8c6160.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_annassign_03-f8c6160.stderr", - "stderr_hash": "e87d692cc8404a7e66f41d61635f318e20003991138c3db5a0794884", + "stderr_hash": "90d7421450d9b2250a207a64611593df83c2cb1f42abcd68f2f7a28c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_annassign_03-f8c6160.stderr b/tests/reference/asr-test_annassign_03-f8c6160.stderr index 5a89637eb4..76023fa60a 100644 --- a/tests/reference/asr-test_annassign_03-f8c6160.stderr +++ b/tests/reference/asr-test_annassign_03-f8c6160.stderr @@ -3,3 +3,7 @@ semantic error: Intent annotation 'InOut' cannot be used here | 6 | lexer : InOut[LasrLexer] = LasrLexer(5) | ^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_annassign_type_mismatch-7dac7be.json b/tests/reference/asr-test_annassign_type_mismatch-7dac7be.json index b9527150ed..cc394fccd0 100644 --- a/tests/reference/asr-test_annassign_type_mismatch-7dac7be.json +++ b/tests/reference/asr-test_annassign_type_mismatch-7dac7be.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_annassign_type_mismatch-7dac7be.stderr", - "stderr_hash": "26fc89f95c7dda5f1d9c3cb1af9843880cf693eb7b97125372b11f80", + "stderr_hash": "20447c2ea0541e4706c08811f5ad94788e26d2309c58dd9d7be68c5b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_annassign_type_mismatch-7dac7be.stderr b/tests/reference/asr-test_annassign_type_mismatch-7dac7be.stderr index 6fd7b199ea..252510e101 100644 --- a/tests/reference/asr-test_annassign_type_mismatch-7dac7be.stderr +++ b/tests/reference/asr-test_annassign_type_mismatch-7dac7be.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 4 | x: i32[4] = [1, 2, 3, 4] | ^ ^^^^^^^^^^^^ type mismatch ('i32[4]' and 'list[i32]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.json b/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.json index 2bb48c32dd..a29980e845 100644 --- a/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.json +++ b/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_annassign_type_mismatch2-fc883f7.stderr", - "stderr_hash": "873b4521e2155bc92405db41e7745a4fb5441b5d80f94467d7b1b637", + "stderr_hash": "23ef251532ca65740ff7f9930ac70a8d55e3b5d71583d9fb50a484c2", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.stderr b/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.stderr index 2a4f9ccd10..f1b6e8549b 100644 --- a/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.stderr +++ b/tests/reference/asr-test_annassign_type_mismatch2-fc883f7.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 4 | x: f64[5] = [1.0, 2.0, 3.0, 4.0, 5.0] | ^ ^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch ('f64[5]' and 'list[f64]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_append_type_mismatch-030e9c7.json b/tests/reference/asr-test_append_type_mismatch-030e9c7.json index e2edd78183..189cd7175a 100644 --- a/tests/reference/asr-test_append_type_mismatch-030e9c7.json +++ b/tests/reference/asr-test_append_type_mismatch-030e9c7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_append_type_mismatch-030e9c7.stderr", - "stderr_hash": "6610c87a3c164e9cc8884eaf66397658c311199814689ebd4793c92a", + "stderr_hash": "072890a1cc0bd9d287a934f9cee15f632adb8d9e6a21dc7a6de5e083", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_append_type_mismatch-030e9c7.stderr b/tests/reference/asr-test_append_type_mismatch-030e9c7.stderr index a860db8a46..efe8389a3a 100644 --- a/tests/reference/asr-test_append_type_mismatch-030e9c7.stderr +++ b/tests/reference/asr-test_append_type_mismatch-030e9c7.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in 'append', the types must be compatible | 6 | l.append('a') | ^^^ type mismatch (found: 'str', expected: 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign1-a94d41e.json b/tests/reference/asr-test_assign1-a94d41e.json index 35e6aa7403..955b092944 100644 --- a/tests/reference/asr-test_assign1-a94d41e.json +++ b/tests/reference/asr-test_assign1-a94d41e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign1-a94d41e.stderr", - "stderr_hash": "cb4455d360373e13730d3a9fd5e2c551bd0f6640d066ceafd8841f9b", + "stderr_hash": "2d24538a064229771d963639ad8d83a0cd87a9e1bf778e01514c467b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign1-a94d41e.stderr b/tests/reference/asr-test_assign1-a94d41e.stderr index abd1f376fa..b76048ad51 100644 --- a/tests/reference/asr-test_assign1-a94d41e.stderr +++ b/tests/reference/asr-test_assign1-a94d41e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 6 | a = b | ^ ^ type mismatch ('list[i32]' and 'list[str]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign2-fa29029.json b/tests/reference/asr-test_assign2-fa29029.json index 4603aee52e..c76a07d9d0 100644 --- a/tests/reference/asr-test_assign2-fa29029.json +++ b/tests/reference/asr-test_assign2-fa29029.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign2-fa29029.stderr", - "stderr_hash": "55f02e505bda066604eb94cec8bdc5081c7ec25e219f0ea46851100a", + "stderr_hash": "54fd3e0d2fc60992a9ed6f562befc2c84f67c56e7f28e530e0222940", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign2-fa29029.stderr b/tests/reference/asr-test_assign2-fa29029.stderr index 6a0fbd1522..6eed153c3c 100644 --- a/tests/reference/asr-test_assign2-fa29029.stderr +++ b/tests/reference/asr-test_assign2-fa29029.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 6 | a = b | ^ ^ type mismatch ('set[i32]' and 'set[str]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign3-cc6fc9d.json b/tests/reference/asr-test_assign3-cc6fc9d.json index 5db5f77a33..a4666b1589 100644 --- a/tests/reference/asr-test_assign3-cc6fc9d.json +++ b/tests/reference/asr-test_assign3-cc6fc9d.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign3-cc6fc9d.stderr", - "stderr_hash": "cff7850ce5507a70e7c730dd1ff23d16f8839dedac07d5b60a73a8b8", + "stderr_hash": "e7f1e8c61e1b449b1768543944d6d584c809a4344c859a124c16e6e2", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign3-cc6fc9d.stderr b/tests/reference/asr-test_assign3-cc6fc9d.stderr index abec0f4c51..586f7b0007 100644 --- a/tests/reference/asr-test_assign3-cc6fc9d.stderr +++ b/tests/reference/asr-test_assign3-cc6fc9d.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 6 | a = b | ^ ^ type mismatch ('list[i32]' and 'set[i32]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign4-a2136e0.json b/tests/reference/asr-test_assign4-a2136e0.json index e09dfa9249..0d5114193b 100644 --- a/tests/reference/asr-test_assign4-a2136e0.json +++ b/tests/reference/asr-test_assign4-a2136e0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign4-a2136e0.stderr", - "stderr_hash": "a871819fb4bd2139f16a7407208ea210276e5b12c9f13ae442132483", + "stderr_hash": "396ec086f73ff4e58f5a4817d4d25af3f17ba6f8daaed687ddba51ca", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign4-a2136e0.stderr b/tests/reference/asr-test_assign4-a2136e0.stderr index 43d32d2933..7423fbe056 100644 --- a/tests/reference/asr-test_assign4-a2136e0.stderr +++ b/tests/reference/asr-test_assign4-a2136e0.stderr @@ -3,3 +3,7 @@ semantic error: Assigning integer to float is not supported | 7 | f = x | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign5-694a98f.json b/tests/reference/asr-test_assign5-694a98f.json index 312c85ffed..1fafd72632 100644 --- a/tests/reference/asr-test_assign5-694a98f.json +++ b/tests/reference/asr-test_assign5-694a98f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign5-694a98f.stderr", - "stderr_hash": "172b2f13e9b7670cbdd718452713fb15ed4bcd19f6193d328e459fbe", + "stderr_hash": "29c2388315bcc4ce0815c7236615f9454b040871b3c7f17181f0ce29", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign5-694a98f.stderr b/tests/reference/asr-test_assign5-694a98f.stderr index 0847cb828c..fb465f3661 100644 --- a/tests/reference/asr-test_assign5-694a98f.stderr +++ b/tests/reference/asr-test_assign5-694a98f.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 6 | x = y | ^ ^ type mismatch ('list[list[i32]]' and 'list[list[str]]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign6-05cd64f.json b/tests/reference/asr-test_assign6-05cd64f.json index 4bab9d7802..5018a9010c 100644 --- a/tests/reference/asr-test_assign6-05cd64f.json +++ b/tests/reference/asr-test_assign6-05cd64f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign6-05cd64f.stderr", - "stderr_hash": "5bc5e0f7454a31bb924cf1318c59e73da2446502181b92faffd9f5d4", + "stderr_hash": "42abe9caaa035ece3f78bb8a09ce0f2af93c46d22fd653f8a1a08d97", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign6-05cd64f.stderr b/tests/reference/asr-test_assign6-05cd64f.stderr index 3eb1a1d84e..2ae5132775 100644 --- a/tests/reference/asr-test_assign6-05cd64f.stderr +++ b/tests/reference/asr-test_assign6-05cd64f.stderr @@ -3,3 +3,7 @@ semantic error: 'str' object does not support item assignment | 4 | s[0] = 'f' | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign7-beebac3.json b/tests/reference/asr-test_assign7-beebac3.json index e5197e2be8..a47c2a3f01 100644 --- a/tests/reference/asr-test_assign7-beebac3.json +++ b/tests/reference/asr-test_assign7-beebac3.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign7-beebac3.stderr", - "stderr_hash": "109f7da7ac86c0c2add0ff034655336396cb58ebe81570c1d0ce6e81", + "stderr_hash": "d2eeea63021bd9a1db711d5f3c55596ea267f0eaa3f41e4dd0be5b60", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign7-beebac3.stderr b/tests/reference/asr-test_assign7-beebac3.stderr index 87c04ca904..c5536c977f 100644 --- a/tests/reference/asr-test_assign7-beebac3.stderr +++ b/tests/reference/asr-test_assign7-beebac3.stderr @@ -3,3 +3,7 @@ semantic error: 'tuple[i32, i32]' object does not support item assignment | 4 | t[0] = 3 | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign8-4b26e63.json b/tests/reference/asr-test_assign8-4b26e63.json index fb449632d9..f8c61fdf9d 100644 --- a/tests/reference/asr-test_assign8-4b26e63.json +++ b/tests/reference/asr-test_assign8-4b26e63.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign8-4b26e63.stderr", - "stderr_hash": "c8ad8a6c89a23c0e2bd0cbaf7c9568625f093e526ff8ff26ae300e07", + "stderr_hash": "5c161085c4dbb01bb13bf31904286d202d059c13538224710c36eb64", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign8-4b26e63.stderr b/tests/reference/asr-test_assign8-4b26e63.stderr index dcb47d9356..6ad3da66ff 100644 --- a/tests/reference/asr-test_assign8-4b26e63.stderr +++ b/tests/reference/asr-test_assign8-4b26e63.stderr @@ -3,3 +3,7 @@ semantic error: readonly attribute | 6 | c.real = 5.0 | ^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_assign9-51278b8.json b/tests/reference/asr-test_assign9-51278b8.json index 2f05c4e5e5..14cc45e03b 100644 --- a/tests/reference/asr-test_assign9-51278b8.json +++ b/tests/reference/asr-test_assign9-51278b8.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_assign9-51278b8.stderr", - "stderr_hash": "602e4fa615e929bad9586849d2a5167741930e56db6373cdca3695d0", + "stderr_hash": "10087e66c7772cea82b88b0d91c3d0ebf868d0a496daf0ae4cba4f42", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_assign9-51278b8.stderr b/tests/reference/asr-test_assign9-51278b8.stderr index f3c3e9716a..fc095c6c41 100644 --- a/tests/reference/asr-test_assign9-51278b8.stderr +++ b/tests/reference/asr-test_assign9-51278b8.stderr @@ -3,3 +3,7 @@ semantic error: Assignment to an input function parameter `x` is not allowed | 2 | x = 2 | ^ Hint: create a new local variable with a different name + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_async-361297c.json b/tests/reference/asr-test_async-361297c.json index 4477cbad49..ec6eda63d4 100644 --- a/tests/reference/asr-test_async-361297c.json +++ b/tests/reference/asr-test_async-361297c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_async-361297c.stderr", - "stderr_hash": "abf614594f89a7a6d93d469d512e31de5adc64feef866957de80cd03", + "stderr_hash": "ae75ca7088e02f7f07053d3f249ef0461aa5be03444696bd3afad4be", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_async-361297c.stderr b/tests/reference/asr-test_async-361297c.stderr index c24b2174ae..4c9b502985 100644 --- a/tests/reference/asr-test_async-361297c.stderr +++ b/tests/reference/asr-test_async-361297c.stderr @@ -7,3 +7,7 @@ semantic error: The `async` keyword is currently not supported | 2 | print("done") | ...^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_binop1-50b63f6.json b/tests/reference/asr-test_binop1-50b63f6.json index 343aa48bf2..f031e0a0a9 100644 --- a/tests/reference/asr-test_binop1-50b63f6.json +++ b/tests/reference/asr-test_binop1-50b63f6.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_binop1-50b63f6.stderr", - "stderr_hash": "6883d11d4de52f03fa684252229715e39aa52c830d186f787159faaa", + "stderr_hash": "179bd3156d35b9620ab1d611cb6f9b9ba7a2e1732365a68f9cfeacc7", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_binop1-50b63f6.stderr b/tests/reference/asr-test_binop1-50b63f6.stderr index 67e6ee1aa1..85d3bec5bf 100644 --- a/tests/reference/asr-test_binop1-50b63f6.stderr +++ b/tests/reference/asr-test_binop1-50b63f6.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in binary operator; the types must be compatible | 6 | print(x+s) | ^ ^ type mismatch (i32 and str) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_binop2-e5749af.json b/tests/reference/asr-test_binop2-e5749af.json index 8de84da8ec..85e95662d8 100644 --- a/tests/reference/asr-test_binop2-e5749af.json +++ b/tests/reference/asr-test_binop2-e5749af.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_binop2-e5749af.stderr", - "stderr_hash": "3214693e7c1f71d8343f547e7a3ab0167b4f9310540009475d2f1c79", + "stderr_hash": "afd4494a9e1f0f2958e68f751a8bc70adf89b47729032c2dcd6a1bf8", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_binop2-e5749af.stderr b/tests/reference/asr-test_binop2-e5749af.stderr index fe0d054eee..6d34ed6d90 100644 --- a/tests/reference/asr-test_binop2-e5749af.stderr +++ b/tests/reference/asr-test_binop2-e5749af.stderr @@ -3,3 +3,7 @@ semantic error: Division is not supported for string type | 6 | print(a/b) | ^ ^ string not supported in division + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_binop3-a67201d.json b/tests/reference/asr-test_binop3-a67201d.json index dc238a62cb..a160bc4ef8 100644 --- a/tests/reference/asr-test_binop3-a67201d.json +++ b/tests/reference/asr-test_binop3-a67201d.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_binop3-a67201d.stderr", - "stderr_hash": "ff683b1bc0695903f2d2ea7bbd1963346fcb5f84bbfd10a4da0e27d7", + "stderr_hash": "0a9565ce5ba341309a0ea2a81b1eed455a4043ee6c824c1465fc3df1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_binop3-a67201d.stderr b/tests/reference/asr-test_binop3-a67201d.stderr index 84e374e2f5..68f11ab9dd 100644 --- a/tests/reference/asr-test_binop3-a67201d.stderr +++ b/tests/reference/asr-test_binop3-a67201d.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in binary operator; the types must be compatible | 5 | y = complex(5)+100 | ^^^^^^^^^^ ^^^ type mismatch (c32 and i32) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_bit_length-da3a264.json b/tests/reference/asr-test_bit_length-da3a264.json index 56a237ac34..b151e00bd0 100644 --- a/tests/reference/asr-test_bit_length-da3a264.json +++ b/tests/reference/asr-test_bit_length-da3a264.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_bit_length-da3a264.stderr", - "stderr_hash": "0f371300055a9e3f6c01f73b1e276d9ae8007fd507eb0c75e1bda3ef", + "stderr_hash": "588be2ebf4b260ff90313b58763bcb37eceab1d0e9cae576851f7182", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_bit_length-da3a264.stderr b/tests/reference/asr-test_bit_length-da3a264.stderr index 5820f4cd21..7285aa5d00 100644 --- a/tests/reference/asr-test_bit_length-da3a264.stderr +++ b/tests/reference/asr-test_bit_length-da3a264.stderr @@ -3,3 +3,7 @@ semantic error: int.bit_length() takes no arguments | 4 | print(x.bit_length(23)) | ^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_bitwise_on_complex-dd9568b.json b/tests/reference/asr-test_bitwise_on_complex-dd9568b.json index 7fa9b4be57..b5355e0747 100644 --- a/tests/reference/asr-test_bitwise_on_complex-dd9568b.json +++ b/tests/reference/asr-test_bitwise_on_complex-dd9568b.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_bitwise_on_complex-dd9568b.stderr", - "stderr_hash": "58f7acb7f7187308d38c7c97fcd9e34b2022c42be1b6583b95b379af", + "stderr_hash": "964507f47d281484f82f8772ea1ea03c6a0c8d34f0799df86cbbdabe", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_bitwise_on_complex-dd9568b.stderr b/tests/reference/asr-test_bitwise_on_complex-dd9568b.stderr index 7bb1052707..8bc5b402d5 100644 --- a/tests/reference/asr-test_bitwise_on_complex-dd9568b.stderr +++ b/tests/reference/asr-test_bitwise_on_complex-dd9568b.stderr @@ -3,3 +3,7 @@ semantic error: Unsupported binary operation on complex: '|' | 8 | print(c1 | c2) | ^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_bitwise_on_float-2e09b30.json b/tests/reference/asr-test_bitwise_on_float-2e09b30.json index df6b412bad..b9e62ed162 100644 --- a/tests/reference/asr-test_bitwise_on_float-2e09b30.json +++ b/tests/reference/asr-test_bitwise_on_float-2e09b30.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_bitwise_on_float-2e09b30.stderr", - "stderr_hash": "1e77fcf2484ec7c10436c14ac2a498db59706d30d3c294b89b6b9090", + "stderr_hash": "bfd9481140ad60fba6aef69dd04bb1e832e0bafaea1041eaa9b91f84", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_bitwise_on_float-2e09b30.stderr b/tests/reference/asr-test_bitwise_on_float-2e09b30.stderr index d6733722d6..75d5f3149c 100644 --- a/tests/reference/asr-test_bitwise_on_float-2e09b30.stderr +++ b/tests/reference/asr-test_bitwise_on_float-2e09b30.stderr @@ -3,3 +3,7 @@ semantic error: Unsupported binary operation on floats: '<<' | 8 | print(f1 << f2) | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_bool_binop-f856ef0.json b/tests/reference/asr-test_bool_binop-f856ef0.json index b74825e8d7..f8ed655e50 100644 --- a/tests/reference/asr-test_bool_binop-f856ef0.json +++ b/tests/reference/asr-test_bool_binop-f856ef0.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_bool_binop-f856ef0.stdout", - "stdout_hash": "b2d6b1205576cabc7c44ae611eec55ba5af026dbd918972e05e8f7da", + "stdout_hash": "e49cfc7503cc6ab45724e70ede9f036526df9e1e3ac010e6bc484e69", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_bool_binop-f856ef0.stdout b/tests/reference/asr-test_bool_binop-f856ef0.stdout index f93267c185..1492774f2b 100644 --- a/tests/reference/asr-test_bool_binop-f856ef0.stdout +++ b/tests/reference/asr-test_bool_binop-f856ef0.stdout @@ -130,7 +130,7 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerBinOp (Cast @@ -167,7 +167,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerBinOp (Cast @@ -204,7 +204,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerBinOp (Cast @@ -241,10 +241,10 @@ ) () ) - (= + (Assignment (Var 3 i) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(LogicalConstant .true. @@ -277,10 +277,10 @@ ) () ) - (= + (Assignment (Var 3 i) (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(LogicalConstant .false. @@ -313,7 +313,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerBinOp (Cast @@ -350,7 +350,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (LogicalConstant .false. @@ -358,7 +358,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (LogicalConstant .true. @@ -366,7 +366,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealBinOp (Cast diff --git a/tests/reference/asr-test_builtin-aa64615.json b/tests/reference/asr-test_builtin-aa64615.json index 045b711861..c25457bb57 100644 --- a/tests/reference/asr-test_builtin-aa64615.json +++ b/tests/reference/asr-test_builtin-aa64615.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin-aa64615.stdout", - "stdout_hash": "ff6e31c59ee1a4e5c58817bda1a3a152593770a5269929c552fd2d6d", + "stdout_hash": "3e43ed1fbc6e4954aa998229650787bdf543f6a6a071f93e89dbdef2", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin-aa64615.stdout b/tests/reference/asr-test_builtin-aa64615.stdout index fa9b720f48..33998796ff 100644 --- a/tests/reference/asr-test_builtin-aa64615.stdout +++ b/tests/reference/asr-test_builtin-aa64615.stdout @@ -208,22 +208,22 @@ ) [] [] - [(= + [(Assignment (Var 5 p) (IntegerConstant 97 (Integer 4)) () ) - (= + (Assignment (Var 5 q) (IntegerConstant 112 (Integer 4)) () ) - (= + (Assignment (Var 5 r) (IntegerConstant 10 (Integer 4)) () ) - (= + (Assignment (Var 5 s) (IntegerConstant 65 (Integer 4)) () @@ -264,7 +264,7 @@ () () ) - (= + (Assignment (Var 5 a) (StringConstant "!" @@ -272,7 +272,7 @@ ) () ) - (= + (Assignment (Var 5 b) (StringConstant " " @@ -280,7 +280,7 @@ ) () ) - (= + (Assignment (Var 5 c) (StringConstant "Z" @@ -288,7 +288,7 @@ ) () ) - (= + (Assignment (Var 5 d) (StringConstant "g" @@ -585,12 +585,12 @@ ) [] [] - [(= + [(Assignment (Var 4 i) (IntegerConstant 33 (Integer 4)) () ) - (= + (Assignment (Var 4 exclamation) (StringChr (Var 4 i) @@ -635,12 +635,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 36 (Integer 4)) () ) - (= + (Assignment (Var 4 dollar) (StringChr (Var 4 i) @@ -685,12 +685,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 40 (Integer 4)) () ) - (= + (Assignment (Var 4 left_parenthesis) (StringChr (Var 4 i) @@ -735,12 +735,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 43 (Integer 4)) () ) - (= + (Assignment (Var 4 plus) (StringChr (Var 4 i) @@ -785,12 +785,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 48 (Integer 4)) () ) - (= + (Assignment (Var 4 zero) (StringChr (Var 4 i) @@ -835,12 +835,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 57 (Integer 4)) () ) - (= + (Assignment (Var 4 nine) (StringChr (Var 4 i) @@ -885,12 +885,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 59 (Integer 4)) () ) - (= + (Assignment (Var 4 semicolon) (StringChr (Var 4 i) @@ -935,12 +935,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 65 (Integer 4)) () ) - (= + (Assignment (Var 4 capital_a) (StringChr (Var 4 i) @@ -985,12 +985,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 90 (Integer 4)) () ) - (= + (Assignment (Var 4 capital_z) (StringChr (Var 4 i) @@ -1035,12 +1035,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 93 (Integer 4)) () ) - (= + (Assignment (Var 4 right_bracket) (StringChr (Var 4 i) @@ -1085,12 +1085,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 97 (Integer 4)) () ) - (= + (Assignment (Var 4 small_a) (StringChr (Var 4 i) @@ -1135,12 +1135,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 122 (Integer 4)) () ) - (= + (Assignment (Var 4 small_z) (StringChr (Var 4 i) @@ -1185,12 +1185,12 @@ ) () ) - (= + (Assignment (Var 4 i) (IntegerConstant 125 (Integer 4)) () ) - (= + (Assignment (Var 4 right_brace) (StringChr (Var 4 i) @@ -1488,7 +1488,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringConstant "!" @@ -1496,7 +1496,7 @@ ) () ) - (= + (Assignment (Var 3 exclamation_unicode) (StringOrd (Var 3 s) @@ -1535,7 +1535,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "$" @@ -1543,7 +1543,7 @@ ) () ) - (= + (Assignment (Var 3 dollar_unicode) (StringOrd (Var 3 s) @@ -1582,7 +1582,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "(" @@ -1590,7 +1590,7 @@ ) () ) - (= + (Assignment (Var 3 left_parenthesis_unicode) (StringOrd (Var 3 s) @@ -1629,7 +1629,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "+" @@ -1637,7 +1637,7 @@ ) () ) - (= + (Assignment (Var 3 plus_unicode) (StringOrd (Var 3 s) @@ -1676,7 +1676,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "0" @@ -1684,7 +1684,7 @@ ) () ) - (= + (Assignment (Var 3 zero_unicode) (StringOrd (Var 3 s) @@ -1723,7 +1723,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "9" @@ -1731,7 +1731,7 @@ ) () ) - (= + (Assignment (Var 3 nine_unicode) (StringOrd (Var 3 s) @@ -1770,7 +1770,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant ";" @@ -1778,7 +1778,7 @@ ) () ) - (= + (Assignment (Var 3 semicolon_unicode) (StringOrd (Var 3 s) @@ -1817,7 +1817,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "A" @@ -1825,7 +1825,7 @@ ) () ) - (= + (Assignment (Var 3 capital_a_unicode) (StringOrd (Var 3 s) @@ -1864,7 +1864,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "Z" @@ -1872,7 +1872,7 @@ ) () ) - (= + (Assignment (Var 3 capital_z_unicode) (StringOrd (Var 3 s) @@ -1911,7 +1911,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "]" @@ -1919,7 +1919,7 @@ ) () ) - (= + (Assignment (Var 3 right_bracket_unicode) (StringOrd (Var 3 s) @@ -1958,7 +1958,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "a" @@ -1966,7 +1966,7 @@ ) () ) - (= + (Assignment (Var 3 small_a_unicode) (StringOrd (Var 3 s) @@ -2005,7 +2005,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "z" @@ -2013,7 +2013,7 @@ ) () ) - (= + (Assignment (Var 3 small_z_unicode) (StringOrd (Var 3 s) @@ -2052,7 +2052,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "}" @@ -2060,7 +2060,7 @@ ) () ) - (= + (Assignment (Var 3 right_brace_unicode) (StringOrd (Var 3 s) diff --git a/tests/reference/asr-test_builtin_abs-c74d2c9.json b/tests/reference/asr-test_builtin_abs-c74d2c9.json index ce0899d23b..1a1a9753c8 100644 --- a/tests/reference/asr-test_builtin_abs-c74d2c9.json +++ b/tests/reference/asr-test_builtin_abs-c74d2c9.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_abs-c74d2c9.stdout", - "stdout_hash": "86d0821d3e240a6645d0f7778a81076160e627a1e8a61e4b2c9056b3", + "stdout_hash": "ee62300be1542cd9be250a10d8e904d206894fc6d9031c9d1752a2c4", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_abs-c74d2c9.stdout b/tests/reference/asr-test_builtin_abs-c74d2c9.stdout index 45fc58f6b9..4d2bd81d58 100644 --- a/tests/reference/asr-test_builtin_abs-c74d2c9.stdout +++ b/tests/reference/asr-test_builtin_abs-c74d2c9.stdout @@ -178,7 +178,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (RealConstant 5.500000 @@ -188,7 +188,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 x)] 0 @@ -205,7 +205,7 @@ ) () ) - (= + (Assignment (Var 3 x) (RealUnaryMinus (RealConstant @@ -222,7 +222,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 x)] 0 @@ -241,7 +241,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealConstant 5.500000 @@ -269,7 +269,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealUnaryMinus (RealConstant @@ -302,7 +302,7 @@ ) () ) - (= + (Assignment (Var 3 x2) (RealUnaryMinus (Cast @@ -327,7 +327,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 x2)] 0 @@ -352,7 +352,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 5 (Integer 4)) @@ -363,7 +363,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 i)] 0 @@ -379,7 +379,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerUnaryMinus (IntegerConstant 1 (Integer 4)) @@ -400,7 +400,7 @@ ) () ) - (= + (Assignment (Var 3 i2) (IntegerUnaryMinus (Cast @@ -416,7 +416,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 i2)] 0 @@ -435,7 +435,7 @@ ) () ) - (= + (Assignment (Var 3 i3) (IntegerUnaryMinus (Cast @@ -451,7 +451,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 i3)] 0 @@ -470,7 +470,7 @@ ) () ) - (= + (Assignment (Var 3 i4) (IntegerUnaryMinus (Cast @@ -486,7 +486,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 i4)] 0 @@ -505,7 +505,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .true. @@ -515,7 +515,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Cast (Var 3 b) @@ -534,7 +534,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .false. @@ -544,7 +544,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Cast (Var 3 b) diff --git a/tests/reference/asr-test_builtin_bin-52ba9fa.json b/tests/reference/asr-test_builtin_bin-52ba9fa.json index 80e844ac57..543f42e831 100644 --- a/tests/reference/asr-test_builtin_bin-52ba9fa.json +++ b/tests/reference/asr-test_builtin_bin-52ba9fa.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_bin-52ba9fa.stdout", - "stdout_hash": "be51d8466bb796401961ebaba18dc3274a4e107f1a9b2047778a16c0", + "stdout_hash": "0e232d24c751c39c76219b271d037fb44367b2019443abec83aec30e", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_bin-52ba9fa.stdout b/tests/reference/asr-test_builtin_bin-52ba9fa.stdout index 3e4a8a8c6d..8eb9d59653 100644 --- a/tests/reference/asr-test_builtin_bin-52ba9fa.stdout +++ b/tests/reference/asr-test_builtin_bin-52ba9fa.stdout @@ -92,7 +92,7 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerConstant 5 (Integer 4)) () @@ -117,7 +117,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerConstant 64 (Integer 4)) () @@ -142,7 +142,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 534 (Integer 4)) diff --git a/tests/reference/asr-test_builtin_bool-330223a.json b/tests/reference/asr-test_builtin_bool-330223a.json index 9cc04790f8..bd50f826e0 100644 --- a/tests/reference/asr-test_builtin_bool-330223a.json +++ b/tests/reference/asr-test_builtin_bool-330223a.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_bool-330223a.stdout", - "stdout_hash": "a3c583c97286a6bcd315d229b5beeb35dccf75adc147acb25a7ee3c9", + "stdout_hash": "4595de8f8735987408fc6ab8e2829186790e50baebba18fd9ced22d5", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_bool-330223a.stdout b/tests/reference/asr-test_builtin_bool-330223a.stdout index 3f23cd6288..75791f89e6 100644 --- a/tests/reference/asr-test_builtin_bool-330223a.stdout +++ b/tests/reference/asr-test_builtin_bool-330223a.stdout @@ -256,7 +256,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 34 (Integer 4)) () @@ -270,7 +270,7 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 0 (Integer 4)) () @@ -323,7 +323,7 @@ ) () ) - (= + (Assignment (Var 3 a2) (Cast (IntegerConstant 34 (Integer 4)) @@ -342,7 +342,7 @@ ) () ) - (= + (Assignment (Var 3 a3) (Cast (IntegerConstant 34 (Integer 4)) @@ -361,7 +361,7 @@ ) () ) - (= + (Assignment (Var 3 a4) (IntegerUnaryMinus (Cast @@ -384,7 +384,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 0.000000 @@ -405,7 +405,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 1.000000 @@ -459,7 +459,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (RealUnaryMinus (Cast @@ -491,7 +491,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (Cast (RealConstant @@ -516,7 +516,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "" @@ -537,7 +537,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "str" @@ -591,7 +591,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .true. @@ -603,7 +603,7 @@ (Var 3 b) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .false. @@ -640,7 +640,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (FunctionCall @@ -675,7 +675,7 @@ ) () ) - (= + (Assignment (Var 3 c) (Cast (FunctionCall @@ -756,7 +756,7 @@ ) () ) - (= + (Assignment (Var 3 c1) (FunctionCall 3 complex@__lpython_overloaded_13__complex diff --git a/tests/reference/asr-test_builtin_float-20601dd.json b/tests/reference/asr-test_builtin_float-20601dd.json index 7b0de8b9c0..b014b5a23a 100644 --- a/tests/reference/asr-test_builtin_float-20601dd.json +++ b/tests/reference/asr-test_builtin_float-20601dd.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_float-20601dd.stdout", - "stdout_hash": "30bd7a1456c6e4b74a7c6310f2c49c9593924e9728cdba8151b2c15a", + "stdout_hash": "6f0ea985e3f8854f200517d79baa5b8f8a75ce97a664b0de2233f557", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_float-20601dd.stdout b/tests/reference/asr-test_builtin_float-20601dd.stdout index cee0c2a04c..49aa8fc9c5 100644 --- a/tests/reference/asr-test_builtin_float-20601dd.stdout +++ b/tests/reference/asr-test_builtin_float-20601dd.stdout @@ -130,12 +130,12 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerConstant 34 (Integer 4)) () ) - (= + (Assignment (Var 3 f) (Cast (RealConstant @@ -212,7 +212,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 4235 (Integer 4)) @@ -431,7 +431,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .true. @@ -439,7 +439,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (Cast (Var 3 b) @@ -462,7 +462,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .false. diff --git a/tests/reference/asr-test_builtin_hex-64bd268.json b/tests/reference/asr-test_builtin_hex-64bd268.json index c3c0b91827..46c4fbebcc 100644 --- a/tests/reference/asr-test_builtin_hex-64bd268.json +++ b/tests/reference/asr-test_builtin_hex-64bd268.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_hex-64bd268.stdout", - "stdout_hash": "60b7a5942be2da46fb5e7ebec29e6f0e3c8a9fb01257e296ec4af9db", + "stdout_hash": "17e08baca9c4ff3b1dc27ddd873a94bea5a11392da51f50b7afac131", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_hex-64bd268.stdout b/tests/reference/asr-test_builtin_hex-64bd268.stdout index 22f1151820..af94490790 100644 --- a/tests/reference/asr-test_builtin_hex-64bd268.stdout +++ b/tests/reference/asr-test_builtin_hex-64bd268.stdout @@ -92,7 +92,7 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerConstant 34 (Integer 4)) () @@ -117,7 +117,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 4235 (Integer 4)) diff --git a/tests/reference/asr-test_builtin_int-8f88fdc.json b/tests/reference/asr-test_builtin_int-8f88fdc.json index 6a7855513a..8bde15855d 100644 --- a/tests/reference/asr-test_builtin_int-8f88fdc.json +++ b/tests/reference/asr-test_builtin_int-8f88fdc.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_int-8f88fdc.stdout", - "stdout_hash": "55a54609eea6ca7af35de1398a437d5ac78a396250ef1c52fe510b07", + "stdout_hash": "e3bd369c6e5beb4cb74a685058453f560a534b518a57d066010f7d11", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_int-8f88fdc.stdout b/tests/reference/asr-test_builtin_int-8f88fdc.stdout index 6239802ef9..6128a10e66 100644 --- a/tests/reference/asr-test_builtin_int-8f88fdc.stdout +++ b/tests/reference/asr-test_builtin_int-8f88fdc.stdout @@ -125,7 +125,7 @@ ) [] [] - [(= + [(Assignment (Var 4 b) (IntegerBinOp (Cast @@ -162,7 +162,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -199,7 +199,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -240,7 +240,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -277,7 +277,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -314,7 +314,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -351,7 +351,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -388,7 +388,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (Cast @@ -425,7 +425,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (IntegerBinOp @@ -495,7 +495,7 @@ ) () ) - (= + (Assignment (Var 4 b) (IntegerBinOp (IntegerBinOp @@ -651,7 +651,7 @@ ) [] [] - [(= + [(Assignment (Var 3 f) (RealConstant 5.678000 @@ -659,7 +659,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerConstant 4 (Integer 4)) () @@ -702,7 +702,7 @@ ) () ) - (= + (Assignment (Var 3 i2) (Cast (RealConstant @@ -776,7 +776,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealUnaryMinus (RealConstant diff --git a/tests/reference/asr-test_builtin_len-55b0dec.json b/tests/reference/asr-test_builtin_len-55b0dec.json index 62b9381b2e..fb11d4264b 100644 --- a/tests/reference/asr-test_builtin_len-55b0dec.json +++ b/tests/reference/asr-test_builtin_len-55b0dec.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_len-55b0dec.stdout", - "stdout_hash": "d40259d3cc79bda39299a6ee28fe96593637589eaefc2e565696f626", + "stdout_hash": "e3800dde0706bb5dc06f1c7e0bc748780d7af02bf76d28ee05cecfa3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_len-55b0dec.stdout b/tests/reference/asr-test_builtin_len-55b0dec.stdout index d9c725e174..e70ec43593 100644 --- a/tests/reference/asr-test_builtin_len-55b0dec.stdout +++ b/tests/reference/asr-test_builtin_len-55b0dec.stdout @@ -242,7 +242,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (StringConstant "abcd" @@ -264,7 +264,7 @@ ) () ) - (= + (Assignment (Var 3 s) (StringConstant "" @@ -326,7 +326,7 @@ ) () ) - (= + (Assignment (Var 3 l) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -353,7 +353,7 @@ ) () ) - (= + (Assignment (Var 3 l2) (ListConstant [(RealConstant @@ -396,7 +396,7 @@ ) () ) - (= + (Assignment (Var 3 l3) (ListConstant [] @@ -452,7 +452,7 @@ ) () ) - (= + (Assignment (Var 3 list_len) (ListLen (ListConstant @@ -483,7 +483,7 @@ ) () ) - (= + (Assignment (Var 3 t) (TupleConstant [(IntegerConstant 1 (Integer 4)) @@ -517,7 +517,7 @@ ) () ) - (= + (Assignment (Var 3 t2) (TupleConstant [(RealConstant @@ -564,7 +564,7 @@ ) () ) - (= + (Assignment (Var 3 t3) (TupleLen (TupleConstant @@ -596,7 +596,7 @@ ) () ) - (= + (Assignment (Var 3 tmp) (ListLen (Var 3 l) diff --git a/tests/reference/asr-test_builtin_oct-20b9066.json b/tests/reference/asr-test_builtin_oct-20b9066.json index bfe42d8697..6733a98ad7 100644 --- a/tests/reference/asr-test_builtin_oct-20b9066.json +++ b/tests/reference/asr-test_builtin_oct-20b9066.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_oct-20b9066.stdout", - "stdout_hash": "b523d67bd8d17c176afaa1ec7fe635059d5e87eb46369a7b464535e9", + "stdout_hash": "5b198d4f23fc77b239feb4ee72810430a3afd0705c71dad5ce4431fe", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_oct-20b9066.stdout b/tests/reference/asr-test_builtin_oct-20b9066.stdout index e3fd32959c..bb52e030f7 100644 --- a/tests/reference/asr-test_builtin_oct-20b9066.stdout +++ b/tests/reference/asr-test_builtin_oct-20b9066.stdout @@ -92,7 +92,7 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerConstant 34 (Integer 4)) () @@ -117,7 +117,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 4235 (Integer 4)) diff --git a/tests/reference/asr-test_builtin_pow-f02fcda.json b/tests/reference/asr-test_builtin_pow-f02fcda.json index 1fc183a638..04b1fdd149 100644 --- a/tests/reference/asr-test_builtin_pow-f02fcda.json +++ b/tests/reference/asr-test_builtin_pow-f02fcda.json @@ -6,8 +6,8 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_pow-f02fcda.stdout", - "stdout_hash": "0437ce1453ee48dd1664d03df14c9143e03b170f160664b0fa65fd51", + "stdout_hash": "f7419d8aa70e29f98f056a4ef4fbc09582e3b4fc452923f31d8a146c", "stderr": "asr-test_builtin_pow-f02fcda.stderr", - "stderr_hash": "859ce76c74748f2d32c7eab92cfbba789a78d4cbf5818646b99806ea", + "stderr_hash": "c6495babe2f9dc8ec8cdc1e8009ed03c4bca6316839caed43f198e7a", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_builtin_pow-f02fcda.stderr b/tests/reference/asr-test_builtin_pow-f02fcda.stderr index 5dbb75ad24..f43034705c 100644 --- a/tests/reference/asr-test_builtin_pow-f02fcda.stderr +++ b/tests/reference/asr-test_builtin_pow-f02fcda.stderr @@ -3,3 +3,7 @@ style suggestion: Could have used '**' instead of 'pow' | 11 | assert i32(pow(a, b)) == 32 | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_builtin_pow-f02fcda.stdout b/tests/reference/asr-test_builtin_pow-f02fcda.stdout index 4bf941256f..7bf4c53a58 100644 --- a/tests/reference/asr-test_builtin_pow-f02fcda.stdout +++ b/tests/reference/asr-test_builtin_pow-f02fcda.stdout @@ -504,7 +504,7 @@ ) [] [] - [(= + [(Assignment (Var 3 eps) (RealConstant 0.000000 @@ -512,12 +512,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerConstant 5 (Integer 4)) () @@ -545,12 +545,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 6 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerConstant 3 (Integer 4)) () @@ -578,12 +578,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerConstant 0 (Integer 4)) () @@ -611,12 +611,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerUnaryMinus (IntegerConstant 1 (Integer 4)) @@ -625,12 +625,12 @@ ) () ) - (= + (Assignment (Var 3 a) (IntegerConstant 6 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerUnaryMinus (IntegerConstant 4 (Integer 4)) @@ -639,7 +639,7 @@ ) () ) - (= + (Assignment (Var 3 i1) (Cast (IntegerConstant 2 (Integer 4)) @@ -649,7 +649,7 @@ ) () ) - (= + (Assignment (Var 3 i2) (Cast (IntegerConstant 5 (Integer 4)) @@ -687,7 +687,7 @@ ) () ) - (= + (Assignment (Var 3 i1) (Cast (IntegerConstant 6 (Integer 4)) @@ -697,7 +697,7 @@ ) () ) - (= + (Assignment (Var 3 i2) (IntegerUnaryMinus (Cast @@ -711,7 +711,7 @@ ) () ) - (= + (Assignment (Var 3 f1) (Cast (RealBinOp @@ -749,7 +749,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (Cast (RealConstant @@ -765,7 +765,7 @@ ) () ) - (= + (Assignment (Var 3 p) (FunctionCall 3 pow@__lpython_overloaded_2__pow @@ -778,7 +778,7 @@ ) () ) - (= + (Assignment (Var 3 f1) (FunctionCall 3 pow@__lpython_overloaded_4__pow @@ -791,7 +791,7 @@ ) () ) - (= + (Assignment (Var 3 f1) (FunctionCall 3 pow@__lpython_overloaded_5__pow @@ -804,7 +804,7 @@ ) () ) - (= + (Assignment (Var 3 b1) (LogicalConstant .true. @@ -812,7 +812,7 @@ ) () ) - (= + (Assignment (Var 3 b2) (LogicalConstant .false. @@ -901,7 +901,7 @@ ) () ) - (= + (Assignment (Var 3 a1) (RealConstant 4.500000 @@ -909,7 +909,7 @@ ) () ) - (= + (Assignment (Var 3 a2) (RealConstant 2.300000 @@ -919,7 +919,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -952,7 +952,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -983,12 +983,12 @@ ) () ) - (= + (Assignment (Var 3 x) (IntegerConstant 3 (Integer 4)) () ) - (= + (Assignment (Var 3 y) (RealConstant 2.300000 @@ -998,7 +998,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1031,7 +1031,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1064,7 +1064,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1100,7 +1100,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1156,7 +1156,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1212,7 +1212,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1272,7 +1272,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1328,7 +1328,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1376,7 +1376,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1424,7 +1424,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1479,7 +1479,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1524,7 +1524,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1576,7 +1576,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1621,7 +1621,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1695,7 +1695,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -1745,7 +1745,7 @@ ) () ) - (= + (Assignment (Var 3 i) (Cast (IntegerConstant 7 (Integer 4)) @@ -1755,7 +1755,7 @@ ) () ) - (= + (Assignment (Var 3 j) (Cast (IntegerConstant 2 (Integer 4)) @@ -1765,7 +1765,7 @@ ) () ) - (= + (Assignment (Var 3 k) (Cast (IntegerConstant 5 (Integer 4)) @@ -1824,7 +1824,7 @@ ) () ) - (= + (Assignment (Var 3 c1) (Cast (FunctionCall @@ -1850,7 +1850,7 @@ ) () ) - (= + (Assignment (Var 3 c1) (FunctionCall 3 pow@__lpython_overloaded_9__pow diff --git a/tests/reference/asr-test_builtin_round-7417a21.json b/tests/reference/asr-test_builtin_round-7417a21.json index d4e3e88078..f2e151a572 100644 --- a/tests/reference/asr-test_builtin_round-7417a21.json +++ b/tests/reference/asr-test_builtin_round-7417a21.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_round-7417a21.stdout", - "stdout_hash": "fd3cab85c4f2b8a2edc117191bab4eacb7a01184e9430730fa526b65", + "stdout_hash": "7de076823367bb7600448ad028dc18c7fd0b34c6b1ac951fda3c4e44", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_round-7417a21.stdout b/tests/reference/asr-test_builtin_round-7417a21.stdout index 344e7aca63..44dcb4e118 100644 --- a/tests/reference/asr-test_builtin_round-7417a21.stdout +++ b/tests/reference/asr-test_builtin_round-7417a21.stdout @@ -258,7 +258,7 @@ ) [] [] - [(= + [(Assignment (Var 3 f) (RealConstant 5.678000 @@ -283,7 +283,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealUnaryMinus (RealConstant @@ -319,7 +319,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 44.340000 @@ -344,7 +344,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 0.500000 @@ -369,7 +369,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealUnaryMinus (RealConstant @@ -405,7 +405,7 @@ ) () ) - (= + (Assignment (Var 3 f) (RealConstant 1.500000 @@ -609,7 +609,7 @@ ) () ) - (= + (Assignment (Var 3 f2) (Cast (RealConstant @@ -642,7 +642,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 5 (Integer 4)) @@ -692,7 +692,7 @@ ) () ) - (= + (Assignment (Var 3 i2) (Cast (IntegerConstant 7 (Integer 4)) @@ -724,7 +724,7 @@ ) () ) - (= + (Assignment (Var 3 i3) (Cast (IntegerUnaryMinus @@ -764,7 +764,7 @@ ) () ) - (= + (Assignment (Var 3 i4) (Cast (IntegerConstant 0 (Integer 4)) @@ -796,7 +796,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .true. @@ -821,7 +821,7 @@ ) () ) - (= + (Assignment (Var 3 b) (LogicalConstant .false. diff --git a/tests/reference/asr-test_builtin_str-580e920.json b/tests/reference/asr-test_builtin_str-580e920.json index 8f94593f26..9c87a89ef2 100644 --- a/tests/reference/asr-test_builtin_str-580e920.json +++ b/tests/reference/asr-test_builtin_str-580e920.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_builtin_str-580e920.stdout", - "stdout_hash": "ed50db5ad4282dc18715d2ad9c6e7a4d3d0a52e35b65e53e4981af3c", + "stdout_hash": "2a7e18b0fbf5d33795b7f729926a8fd750d433081a9998d526c7a1e3", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_builtin_str-580e920.stdout b/tests/reference/asr-test_builtin_str-580e920.stdout index a1988733e1..20458024b2 100644 --- a/tests/reference/asr-test_builtin_str-580e920.stdout +++ b/tests/reference/asr-test_builtin_str-580e920.stdout @@ -167,7 +167,7 @@ ) [] [] - [(= + [(Assignment (Var 4 x) (IntegerConstant 123 (Integer 4)) () @@ -190,7 +190,7 @@ ) () ) - (= + (Assignment (Var 4 x) (IntegerConstant 12345 (Integer 4)) () @@ -213,7 +213,7 @@ ) () ) - (= + (Assignment (Var 4 x) (IntegerUnaryMinus (IntegerConstant 12 (Integer 4)) @@ -240,7 +240,7 @@ ) () ) - (= + (Assignment (Var 4 x) (IntegerUnaryMinus (IntegerConstant 121212 (Integer 4)) @@ -267,7 +267,7 @@ ) () ) - (= + (Assignment (Var 4 xx) (Cast (RealConstant @@ -301,7 +301,7 @@ ) () ) - (= + (Assignment (Var 4 yy) (RealConstant 12.322234 @@ -327,7 +327,7 @@ ) () ) - (= + (Assignment (Var 4 bool_t) (LogicalConstant .true. @@ -353,7 +353,7 @@ ) () ) - (= + (Assignment (Var 4 bool_t) (LogicalConstant .false. @@ -379,7 +379,7 @@ ) () ) - (= + (Assignment (Var 4 str_t) (StringConstant "just a str" @@ -522,7 +522,7 @@ ) [] [] - [(= + [(Assignment (Var 6 s) (StringConstant "abcde" @@ -530,7 +530,7 @@ ) () ) - (= + (Assignment (Var 6 d) (StringConstant "edcba" @@ -538,12 +538,12 @@ ) () ) - (= + (Assignment (Var 6 i) (IntegerConstant 0 (Integer 4)) () ) - (= + (Assignment (Var 6 __tmp_assign_for_loop) (StringSection (Var 6 s) @@ -575,7 +575,7 @@ () ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 6 c) (StringItem (Var 6 __tmp_assign_for_loop) @@ -617,7 +617,7 @@ ) () ) - (= + (Assignment (Var 6 i) (IntegerBinOp (Var 6 i) @@ -675,7 +675,7 @@ ) [] [] - [(= + [(Assignment (Var 3 s) (Cast (IntegerConstant 356 (Integer 4)) @@ -701,7 +701,7 @@ ) () ) - (= + (Assignment (Var 3 s) (Cast (IntegerUnaryMinus @@ -1018,7 +1018,7 @@ ) [] [] - [(= + [(Assignment (Var 5 s) (StringConstant "abcdefghijk" @@ -1026,17 +1026,17 @@ ) () ) - (= + (Assignment (Var 5 start) (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 5 end) (IntegerConstant 4 (Integer 4)) () ) - (= + (Assignment (Var 5 step) (IntegerConstant 1 (Integer 4)) () diff --git a/tests/reference/asr-test_c_interop_01-e374f43.json b/tests/reference/asr-test_c_interop_01-e374f43.json index a35f2d0c2b..719c79eb57 100644 --- a/tests/reference/asr-test_c_interop_01-e374f43.json +++ b/tests/reference/asr-test_c_interop_01-e374f43.json @@ -2,11 +2,11 @@ "basename": "asr-test_c_interop_01-e374f43", "cmd": "lpython --show-asr --no-color {infile} -o {outfile}", "infile": "tests/../integration_tests/test_c_interop_01.py", - "infile_hash": "f5363d49163fefe382a94462e7c305a7938ddcc44c4595f8a0c5bc3f", + "infile_hash": "26515894348fdf2eb4b6e2e277127972e5cd91232f06ee78e4d52af6", "outfile": null, "outfile_hash": null, "stdout": "asr-test_c_interop_01-e374f43.stdout", - "stdout_hash": "54f0e7b627f6a658a8ff7c49f02434b2c7e8393c3c9553a884506837", + "stdout_hash": "4efb998838b9227640cf653fe7a403a132a5b12ec1312a119ab76b59", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_c_interop_01-e374f43.stdout b/tests/reference/asr-test_c_interop_01-e374f43.stdout index cffa869f5b..2e67b18e22 100644 --- a/tests/reference/asr-test_c_interop_01-e374f43.stdout +++ b/tests/reference/asr-test_c_interop_01-e374f43.stdout @@ -10,7 +10,7 @@ __main__global_stmts: (Function (SymbolTable - 8 + 6 { }) @@ -43,166 +43,6 @@ .false. () ), - _lfortran_bgt32: - (Function - (SymbolTable - 5 - { - _lpython_return_variable: - (Variable - 5 - _lpython_return_variable - [] - ReturnVar - () - () - Default - (Integer 4) - () - BindC - Public - Required - .false. - ), - i: - (Variable - 5 - i - [] - In - () - () - Default - (Integer 4) - () - BindC - Public - Required - .true. - ), - j: - (Variable - 5 - j - [] - In - () - () - Default - (Integer 4) - () - BindC - Public - Required - .true. - ) - }) - _lfortran_bgt32 - (FunctionType - [(Integer 4) - (Integer 4)] - (Integer 4) - BindC - Interface - () - .false. - .false. - .false. - .false. - .false. - [] - .false. - ) - [] - [(Var 5 i) - (Var 5 j)] - [] - (Var 5 _lpython_return_variable) - Public - .false. - .false. - () - ), - _lfortran_bgt64: - (Function - (SymbolTable - 6 - { - _lpython_return_variable: - (Variable - 6 - _lpython_return_variable - [] - ReturnVar - () - () - Default - (Integer 4) - () - BindC - Public - Required - .false. - ), - i: - (Variable - 6 - i - [] - In - () - () - Default - (Integer 8) - () - BindC - Public - Required - .true. - ), - j: - (Variable - 6 - j - [] - In - () - () - Default - (Integer 8) - () - BindC - Public - Required - .true. - ) - }) - _lfortran_bgt64 - (FunctionType - [(Integer 8) - (Integer 8)] - (Integer 4) - BindC - Interface - () - .false. - .false. - .false. - .false. - .false. - [] - .false. - ) - [] - [(Var 6 i) - (Var 6 j)] - [] - (Var 6 _lpython_return_variable) - Public - .false. - .false. - () - ), _lfortran_dsin: (Function (SymbolTable @@ -330,11 +170,11 @@ test_c_callbacks: (Function (SymbolTable - 7 + 5 { pi: (Variable - 7 + 5 pi [] Local @@ -365,12 +205,10 @@ .false. ) [_lfortran_dsin - _lfortran_ssin - _lfortran_bgt32 - _lfortran_bgt64] + _lfortran_ssin] [] - [(= - (Var 7 pi) + [(Assignment + (Var 5 pi) (RealConstant 3.141593 (Real 8) @@ -379,13 +217,13 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall 2 _lfortran_dsin () - [((Var 7 pi))] + [((Var 5 pi))] (Real 8) () () @@ -414,14 +252,14 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall 2 _lfortran_dsin () [((RealBinOp - (Var 7 pi) + (Var 5 pi) Div (RealConstant 2.000000 @@ -458,14 +296,14 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall 2 _lfortran_ssin () [((Cast - (Var 7 pi) + (Var 5 pi) RealToReal (Real 4) () @@ -514,7 +352,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (FunctionCall @@ -522,7 +360,7 @@ () [((Cast (RealBinOp - (Var 7 pi) + (Var 5 pi) Div (RealConstant 2.000000 @@ -576,98 +414,6 @@ () ) () - ) - (Assert - (IntegerCompare - (FunctionCall - 2 _lfortran_bgt32 - () - [((IntegerConstant 3 (Integer 4))) - ((IntegerConstant 4 (Integer 4)))] - (Integer 4) - () - () - ) - Eq - (IntegerConstant 0 (Integer 4)) - (Logical 4) - () - ) - () - ) - (Assert - (IntegerCompare - (FunctionCall - 2 _lfortran_bgt32 - () - [((IntegerConstant 4 (Integer 4))) - ((IntegerConstant 3 (Integer 4)))] - (Integer 4) - () - () - ) - Eq - (IntegerConstant 1 (Integer 4)) - (Logical 4) - () - ) - () - ) - (Assert - (IntegerCompare - (FunctionCall - 2 _lfortran_bgt64 - () - [((Cast - (IntegerConstant 3 (Integer 4)) - IntegerToInteger - (Integer 8) - (IntegerConstant 3 (Integer 8)) - )) - ((Cast - (IntegerConstant 4 (Integer 4)) - IntegerToInteger - (Integer 8) - (IntegerConstant 4 (Integer 8)) - ))] - (Integer 4) - () - () - ) - Eq - (IntegerConstant 0 (Integer 4)) - (Logical 4) - () - ) - () - ) - (Assert - (IntegerCompare - (FunctionCall - 2 _lfortran_bgt64 - () - [((Cast - (IntegerConstant 4 (Integer 4)) - IntegerToInteger - (Integer 8) - (IntegerConstant 4 (Integer 8)) - )) - ((Cast - (IntegerConstant 3 (Integer 4)) - IntegerToInteger - (Integer 8) - (IntegerConstant 3 (Integer 8)) - ))] - (Integer 4) - () - () - ) - Eq - (IntegerConstant 1 (Integer 4)) - (Logical 4) - () - ) - () )] () Public @@ -684,11 +430,11 @@ main_program: (Program (SymbolTable - 9 + 7 { __main__global_stmts: (ExternalSymbol - 9 + 7 __main__global_stmts 2 __main__global_stmts __main__ @@ -700,7 +446,7 @@ main_program [__main__] [(SubroutineCall - 9 __main__global_stmts + 7 __main__global_stmts 2 __main__global_stmts [] () diff --git a/tests/reference/asr-test_chr-91f4987.json b/tests/reference/asr-test_chr-91f4987.json index ca5829edf9..9ff30498f9 100644 --- a/tests/reference/asr-test_chr-91f4987.json +++ b/tests/reference/asr-test_chr-91f4987.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_chr-91f4987.stderr", - "stderr_hash": "87fff5dabdc4a4c52a0f07fd59bcc25ba6a3b29a391b39d404b8e2bc", + "stderr_hash": "442cc31382f37e87185b3e3ec3f86831ce9f7a64af3a6cd2655d5c7b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_chr-91f4987.stderr b/tests/reference/asr-test_chr-91f4987.stderr index 18bb9fac87..cb2b893c3e 100644 --- a/tests/reference/asr-test_chr-91f4987.stderr +++ b/tests/reference/asr-test_chr-91f4987.stderr @@ -3,3 +3,7 @@ semantic error: 'f64' object cannot be interpreted as an integer | 3 | s = chr(973.2) | ^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_compare_01-c594bbe.json b/tests/reference/asr-test_compare_01-c594bbe.json index 4871c78f6e..41865c9010 100644 --- a/tests/reference/asr-test_compare_01-c594bbe.json +++ b/tests/reference/asr-test_compare_01-c594bbe.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_compare_01-c594bbe.stderr", - "stderr_hash": "65fb5b04ca1f56cae946ed2db3cde1380d0d9976114c340acfbbcf7b", + "stderr_hash": "69befcaa10db643b167dc312a54d62c054d93900a7b05cf23986415c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_compare_01-c594bbe.stderr b/tests/reference/asr-test_compare_01-c594bbe.stderr index 868af63d50..efdce31c39 100644 --- a/tests/reference/asr-test_compare_01-c594bbe.stderr +++ b/tests/reference/asr-test_compare_01-c594bbe.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in comparison operator, the types must be compatib | 6 | print(i16(x) > f32(y)) | ^^^^^^ ^^^^^^ type mismatch ('i16' and 'f32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_compare_02-bf2c76e.json b/tests/reference/asr-test_compare_02-bf2c76e.json index de5b576dce..9b3bb6a4e3 100644 --- a/tests/reference/asr-test_compare_02-bf2c76e.json +++ b/tests/reference/asr-test_compare_02-bf2c76e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_compare_02-bf2c76e.stderr", - "stderr_hash": "b7fd0ded0c7519927e22a838a2b5156d7cb6b3728bb463ecb5907bfd", + "stderr_hash": "f37d7d40e45b8e7fd25d963085ff1c0060fc744da76b168ea84d341f", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_compare_02-bf2c76e.stderr b/tests/reference/asr-test_compare_02-bf2c76e.stderr index a8843ae5ee..3ddddf6170 100644 --- a/tests/reference/asr-test_compare_02-bf2c76e.stderr +++ b/tests/reference/asr-test_compare_02-bf2c76e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in comparison operator, the types must be compatib | 6 | print(x > y) | ^ ^ type mismatch ('i32' and 'u32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_complex_01-a6def58.json b/tests/reference/asr-test_complex_01-a6def58.json index 9a9c3d09dd..2635b8108b 100644 --- a/tests/reference/asr-test_complex_01-a6def58.json +++ b/tests/reference/asr-test_complex_01-a6def58.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_complex_01-a6def58.stdout", - "stdout_hash": "82664484d6390ba35085ab89ee7b745015aea93df785c9b5f8c5b865", + "stdout_hash": "f27c59a3db1bd0d4623a60d3ceceec2cf5bdef7c72da450a51e90971", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_complex_01-a6def58.stdout b/tests/reference/asr-test_complex_01-a6def58.stdout index 2d13acac1c..2f3e0b17f7 100644 --- a/tests/reference/asr-test_complex_01-a6def58.stdout +++ b/tests/reference/asr-test_complex_01-a6def58.stdout @@ -361,7 +361,7 @@ ) [] [] - [(= + [(Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_5__complex @@ -384,7 +384,7 @@ ) () ) - (= + (Assignment (Var 4 eps) (RealConstant 0.000000 @@ -394,7 +394,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -423,7 +423,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -450,7 +450,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_9__complex @@ -473,7 +473,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -509,7 +509,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -536,7 +536,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_13__complex @@ -558,7 +558,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -587,7 +587,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -614,7 +614,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_14__complex @@ -636,7 +636,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -665,7 +665,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -692,7 +692,7 @@ ) () ) - (= + (Assignment (Var 4 a) (RealConstant 534.600000 @@ -700,7 +700,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_5__complex @@ -719,7 +719,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -748,7 +748,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -782,7 +782,7 @@ ) () ) - (= + (Assignment (Var 4 a2) (RealUnaryMinus (Cast @@ -805,7 +805,7 @@ ) () ) - (= + (Assignment (Var 4 a3) (Cast (RealConstant @@ -821,7 +821,7 @@ ) () ) - (= + (Assignment (Var 4 x2) (FunctionCall 4 complex@__lpython_overloaded_6__complex @@ -837,7 +837,7 @@ (Assert (RealCompare (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -876,7 +876,7 @@ ) () ) - (= + (Assignment (Var 4 i1) (IntegerUnaryMinus (IntegerConstant 5 (Integer 4)) @@ -885,7 +885,7 @@ ) () ) - (= + (Assignment (Var 4 i2) (IntegerUnaryMinus (Cast @@ -899,7 +899,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_7__complex @@ -912,7 +912,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_8__complex @@ -925,7 +925,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_11__complex @@ -938,7 +938,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_9__complex @@ -955,7 +955,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_10__complex @@ -976,7 +976,7 @@ ) () ) - (= + (Assignment (Var 4 x) (FunctionCall 4 complex@__lpython_overloaded_12__complex @@ -1090,7 +1090,7 @@ ) [] [] - [(= + [(Assignment (Var 6 c) (Cast (FunctionCall @@ -1116,7 +1116,7 @@ ) () ) - (= + (Assignment (Var 6 b) (LogicalNot (Cast @@ -1138,7 +1138,7 @@ ) () ) - (= + (Assignment (Var 6 c2) (FunctionCall 6 complex@__lpython_overloaded_9__complex @@ -1155,7 +1155,7 @@ ) () ) - (= + (Assignment (Var 6 b) (LogicalNot (Cast @@ -1290,7 +1290,7 @@ ) [] [] - [(= + [(Assignment (Var 5 c) (Cast (FunctionCall @@ -1319,7 +1319,7 @@ ) () ) - (= + (Assignment (Var 5 _c) (ComplexUnaryMinus (Var 5 c) @@ -1330,7 +1330,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Cast @@ -1374,7 +1374,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Cast @@ -1416,7 +1416,7 @@ ) () ) - (= + (Assignment (Var 5 _c) (Cast (FunctionCall @@ -1446,7 +1446,7 @@ ) () ) - (= + (Assignment (Var 5 _c) (ComplexUnaryMinus (Var 5 _c) @@ -1457,7 +1457,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Cast @@ -1501,7 +1501,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Cast @@ -1536,7 +1536,7 @@ ) () ) - (= + (Assignment (Var 5 c2) (FunctionCall 5 complex@__lpython_overloaded_5__complex @@ -1573,7 +1573,7 @@ ) () ) - (= + (Assignment (Var 5 c2) (ComplexUnaryMinus (Var 5 c2) @@ -1584,7 +1584,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -1616,7 +1616,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -1646,7 +1646,7 @@ ) () ) - (= + (Assignment (Var 5 c2) (ComplexBinOp (Cast @@ -1674,7 +1674,7 @@ ) () ) - (= + (Assignment (Var 5 c2) (ComplexUnaryMinus (Var 5 c2) @@ -1685,7 +1685,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexRe @@ -1724,7 +1724,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ComplexIm @@ -1854,7 +1854,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (ComplexBinOp (Cast @@ -1882,7 +1882,7 @@ ) () ) - (= + (Assignment (Var 3 eps) (RealConstant 0.000000 @@ -1890,7 +1890,7 @@ ) () ) - (= + (Assignment (Var 3 a) (ComplexRe (Var 3 x) @@ -1899,7 +1899,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ComplexIm (Var 3 x) @@ -1910,7 +1910,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 a) @@ -1935,7 +1935,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Var 3 b) diff --git a/tests/reference/asr-test_complex_02-782ba2d.json b/tests/reference/asr-test_complex_02-782ba2d.json index 716cd6db0d..b88e353f76 100644 --- a/tests/reference/asr-test_complex_02-782ba2d.json +++ b/tests/reference/asr-test_complex_02-782ba2d.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_complex_02-782ba2d.stdout", - "stdout_hash": "8ab7f5cd65918128791225ed99a8fa422d9fc3a1811a1557d587af26", + "stdout_hash": "0a3aedd526271c84ad5a03e8ec1ed1d6f1377bf232e18f9297d4ba46", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_complex_02-782ba2d.stdout b/tests/reference/asr-test_complex_02-782ba2d.stdout index 2a89462be4..4af04f04c6 100644 --- a/tests/reference/asr-test_complex_02-782ba2d.stdout +++ b/tests/reference/asr-test_complex_02-782ba2d.stdout @@ -184,7 +184,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (Cast (FunctionCall @@ -210,7 +210,7 @@ ) () ) - (= + (Assignment (Var 3 eps) (RealConstant 0.000000 @@ -220,11 +220,11 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 x)] 0 @@ -254,7 +254,7 @@ ) () ) - (= + (Assignment (Var 3 y) (FunctionCall 3 complex@__lpython_overloaded_9__complex @@ -273,10 +273,10 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(Var 3 y)] 0 @@ -379,7 +379,7 @@ ) [] [] - [(= + [(Assignment (Var 4 x) (Cast (ComplexBinOp @@ -416,7 +416,7 @@ ) () ) - (= + (Assignment (Var 4 y) (Cast (ComplexBinOp @@ -453,7 +453,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ComplexBinOp (Var 4 x) @@ -464,7 +464,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ComplexBinOp (Var 4 x) @@ -475,7 +475,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ComplexBinOp (Var 4 x) @@ -486,7 +486,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ComplexBinOp (Var 4 x) @@ -574,7 +574,7 @@ ) [] [] - [(= + [(Assignment (Var 5 x) (ComplexBinOp (Cast @@ -602,7 +602,7 @@ ) () ) - (= + (Assignment (Var 5 y) (ComplexBinOp (Cast @@ -630,7 +630,7 @@ ) () ) - (= + (Assignment (Var 5 z) (ComplexBinOp (Var 5 x) @@ -641,7 +641,7 @@ ) () ) - (= + (Assignment (Var 5 z) (ComplexBinOp (Var 5 x) @@ -652,7 +652,7 @@ ) () ) - (= + (Assignment (Var 5 z) (ComplexBinOp (Var 5 x) @@ -663,7 +663,7 @@ ) () ) - (= + (Assignment (Var 5 z) (ComplexBinOp (Var 5 x) diff --git a/tests/reference/asr-test_const_list_append-ada1ade.json b/tests/reference/asr-test_const_list_append-ada1ade.json index 484830324d..575620a186 100644 --- a/tests/reference/asr-test_const_list_append-ada1ade.json +++ b/tests/reference/asr-test_const_list_append-ada1ade.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_append-ada1ade.stderr", - "stderr_hash": "84fe0a7a75edd73700bce92d3e43cdc85e7f3c58f0047f53fb4412ad", + "stderr_hash": "e6b99d37416c0ab5200019e594f68f1c175e068d04b241cf08ce881c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_append-ada1ade.stderr b/tests/reference/asr-test_const_list_append-ada1ade.stderr index 08b7bf6c6b..7b42b483fa 100644 --- a/tests/reference/asr-test_const_list_append-ada1ade.stderr +++ b/tests/reference/asr-test_const_list_append-ada1ade.stderr @@ -3,3 +3,7 @@ semantic error: cannot append element to a const list | 7 | CONST_INTEGER_LIST.append(6) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_const_list_clear-33bfae7.json b/tests/reference/asr-test_const_list_clear-33bfae7.json index a4ac6699f7..090e03f4db 100644 --- a/tests/reference/asr-test_const_list_clear-33bfae7.json +++ b/tests/reference/asr-test_const_list_clear-33bfae7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_clear-33bfae7.stderr", - "stderr_hash": "5c0c698319211c447c76e3309a027ee068dffded22d87bb3024cedf9", + "stderr_hash": "1a4b0b9abd4b00fbab4ae25aab6ed9de79140cfb24c9338f3b9da9c1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_clear-33bfae7.stderr b/tests/reference/asr-test_const_list_clear-33bfae7.stderr index 89fc62b51a..4aeac71640 100644 --- a/tests/reference/asr-test_const_list_clear-33bfae7.stderr +++ b/tests/reference/asr-test_const_list_clear-33bfae7.stderr @@ -3,3 +3,7 @@ semantic error: cannot clear elements from a const list | 7 | CONST_INTEGER_LIST.clear() | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_const_list_insert-4c81295.json b/tests/reference/asr-test_const_list_insert-4c81295.json index 6113030e62..68a37135f1 100644 --- a/tests/reference/asr-test_const_list_insert-4c81295.json +++ b/tests/reference/asr-test_const_list_insert-4c81295.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_insert-4c81295.stderr", - "stderr_hash": "148e2a44028dd423007236ebf7a2c393fcefa4e8c12aad565f1c87fe", + "stderr_hash": "6333bcb95fdcb09561fd714b3a0019c5e94a05d7f21079d6a75569f9", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_insert-4c81295.stderr b/tests/reference/asr-test_const_list_insert-4c81295.stderr index 0a416adfd3..16c26b033a 100644 --- a/tests/reference/asr-test_const_list_insert-4c81295.stderr +++ b/tests/reference/asr-test_const_list_insert-4c81295.stderr @@ -3,3 +3,7 @@ semantic error: cannot insert element in a const list | 7 | CONST_INTEGER_LIST.insert(3, 8) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_const_list_pop-568b207.json b/tests/reference/asr-test_const_list_pop-568b207.json index eb4e398c99..a7add682f2 100644 --- a/tests/reference/asr-test_const_list_pop-568b207.json +++ b/tests/reference/asr-test_const_list_pop-568b207.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_pop-568b207.stderr", - "stderr_hash": "32d57cbb983509ca6c54bc0812c9a74b3c1886ecc94e635c5011c378", + "stderr_hash": "fd9c42a0a699e0b1ed4404a22b196916494e8d63c8de4f8188fa6180", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_pop-568b207.stderr b/tests/reference/asr-test_const_list_pop-568b207.stderr index ad22224de1..f55f17cf09 100644 --- a/tests/reference/asr-test_const_list_pop-568b207.stderr +++ b/tests/reference/asr-test_const_list_pop-568b207.stderr @@ -3,3 +3,7 @@ semantic error: cannot pop element from a const list | 7 | CONST_INTEGER_LIST.pop() | ^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_const_list_remove-c5deb20.json b/tests/reference/asr-test_const_list_remove-c5deb20.json index 4abd87a66b..57b3477c4e 100644 --- a/tests/reference/asr-test_const_list_remove-c5deb20.json +++ b/tests/reference/asr-test_const_list_remove-c5deb20.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_remove-c5deb20.stderr", - "stderr_hash": "3529d822548d9327dbd0eab32aebc7b4a0da518cc0a6c2356e65c7b8", + "stderr_hash": "fdc0593ffd5807da577db67b457e53749498f6d8294ba1d0dc6aac49", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_remove-c5deb20.stderr b/tests/reference/asr-test_const_list_remove-c5deb20.stderr index cdc585f4fc..533c518cd2 100644 --- a/tests/reference/asr-test_const_list_remove-c5deb20.stderr +++ b/tests/reference/asr-test_const_list_remove-c5deb20.stderr @@ -3,3 +3,7 @@ semantic error: cannot remove element from a const list | 7 | CONST_INTEGER_LIST.remove(1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_const_list_reverse-2df1a6f.json b/tests/reference/asr-test_const_list_reverse-2df1a6f.json index b463e10677..58f4e050a9 100644 --- a/tests/reference/asr-test_const_list_reverse-2df1a6f.json +++ b/tests/reference/asr-test_const_list_reverse-2df1a6f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_const_list_reverse-2df1a6f.stderr", - "stderr_hash": "78d4df28bbde66600867165e7c4d2b7e56874ba0f459052f8ab1b7fc", + "stderr_hash": "c5f24fc2dd6095dffe16dc5ed7de9b5956b89639be4a70db29814cab", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_const_list_reverse-2df1a6f.stderr b/tests/reference/asr-test_const_list_reverse-2df1a6f.stderr index f49888969e..df7b8b2cf9 100644 --- a/tests/reference/asr-test_const_list_reverse-2df1a6f.stderr +++ b/tests/reference/asr-test_const_list_reverse-2df1a6f.stderr @@ -3,3 +3,7 @@ semantic error: cannot reverse a const list | 7 | CONST_INTEGER_LIST.reverse() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict1-a45a075.json b/tests/reference/asr-test_dict1-a45a075.json index eeb9ffe3f7..19ba842502 100644 --- a/tests/reference/asr-test_dict1-a45a075.json +++ b/tests/reference/asr-test_dict1-a45a075.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict1-a45a075.stderr", - "stderr_hash": "a9fbe4acc4f82141b1111e9aef3d3c50f27540d41ff3382fe46da8ea", + "stderr_hash": "0e3b1104b9ed857a9142b9caa4a11cdb879a9699f5543ebc29937fef", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict1-a45a075.stderr b/tests/reference/asr-test_dict1-a45a075.stderr index 01fe7b133f..b0d8cfb2fa 100644 --- a/tests/reference/asr-test_dict1-a45a075.stderr +++ b/tests/reference/asr-test_dict1-a45a075.stderr @@ -3,3 +3,7 @@ semantic error: Key type should be 'i32' instead of 'str' | 5 | z = x["a"] | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict10-8c0beff.json b/tests/reference/asr-test_dict10-8c0beff.json index 2b2342369e..15958f55f0 100644 --- a/tests/reference/asr-test_dict10-8c0beff.json +++ b/tests/reference/asr-test_dict10-8c0beff.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict10-8c0beff.stderr", - "stderr_hash": "06772bed43d8fff0fb889a763afb49307005f50ce26c7a601652e258", + "stderr_hash": "15f8c2e84c305015f7031792aaf61a3140a69d99075ee1f6390b99d6", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict10-8c0beff.stderr b/tests/reference/asr-test_dict10-8c0beff.stderr index 58c4edd7d3..b99ee2093d 100644 --- a/tests/reference/asr-test_dict10-8c0beff.stderr +++ b/tests/reference/asr-test_dict10-8c0beff.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 4 | d: dict[c32, f64] = {} | ^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict11-2ab4e6c.json b/tests/reference/asr-test_dict11-2ab4e6c.json index c91886a137..dff0b9019a 100644 --- a/tests/reference/asr-test_dict11-2ab4e6c.json +++ b/tests/reference/asr-test_dict11-2ab4e6c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict11-2ab4e6c.stderr", - "stderr_hash": "6ef78d7738e0780fc0f9b9567390798b3d74374b95d0dd156ccbdab4", + "stderr_hash": "4feebf03a1adde189a82be34ee36d813036c5bb30a0a182b938029ad", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict11-2ab4e6c.stderr b/tests/reference/asr-test_dict11-2ab4e6c.stderr index fcc460b76f..1fc9b4e5e5 100644 --- a/tests/reference/asr-test_dict11-2ab4e6c.stderr +++ b/tests/reference/asr-test_dict11-2ab4e6c.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 4 | d: dict[c64, f32] = {} | ^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict12-7c74d08.json b/tests/reference/asr-test_dict12-7c74d08.json index 9922026e7b..ebe1fc3472 100644 --- a/tests/reference/asr-test_dict12-7c74d08.json +++ b/tests/reference/asr-test_dict12-7c74d08.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict12-7c74d08.stderr", - "stderr_hash": "9243262b97e5e6a555eafbbfd93440e86e66a3536cc0fb9902a7e0d2", + "stderr_hash": "751513996872b77f6e8f7a2c244debb99e0c482a8988dd0edbdda86f", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict12-7c74d08.stderr b/tests/reference/asr-test_dict12-7c74d08.stderr index 5f9fb390f6..2407bf6062 100644 --- a/tests/reference/asr-test_dict12-7c74d08.stderr +++ b/tests/reference/asr-test_dict12-7c74d08.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 2 | print({0.0: 1.1}) # constant dict with floating point value as key | ^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict13-683b290.json b/tests/reference/asr-test_dict13-683b290.json index 982bd80540..92dc8ebf9d 100644 --- a/tests/reference/asr-test_dict13-683b290.json +++ b/tests/reference/asr-test_dict13-683b290.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict13-683b290.stderr", - "stderr_hash": "60bc3be332a1b638ade1cf40068ee4381ba4a79942a76c104c9cdebd", + "stderr_hash": "38f9acbaebebd19e95f3d298ab13eb99f22efa86c6f1e9d495ad5f3a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict13-683b290.stderr b/tests/reference/asr-test_dict13-683b290.stderr index 9dc7b6ef9c..c27255be7c 100644 --- a/tests/reference/asr-test_dict13-683b290.stderr +++ b/tests/reference/asr-test_dict13-683b290.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 2 | print({complex(0.0, 1.0): 1.1}) # constant dict with complex value as key | ^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict2-4587f02.json b/tests/reference/asr-test_dict2-4587f02.json index 270d51c545..5947865cda 100644 --- a/tests/reference/asr-test_dict2-4587f02.json +++ b/tests/reference/asr-test_dict2-4587f02.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict2-4587f02.stderr", - "stderr_hash": "9de5d75622644a0cb98bdd3f73249772c25c293f508343b31cc34607", + "stderr_hash": "291c5956c4006303abdbe6d41bcac8de6c0a967a04a4747ef6a5e456", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict2-4587f02.stderr b/tests/reference/asr-test_dict2-4587f02.stderr index dde39a40a8..09d4b7e673 100644 --- a/tests/reference/asr-test_dict2-4587f02.stderr +++ b/tests/reference/asr-test_dict2-4587f02.stderr @@ -3,3 +3,7 @@ semantic error: Key type should be 'str' instead of 'i32' | 4 | y[1] = -3 | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict3-d28f38f.json b/tests/reference/asr-test_dict3-d28f38f.json index ea944408ea..383f6a71ce 100644 --- a/tests/reference/asr-test_dict3-d28f38f.json +++ b/tests/reference/asr-test_dict3-d28f38f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict3-d28f38f.stderr", - "stderr_hash": "e2cc26634c1ee7aeca96c006b3bd01205200e1a6187e01fde041c3b4", + "stderr_hash": "5a41c9ce5829ee6b89bb03c21d2fd490a115845ae41c798b0e1e4940", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict3-d28f38f.stderr b/tests/reference/asr-test_dict3-d28f38f.stderr index da5a97b2ce..9bfe4962e1 100644 --- a/tests/reference/asr-test_dict3-d28f38f.stderr +++ b/tests/reference/asr-test_dict3-d28f38f.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in get's key value, the types must be compatible | 5 | x = y.get(1) | ^ type mismatch (found: 'i32', expected: 'str') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict4-39489fa.json b/tests/reference/asr-test_dict4-39489fa.json index dbe64e91c0..5a3b44239b 100644 --- a/tests/reference/asr-test_dict4-39489fa.json +++ b/tests/reference/asr-test_dict4-39489fa.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict4-39489fa.stderr", - "stderr_hash": "fee0e93265feaf634ae62eded08ec63f6c37530369217731b552de61", + "stderr_hash": "cc2d7602ef35b6695e01113c11fa21dcd3836fe2d7c9734cc6c2ba89", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict4-39489fa.stderr b/tests/reference/asr-test_dict4-39489fa.stderr index 1b9e3847a8..bcd421563e 100644 --- a/tests/reference/asr-test_dict4-39489fa.stderr +++ b/tests/reference/asr-test_dict4-39489fa.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 2 | d: dict[i32, i32] = {1: "a", 2: "b"} | ^ ^^^^^^^^^^^^^^^^ type mismatch ('dict[i32, i32]' and 'dict[i32, str]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict5-c436d37.json b/tests/reference/asr-test_dict5-c436d37.json index 4c7034730c..79821e16e9 100644 --- a/tests/reference/asr-test_dict5-c436d37.json +++ b/tests/reference/asr-test_dict5-c436d37.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict5-c436d37.stderr", - "stderr_hash": "85918b86a904812b9f151ec636dac3c770446a33ebac2f5910591ea7", + "stderr_hash": "3931655b3967ece317bb4f759df5e31fa8970bc34b740a2ad187cce5", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict5-c436d37.stderr b/tests/reference/asr-test_dict5-c436d37.stderr index c38b8997ba..eb5f0ffa5d 100644 --- a/tests/reference/asr-test_dict5-c436d37.stderr +++ b/tests/reference/asr-test_dict5-c436d37.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 3 | d = {1: "a", 2: "b"} | ^ ^^^^^^^^^^^^^^^^ type mismatch ('dict[i32, i32]' and 'dict[i32, str]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict6-95e3b14.json b/tests/reference/asr-test_dict6-95e3b14.json index 02c62b38c2..f067b0f0ae 100644 --- a/tests/reference/asr-test_dict6-95e3b14.json +++ b/tests/reference/asr-test_dict6-95e3b14.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict6-95e3b14.stderr", - "stderr_hash": "786fd07ddc3919823741b0db9a9ff0ba898b106d677657ea5f80fd2e", + "stderr_hash": "874dd0405e09cb7f345ec74a015fec0aa7d8185df22ae9d611633c26", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict6-95e3b14.stderr b/tests/reference/asr-test_dict6-95e3b14.stderr index 9da26030e6..1c3dcf03aa 100644 --- a/tests/reference/asr-test_dict6-95e3b14.stderr +++ b/tests/reference/asr-test_dict6-95e3b14.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in pop's key value, the types must be compatible | 5 | res = d.pop("a") | ^^^ type mismatch (found: 'str', expected: 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict7-1415e14.json b/tests/reference/asr-test_dict7-1415e14.json index 64eb4e7eb3..f359fab8ab 100644 --- a/tests/reference/asr-test_dict7-1415e14.json +++ b/tests/reference/asr-test_dict7-1415e14.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict7-1415e14.stderr", - "stderr_hash": "a51d1d4a46839e1f4258410e979ba83a14abe8c011482e30be2336cd", + "stderr_hash": "25ac6ccfcf5724a3c69a51e57c4f2661da77f8ea9d6d219f20452297", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict7-1415e14.stderr b/tests/reference/asr-test_dict7-1415e14.stderr index 7884efa64e..9ef2b1cf6f 100644 --- a/tests/reference/asr-test_dict7-1415e14.stderr +++ b/tests/reference/asr-test_dict7-1415e14.stderr @@ -3,3 +3,7 @@ semantic error: unhashable type in dict: 'slice' | 4 | print(d[1:2]) | ^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict8-d960ce0.json b/tests/reference/asr-test_dict8-d960ce0.json index 303c677d1d..8116026ab3 100644 --- a/tests/reference/asr-test_dict8-d960ce0.json +++ b/tests/reference/asr-test_dict8-d960ce0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict8-d960ce0.stderr", - "stderr_hash": "c2dcf3e38154f9a69328274fafd4940b8b6296d31f442c01c88eaa0e", + "stderr_hash": "874fe99874eb5849c3ead7894c52cc1629c6cce8ea9a3d4d3e94169e", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict8-d960ce0.stderr b/tests/reference/asr-test_dict8-d960ce0.stderr index 050138ffac..728a042b9d 100644 --- a/tests/reference/asr-test_dict8-d960ce0.stderr +++ b/tests/reference/asr-test_dict8-d960ce0.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 4 | d: dict[f64, f64] = {} | ^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_dict9-907bda7.json b/tests/reference/asr-test_dict9-907bda7.json index 3603e2ca62..ec81d39ebb 100644 --- a/tests/reference/asr-test_dict9-907bda7.json +++ b/tests/reference/asr-test_dict9-907bda7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_dict9-907bda7.stderr", - "stderr_hash": "3278571c4f1c492f88f33ca78dcf8fb5051f9e3ca89df7557b7881f6", + "stderr_hash": "990ee479c2b779810f75e956bfbd05f6237f54be37fe69ce4d958cdc", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_dict9-907bda7.stderr b/tests/reference/asr-test_dict9-907bda7.stderr index a1394398fa..d509ff13a8 100644 --- a/tests/reference/asr-test_dict9-907bda7.stderr +++ b/tests/reference/asr-test_dict9-907bda7.stderr @@ -3,3 +3,7 @@ semantic error: 'dict' key type cannot be float/complex because resolving collis | 4 | d: dict[f32, f64] = {} | ^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_float_semantic_error-58c0c90.json b/tests/reference/asr-test_float_semantic_error-58c0c90.json index e451309c05..139e47a11d 100644 --- a/tests/reference/asr-test_float_semantic_error-58c0c90.json +++ b/tests/reference/asr-test_float_semantic_error-58c0c90.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_float_semantic_error-58c0c90.stderr", - "stderr_hash": "c11166fb86be513e74796a51f5c9e84653c2eb894ed95d502ed8af57", + "stderr_hash": "0f5559b6283133ffed614017f2d7606c5c6511467d127638cb555c0c", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_float_semantic_error-58c0c90.stderr b/tests/reference/asr-test_float_semantic_error-58c0c90.stderr index 2698ced8c9..687878ef05 100644 --- a/tests/reference/asr-test_float_semantic_error-58c0c90.stderr +++ b/tests/reference/asr-test_float_semantic_error-58c0c90.stderr @@ -3,3 +3,7 @@ semantic error: float type is not supported yet. | 4 | pi: float = 3.14 | ^^^^^ Hint: Use f32 or f64 for now. + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_for2-e5d893f.json b/tests/reference/asr-test_for2-e5d893f.json index 0067f33cd4..796ab45c73 100644 --- a/tests/reference/asr-test_for2-e5d893f.json +++ b/tests/reference/asr-test_for2-e5d893f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_for2-e5d893f.stderr", - "stderr_hash": "07152b2e843a1a3ea9ab8e5c7c620d4ecc9f29ef1408d48055028b95", + "stderr_hash": "eaaf63c17487bf1883a098fc4551c90cac26e8d0c00d8e4b27f830bd", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_for2-e5d893f.stderr b/tests/reference/asr-test_for2-e5d893f.stderr index db88c88721..1b2b33e12d 100644 --- a/tests/reference/asr-test_for2-e5d893f.stderr +++ b/tests/reference/asr-test_for2-e5d893f.stderr @@ -7,3 +7,7 @@ semantic error: For loop increment type should be Integer. | 4 | print(i) | ...^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_func_args-a898a72.json b/tests/reference/asr-test_func_args-a898a72.json index 52ff1af35d..50187a7664 100644 --- a/tests/reference/asr-test_func_args-a898a72.json +++ b/tests/reference/asr-test_func_args-a898a72.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_func_args-a898a72.stderr", - "stderr_hash": "b498b34cd18395e17ab982dc47abb832c01bd16ede103fad53068304", + "stderr_hash": "81c7b0c6d133c456c6d08779ade1f7c3a4f0eb32bb935caa2ff0286e", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_func_args-a898a72.stderr b/tests/reference/asr-test_func_args-a898a72.stderr index ec5891080a..37b2184ed6 100644 --- a/tests/reference/asr-test_func_args-a898a72.stderr +++ b/tests/reference/asr-test_func_args-a898a72.stderr @@ -3,3 +3,7 @@ semantic error: Number of arguments does not match in the function call | 11 | ans = fib(35, 10) | ^^^^^^^^^^^ (found: '2', expected: '1') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_import_01-b859c43.json b/tests/reference/asr-test_import_01-b859c43.json index 4c1f0a511b..4fc1c59406 100644 --- a/tests/reference/asr-test_import_01-b859c43.json +++ b/tests/reference/asr-test_import_01-b859c43.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_import_01-b859c43.stderr", - "stderr_hash": "ef59d49c8273cdd97e830cac94b3cc620fb24b07ce00c3394081c9c5", + "stderr_hash": "0f8409943b664b0fc9dcc12cbc61816e1ed556ccff2e9ccc833b16b4", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_import_01-b859c43.stderr b/tests/reference/asr-test_import_01-b859c43.stderr index a2a50d4911..497eeb6792 100644 --- a/tests/reference/asr-test_import_01-b859c43.stderr +++ b/tests/reference/asr-test_import_01-b859c43.stderr @@ -8,3 +8,7 @@ semantic error: Type mismatch in procedure call; the types must be compatible | 3 | def test(x: i32) -> i32: | ^^^ type mismatch (passed argument type is f64 but required type is i32) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_import_02-55b47fa.json b/tests/reference/asr-test_import_02-55b47fa.json index 04b0cf247e..59e7a3df2a 100644 --- a/tests/reference/asr-test_import_02-55b47fa.json +++ b/tests/reference/asr-test_import_02-55b47fa.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_import_02-55b47fa.stderr", - "stderr_hash": "b30859152322cc22b1593d3af229c7b28fbc8bc03eb6542fec3a3c91", + "stderr_hash": "3b854e9889cf37acf07c6670c9a5edfb1a261c94aa04c68dad9adf51", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_import_02-55b47fa.stderr b/tests/reference/asr-test_import_02-55b47fa.stderr index 2c4a4fd389..af305b49cf 100644 --- a/tests/reference/asr-test_import_02-55b47fa.stderr +++ b/tests/reference/asr-test_import_02-55b47fa.stderr @@ -9,3 +9,7 @@ semantic error: Type mismatch in annotation-assignment, the types must be compat | 3 | X: Const[i32] = 1.23 | ^ ^^^^ type mismatch ('i32' and 'f64') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_int_semantic_error-44fe25e.json b/tests/reference/asr-test_int_semantic_error-44fe25e.json index 3747fc7b8b..da296ce8a6 100644 --- a/tests/reference/asr-test_int_semantic_error-44fe25e.json +++ b/tests/reference/asr-test_int_semantic_error-44fe25e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_int_semantic_error-44fe25e.stderr", - "stderr_hash": "a1cd1ec0fee194e3c1651668753a1666ca46c925fa91335c6230e026", + "stderr_hash": "f7c05f58aea2d0d4bed0b3442fc71fb6a2f6f9574ec9df6cdb609065", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_int_semantic_error-44fe25e.stderr b/tests/reference/asr-test_int_semantic_error-44fe25e.stderr index f75e0f05a6..997f1ad653 100644 --- a/tests/reference/asr-test_int_semantic_error-44fe25e.stderr +++ b/tests/reference/asr-test_int_semantic_error-44fe25e.stderr @@ -3,3 +3,7 @@ semantic error: int type is not supported yet. | 4 | x: int = 1 | ^^^ Hint: Use i8, i16, i32 or i64 for now. + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_len1-839a615.json b/tests/reference/asr-test_len1-839a615.json index ee88e63b6e..647ef7db9b 100644 --- a/tests/reference/asr-test_len1-839a615.json +++ b/tests/reference/asr-test_len1-839a615.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_len1-839a615.stderr", - "stderr_hash": "50478fbc4d3bc86e9bf6cf012d810f31885d5e654423a0384557f919", + "stderr_hash": "36d068d445571f426a27d96788b38c67bbdd9fa7f7f55bd9f0e2984d", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_len1-839a615.stderr b/tests/reference/asr-test_len1-839a615.stderr index 2a491e7a48..3d1bc840ce 100644 --- a/tests/reference/asr-test_len1-839a615.stderr +++ b/tests/reference/asr-test_len1-839a615.stderr @@ -3,3 +3,7 @@ semantic error: len() is only supported for `str`, `set`, `dict`, `list` and `tu | 4 | print(len(x)) | ^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list1-73fd538.json b/tests/reference/asr-test_list1-73fd538.json index 33b0c94fc7..9a83f05128 100644 --- a/tests/reference/asr-test_list1-73fd538.json +++ b/tests/reference/asr-test_list1-73fd538.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list1-73fd538.stderr", - "stderr_hash": "8c791203aa1be4c1cb8911aaaf447a5e706cc00d17dfeba0b17c283b", + "stderr_hash": "750bd9322d9ea11413d91b9edaeebfc20c24fd7057a8b0051e22eb2e", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list1-73fd538.stderr b/tests/reference/asr-test_list1-73fd538.stderr index a9f4fd03cf..69dbb33a66 100644 --- a/tests/reference/asr-test_list1-73fd538.stderr +++ b/tests/reference/asr-test_list1-73fd538.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in 'remove', the types must be compatible | 6 | a.remove('error') | ^^^^^^^ type mismatch (found: 'str', expected: 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list2-10ffdd7.json b/tests/reference/asr-test_list2-10ffdd7.json index 0510d548d4..cc31728d2d 100644 --- a/tests/reference/asr-test_list2-10ffdd7.json +++ b/tests/reference/asr-test_list2-10ffdd7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list2-10ffdd7.stderr", - "stderr_hash": "be192bc4655f28313c415c7180d676e0383f0acb7e4de75a6b3d1a37", + "stderr_hash": "9516440123f4d2d64fe5de904159be272b692a1fe72c984f360f27a4", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list2-10ffdd7.stderr b/tests/reference/asr-test_list2-10ffdd7.stderr index 0607fb8266..dc634baee2 100644 --- a/tests/reference/asr-test_list2-10ffdd7.stderr +++ b/tests/reference/asr-test_list2-10ffdd7.stderr @@ -3,3 +3,7 @@ semantic error: append() takes exactly one argument | 6 | a.append(4, 5) | ^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list3-5f4d2a8.json b/tests/reference/asr-test_list3-5f4d2a8.json index 09d515e69a..6f69f1d430 100644 --- a/tests/reference/asr-test_list3-5f4d2a8.json +++ b/tests/reference/asr-test_list3-5f4d2a8.json @@ -5,9 +5,9 @@ "infile_hash": "f512b77e66fe356108135243473cf9441bc532310547070a9aeef3e9", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, + "stdout": "asr-test_list3-5f4d2a8.stdout", + "stdout_hash": "513c87cf17bc1cd3a1255ca0fec74484c144ba2083173f0c2c0ededa", "stderr": "asr-test_list3-5f4d2a8.stderr", - "stderr_hash": "3e8e102841bfe5ae8524aa793b39cdf33de7e7073744a01f0049b424", - "returncode": 2 + "stderr_hash": "61882ce7e951b985e294ac3529e8574d48212180a319380b2f103312", + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_list3-5f4d2a8.stderr b/tests/reference/asr-test_list3-5f4d2a8.stderr index 45d1ab0536..be62c2ed55 100644 --- a/tests/reference/asr-test_list3-5f4d2a8.stderr +++ b/tests/reference/asr-test_list3-5f4d2a8.stderr @@ -3,3 +3,7 @@ semantic error: Argument to list.pop must be an integer | 5 | x = a.pop(2.2) | ^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list3-5f4d2a8.stdout b/tests/reference/asr-test_list3-5f4d2a8.stdout new file mode 100644 index 0000000000..4452226a97 --- /dev/null +++ b/tests/reference/asr-test_list3-5f4d2a8.stdout @@ -0,0 +1,104 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + test_e1: + (Function + (SymbolTable + 3 + { + a: + (Variable + 3 + a + [] + Local + () + () + Default + (List + (Integer 4) + ) + () + Source + Public + Required + .false. + ), + x: + (Variable + 3 + x + [] + Local + () + () + Default + (Integer 4) + () + Source + Public + Required + .false. + ) + }) + test_e1 + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 a) + (ListConstant + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 2 (Integer 4)) + (IntegerConstant 3 (Integer 4))] + (List + (Integer 4) + ) + ) + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 4 + { + + }) + main_program + [] + [] + ) + }) + [] +) diff --git a/tests/reference/asr-test_list4-d18a7e3.json b/tests/reference/asr-test_list4-d18a7e3.json index af9e9f1da7..62028826e7 100644 --- a/tests/reference/asr-test_list4-d18a7e3.json +++ b/tests/reference/asr-test_list4-d18a7e3.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list4-d18a7e3.stderr", - "stderr_hash": "98922e9f57ab8e9d7af05424e9fdb93a9a1722114f5abb816439b161", + "stderr_hash": "58fc47e24ec3d6aa96ec247629c2ef6e0d996e481902aa9af62c87cb", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list4-d18a7e3.stderr b/tests/reference/asr-test_list4-d18a7e3.stderr index b3b4683868..23e3741f19 100644 --- a/tests/reference/asr-test_list4-d18a7e3.stderr +++ b/tests/reference/asr-test_list4-d18a7e3.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in index, expected a single integer or slice | 7 | x = a[0.2] | ^^^ type mismatch (found: 'f64', expected: 'i32' or slice) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list_concat-41d186f.json b/tests/reference/asr-test_list_concat-41d186f.json index ff64ae4aac..34b3e75f8a 100644 --- a/tests/reference/asr-test_list_concat-41d186f.json +++ b/tests/reference/asr-test_list_concat-41d186f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list_concat-41d186f.stderr", - "stderr_hash": "b0a3cfa79525db1ed6aa4ed1f47b11e4852da5a59e043d32a7814ede", + "stderr_hash": "9bb9a39f1d0dc4e9e90199ac9fdb190fb4fbf4e42cb4bec96d6174c8", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list_concat-41d186f.stderr b/tests/reference/asr-test_list_concat-41d186f.stderr index bdfcab29af..052f4c0fbb 100644 --- a/tests/reference/asr-test_list_concat-41d186f.stderr +++ b/tests/reference/asr-test_list_concat-41d186f.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in shorthand operator, the types must be compatibl | 8 | a += b | ^ ^ type mismatch ('list[i32]' and 'list[f64]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list_count-4b42498.json b/tests/reference/asr-test_list_count-4b42498.json index f4864b55fb..a89270c1e1 100644 --- a/tests/reference/asr-test_list_count-4b42498.json +++ b/tests/reference/asr-test_list_count-4b42498.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list_count-4b42498.stderr", - "stderr_hash": "f26efcc623b68ca43ef871eb01c8e3cbd1ae464baaa491c6e4969696", + "stderr_hash": "3243061047f267a18ab172f35c154ffc38e67db5d1adf8f861100dbc", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list_count-4b42498.stderr b/tests/reference/asr-test_list_count-4b42498.stderr index ad60a50f0e..cf53d8e8c0 100644 --- a/tests/reference/asr-test_list_count-4b42498.stderr +++ b/tests/reference/asr-test_list_count-4b42498.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in 'count', the types must be compatible | 6 | a.count(1.0) | ^^^ type mismatch (found: 'f64', expected: 'i32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_list_slicing-984fbf0.json b/tests/reference/asr-test_list_slicing-984fbf0.json index d525b6d6c9..615d281c3f 100644 --- a/tests/reference/asr-test_list_slicing-984fbf0.json +++ b/tests/reference/asr-test_list_slicing-984fbf0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_list_slicing-984fbf0.stderr", - "stderr_hash": "6763533f9c1730429d50f58b653595bfeef48c4d19943c36d037d023", + "stderr_hash": "56700e105a59d772c5c08c15ffd02cb9d15275ad2be505cb708ae7f7", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_list_slicing-984fbf0.stderr b/tests/reference/asr-test_list_slicing-984fbf0.stderr index dc773c9f70..bf9e980a05 100644 --- a/tests/reference/asr-test_list_slicing-984fbf0.stderr +++ b/tests/reference/asr-test_list_slicing-984fbf0.stderr @@ -3,3 +3,7 @@ semantic error: slice step cannot be zero | 6 | print(l[0:10:0]) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_logical_compare_01-5db0e2e.json b/tests/reference/asr-test_logical_compare_01-5db0e2e.json index 7030df8c0e..3fbd6af126 100644 --- a/tests/reference/asr-test_logical_compare_01-5db0e2e.json +++ b/tests/reference/asr-test_logical_compare_01-5db0e2e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_logical_compare_01-5db0e2e.stderr", - "stderr_hash": "d10cac68687315b5d29828e0acb5170f44bd91dd30784f8bd4943bb0", + "stderr_hash": "0416107a994b387574dbac2fd87fc8e329917db9e1b1cee13af0df5a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_logical_compare_01-5db0e2e.stderr b/tests/reference/asr-test_logical_compare_01-5db0e2e.stderr index c1e876782c..acd041727b 100644 --- a/tests/reference/asr-test_logical_compare_01-5db0e2e.stderr +++ b/tests/reference/asr-test_logical_compare_01-5db0e2e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch: 'str' and 'i32'. Both operands must be of the sam | 2 | print("hello" or 10) | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_max_min-3c2fc51.json b/tests/reference/asr-test_max_min-3c2fc51.json index 22173da66d..ddb2b232f7 100644 --- a/tests/reference/asr-test_max_min-3c2fc51.json +++ b/tests/reference/asr-test_max_min-3c2fc51.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_max_min-3c2fc51.stdout", - "stdout_hash": "0e90edcd031f0437467ad7e94484aa97a9b9fad2c07c511a574d6593", + "stdout_hash": "a6759cdd5e7de0f5151996c1e75ff24b9e5007425e580c942f4de11b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_max_min-3c2fc51.stdout b/tests/reference/asr-test_max_min-3c2fc51.stdout index b33084f974..bbab756eeb 100644 --- a/tests/reference/asr-test_max_min-3c2fc51.stdout +++ b/tests/reference/asr-test_max_min-3c2fc51.stdout @@ -10,7 +10,7 @@ __main__global_stmts: (Function (SymbolTable - 140 + 8 { }) @@ -152,36 +152,6 @@ Public Required .false. - ), - max: - (ExternalSymbol - 4 - max - 8 max - lpython_builtin - [] - max - Private - ), - max@__lpython_overloaded_2__max: - (ExternalSymbol - 4 - max@__lpython_overloaded_2__max - 8 __lpython_overloaded_2__max - lpython_builtin - [] - __lpython_overloaded_2__max - Public - ), - max@__lpython_overloaded_3__max: - (ExternalSymbol - 4 - max@__lpython_overloaded_3__max - 8 __lpython_overloaded_3__max - lpython_builtin - [] - __lpython_overloaded_3__max - Public ) }) test_max_float @@ -201,7 +171,7 @@ ) [] [] - [(= + [(Assignment (Var 4 d) (RealConstant 23.233000 @@ -209,7 +179,7 @@ ) () ) - (= + (Assignment (Var 4 e) (RealConstant 23.223300 @@ -217,7 +187,7 @@ ) () ) - (= + (Assignment (Var 4 f) (RealConstant 21.230000 @@ -227,15 +197,14 @@ ) (Assert (RealCompare - (FunctionCall - 4 max@__lpython_overloaded_2__max - 4 max - [((Var 4 d)) - ((Var 4 e)) - ((Var 4 f))] + (IntrinsicElementalFunction + Max + [(Var 4 d) + (Var 4 e) + (Var 4 f)] + 0 (Real 8) () - () ) Eq (Var 4 d) @@ -246,14 +215,13 @@ ) (Assert (RealCompare - (FunctionCall - 4 max@__lpython_overloaded_3__max - 4 max - [((Var 4 e)) - ((Var 4 f))] + (IntrinsicElementalFunction + Max + [(Var 4 e) + (Var 4 f)] + 0 (Real 8) () - () ) Eq (Var 4 e) @@ -320,36 +288,6 @@ Public Required .false. - ), - max: - (ExternalSymbol - 3 - max - 8 max - lpython_builtin - [] - max - Private - ), - max@__lpython_overloaded_0__max: - (ExternalSymbol - 3 - max@__lpython_overloaded_0__max - 8 __lpython_overloaded_0__max - lpython_builtin - [] - __lpython_overloaded_0__max - Public - ), - max@__lpython_overloaded_1__max: - (ExternalSymbol - 3 - max@__lpython_overloaded_1__max - 8 __lpython_overloaded_1__max - lpython_builtin - [] - __lpython_overloaded_1__max - Public ) }) test_max_int @@ -369,31 +307,30 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 3 b) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 3 c) (IntegerConstant 3 (Integer 4)) () ) (Assert (IntegerCompare - (FunctionCall - 3 max@__lpython_overloaded_0__max - 3 max - [((Var 3 a)) - ((Var 3 b))] + (IntrinsicElementalFunction + Max + [(Var 3 a) + (Var 3 b)] + 0 (Integer 4) () - () ) Eq (Var 3 b) @@ -404,15 +341,14 @@ ) (Assert (IntegerCompare - (FunctionCall - 3 max@__lpython_overloaded_1__max - 3 max - [((Var 3 a)) - ((Var 3 b)) - ((Var 3 c))] + (IntrinsicElementalFunction + Max + [(Var 3 a) + (Var 3 b) + (Var 3 c)] + 0 (Integer 4) () - () ) Eq (Var 3 c) @@ -423,15 +359,14 @@ ) (Assert (IntegerCompare - (FunctionCall - 3 max@__lpython_overloaded_1__max - 3 max - [((IntegerConstant 1 (Integer 4))) - ((IntegerConstant 2 (Integer 4))) - ((IntegerConstant 3 (Integer 4)))] + (IntrinsicElementalFunction + Max + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 2 (Integer 4)) + (IntegerConstant 3 (Integer 4))] + 0 (Integer 4) (IntegerConstant 3 (Integer 4)) - () ) Eq (IntegerConstant 3 (Integer 4)) @@ -445,14 +380,13 @@ ) (Assert (IntegerCompare - (FunctionCall - 3 max@__lpython_overloaded_0__max - 3 max - [((IntegerConstant 1 (Integer 4))) - ((IntegerConstant 6 (Integer 4)))] + (IntrinsicElementalFunction + Max + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 6 (Integer 4))] + 0 (Integer 4) (IntegerConstant 6 (Integer 4)) - () ) Eq (IntegerConstant 6 (Integer 4)) @@ -541,7 +475,7 @@ ) [] [] - [(= + [(Assignment (Var 6 d) (RealConstant 23.233000 @@ -549,7 +483,7 @@ ) () ) - (= + (Assignment (Var 6 e) (RealConstant 23.223300 @@ -557,7 +491,7 @@ ) () ) - (= + (Assignment (Var 6 f) (RealConstant 21.230000 @@ -567,7 +501,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(Var 6 d) (Var 6 e) @@ -585,7 +519,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(Var 6 e) (Var 6 f)] @@ -677,24 +611,24 @@ ) [] [] - [(= + [(Assignment (Var 5 a) (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (Var 5 b) (IntegerConstant 2 (Integer 4)) () ) - (= + (Assignment (Var 5 c) (IntegerConstant 3 (Integer 4)) () ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(Var 5 a) (Var 5 b)] @@ -711,7 +645,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(Var 5 a) (Var 5 b) @@ -729,7 +663,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(IntegerConstant 1 (Integer 4)) (IntegerConstant 2 (Integer 4)) @@ -750,7 +684,7 @@ ) (Assert (IntegerCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Min [(IntegerConstant 1 (Integer 4)) (IntegerConstant 6 (Integer 4))] @@ -776,20 +710,18 @@ ) }) __main__ - [lpython_builtin] + [] .false. .false. ), - lpython_builtin: - (IntrinsicModule lpython_builtin), main_program: (Program (SymbolTable - 141 + 9 { __main__global_stmts: (ExternalSymbol - 141 + 9 __main__global_stmts 2 __main__global_stmts __main__ @@ -801,7 +733,7 @@ main_program [__main__] [(SubroutineCall - 141 __main__global_stmts + 9 __main__global_stmts 2 __main__global_stmts [] () diff --git a/tests/reference/asr-test_numpy_03-e600a49.json b/tests/reference/asr-test_numpy_03-e600a49.json index 1a2834dbcb..0db96efd5d 100644 --- a/tests/reference/asr-test_numpy_03-e600a49.json +++ b/tests/reference/asr-test_numpy_03-e600a49.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_numpy_03-e600a49.stdout", - "stdout_hash": "2eb1440f0b8ed4f4faf19d9d995c7a7a0c903f895d549598bf4d7bb7", + "stdout_hash": "69fea28dc782f491d19d9df5a28c41a919e3ab5bfec6fa80b24a3b20", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_numpy_03-e600a49.stdout b/tests/reference/asr-test_numpy_03-e600a49.stdout index 567a9cb860..bf5f0a335e 100644 --- a/tests/reference/asr-test_numpy_03-e600a49.stdout +++ b/tests/reference/asr-test_numpy_03-e600a49.stdout @@ -283,7 +283,7 @@ ) [] [(Var 221 d)] - [(= + [(Assignment (Var 221 eps) (RealConstant 0.000000 @@ -291,9 +291,9 @@ ) () ) - (= + (Assignment (Var 221 b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -301,6 +301,7 @@ (IntegerConstant 256 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -317,9 +318,9 @@ (IntegerConstant 255 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 221 i) - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(Var 221 k) (IntegerConstant 16 (Integer 4))] @@ -329,7 +330,7 @@ ) () ) - (= + (Assignment (Var 221 j) (IntegerBinOp (Var 221 k) @@ -346,7 +347,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 221 b) [(() @@ -381,9 +382,9 @@ )] [] ) - (= + (Assignment (Var 221 a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -393,13 +394,14 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 221 newshape) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -407,11 +409,12 @@ (IntegerConstant 2 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 221 newshape) [(() @@ -424,7 +427,7 @@ (IntegerConstant 16 (Integer 4)) () ) - (= + (Assignment (ArrayItem (Var 221 newshape) [(() @@ -437,7 +440,7 @@ (IntegerConstant 16 (Integer 4)) () ) - (= + (Assignment (Var 221 a) (ArrayReshape (Var 221 b) @@ -489,7 +492,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -544,9 +547,9 @@ )] [] ) - (= + (Assignment (Var 221 c) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -558,13 +561,14 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 221 newshape1) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -572,11 +576,12 @@ (IntegerConstant 3 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 221 newshape1) [(() @@ -589,7 +594,7 @@ (IntegerConstant 16 (Integer 4)) () ) - (= + (Assignment (ArrayItem (Var 221 newshape1) [(() @@ -602,7 +607,7 @@ (IntegerConstant 16 (Integer 4)) () ) - (= + (Assignment (ArrayItem (Var 221 newshape1) [(() @@ -615,7 +620,7 @@ (IntegerConstant 16 (Integer 4)) () ) - (= + (Assignment (Var 221 c) (ArrayReshape (Var 221 d) @@ -679,7 +684,7 @@ (IntegerConstant 1 (Integer 4))) [(Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -993,7 +998,7 @@ ) [] [(Var 220 a)] - [(= + [(Assignment (Var 220 eps) (RealConstant 0.000000 @@ -1001,9 +1006,9 @@ ) () ) - (= + (Assignment (Var 220 b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1011,13 +1016,14 @@ (IntegerConstant 256 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 220 newshape) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1025,11 +1031,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 220 newshape) [(() @@ -1042,7 +1049,7 @@ (IntegerConstant 256 (Integer 4)) () ) - (= + (Assignment (Var 220 b) (ArrayReshape (Var 220 a) @@ -1080,9 +1087,9 @@ (IntegerConstant 255 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 220 i) - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(Var 220 k) (IntegerConstant 16 (Integer 4))] @@ -1092,7 +1099,7 @@ ) () ) - (= + (Assignment (Var 220 j) (IntegerBinOp (Var 220 k) @@ -1111,7 +1118,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -1161,9 +1168,9 @@ )] [] ) - (= + (Assignment (Var 220 c) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1175,13 +1182,14 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 220 c) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1193,6 +1201,7 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1233,7 +1242,7 @@ (IntegerConstant 15 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 220 c) [(() @@ -1284,9 +1293,9 @@ )] [] ) - (= + (Assignment (Var 220 d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1294,13 +1303,14 @@ (IntegerConstant 4096 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 220 newshape1) - (ArrayConstant + (ArrayConstructor [] (Array (Integer 4) @@ -1308,11 +1318,12 @@ (IntegerConstant 1 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (ArrayItem (Var 220 newshape1) [(() @@ -1325,7 +1336,7 @@ (IntegerConstant 4096 (Integer 4)) () ) - (= + (Assignment (Var 220 d) (ArrayReshape (Var 220 c) @@ -1363,7 +1374,7 @@ (IntegerConstant 4095 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 220 i) (Cast (RealBinOp @@ -1392,9 +1403,9 @@ ) () ) - (= + (Assignment (Var 220 j) - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(IntegerBinOp (Var 220 l) @@ -1416,7 +1427,7 @@ ) () ) - (= + (Assignment (Var 220 k) (IntegerBinOp (IntegerBinOp @@ -1447,7 +1458,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (RealBinOp @@ -1641,9 +1652,9 @@ [test_nd_to_1d test_1d_to_nd] [] - [(= + [(Assignment (Var 222 a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1653,6 +1664,7 @@ (IntegerConstant 16 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1681,7 +1693,7 @@ (IntegerConstant 15 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 222 a) [(() @@ -1740,9 +1752,9 @@ ))] () ) - (= + (Assignment (Var 222 d) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -1750,6 +1762,7 @@ (IntegerConstant 4096 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -1766,7 +1779,7 @@ (IntegerConstant 4095 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (Var 222 i) (Cast (RealBinOp @@ -1795,9 +1808,9 @@ ) () ) - (= + (Assignment (Var 222 j) - (IntrinsicScalarFunction + (IntrinsicElementalFunction FloorDiv [(IntegerBinOp (Var 222 l) @@ -1819,7 +1832,7 @@ ) () ) - (= + (Assignment (Var 222 k) (IntegerBinOp (IntegerBinOp @@ -1848,7 +1861,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 222 d) [(() diff --git a/tests/reference/asr-test_numpy_04-ecbb614.json b/tests/reference/asr-test_numpy_04-ecbb614.json index 5b681bab99..af3af53fb2 100644 --- a/tests/reference/asr-test_numpy_04-ecbb614.json +++ b/tests/reference/asr-test_numpy_04-ecbb614.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_numpy_04-ecbb614.stdout", - "stdout_hash": "9ef682c04c3f77549cef1fd1073983fdfef987c2491900a3bfa6dd02", + "stdout_hash": "19c7ccaca422743ad98392c5641b61a0874cc42140d1ad9fd0abaacf", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_numpy_04-ecbb614.stdout b/tests/reference/asr-test_numpy_04-ecbb614.stdout index 7c26dc63af..f47f146f62 100644 --- a/tests/reference/asr-test_numpy_04-ecbb614.stdout +++ b/tests/reference/asr-test_numpy_04-ecbb614.stdout @@ -146,7 +146,7 @@ ) [] [] - [(= + [(Assignment (Var 220 x) (ArrayConstant [(RealConstant @@ -171,7 +171,7 @@ ) () ) - (= + (Assignment (Var 220 eps) (RealConstant 0.000000 @@ -181,7 +181,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ArrayItem @@ -214,7 +214,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ArrayItem @@ -247,7 +247,7 @@ ) (Assert (RealCompare - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(RealBinOp (ArrayItem @@ -344,7 +344,7 @@ ) [] [] - [(= + [(Assignment (Var 221 x) (ArrayConstant [(IntegerConstant 1 (Integer 4)) @@ -360,7 +360,7 @@ ) () ) - (= + (Assignment (Var 221 eps) (RealConstant 0.000000 @@ -371,7 +371,7 @@ (Assert (RealCompare (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerBinOp (ArrayItem @@ -406,7 +406,7 @@ (Assert (RealCompare (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerBinOp (ArrayItem @@ -441,7 +441,7 @@ (Assert (RealCompare (Cast - (IntrinsicScalarFunction + (IntrinsicElementalFunction Abs [(IntegerBinOp (ArrayItem diff --git a/tests/reference/asr-test_operator_01-0f232bf.json b/tests/reference/asr-test_operator_01-0f232bf.json index 9cb9b85ba8..c154bb190c 100644 --- a/tests/reference/asr-test_operator_01-0f232bf.json +++ b/tests/reference/asr-test_operator_01-0f232bf.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_operator_01-0f232bf.stderr", - "stderr_hash": "6f529c2fc1fc5a489879c5d684c3415269794e563be85d62098aed7c", + "stderr_hash": "6e1377772200a65ab05a2abdab74d350f87c4a1f1f3c69cc321106fe", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_operator_01-0f232bf.stderr b/tests/reference/asr-test_operator_01-0f232bf.stderr index 1a939f05a8..d95933177d 100644 --- a/tests/reference/asr-test_operator_01-0f232bf.stderr +++ b/tests/reference/asr-test_operator_01-0f232bf.stderr @@ -3,3 +3,7 @@ semantic error: Unary operator '-' not supported for type struct A | 9 | print(-a) | ^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_optional-97e5371.json b/tests/reference/asr-test_optional-97e5371.json index 7dbe53ca63..7b11169efa 100644 --- a/tests/reference/asr-test_optional-97e5371.json +++ b/tests/reference/asr-test_optional-97e5371.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_optional-97e5371.stderr", - "stderr_hash": "b9cc75eb200847db5d4d39d9f511959ebf22faad68cf0096c7a2b68c", + "stderr_hash": "651a42d14e426b122a1048a63882de59e3508c8c68cdb1c25449e47a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_optional-97e5371.stderr b/tests/reference/asr-test_optional-97e5371.stderr index 4c93a66d6b..1dfcd81cb4 100644 --- a/tests/reference/asr-test_optional-97e5371.stderr +++ b/tests/reference/asr-test_optional-97e5371.stderr @@ -3,3 +3,7 @@ semantic error: The type 'Optional' is undeclared. | 1 | def match(pat : str, string : str) -> Optional[list[str] | str]: | ^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_ord-316ce61.json b/tests/reference/asr-test_ord-316ce61.json index 362e582d03..b7b8753175 100644 --- a/tests/reference/asr-test_ord-316ce61.json +++ b/tests/reference/asr-test_ord-316ce61.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_ord-316ce61.stderr", - "stderr_hash": "dda39c93777d64449510b35e893d516cd53ac299cd2b5f19b08464bd", + "stderr_hash": "46657c4e3818a75f46a02f519ec235038d7b7b026dc486817d2457c8", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_ord-316ce61.stderr b/tests/reference/asr-test_ord-316ce61.stderr index 45103fea10..7c55fcceaa 100644 --- a/tests/reference/asr-test_ord-316ce61.stderr +++ b/tests/reference/asr-test_ord-316ce61.stderr @@ -3,3 +3,7 @@ semantic error: ord() is only supported for `str` of length 1 | 3 | i = ord('ab') | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pointer_types-1bf0d01.json b/tests/reference/asr-test_pointer_types-1bf0d01.json index a832067275..7e1031bd8b 100644 --- a/tests/reference/asr-test_pointer_types-1bf0d01.json +++ b/tests/reference/asr-test_pointer_types-1bf0d01.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_pointer_types-1bf0d01.stderr", - "stderr_hash": "3fcd692a6b79b6b3f22fc7a2957df19219fc817446aa6d46f47d049f", + "stderr_hash": "b4df27ea3ce9cb7b84a7dc30a2411e1b0521995bc564c60bdd1944f3", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_pointer_types-1bf0d01.stderr b/tests/reference/asr-test_pointer_types-1bf0d01.stderr index 4a61aeb2e6..9cc01c29ad 100644 --- a/tests/reference/asr-test_pointer_types-1bf0d01.stderr +++ b/tests/reference/asr-test_pointer_types-1bf0d01.stderr @@ -3,3 +3,7 @@ semantic error: Casting not supported for different pointer types. Received targ | 8 | yptr1 = pointer(y) | ^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pow-3f5d550.json b/tests/reference/asr-test_pow-3f5d550.json index 894399f654..71a5367d84 100644 --- a/tests/reference/asr-test_pow-3f5d550.json +++ b/tests/reference/asr-test_pow-3f5d550.json @@ -8,6 +8,6 @@ "stdout": "asr-test_pow-3f5d550.stdout", "stdout_hash": "407d7a20ed3b5b82ff211a9578e4978b68beca005c6791f49a0a6c1d", "stderr": "asr-test_pow-3f5d550.stderr", - "stderr_hash": "3d950301563cce75654f28bf41f6f53428ed1f5ae997774345f374a3", + "stderr_hash": "c8d2ad5bada75565722f6b33ab7bcc685bbf13892eb141b8086b56cf", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_pow-3f5d550.stderr b/tests/reference/asr-test_pow-3f5d550.stderr index 712d80384b..71556ee754 100644 --- a/tests/reference/asr-test_pow-3f5d550.stderr +++ b/tests/reference/asr-test_pow-3f5d550.stderr @@ -3,3 +3,7 @@ style suggestion: Could have used '**' instead of 'pow' | 2 | print(pow(2, 2)) | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pow1-581ef42.json b/tests/reference/asr-test_pow1-581ef42.json index a5584b1bc7..a39546dc88 100644 --- a/tests/reference/asr-test_pow1-581ef42.json +++ b/tests/reference/asr-test_pow1-581ef42.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_pow1-581ef42.stderr", - "stderr_hash": "7f7cc07cf6f08f2d953d6e6c1f4892e6379faaf8aa668117234293d0", + "stderr_hash": "21da5f9184a23c2acd4c61ce960a2223f03ef94a7c64bd8541e13d88", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_pow1-581ef42.stderr b/tests/reference/asr-test_pow1-581ef42.stderr index fa7160f584..26d3347bfb 100644 --- a/tests/reference/asr-test_pow1-581ef42.stderr +++ b/tests/reference/asr-test_pow1-581ef42.stderr @@ -9,3 +9,7 @@ semantic error: Arguments do not match for any generic procedure, pow | 4 | print(pow(x,3)) | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pow2-0dcbd7d.json b/tests/reference/asr-test_pow2-0dcbd7d.json index 083bc76b8d..4c75f9c0ad 100644 --- a/tests/reference/asr-test_pow2-0dcbd7d.json +++ b/tests/reference/asr-test_pow2-0dcbd7d.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_pow2-0dcbd7d.stderr", - "stderr_hash": "1d1d3a4a308e068439ac40685fcad6f29750560722b910be3341ce3c", + "stderr_hash": "bfb63764cf1f2e0ba85a55ac662e175793c1277192dda8663bca016e", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_pow2-0dcbd7d.stderr b/tests/reference/asr-test_pow2-0dcbd7d.stderr index 896faa98e5..81cc979f80 100644 --- a/tests/reference/asr-test_pow2-0dcbd7d.stderr +++ b/tests/reference/asr-test_pow2-0dcbd7d.stderr @@ -9,3 +9,7 @@ semantic error: Arguments do not match for any generic procedure, pow | 12 | print(pow(a, b, c, d)) | ^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pow3-79749ed.json b/tests/reference/asr-test_pow3-79749ed.json index cd0f9f0d33..fbf05560d0 100644 --- a/tests/reference/asr-test_pow3-79749ed.json +++ b/tests/reference/asr-test_pow3-79749ed.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_pow3-79749ed.stderr", - "stderr_hash": "4a6600740ad466d250f39b76130ab5ab796312b1ee89c2d72847500f", + "stderr_hash": "e10268a09c7b62c80c73519819df3a0244adb3e7751802c3d9cf24de", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_pow3-79749ed.stderr b/tests/reference/asr-test_pow3-79749ed.stderr index 6456498803..631c4bf14d 100644 --- a/tests/reference/asr-test_pow3-79749ed.stderr +++ b/tests/reference/asr-test_pow3-79749ed.stderr @@ -9,3 +9,7 @@ semantic error: Arguments do not match for any generic procedure, pow | 8 | print(pow(x, a)) | ^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_pow4-ef60978.json b/tests/reference/asr-test_pow4-ef60978.json index 2e98c401ce..d7db59f197 100644 --- a/tests/reference/asr-test_pow4-ef60978.json +++ b/tests/reference/asr-test_pow4-ef60978.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_pow4-ef60978.stderr", - "stderr_hash": "ddc8a81609479bf82d256c9cb8d4d54526bd6656632a0d1e2f1ada2c", + "stderr_hash": "ca9308b1cd1d33f159f59c7181ed31e75579eb657f066f97604dee84", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_pow4-ef60978.stderr b/tests/reference/asr-test_pow4-ef60978.stderr index 0663475b44..825dbaaed4 100644 --- a/tests/reference/asr-test_pow4-ef60978.stderr +++ b/tests/reference/asr-test_pow4-ef60978.stderr @@ -9,3 +9,7 @@ semantic error: Arguments do not match for any generic procedure, pow | 10 | print(pow(x, a, b)) | ^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_print1-f1f36f1.json b/tests/reference/asr-test_print1-f1f36f1.json index 0c4988e3a3..e0adc68f51 100644 --- a/tests/reference/asr-test_print1-f1f36f1.json +++ b/tests/reference/asr-test_print1-f1f36f1.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_print1-f1f36f1.stderr", - "stderr_hash": "da6324bcc282ecb93fe6784b206f8a9d8f04ae56341339b13de71bd4", + "stderr_hash": "d410c2fa1582a61b0760f4417c734352412008486e9120cdf392c933", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_print1-f1f36f1.stderr b/tests/reference/asr-test_print1-f1f36f1.stderr index b28bc75a72..13346da034 100644 --- a/tests/reference/asr-test_print1-f1f36f1.stderr +++ b/tests/reference/asr-test_print1-f1f36f1.stderr @@ -3,3 +3,7 @@ semantic error: Separator is expected to be of string type | 2 | print("a", "b", sep=2) | ^ Expected string, found: integer + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_print2-64acb15.json b/tests/reference/asr-test_print2-64acb15.json index 050b4cc698..c99ecf4788 100644 --- a/tests/reference/asr-test_print2-64acb15.json +++ b/tests/reference/asr-test_print2-64acb15.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_print2-64acb15.stderr", - "stderr_hash": "e92bba85b957e7034c5172981b3b27ed7b3f0ac62167d82175890bc9", + "stderr_hash": "a6e1dac571eb446d22562c399026488538fd181edd7455cf5d2fd92a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_print2-64acb15.stderr b/tests/reference/asr-test_print2-64acb15.stderr index 6ed1c334b1..8a2c71172d 100644 --- a/tests/reference/asr-test_print2-64acb15.stderr +++ b/tests/reference/asr-test_print2-64acb15.stderr @@ -3,3 +3,7 @@ semantic error: End is expected to be of string type | 2 | print("a", "b", end=1) | ^ Expected string, found: integer + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_return1-2603c9e.json b/tests/reference/asr-test_return1-2603c9e.json index cc65ed1a6a..f41bf64d24 100644 --- a/tests/reference/asr-test_return1-2603c9e.json +++ b/tests/reference/asr-test_return1-2603c9e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_return1-2603c9e.stderr", - "stderr_hash": "6449cc5e148acf72281e7ef604decd32889ceb27b87052fe8ff8eb50", + "stderr_hash": "e15b438a085131755392d90c9b2f3c760d765200844fd13ae44b6efe", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_return1-2603c9e.stderr b/tests/reference/asr-test_return1-2603c9e.stderr index 82fec8d42d..5f8496938d 100644 --- a/tests/reference/asr-test_return1-2603c9e.stderr +++ b/tests/reference/asr-test_return1-2603c9e.stderr @@ -3,3 +3,7 @@ semantic error: Type Mismatch in return, found ('f64' and 'i32') | 4 | return x | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_return2-add829b.json b/tests/reference/asr-test_return2-add829b.json index abdb4461f7..3b6762bb2d 100644 --- a/tests/reference/asr-test_return2-add829b.json +++ b/tests/reference/asr-test_return2-add829b.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_return2-add829b.stderr", - "stderr_hash": "493f7a8431e00a1bfeb1756b0718b0a40458883c8b9eb379f0c5b536", + "stderr_hash": "774b498d1df74f52cd7cd4992c98059f1895a0f5cb182538e79080db", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_return2-add829b.stderr b/tests/reference/asr-test_return2-add829b.stderr index a9070a952d..152ae04127 100644 --- a/tests/reference/asr-test_return2-add829b.stderr +++ b/tests/reference/asr-test_return2-add829b.stderr @@ -3,3 +3,7 @@ semantic error: Return type of function is not defined | 4 | return x | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_set1-11379c7.json b/tests/reference/asr-test_set1-11379c7.json index 417bba61b8..df336cdc65 100644 --- a/tests/reference/asr-test_set1-11379c7.json +++ b/tests/reference/asr-test_set1-11379c7.json @@ -5,9 +5,9 @@ "infile_hash": "54179c34d3818cd0b57d582c930226ce5443a43386ae981aab02e50b", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, + "stdout": "asr-test_set1-11379c7.stdout", + "stdout_hash": "857687f9f250fb69bc80b8c9645929d6cb586a0397ce964a15fd81d2", "stderr": "asr-test_set1-11379c7.stderr", - "stderr_hash": "64dea3d94817d0666cf71481546f7ec61639f47a3b696fe96ae287c6", - "returncode": 2 + "stderr_hash": "e027b0450496c25fb49e362f0f9a98bea7327dc37bdd5da486bc2f69", + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_set1-11379c7.stderr b/tests/reference/asr-test_set1-11379c7.stderr index f5851bc83d..9fe2f48e9a 100644 --- a/tests/reference/asr-test_set1-11379c7.stderr +++ b/tests/reference/asr-test_set1-11379c7.stderr @@ -3,3 +3,7 @@ semantic error: Argument to set.add must be of same type as set's element type | 6 | a.add('err') | ^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_set1-11379c7.stdout b/tests/reference/asr-test_set1-11379c7.stdout new file mode 100644 index 0000000000..883a3343ea --- /dev/null +++ b/tests/reference/asr-test_set1-11379c7.stdout @@ -0,0 +1,88 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + test1: + (Function + (SymbolTable + 3 + { + a: + (Variable + 3 + a + [] + Local + () + () + Default + (Set + (Integer 4) + ) + () + Source + Public + Required + .false. + ) + }) + test1 + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 a) + (SetConstant + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 2 (Integer 4)) + (IntegerConstant 3 (Integer 4))] + (Set + (Integer 4) + ) + ) + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 4 + { + + }) + main_program + [] + [] + ) + }) + [] +) diff --git a/tests/reference/asr-test_set2-d91a6f0.json b/tests/reference/asr-test_set2-d91a6f0.json index 4c1d7ad258..1600612a87 100644 --- a/tests/reference/asr-test_set2-d91a6f0.json +++ b/tests/reference/asr-test_set2-d91a6f0.json @@ -5,9 +5,9 @@ "infile_hash": "2d561d934090bedc052b2ef17bc3ac9b59ed94298fd39cbea2c9ba15", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, + "stdout": "asr-test_set2-d91a6f0.stdout", + "stdout_hash": "857687f9f250fb69bc80b8c9645929d6cb586a0397ce964a15fd81d2", "stderr": "asr-test_set2-d91a6f0.stderr", - "stderr_hash": "36a3e507b04f030fc4e281ffe82947765ef640b6c558030957bd3e90", - "returncode": 2 + "stderr_hash": "4fae03841fb86eb53e927579d7a9d8baf4759043afb220fff1f450df", + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_set2-d91a6f0.stderr b/tests/reference/asr-test_set2-d91a6f0.stderr index 29a2683c11..1803823d03 100644 --- a/tests/reference/asr-test_set2-d91a6f0.stderr +++ b/tests/reference/asr-test_set2-d91a6f0.stderr @@ -3,3 +3,7 @@ semantic error: Call to set.remove must have exactly one argument | 6 | a.remove('error', 'error2') | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_set2-d91a6f0.stdout b/tests/reference/asr-test_set2-d91a6f0.stdout new file mode 100644 index 0000000000..883a3343ea --- /dev/null +++ b/tests/reference/asr-test_set2-d91a6f0.stdout @@ -0,0 +1,88 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + test1: + (Function + (SymbolTable + 3 + { + a: + (Variable + 3 + a + [] + Local + () + () + Default + (Set + (Integer 4) + ) + () + Source + Public + Required + .false. + ) + }) + test1 + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 a) + (SetConstant + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 2 (Integer 4)) + (IntegerConstant 3 (Integer 4))] + (Set + (Integer 4) + ) + ) + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 4 + { + + }) + main_program + [] + [] + ) + }) + [] +) diff --git a/tests/reference/asr-test_set3-f9bbffb.json b/tests/reference/asr-test_set3-f9bbffb.json index 877113068e..e9142fb6a0 100644 --- a/tests/reference/asr-test_set3-f9bbffb.json +++ b/tests/reference/asr-test_set3-f9bbffb.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_set3-f9bbffb.stderr", - "stderr_hash": "1ec6cfef0827e97a905c5927de43b74452777394b1f5110e94e5cf97", + "stderr_hash": "cc740ba3fe5e858473af83c53e76abf8862b1b3a9e2ef2acf774606a", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_set3-f9bbffb.stderr b/tests/reference/asr-test_set3-f9bbffb.stderr index ecc3bf6177..156c762d2b 100644 --- a/tests/reference/asr-test_set3-f9bbffb.stderr +++ b/tests/reference/asr-test_set3-f9bbffb.stderr @@ -3,3 +3,7 @@ semantic error: pop() takes no arguments (1 given) | 5 | i = s.pop(3) | ^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_set4-53fea39.json b/tests/reference/asr-test_set4-53fea39.json index aad37eb089..f765383e83 100644 --- a/tests/reference/asr-test_set4-53fea39.json +++ b/tests/reference/asr-test_set4-53fea39.json @@ -5,9 +5,9 @@ "infile_hash": "3d78c7ad82aa32c3a4cc5f1a7d44e53b81639194f55672ddc99b4d2d", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, + "stdout": "asr-test_set4-53fea39.stdout", + "stdout_hash": "23bfad9943e2e8e357c231e80e963e3d43273857a5c011ef5739a97e", "stderr": "asr-test_set4-53fea39.stderr", - "stderr_hash": "d9646bd3609c55ff39f57ca435fedc7dabed530caf28caddc9e58a06", - "returncode": 2 + "stderr_hash": "926265c535aa5cc581a1e427cc1aea9279568b7b56de80e8232d4d7e", + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_set4-53fea39.stderr b/tests/reference/asr-test_set4-53fea39.stderr index 9ce2e3863c..c3879154ee 100644 --- a/tests/reference/asr-test_set4-53fea39.stderr +++ b/tests/reference/asr-test_set4-53fea39.stderr @@ -3,3 +3,7 @@ semantic error: Call to set.add must have exactly one argument | 6 | a.add(3, 4) | ^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_set4-53fea39.stdout b/tests/reference/asr-test_set4-53fea39.stdout new file mode 100644 index 0000000000..5753962ce2 --- /dev/null +++ b/tests/reference/asr-test_set4-53fea39.stdout @@ -0,0 +1,88 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + test4: + (Function + (SymbolTable + 3 + { + a: + (Variable + 3 + a + [] + Local + () + () + Default + (Set + (Integer 4) + ) + () + Source + Public + Required + .false. + ) + }) + test4 + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 a) + (SetConstant + [(IntegerConstant 1 (Integer 4)) + (IntegerConstant 2 (Integer 4)) + (IntegerConstant 3 (Integer 4))] + (Set + (Integer 4) + ) + ) + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 4 + { + + }) + main_program + [] + [] + ) + }) + [] +) diff --git a/tests/reference/asr-test_set_indexing-a1c21b8.json b/tests/reference/asr-test_set_indexing-a1c21b8.json index 6bb6e96be3..c98fd7babc 100644 --- a/tests/reference/asr-test_set_indexing-a1c21b8.json +++ b/tests/reference/asr-test_set_indexing-a1c21b8.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_set_indexing-a1c21b8.stderr", - "stderr_hash": "fe69096aca9c3be072acac0e28081e5378f30d4ba335176abc76c555", + "stderr_hash": "8c029f85f2a003973287c72d0e800a5723a4e408cf9d697b1d98fc18", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_set_indexing-a1c21b8.stderr b/tests/reference/asr-test_set_indexing-a1c21b8.stderr index 1a7be88156..cb502632db 100644 --- a/tests/reference/asr-test_set_indexing-a1c21b8.stderr +++ b/tests/reference/asr-test_set_indexing-a1c21b8.stderr @@ -3,3 +3,7 @@ semantic error: 'set' object is not subscriptable | 7 | a = s[0] | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_capitalize-9f8dfa9.json b/tests/reference/asr-test_str_capitalize-9f8dfa9.json index 88a959a54d..d3d78923fc 100644 --- a/tests/reference/asr-test_str_capitalize-9f8dfa9.json +++ b/tests/reference/asr-test_str_capitalize-9f8dfa9.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_capitalize-9f8dfa9.stderr", - "stderr_hash": "7dea3deffeee54e7f479d4c0dbcd7b5aab3b1a28e4a568adfb52cf51", + "stderr_hash": "7da52775a48272ea41acf548fc9b0230c4978de9263ae0e06f22a6ff", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_capitalize-9f8dfa9.stderr b/tests/reference/asr-test_str_capitalize-9f8dfa9.stderr index c04687d572..3898e44e76 100644 --- a/tests/reference/asr-test_str_capitalize-9f8dfa9.stderr +++ b/tests/reference/asr-test_str_capitalize-9f8dfa9.stderr @@ -3,3 +3,7 @@ semantic error: str.capitalize() takes no arguments | 4 | s = s.capitalize(23) | ^^^^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_indexing-b200a4e.json b/tests/reference/asr-test_str_indexing-b200a4e.json index 1193d8bad7..47a68e0897 100644 --- a/tests/reference/asr-test_str_indexing-b200a4e.json +++ b/tests/reference/asr-test_str_indexing-b200a4e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_indexing-b200a4e.stderr", - "stderr_hash": "eddc45a6ba83dc10551fd9685b6ea1096828ae29f6b9cce07cfe5de1", + "stderr_hash": "0219e81533d69f5cf7a5664282908bf507ace1a571febcf7c2938698", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_indexing-b200a4e.stderr b/tests/reference/asr-test_str_indexing-b200a4e.stderr index fb521217df..64311de077 100644 --- a/tests/reference/asr-test_str_indexing-b200a4e.stderr +++ b/tests/reference/asr-test_str_indexing-b200a4e.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in index, expected a single integer or slice | 4 | print(s[1.2]) | ^^^ type mismatch (found: 'f64', expected: 'i32' or slice) + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_slicing-eca1381.json b/tests/reference/asr-test_str_slicing-eca1381.json index 684a869d6a..51efc8dc65 100644 --- a/tests/reference/asr-test_str_slicing-eca1381.json +++ b/tests/reference/asr-test_str_slicing-eca1381.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_slicing-eca1381.stderr", - "stderr_hash": "7374319e4378d1cc717e1bab3f68f207cb90c40c168d5700c77d189b", + "stderr_hash": "2b843ddc51109f0b9edeb15655b9c5fab27ca0b521b74da99ab50351", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_slicing-eca1381.stderr b/tests/reference/asr-test_str_slicing-eca1381.stderr index d50b2ffd94..c8bef51c64 100644 --- a/tests/reference/asr-test_str_slicing-eca1381.stderr +++ b/tests/reference/asr-test_str_slicing-eca1381.stderr @@ -3,3 +3,7 @@ semantic error: slice indices must be integers or None | 4 | print(s[1:2.2]) | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_slicing2-2f07e9a.json b/tests/reference/asr-test_str_slicing2-2f07e9a.json index dc63e9a7b0..52f94de8a5 100644 --- a/tests/reference/asr-test_str_slicing2-2f07e9a.json +++ b/tests/reference/asr-test_str_slicing2-2f07e9a.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_slicing2-2f07e9a.stderr", - "stderr_hash": "48a9286126c2333bdf5237358bd4ad27acac4a16a78069c9bd36d089", + "stderr_hash": "ad9eb0eea074a4462ebc45713d14d3b6e11e2c4ca86c82f053f53a25", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_slicing2-2f07e9a.stderr b/tests/reference/asr-test_str_slicing2-2f07e9a.stderr index 94a5f03259..edea305c9e 100644 --- a/tests/reference/asr-test_str_slicing2-2f07e9a.stderr +++ b/tests/reference/asr-test_str_slicing2-2f07e9a.stderr @@ -3,3 +3,7 @@ semantic error: slice indices must be integers or None | 4 | print(s[1.5:3]) | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_slicing3-fe6a03c.json b/tests/reference/asr-test_str_slicing3-fe6a03c.json index d1fe49fdfe..8e12247a83 100644 --- a/tests/reference/asr-test_str_slicing3-fe6a03c.json +++ b/tests/reference/asr-test_str_slicing3-fe6a03c.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_slicing3-fe6a03c.stderr", - "stderr_hash": "5f7553d1509bed25d5137abc4fc2cb1d2cb983a1fab81d8d178ed197", + "stderr_hash": "d5d6a1b00748dccfea12a4e78c3047d22cee746035e20953bff636ee", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_slicing3-fe6a03c.stderr b/tests/reference/asr-test_str_slicing3-fe6a03c.stderr index b1180c30ae..8833eb5539 100644 --- a/tests/reference/asr-test_str_slicing3-fe6a03c.stderr +++ b/tests/reference/asr-test_str_slicing3-fe6a03c.stderr @@ -3,3 +3,7 @@ semantic error: slice indices must be integers or None | 4 | print(s[1:3:0.5]) | ^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_slicing4-a0c7a69.json b/tests/reference/asr-test_str_slicing4-a0c7a69.json index ceff8659bb..9203e1aae9 100644 --- a/tests/reference/asr-test_str_slicing4-a0c7a69.json +++ b/tests/reference/asr-test_str_slicing4-a0c7a69.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_slicing4-a0c7a69.stderr", - "stderr_hash": "a5dd047df86649936606a0b134d10e76c6aacb224319be4aefd64bfe", + "stderr_hash": "09940a012368e10f6c63113d8eef43973da2570f1e3eda18b4db1016", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_slicing4-a0c7a69.stderr b/tests/reference/asr-test_str_slicing4-a0c7a69.stderr index 8709b99ee8..3888ac89a4 100644 --- a/tests/reference/asr-test_str_slicing4-a0c7a69.stderr +++ b/tests/reference/asr-test_str_slicing4-a0c7a69.stderr @@ -3,3 +3,7 @@ semantic error: slice step cannot be zero | 4 | print(s[0:1:0]) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_str_to_int-61553e7.json b/tests/reference/asr-test_str_to_int-61553e7.json index ac1093b9c8..78e8f24156 100644 --- a/tests/reference/asr-test_str_to_int-61553e7.json +++ b/tests/reference/asr-test_str_to_int-61553e7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_str_to_int-61553e7.stderr", - "stderr_hash": "1998e37d9abe044f164c73ea1e000ce748ed43af5ea14c2eb4715f11", + "stderr_hash": "18dc06e9636f1028811bf8add4615471ff55ced13de0bb9c6c9c35c6", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_str_to_int-61553e7.stderr b/tests/reference/asr-test_str_to_int-61553e7.stderr index 785d95ba7f..f96780d866 100644 --- a/tests/reference/asr-test_str_to_int-61553e7.stderr +++ b/tests/reference/asr-test_str_to_int-61553e7.stderr @@ -3,3 +3,7 @@ semantic error: invalid literal for int() with base 10: '3abc' | 2 | print(int('3abc')) | ^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_tuple1-7abe88f.json b/tests/reference/asr-test_tuple1-7abe88f.json index e308970eea..dab943945d 100644 --- a/tests/reference/asr-test_tuple1-7abe88f.json +++ b/tests/reference/asr-test_tuple1-7abe88f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_tuple1-7abe88f.stderr", - "stderr_hash": "56df3d46c63077fcdd09c3b54b63e6e096d7d39b2f8cfb61dab0930a", + "stderr_hash": "e7c4c4d58e01c5214ed5347828ca2b067a54a3525ee036ac564d6001", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_tuple1-7abe88f.stderr b/tests/reference/asr-test_tuple1-7abe88f.stderr index c66cc64946..5f2473b23a 100644 --- a/tests/reference/asr-test_tuple1-7abe88f.stderr +++ b/tests/reference/asr-test_tuple1-7abe88f.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in assignment, the types must be compatible | 3 | t = (1, 2) | ^ ^^^^^^ type mismatch ('tuple[i32, str]' and 'tuple[i32, i32]') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_tuple2-b046610.json b/tests/reference/asr-test_tuple2-b046610.json index 051ed20bfb..f6c6125d0b 100644 --- a/tests/reference/asr-test_tuple2-b046610.json +++ b/tests/reference/asr-test_tuple2-b046610.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_tuple2-b046610.stderr", - "stderr_hash": "1e22bbde9c9fdc171314f1158dcac6bf6373d94e00c9878f66d7b667", + "stderr_hash": "6e5fabb92f9ff098bd66a44fc35fa3ad474ec51d76277166a474552b", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_tuple2-b046610.stderr b/tests/reference/asr-test_tuple2-b046610.stderr index e99518093e..a32a938a78 100644 --- a/tests/reference/asr-test_tuple2-b046610.stderr +++ b/tests/reference/asr-test_tuple2-b046610.stderr @@ -3,3 +3,7 @@ semantic error: Runtime Indexing with tuple[i32, i32, i32] is not possible. | 4 | print(t[x]) | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_tuple3-19fa47f.json b/tests/reference/asr-test_tuple3-19fa47f.json index 0a703f17d4..d1674c36aa 100644 --- a/tests/reference/asr-test_tuple3-19fa47f.json +++ b/tests/reference/asr-test_tuple3-19fa47f.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_tuple3-19fa47f.stderr", - "stderr_hash": "780d951c4bfa3476ee84d16d9a89c5a9255691b270bfb312d974608e", + "stderr_hash": "842e7a83a11ec5b255d3891c08438a4ce4b0e1a375b754d69434db93", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_tuple3-19fa47f.stderr b/tests/reference/asr-test_tuple3-19fa47f.stderr index fe438fb382..4e4d47db23 100644 --- a/tests/reference/asr-test_tuple3-19fa47f.stderr +++ b/tests/reference/asr-test_tuple3-19fa47f.stderr @@ -3,3 +3,7 @@ semantic error: Tuple index out of bounds | 3 | print(t[-4]) | ^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_type_mismatch_01-09e8af3.json b/tests/reference/asr-test_type_mismatch_01-09e8af3.json index ce2513c935..929c226258 100644 --- a/tests/reference/asr-test_type_mismatch_01-09e8af3.json +++ b/tests/reference/asr-test_type_mismatch_01-09e8af3.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_type_mismatch_01-09e8af3.stderr", - "stderr_hash": "78ff11b22438e133b740e778063db612841fb15ef00f8599bdf8602c", + "stderr_hash": "f7d859ea11d62a6c968ba5dcd8b9c8507f584beaaa6a48198e476f7d", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_type_mismatch_01-09e8af3.stderr b/tests/reference/asr-test_type_mismatch_01-09e8af3.stderr index 3dc100fad6..cbbed3fb96 100644 --- a/tests/reference/asr-test_type_mismatch_01-09e8af3.stderr +++ b/tests/reference/asr-test_type_mismatch_01-09e8af3.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in shorthand operator, the types must be compatibl | 6 | a /= b | ^ ^ type mismatch ('i32' and 'f64') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_unary_op_03-e799eae.json b/tests/reference/asr-test_unary_op_03-e799eae.json index e3cad84dd5..025e9de9a2 100644 --- a/tests/reference/asr-test_unary_op_03-e799eae.json +++ b/tests/reference/asr-test_unary_op_03-e799eae.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-test_unary_op_03-e799eae.stdout", - "stdout_hash": "4511db7e0936003a81bcb4c6b4c1cbc60070f29a9fd7dd04e8d3d137", + "stdout_hash": "15a19e670176a5670449287ffdb4a8b399018063c96175874a826507", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-test_unary_op_03-e799eae.stdout b/tests/reference/asr-test_unary_op_03-e799eae.stdout index e4cdc4204f..858f09690f 100644 --- a/tests/reference/asr-test_unary_op_03-e799eae.stdout +++ b/tests/reference/asr-test_unary_op_03-e799eae.stdout @@ -98,12 +98,12 @@ ) [] [] - [(= + [(Assignment (Var 3 i) (IntegerConstant 5 (Integer 4)) () ) - (= + (Assignment (Var 3 res) (IntegerBitNot (Var 3 i) @@ -126,7 +126,7 @@ ) () ) - (= + (Assignment (Var 3 i) (IntegerUnaryMinus (IntegerConstant 235346 (Integer 4)) diff --git a/tests/reference/asr-test_unsupported_type-0d813dd.json b/tests/reference/asr-test_unsupported_type-0d813dd.json index ab828c49da..830a68264c 100644 --- a/tests/reference/asr-test_unsupported_type-0d813dd.json +++ b/tests/reference/asr-test_unsupported_type-0d813dd.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_unsupported_type-0d813dd.stderr", - "stderr_hash": "df2464bbcb9d52d4dbe40236762e965b1b771406f16ef90cf53b8611", + "stderr_hash": "21fc45a6699d6b420540b4b862766fc022ac9978ceffc10c2b613c25", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_unsupported_type-0d813dd.stderr b/tests/reference/asr-test_unsupported_type-0d813dd.stderr index b5e5249813..d720e3ea49 100644 --- a/tests/reference/asr-test_unsupported_type-0d813dd.stderr +++ b/tests/reference/asr-test_unsupported_type-0d813dd.stderr @@ -3,3 +3,7 @@ semantic error: The type 'i128' is undeclared. | 2 | i: i128 | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_zero_division-3dd84e8.json b/tests/reference/asr-test_zero_division-3dd84e8.json index 5c135e76d4..bce9c5dd5f 100644 --- a/tests/reference/asr-test_zero_division-3dd84e8.json +++ b/tests/reference/asr-test_zero_division-3dd84e8.json @@ -5,9 +5,9 @@ "infile_hash": "cef09721d9ea9f3846f213e1b1718f2aac2edba08d555af776293504", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, - "stderr": "asr-test_zero_division-3dd84e8.stderr", - "stderr_hash": "e1770a0ba87c5155926e3d6bb3bd67e14a5c040b7584c4cf114a41b2", - "returncode": 2 + "stdout": "asr-test_zero_division-3dd84e8.stdout", + "stdout_hash": "ef34e51b3fe2cf233a43091adee05bccf5c782d5cc9df1a2d0afe64c", + "stderr": null, + "stderr_hash": null, + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_zero_division-3dd84e8.stdout b/tests/reference/asr-test_zero_division-3dd84e8.stdout new file mode 100644 index 0000000000..3a6e590a20 --- /dev/null +++ b/tests/reference/asr-test_zero_division-3dd84e8.stdout @@ -0,0 +1,141 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + __main__global_stmts: + (Function + (SymbolTable + 4 + { + + }) + __main__global_stmts + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [f] + [] + [(SubroutineCall + 2 f + () + [] + () + )] + () + Public + .false. + .false. + () + ), + f: + (Function + (SymbolTable + 3 + { + i: + (Variable + 3 + i + [] + Local + () + () + Default + (Integer 4) + () + Source + Public + Required + .false. + ) + }) + f + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 i) + (IntegerConstant 4 (Integer 4)) + () + ) + (Print + [(IntrinsicElementalFunction + FloorDiv + [(Var 3 i) + (IntegerConstant 0 (Integer 4))] + 0 + (Integer 4) + () + )] + () + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 5 + { + __main__global_stmts: + (ExternalSymbol + 5 + __main__global_stmts + 2 __main__global_stmts + __main__ + [] + __main__global_stmts + Public + ) + }) + main_program + [__main__] + [(SubroutineCall + 5 __main__global_stmts + 2 __main__global_stmts + [] + () + )] + ) + }) + [] +) diff --git a/tests/reference/asr-test_zero_division2-d84989f.json b/tests/reference/asr-test_zero_division2-d84989f.json index f1fb7cbb0e..d5d4f636d5 100644 --- a/tests/reference/asr-test_zero_division2-d84989f.json +++ b/tests/reference/asr-test_zero_division2-d84989f.json @@ -5,9 +5,9 @@ "infile_hash": "0ddca188fc2e8d665c5af0d438e34ed8afe255611320caa3a27ed483", "outfile": null, "outfile_hash": null, - "stdout": null, - "stdout_hash": null, - "stderr": "asr-test_zero_division2-d84989f.stderr", - "stderr_hash": "d2bac61e7df0875a7c93edb706661c80154b7b4d05dbf26663c36176", - "returncode": 2 + "stdout": "asr-test_zero_division2-d84989f.stdout", + "stdout_hash": "726cdac1b505c25ff2737167120685da62c20c9c42852b35b74888e1", + "stderr": null, + "stderr_hash": null, + "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/asr-test_zero_division2-d84989f.stdout b/tests/reference/asr-test_zero_division2-d84989f.stdout new file mode 100644 index 0000000000..4e1d3599b0 --- /dev/null +++ b/tests/reference/asr-test_zero_division2-d84989f.stdout @@ -0,0 +1,147 @@ +(TranslationUnit + (SymbolTable + 1 + { + __main__: + (Module + (SymbolTable + 2 + { + __main__global_stmts: + (Function + (SymbolTable + 4 + { + + }) + __main__global_stmts + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [f] + [] + [(SubroutineCall + 2 f + () + [] + () + )] + () + Public + .false. + .false. + () + ), + f: + (Function + (SymbolTable + 3 + { + v: + (Variable + 3 + v + [] + Local + () + () + Default + (Real 8) + () + Source + Public + Required + .false. + ) + }) + f + (FunctionType + [] + () + Source + Implementation + () + .false. + .false. + .false. + .false. + .false. + [] + .false. + ) + [] + [] + [(Assignment + (Var 3 v) + (RealConstant + 4.000000 + (Real 8) + ) + () + ) + (Print + [(IntrinsicElementalFunction + FloorDiv + [(Var 3 v) + (RealConstant + 0.000000 + (Real 8) + )] + 0 + (Real 8) + () + )] + () + () + )] + () + Public + .false. + .false. + () + ) + }) + __main__ + [] + .false. + .false. + ), + main_program: + (Program + (SymbolTable + 5 + { + __main__global_stmts: + (ExternalSymbol + 5 + __main__global_stmts + 2 __main__global_stmts + __main__ + [] + __main__global_stmts + Public + ) + }) + main_program + [__main__] + [(SubroutineCall + 5 __main__global_stmts + 2 __main__global_stmts + [] + () + )] + ) + }) + [] +) diff --git a/tests/reference/asr-test_zero_division3-29efb9e.json b/tests/reference/asr-test_zero_division3-29efb9e.json index 0c4f4b3d5d..b564c04e24 100644 --- a/tests/reference/asr-test_zero_division3-29efb9e.json +++ b/tests/reference/asr-test_zero_division3-29efb9e.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_zero_division3-29efb9e.stderr", - "stderr_hash": "061f891a72cebaa335b5db060b27e04f21f6a09d150f78f1a572c135", + "stderr_hash": "a74c3ad340a5b24ffc911bbdb579d30825cb802c2449e86f34d12fc1", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_zero_division3-29efb9e.stderr b/tests/reference/asr-test_zero_division3-29efb9e.stderr index 519946bb81..75c2b32f45 100644 --- a/tests/reference/asr-test_zero_division3-29efb9e.stderr +++ b/tests/reference/asr-test_zero_division3-29efb9e.stderr @@ -3,3 +3,7 @@ semantic error: division by zero is not allowed | 3 | print(i/0) | ^ division by zero + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-test_zero_division4-bf4af64.json b/tests/reference/asr-test_zero_division4-bf4af64.json index e1f6ce6bc0..b5907afe87 100644 --- a/tests/reference/asr-test_zero_division4-bf4af64.json +++ b/tests/reference/asr-test_zero_division4-bf4af64.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-test_zero_division4-bf4af64.stderr", - "stderr_hash": "1d16ac2d95ab997ff9b94f4028d8741121e41471445179d185264884", + "stderr_hash": "514f4599064030f7b57f47d9f18d675203a94ccdb95fe5d81295db96", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-test_zero_division4-bf4af64.stderr b/tests/reference/asr-test_zero_division4-bf4af64.stderr index bdf0d76816..23b24e3fa3 100644 --- a/tests/reference/asr-test_zero_division4-bf4af64.stderr +++ b/tests/reference/asr-test_zero_division4-bf4af64.stderr @@ -3,3 +3,7 @@ semantic error: division by zero is not allowed | 5 | print(f/0.0) | ^^^ division by zero + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-tuple1-09972ab.json b/tests/reference/asr-tuple1-09972ab.json index a8e83fae28..e72fc9f494 100644 --- a/tests/reference/asr-tuple1-09972ab.json +++ b/tests/reference/asr-tuple1-09972ab.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-tuple1-09972ab.stdout", - "stdout_hash": "fcbdc7bd437d77534509c9da987f7b735c1bd319de51956b28924f73", + "stdout_hash": "8d34b15fa3ca19f09a6b0358145ca1b279a67be381729efad479b662", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-tuple1-09972ab.stdout b/tests/reference/asr-tuple1-09972ab.stdout index d4bcbe5dad..8239da91fb 100644 --- a/tests/reference/asr-tuple1-09972ab.stdout +++ b/tests/reference/asr-tuple1-09972ab.stdout @@ -263,7 +263,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a1) (TupleConstant [(IntegerConstant 1 (Integer 4)) @@ -277,7 +277,7 @@ ) () ) - (= + (Assignment (Var 3 a1) (TupleConstant [(IntegerUnaryMinus @@ -303,7 +303,7 @@ ) () ) - (= + (Assignment (Var 3 a2) (TupleConstant [(StringConstant @@ -326,7 +326,7 @@ ) () ) - (= + (Assignment (Var 3 float_mem) (Cast (RealConstant @@ -342,7 +342,7 @@ ) () ) - (= + (Assignment (Var 3 a3) (TupleConstant [(IntegerUnaryMinus @@ -369,7 +369,7 @@ ) () ) - (= + (Assignment (Var 3 a4) (TupleConstant [(TupleConstant @@ -407,7 +407,7 @@ ) () ) - (= + (Assignment (Var 3 float_mem1) (Cast (RealConstant @@ -423,7 +423,7 @@ ) () ) - (= + (Assignment (Var 3 float_mem2) (Cast (RealConstant @@ -439,7 +439,7 @@ ) () ) - (= + (Assignment (Var 3 a5) (TupleConstant [(TupleConstant @@ -486,7 +486,7 @@ ) () ) - (= + (Assignment (Var 3 b0) (TupleItem (Var 3 a1) @@ -496,7 +496,7 @@ ) () ) - (= + (Assignment (TupleConstant [(Var 3 b0) (Var 3 b1)] @@ -525,7 +525,7 @@ ) () ) - (= + (Assignment (Var 3 a11) (TupleConstant [(IntegerConstant 1 (Integer 4)) @@ -537,7 +537,7 @@ ) () ) - (= + (Assignment (Var 3 b11) (TupleConstant [(IntegerConstant 1 (Integer 4)) diff --git a/tests/reference/asr-type_mismatch-61052c7.json b/tests/reference/asr-type_mismatch-61052c7.json index 80ce9f69b3..66dde5f7f1 100644 --- a/tests/reference/asr-type_mismatch-61052c7.json +++ b/tests/reference/asr-type_mismatch-61052c7.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-type_mismatch-61052c7.stderr", - "stderr_hash": "8c0de9edb133ff8cfa5c0e7c6b2a8d425c5d84a5ec98844eb367040c", + "stderr_hash": "b5474d2ae119f3be899c38b058af70e24aac3cbe38b17e8e7e57e0e7", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-type_mismatch-61052c7.stderr b/tests/reference/asr-type_mismatch-61052c7.stderr index 6a402fb67c..2597c4e077 100644 --- a/tests/reference/asr-type_mismatch-61052c7.stderr +++ b/tests/reference/asr-type_mismatch-61052c7.stderr @@ -3,3 +3,7 @@ semantic error: Type mismatch in shorthand operator, the types must be compatibl | 8 | a *= b | ^ ^ type mismatch ('i32' and 'f32') + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-unsigned_01-892b178.json b/tests/reference/asr-unsigned_01-892b178.json index 0a797a2c11..8fc2de6a31 100644 --- a/tests/reference/asr-unsigned_01-892b178.json +++ b/tests/reference/asr-unsigned_01-892b178.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-unsigned_01-892b178.stderr", - "stderr_hash": "54c7cfbd16c73cbe802a3492cd9c9e8d2fb25035192d229232c377b2", + "stderr_hash": "f19389db60f2168bed6694b7a2fc796362a9e5df5a5f5c0b63ee9ab0", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-unsigned_01-892b178.stderr b/tests/reference/asr-unsigned_01-892b178.stderr index c3526cf36e..f30017b04b 100644 --- a/tests/reference/asr-unsigned_01-892b178.stderr +++ b/tests/reference/asr-unsigned_01-892b178.stderr @@ -3,3 +3,7 @@ semantic error: Cannot cast negative value to unsigned integer | 3 | i: u16 = u16(-5) | ^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-unsigned_02-6563e58.json b/tests/reference/asr-unsigned_02-6563e58.json index 40e7b2a0f0..a035a634e3 100644 --- a/tests/reference/asr-unsigned_02-6563e58.json +++ b/tests/reference/asr-unsigned_02-6563e58.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-unsigned_02-6563e58.stderr", - "stderr_hash": "93f2cf309dfa7f13d56df9184615fde6a832b79510d8541f95ad5a70", + "stderr_hash": "48d94d3244a0f54eef37ac93bb7da8bd2be35c3a971e4a1a0babeda4", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-unsigned_02-6563e58.stderr b/tests/reference/asr-unsigned_02-6563e58.stderr index d00c5647fd..b510a16155 100644 --- a/tests/reference/asr-unsigned_02-6563e58.stderr +++ b/tests/reference/asr-unsigned_02-6563e58.stderr @@ -3,3 +3,7 @@ semantic error: The result of the unary minus `-` operation is negative, thus ou | 3 | i: u16 = -u16(5) | ^^^^^^^ use -i32(u) for signed result + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-unsigned_03-f785652.json b/tests/reference/asr-unsigned_03-f785652.json index 6929c59a27..e9ed5cb7d7 100644 --- a/tests/reference/asr-unsigned_03-f785652.json +++ b/tests/reference/asr-unsigned_03-f785652.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-unsigned_03-f785652.stderr", - "stderr_hash": "d90013a25d9aaa91fbbf2b1193cd06be94a4e716f0fe99771cde5601", + "stderr_hash": "acf949ff5d4a2eafc20b9c2ccb96fdf9b45b43bd4ef3c9651e14e5dc", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-unsigned_03-f785652.stderr b/tests/reference/asr-unsigned_03-f785652.stderr index a68ae96697..5e7e5b8b4a 100644 --- a/tests/reference/asr-unsigned_03-f785652.stderr +++ b/tests/reference/asr-unsigned_03-f785652.stderr @@ -3,3 +3,7 @@ semantic error: The result of the unary minus `-` operation is negative, thus ou | 3 | print(-u64(u32(10))) | ^^^^^^^^^^^^^ use -i64(u) for signed result + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-unsigned_04-c856d3a.json b/tests/reference/asr-unsigned_04-c856d3a.json index 3753e9ae30..93d267b30c 100644 --- a/tests/reference/asr-unsigned_04-c856d3a.json +++ b/tests/reference/asr-unsigned_04-c856d3a.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "asr-unsigned_04-c856d3a.stderr", - "stderr_hash": "3dcdf2e97f8c5f2816bed266587c7c3743f666cf2a4602f65e8ec9b8", + "stderr_hash": "1836dc76ffbf584fbff929aab3ce104b7004dd3729459c313cc7adb9", "returncode": 2 } \ No newline at end of file diff --git a/tests/reference/asr-unsigned_04-c856d3a.stderr b/tests/reference/asr-unsigned_04-c856d3a.stderr index 8547a0848c..829c2bc86a 100644 --- a/tests/reference/asr-unsigned_04-c856d3a.stderr +++ b/tests/reference/asr-unsigned_04-c856d3a.stderr @@ -3,3 +3,7 @@ semantic error: The result of the bitnot ~ operation is negative, thus out of ra | 4 | i = ~i | ^^ use ~i32(u) for signed result or bitnot_u16(u) for unsigned result + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/asr-vec_01-66ac423.json b/tests/reference/asr-vec_01-66ac423.json index 0eccea5f38..996baeb0f3 100644 --- a/tests/reference/asr-vec_01-66ac423.json +++ b/tests/reference/asr-vec_01-66ac423.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "asr-vec_01-66ac423.stdout", - "stdout_hash": "3322da0205ca932ee6037839d41a406a93609339bc4b3bbbe0a88638", + "stdout_hash": "4b766cc5368d34ae43b8f00bcf9fe26bfee8ffb23452f0929e784b8f", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/asr-vec_01-66ac423.stdout b/tests/reference/asr-vec_01-66ac423.stdout index 0dc4ab1dd5..9851508335 100644 --- a/tests/reference/asr-vec_01-66ac423.stdout +++ b/tests/reference/asr-vec_01-66ac423.stdout @@ -124,9 +124,9 @@ ) [] [] - [(= + [(Assignment (Var 220 a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -134,13 +134,14 @@ (IntegerConstant 9216 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 220 b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -148,6 +149,7 @@ (IntegerConstant 9216 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -164,7 +166,7 @@ (IntegerConstant 9215 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 220 b) [(() @@ -194,7 +196,7 @@ (IntegerConstant 9215 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 220 a) [(() diff --git a/tests/reference/ast-prefix_string_01-cf221fd.json b/tests/reference/ast-prefix_string_01-cf221fd.json index ed1984236e..7b35875d68 100644 --- a/tests/reference/ast-prefix_string_01-cf221fd.json +++ b/tests/reference/ast-prefix_string_01-cf221fd.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "ast-prefix_string_01-cf221fd.stderr", - "stderr_hash": "b600057f41f59ba7fdebe3971bfea0eadca972747ccf70d575c1cdcd", + "stderr_hash": "01778a489f20dcff14eb922861f176cb7b5998337b0688af164af6e2", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/ast-prefix_string_01-cf221fd.stderr b/tests/reference/ast-prefix_string_01-cf221fd.stderr index e2a05a52c7..12dd736d4d 100644 --- a/tests/reference/ast-prefix_string_01-cf221fd.stderr +++ b/tests/reference/ast-prefix_string_01-cf221fd.stderr @@ -3,3 +3,7 @@ syntax error: Token '"Hello"' (of type 'string') is unexpected here | 3 | print "Hello", "World" | ^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/ast-prefix_string_02-3d530b2.json b/tests/reference/ast-prefix_string_02-3d530b2.json index 9c3ce1081b..1e9358fc95 100644 --- a/tests/reference/ast-prefix_string_02-3d530b2.json +++ b/tests/reference/ast-prefix_string_02-3d530b2.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "ast-prefix_string_02-3d530b2.stderr", - "stderr_hash": "cd72affed29823c0364d52bfb3ba0674d9d7950390b7cd6b04f7538b", + "stderr_hash": "f85ac10d8c4cec3da1256b5b69cc6b383a1c2a66b21e30d094b477fa", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/ast-prefix_string_02-3d530b2.stderr b/tests/reference/ast-prefix_string_02-3d530b2.stderr index 869d52864a..6197e0b89e 100644 --- a/tests/reference/ast-prefix_string_02-3d530b2.stderr +++ b/tests/reference/ast-prefix_string_02-3d530b2.stderr @@ -3,3 +3,7 @@ syntax error: Token '"Hello World"' (of type 'string') is unexpected here | 7 | print(r "Hello World") | ^^^^^^^^^^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/c-expr7-bb2692a.json b/tests/reference/c-expr7-bb2692a.json index 84ee9e5ed5..1b8797d6e8 100644 --- a/tests/reference/c-expr7-bb2692a.json +++ b/tests/reference/c-expr7-bb2692a.json @@ -6,8 +6,8 @@ "outfile": null, "outfile_hash": null, "stdout": "c-expr7-bb2692a.stdout", - "stdout_hash": "1d75b4cf61dcee73adafec2a5448c953bae5476aab2502115df2eecb", + "stdout_hash": "92e36dc1146bef152cab7c8086ce6de203a3d966dc5415331bd27257", "stderr": "c-expr7-bb2692a.stderr", - "stderr_hash": "6e9790ac88db1a9ead8f64a91ba8a6605de67167037908a74b77be0c", + "stderr_hash": "14266d9eecb4272a8102f9495568abd799c50f1741a894f56101ddd8", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/c-expr7-bb2692a.stderr b/tests/reference/c-expr7-bb2692a.stderr index a4fad29beb..3658b5c161 100644 --- a/tests/reference/c-expr7-bb2692a.stderr +++ b/tests/reference/c-expr7-bb2692a.stderr @@ -9,3 +9,7 @@ style suggestion: Could have used '**' instead of 'pow' | 8 | res = i32(pow(a, b)) | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/c-expr7-bb2692a.stdout b/tests/reference/c-expr7-bb2692a.stdout index b85fda16c9..cfd6f33429 100644 --- a/tests/reference/c-expr7-bb2692a.stdout +++ b/tests/reference/c-expr7-bb2692a.stdout @@ -8,26 +8,6 @@ #include #include -float _lcompilers_optimization_floordiv_f32(float a, float b); -double _lcompilers_optimization_floordiv_f64(double a, double b); -int16_t _lcompilers_optimization_floordiv_i16(int16_t a, int16_t b); -int32_t _lcompilers_optimization_floordiv_i32(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i321(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i3210(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i322(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i323(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i324(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i325(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i326(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i327(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i328(int32_t a, int32_t b); -int32_t _lcompilers_optimization_floordiv_i329(int32_t a, int32_t b); -int64_t _lcompilers_optimization_floordiv_i64(int64_t a, int64_t b); -int8_t _lcompilers_optimization_floordiv_i8(int8_t a, int8_t b); -uint16_t _lcompilers_optimization_floordiv_u16(uint16_t a, uint16_t b); -uint32_t _lcompilers_optimization_floordiv_u32(uint32_t a, uint32_t b); -uint64_t _lcompilers_optimization_floordiv_u64(uint64_t a, uint64_t b); -uint8_t _lcompilers_optimization_floordiv_u8(uint8_t a, uint8_t b); void test_pow(); int32_t test_pow_1(int32_t a, int32_t b); void main0(); @@ -36,286 +16,6 @@ void __main__global_stmts(); // Implementations -float _lcompilers_optimization_floordiv_f32(float a, float b) -{ - double r; - float result; - int64_t tmp; - r = a/b; - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (float)(tmp); - return result; -} - -double _lcompilers_optimization_floordiv_f64(double a, double b) -{ - double r; - double result; - int64_t tmp; - r = a/b; - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (double)(tmp); - return result; -} - -int16_t _lcompilers_optimization_floordiv_i16(int16_t a, int16_t b) -{ - double r; - int16_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i32(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i321(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i3210(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i322(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i323(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i324(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i325(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i326(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i327(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i328(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int32_t _lcompilers_optimization_floordiv_i329(int32_t a, int32_t b) -{ - double r; - int32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int64_t _lcompilers_optimization_floordiv_i64(int64_t a, int64_t b) -{ - double r; - int64_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -int8_t _lcompilers_optimization_floordiv_i8(int8_t a, int8_t b) -{ - double r; - int8_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = tmp; - return result; -} - -uint16_t _lcompilers_optimization_floordiv_u16(uint16_t a, uint16_t b) -{ - double r; - uint16_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (uint16_t)(tmp); - return result; -} - -uint32_t _lcompilers_optimization_floordiv_u32(uint32_t a, uint32_t b) -{ - double r; - uint32_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (uint32_t)(tmp); - return result; -} - -uint64_t _lcompilers_optimization_floordiv_u64(uint64_t a, uint64_t b) -{ - double r; - uint64_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (uint64_t)(tmp); - return result; -} - -uint8_t _lcompilers_optimization_floordiv_u8(uint8_t a, uint8_t b) -{ - double r; - uint8_t result; - int64_t tmp; - r = (double)(a)/(double)(b); - tmp = (int64_t)(r); - if (r < 0.00000000000000000e+00 && (double)(tmp) != r) { - tmp = tmp - 1; - } - result = (uint8_t)(tmp); - return result; -} - double __lpython_overloaded_0__pow(int32_t x, int32_t y) { double _lpython_return_variable; diff --git a/tests/reference/cpp-expr7-529bd53.json b/tests/reference/cpp-expr7-529bd53.json index 9697eaa92d..c1ffa27ca4 100644 --- a/tests/reference/cpp-expr7-529bd53.json +++ b/tests/reference/cpp-expr7-529bd53.json @@ -8,6 +8,6 @@ "stdout": "cpp-expr7-529bd53.stdout", "stdout_hash": "8f72ce4b2d8f170884e171b1bdfa4a4ea07344825b6787d814a446cf", "stderr": "cpp-expr7-529bd53.stderr", - "stderr_hash": "6e9790ac88db1a9ead8f64a91ba8a6605de67167037908a74b77be0c", + "stderr_hash": "14266d9eecb4272a8102f9495568abd799c50f1741a894f56101ddd8", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/cpp-expr7-529bd53.stderr b/tests/reference/cpp-expr7-529bd53.stderr index a4fad29beb..3658b5c161 100644 --- a/tests/reference/cpp-expr7-529bd53.stderr +++ b/tests/reference/cpp-expr7-529bd53.stderr @@ -9,3 +9,7 @@ style suggestion: Could have used '**' instead of 'pow' | 8 | res = i32(pow(a, b)) | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/cpp-test_builtin_pow-56b3f92.json b/tests/reference/cpp-test_builtin_pow-56b3f92.json index a18ad0aab9..70edf5661b 100644 --- a/tests/reference/cpp-test_builtin_pow-56b3f92.json +++ b/tests/reference/cpp-test_builtin_pow-56b3f92.json @@ -8,6 +8,6 @@ "stdout": "cpp-test_builtin_pow-56b3f92.stdout", "stdout_hash": "dec0af96e013cd38032672f4812f876e586bf697757278addd17b591", "stderr": "cpp-test_builtin_pow-56b3f92.stderr", - "stderr_hash": "859ce76c74748f2d32c7eab92cfbba789a78d4cbf5818646b99806ea", + "stderr_hash": "c6495babe2f9dc8ec8cdc1e8009ed03c4bca6316839caed43f198e7a", "returncode": 0 } \ No newline at end of file diff --git a/tests/reference/cpp-test_builtin_pow-56b3f92.stderr b/tests/reference/cpp-test_builtin_pow-56b3f92.stderr index 5dbb75ad24..f43034705c 100644 --- a/tests/reference/cpp-test_builtin_pow-56b3f92.stderr +++ b/tests/reference/cpp-test_builtin_pow-56b3f92.stderr @@ -3,3 +3,7 @@ style suggestion: Could have used '**' instead of 'pow' | 11 | assert i32(pow(a, b)) == 32 | ^^^^^^^^^ '**' could be used instead + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/pass_class_constructor-structs_16-5e3508f.json b/tests/reference/pass_class_constructor-structs_16-5e3508f.json index 62901bd56c..8204d2a621 100644 --- a/tests/reference/pass_class_constructor-structs_16-5e3508f.json +++ b/tests/reference/pass_class_constructor-structs_16-5e3508f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_class_constructor-structs_16-5e3508f.stdout", - "stdout_hash": "74b7cad17c2d6f7774e930e8a24b9bf35ca37425c7a3fa6f4851ef84", + "stdout_hash": "b2d0bddf9e8ba1877d428e44cb6bc2a32bb7d2c9db18a20d649dd7cf", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout b/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout index a3b30d3762..7ab18fc44d 100644 --- a/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout +++ b/tests/reference/pass_class_constructor-structs_16-5e3508f.stdout @@ -233,7 +233,7 @@ ) [] [] - [(= + [(Assignment (Var 5 bd) (UnionTypeConstructor 5 A_B @@ -245,7 +245,7 @@ ) () ) - (= + (Assignment (UnionInstanceMember (Var 5 bd) 4 x @@ -255,7 +255,7 @@ (IntegerConstant 1 (Integer 4)) () ) - (= + (Assignment (StructInstanceMember (Var 5 ad) 5 1_A_b @@ -267,7 +267,7 @@ (Var 5 bd) () ) - (= + (Assignment (StructInstanceMember (Var 5 ad) 5 1_A_c diff --git a/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.json b/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.json index 447a7b2cdf..4c672f0719 100644 --- a/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.json +++ b/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_inline_function_calls-func_inline_01-fba3c47.stdout", - "stdout_hash": "1705050e9a2183a2f6aa493125e093e7c4d17a4f2f4949749950e11a", + "stdout_hash": "1aa0f1c94c3cb04aa6009f15f823c65cbda2fd3f3a0b52eedd945469", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.stdout b/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.stdout index 049c262de1..96ffb8f606 100644 --- a/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.stdout +++ b/tests/reference/pass_inline_function_calls-func_inline_01-fba3c47.stdout @@ -111,7 +111,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 3 _lpython_return_variable) (Var 3 n) () @@ -119,7 +119,7 @@ (Return)] [] ) - (= + (Assignment (Var 3 _lpython_return_variable) (IntegerBinOp (FunctionCall @@ -270,7 +270,7 @@ ) [fib] [] - [(= + [(Assignment (Var 4 x) (Cast (IntegerConstant 40 (Integer 4)) @@ -280,7 +280,7 @@ ) () ) - (= + (Assignment (Var 4 n_fib) (Var 4 x) () @@ -298,7 +298,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 4 _lpython_return_variable_fib) (Var 4 n_fib) () @@ -309,7 +309,7 @@ )] [] ) - (= + (Assignment (Var 4 _lpython_return_variable_fib) (IntegerBinOp (FunctionCall @@ -364,7 +364,7 @@ 1 4 ~empty_block ) - (= + (Assignment (Var 4 ans) (Var 4 _lpython_return_variable_fib) () diff --git a/tests/reference/pass_loop_vectorise-vec_01-be9985e.json b/tests/reference/pass_loop_vectorise-vec_01-be9985e.json index 7295f20048..50e0e90dae 100644 --- a/tests/reference/pass_loop_vectorise-vec_01-be9985e.json +++ b/tests/reference/pass_loop_vectorise-vec_01-be9985e.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_loop_vectorise-vec_01-be9985e.stdout", - "stdout_hash": "6f16af23ec8a9515bab82fb531b6813f5df3831eceaeaed946112957", + "stdout_hash": "fcaa5608fe5f73d0fabcae7c837606ab6b80aafd29d3a108c19f4e1c", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_loop_vectorise-vec_01-be9985e.stdout b/tests/reference/pass_loop_vectorise-vec_01-be9985e.stdout index 984c118408..2c26bc6563 100644 --- a/tests/reference/pass_loop_vectorise-vec_01-be9985e.stdout +++ b/tests/reference/pass_loop_vectorise-vec_01-be9985e.stdout @@ -271,7 +271,7 @@ (Var 226 arg3) (Var 226 arg4) (Var 226 arg5)] - [(= + [(Assignment (Var 226 __1_k) (IntegerBinOp (Var 226 arg2) @@ -297,7 +297,7 @@ (Logical 4) () ) - [(= + [(Assignment (Var 226 __1_k) (IntegerBinOp (Var 226 __1_k) @@ -308,7 +308,7 @@ ) () ) - (= + (Assignment (ArrayItem (Var 226 arg0) [(() @@ -355,9 +355,9 @@ ) [] [] - [(= + [(Assignment (Var 220 a) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -365,13 +365,14 @@ (IntegerConstant 9216 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () ) - (= + (Assignment (Var 220 b) - (ArrayConstant + (ArrayConstructor [] (Array (Real 8) @@ -379,6 +380,7 @@ (IntegerConstant 9216 (Integer 4)))] FixedSizeArray ) + () RowMajor ) () @@ -395,7 +397,7 @@ (IntegerConstant 9215 (Integer 4)) ) (IntegerConstant 1 (Integer 4))) - [(= + [(Assignment (ArrayItem (Var 220 b) [(() diff --git a/tests/reference/pass_print_list_tuple-print_02-09600eb.json b/tests/reference/pass_print_list_tuple-print_02-09600eb.json index 8cff508098..a256225c9d 100644 --- a/tests/reference/pass_print_list_tuple-print_02-09600eb.json +++ b/tests/reference/pass_print_list_tuple-print_02-09600eb.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_print_list_tuple-print_02-09600eb.stdout", - "stdout_hash": "16568187a4448877082b52b613458830bbad14ec61abbf478bcf4cb7", + "stdout_hash": "b518803746ffd1666ff29f4bfa2347eb621d81af5e52dc36964cd249", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_print_list_tuple-print_02-09600eb.stdout b/tests/reference/pass_print_list_tuple-print_02-09600eb.stdout index 8145eddc4b..89340fd892 100644 --- a/tests/reference/pass_print_list_tuple-print_02-09600eb.stdout +++ b/tests/reference/pass_print_list_tuple-print_02-09600eb.stdout @@ -499,7 +499,7 @@ ) [] [] - [(= + [(Assignment (Var 3 a) (ListConstant [(StringConstant @@ -520,7 +520,7 @@ ) () ) - (= + (Assignment (Var 3 b) (ListConstant [(IntegerConstant 1 (Integer 4)) @@ -533,7 +533,7 @@ ) () ) - (= + (Assignment (Var 3 c) (ListConstant [(RealConstant @@ -562,7 +562,7 @@ ) () ) - (= + (Assignment (Var 3 d) (ListConstant [] @@ -2783,7 +2783,7 @@ ) [] [] - [(= + [(Assignment (Var 4 w) (ListConstant [(ListConstant @@ -2872,7 +2872,7 @@ ) () ) - (= + (Assignment (Var 4 x) (ListConstant [(ListConstant @@ -2959,7 +2959,7 @@ ) () ) - (= + (Assignment (Var 4 y) (ListConstant [(ListConstant @@ -3010,7 +3010,7 @@ ) () ) - (= + (Assignment (Var 4 z) (ListConstant [(ListConstant @@ -4623,7 +4623,7 @@ ) [] [] - [(= + [(Assignment (Var 6 p) (ListConstant [(ListConstant @@ -4784,7 +4784,7 @@ ) () ) - (= + (Assignment (Var 6 q) (ListConstant [(ListConstant @@ -5607,7 +5607,7 @@ ) () ) - (= + (Assignment (Var 6 r) (ListConstant [(ListConstant @@ -7468,7 +7468,7 @@ ) [] [] - [(= + [(Assignment (Var 5 a) (ListConstant [(TupleConstant @@ -7504,7 +7504,7 @@ ) () ) - (= + (Assignment (Var 5 c) (ListConstant [(ListConstant @@ -7578,7 +7578,7 @@ ) () ) - (= + (Assignment (Var 5 b1) (ListConstant [(StringConstant @@ -7607,7 +7607,7 @@ ) () ) - (= + (Assignment (Var 5 b2) (ListConstant [(IntegerConstant 10 (Integer 4)) @@ -7620,7 +7620,7 @@ ) () ) - (= + (Assignment (Var 5 b) (TupleConstant [(Var 5 b1) diff --git a/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.json b/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.json index a8ff500c91..51e2d47a18 100644 --- a/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.json +++ b/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "pass_print_list_tuple-print_list_tuple_03-195fa9c.stdout", - "stdout_hash": "7f36160fc04369f1dc328606f82179f31dfcf5e375451708012816ec", + "stdout_hash": "080b6913697774b6f98669a991fb0f6d0346e52adc4f2de889d7ffcd", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.stdout b/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.stdout index 6724a6115e..1e56573482 100644 --- a/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.stdout +++ b/tests/reference/pass_print_list_tuple-print_list_tuple_03-195fa9c.stdout @@ -125,7 +125,7 @@ ) [] [] - [(= + [(Assignment (Var 3 x) (DictConstant [(IntegerConstant 1 (Integer 4)) @@ -156,7 +156,7 @@ ) () ) - (= + (Assignment (Var 3 y) (DictConstant [(IntegerConstant 1 (Integer 4)) diff --git a/tests/reference/run_dbg-test_quit_01-30889cc.json b/tests/reference/run_dbg-test_quit_01-30889cc.json index d46739a952..37ce5d232a 100644 --- a/tests/reference/run_dbg-test_quit_01-30889cc.json +++ b/tests/reference/run_dbg-test_quit_01-30889cc.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "run_dbg-test_quit_01-30889cc.stderr", - "stderr_hash": "b3dac87462f9f0650e5a6af68791137ca9d29f9a64139ba7718a9f96", + "stderr_hash": "56a8b2a9b2ee213cbfab4c18870ed93ddbfaa37e421f171155d06d4f", "returncode": 10 } \ No newline at end of file diff --git a/tests/reference/run_dbg-test_quit_01-30889cc.stderr b/tests/reference/run_dbg-test_quit_01-30889cc.stderr index c1c7a54e60..5fd4fe85c8 100644 --- a/tests/reference/run_dbg-test_quit_01-30889cc.stderr +++ b/tests/reference/run_dbg-test_quit_01-30889cc.stderr @@ -4,4 +4,4 @@ test() File "tests/runtime_errors/test_quit_01.py", line 2 quit(10) -STOP +STOP 10 diff --git a/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.json b/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.json index d580243c7b..fde8aee79c 100644 --- a/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.json +++ b/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.json @@ -6,7 +6,7 @@ "outfile": null, "outfile_hash": null, "stdout": "runtime-test_list_item_mixed_print-a3fd49f.stdout", - "stdout_hash": "cffcdb43864ef4e234dec5a10923f9077b7c6d1f4d9c37df1882f375", + "stdout_hash": "9d9a68fea29f11320efb0764ce38ed3d4090f64457b0f1eb10251a2b", "stderr": null, "stderr_hash": null, "returncode": 0 diff --git a/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.stdout b/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.stdout index 8659fad42d..a3f624820b 100644 --- a/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.stdout +++ b/tests/reference/runtime-test_list_item_mixed_print-a3fd49f.stdout @@ -1,12 +1,12 @@ - Hello -This is LPython +Hello +This isLPython 1 2 3 ... 3 4 5 The first element is: 1 The middle element is: 3 3.14000000000000012e+00 * 2 = 6.28000000000000025e+00 Total: 9.41999999999999993e+00 (1, 2, 3) is a tuple, but 1 is a number. -1 is smaller than 2 is smaller than 3 +123 1 # 2 # 3 # 4 # 5 # List 0 : [1, 2] diff --git a/tests/reference/tokens-indent1-0b243c5.json b/tests/reference/tokens-indent1-0b243c5.json index 8f6a69248b..7cfa2371c0 100644 --- a/tests/reference/tokens-indent1-0b243c5.json +++ b/tests/reference/tokens-indent1-0b243c5.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-indent1-0b243c5.stderr", - "stderr_hash": "d642cbfab3b7f5cdc1d373d420877c776d64b9eb6dcdd2491f7970f7", + "stderr_hash": "4aa1509a66bac651d22be84453a3532bb771094363034cd45970bf75", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-indent1-0b243c5.stderr b/tests/reference/tokens-indent1-0b243c5.stderr index ce7ce194d9..5a3c7aac6a 100644 --- a/tests/reference/tokens-indent1-0b243c5.stderr +++ b/tests/reference/tokens-indent1-0b243c5.stderr @@ -3,3 +3,7 @@ tokenizer error: Indentation should be of the same type (either tabs or spaces) | 3 | pass | ^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-indent2-a8438a0.json b/tests/reference/tokens-indent2-a8438a0.json index 6842962c04..ae3c387047 100644 --- a/tests/reference/tokens-indent2-a8438a0.json +++ b/tests/reference/tokens-indent2-a8438a0.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-indent2-a8438a0.stderr", - "stderr_hash": "ab862ff68983c5975d21f13c5b159de2a2888cae1d38a38a24700a88", + "stderr_hash": "17e55ff96e413590e93fd83bb06dc065dda4e0ee563c4216349342f7", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-indent2-a8438a0.stderr b/tests/reference/tokens-indent2-a8438a0.stderr index 75f882f0a8..4e0ac75a40 100644 --- a/tests/reference/tokens-indent2-a8438a0.stderr +++ b/tests/reference/tokens-indent2-a8438a0.stderr @@ -3,3 +3,7 @@ tokenizer error: Indentation should be of the same type (either tabs or spaces) | 4 | else: | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-indent3-0eaf3e6.json b/tests/reference/tokens-indent3-0eaf3e6.json index e1ee281ca3..efe6052467 100644 --- a/tests/reference/tokens-indent3-0eaf3e6.json +++ b/tests/reference/tokens-indent3-0eaf3e6.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-indent3-0eaf3e6.stderr", - "stderr_hash": "1eddb6f37641a3eee16900c7025e6420f21cd97d3f877720bc90401b", + "stderr_hash": "6a6419de94ff032184aedcbe49c8243becdef462d84e66cabd891467", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-indent3-0eaf3e6.stderr b/tests/reference/tokens-indent3-0eaf3e6.stderr index d6f7eb6224..d9926ca2b8 100644 --- a/tests/reference/tokens-indent3-0eaf3e6.stderr +++ b/tests/reference/tokens-indent3-0eaf3e6.stderr @@ -3,3 +3,7 @@ tokenizer error: Expected an indented block. | 5 | pass | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-paren1-94fa736.json b/tests/reference/tokens-paren1-94fa736.json index b939a408f3..9bc01f82d3 100644 --- a/tests/reference/tokens-paren1-94fa736.json +++ b/tests/reference/tokens-paren1-94fa736.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-paren1-94fa736.stderr", - "stderr_hash": "d0af4503aa7935c5215252efbb68900d95a6b897f6ad195850573db0", + "stderr_hash": "8596596679a7a8dc30d0716edf502040725d61cb75a8cc420f0cb295", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-paren1-94fa736.stderr b/tests/reference/tokens-paren1-94fa736.stderr index 9d1d1aee5a..1be8279158 100644 --- a/tests/reference/tokens-paren1-94fa736.stderr +++ b/tests/reference/tokens-paren1-94fa736.stderr @@ -3,3 +3,7 @@ tokenizer error: Too many nested parentheses | 1 | -(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((1))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-paren2-0eef339.json b/tests/reference/tokens-paren2-0eef339.json index 8d1ac74d27..313e04d5ef 100644 --- a/tests/reference/tokens-paren2-0eef339.json +++ b/tests/reference/tokens-paren2-0eef339.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-paren2-0eef339.stderr", - "stderr_hash": "60430252b0f0f0ab667252a10da601d08dcc962d240fbc7c3fe3fd6c", + "stderr_hash": "f17a1fd53733f79a0c99cc3450feb8619f0eec0884dbdd2ed766bb65", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-paren2-0eef339.stderr b/tests/reference/tokens-paren2-0eef339.stderr index e1fa73a259..fa08291d16 100644 --- a/tests/reference/tokens-paren2-0eef339.stderr +++ b/tests/reference/tokens-paren2-0eef339.stderr @@ -3,3 +3,7 @@ tokenizer error: Parentheses does not match | 6 | [{]} | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-paren3-0d47100.json b/tests/reference/tokens-paren3-0d47100.json index a0fc7a5fe8..0789a089f5 100644 --- a/tests/reference/tokens-paren3-0d47100.json +++ b/tests/reference/tokens-paren3-0d47100.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-paren3-0d47100.stderr", - "stderr_hash": "5dfebef8a231835dd95c490a961ef3981b73e717a91351ad9d327676", + "stderr_hash": "cdf04cdb67804d155e043d9966d42bd9046d70d2cd6aecf9201775ea", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-paren3-0d47100.stderr b/tests/reference/tokens-paren3-0d47100.stderr index fd5422d82b..6efa254575 100644 --- a/tests/reference/tokens-paren3-0d47100.stderr +++ b/tests/reference/tokens-paren3-0d47100.stderr @@ -3,3 +3,7 @@ tokenizer error: Parenthesis unexpected | 2 | ] {}} | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-paren4-5c2fc32.json b/tests/reference/tokens-paren4-5c2fc32.json index 184481775c..969c12364c 100644 --- a/tests/reference/tokens-paren4-5c2fc32.json +++ b/tests/reference/tokens-paren4-5c2fc32.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-paren4-5c2fc32.stderr", - "stderr_hash": "4ee038fab6af5c6ed6e0bfc147b98031946c9aa227364e263aaa4913", + "stderr_hash": "d1b1369b365f63a4a700a34fce46c2785ff5b52b99f9ab87250e1aef", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-paren4-5c2fc32.stderr b/tests/reference/tokens-paren4-5c2fc32.stderr index 28331acf02..1d8c03df3b 100644 --- a/tests/reference/tokens-paren4-5c2fc32.stderr +++ b/tests/reference/tokens-paren4-5c2fc32.stderr @@ -3,3 +3,7 @@ tokenizer error: Parentheses was never closed | 6 | | ^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues. diff --git a/tests/reference/tokens-test_literal-e20c024.json b/tests/reference/tokens-test_literal-e20c024.json index de80ac4c4e..efa0c9cb68 100644 --- a/tests/reference/tokens-test_literal-e20c024.json +++ b/tests/reference/tokens-test_literal-e20c024.json @@ -8,6 +8,6 @@ "stdout": null, "stdout_hash": null, "stderr": "tokens-test_literal-e20c024.stderr", - "stderr_hash": "58fe8b74550bd6f81761b173626f3d45eaae346665862f1b085eebe8", + "stderr_hash": "c2e777b21eb08794f3349833d07db3b29df8c62203812cb2af8d2cd5", "returncode": 1 } \ No newline at end of file diff --git a/tests/reference/tokens-test_literal-e20c024.stderr b/tests/reference/tokens-test_literal-e20c024.stderr index 977e7c1fd1..8f8f2d3a9f 100644 --- a/tests/reference/tokens-test_literal-e20c024.stderr +++ b/tests/reference/tokens-test_literal-e20c024.stderr @@ -3,3 +3,7 @@ tokenizer error: Leading zeros in decimal integer are not allowed | 2 | x: i32 = 0123 | ^^^^ + + +Note: Please report unclear or confusing messages as bugs at +https://github.com/lcompilers/lpython/issues.