Skip to content

Commit 118d23e

Browse files
kmr-srbhThirumalai-Shaktivelubaidsk
authored
Add an intrinsic implementation of type(object) function (#2592)
* Basic implementation of `type(name)` * Simplify ASR Node expression and fix error messages * Comment out argument `args` Co-authored-by: Thirumalai Shaktivel <[email protected]> * Remove passing `expr_value` Co-authored-by: Thirumalai Shaktivel <[email protected]> * Remove instantiating the function Co-authored-by: Thirumalai Shaktivel <[email protected]> * Undo registering function instantiation Co-authored-by: Thirumalai Shaktivel <[email protected]> * Add arg check for only 1 argument Co-authored-by: Thirumalai Shaktivel <[email protected]> * Fix arg check for empty function call * Update args check Co-authored-by: Thirumalai Shaktivel <[email protected]> * Update return type Co-authored-by: Thirumalai Shaktivel <[email protected]> * Update registration Co-authored-by: Thirumalai Shaktivel <[email protected]> * Handle the type of `type()` * Tests: Add tests and update test references * Update tests/tests.toml Co-authored-by: Thirumalai Shaktivel <[email protected]> * Add support to work with CPython * Tests: Add tests * Tests: Update tests * Delete tests/reference/asr-test_builtin_type-f795c34.json * Delete tests/reference/asr-test_builtin_type-f795c34.stdout * Tests: Add `C` backend * Make check for number of args more explicit Co-authored-by: Shaikh Ubaid <[email protected]> * Tests: Remove `Const` --------- Co-authored-by: Thirumalai Shaktivel <[email protected]> Co-authored-by: Shaikh Ubaid <[email protected]>
1 parent 0ba09ab commit 118d23e

File tree

5 files changed

+90
-2
lines changed

5 files changed

+90
-2
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ RUN(NAME callback_04 IMPORT_PATH .. LABELS cpython)
819819
# Intrinsic Functions
820820
RUN(NAME intrinsics_01 LABELS cpython llvm NOFAST) # any
821821
RUN(NAME intrinsics_02 LABELS cpython llvm c) # floordiv
822+
RUN(NAME test_builtin_type LABELS cpython llvm c) # type
822823

823824
# lpython decorator
824825
RUN(NAME lpython_decorator_01 LABELS cpython)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from lpython import i32, f64
2+
3+
def test_builtin_type():
4+
i: i32 = 42
5+
f: f64 = 64.0
6+
s: str = "Hello, LPython!"
7+
l: list[i32] = [1, 2, 3, 4, 5]
8+
d: dict[str, i32] = {"a": 1, "b": 2, "c": 3}
9+
res: str = ""
10+
11+
res = str(type(i))
12+
print(res)
13+
assert res == "<class 'int'>"
14+
res = str(type(f))
15+
print(res)
16+
assert res == "<class 'float'>"
17+
res = str(type(s))
18+
print(res)
19+
assert res == "<class 'str'>"
20+
res = str(type(l))
21+
print(res)
22+
assert res == "<class 'list'>"
23+
res = str(type(d))
24+
print(res)
25+
assert res == "<class 'dict'>"
26+
27+
test_builtin_type()

src/libasr/codegen/asr_to_c_cpp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,6 +3040,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
30403040
std::string out;
30413041
std::string indent(4, ' ');
30423042
switch (x.m_intrinsic_id) {
3043+
SET_INTRINSIC_NAME(ObjectType, "type");
30433044
SET_INTRINSIC_NAME(Sin, "sin");
30443045
SET_INTRINSIC_NAME(Cos, "cos");
30453046
SET_INTRINSIC_NAME(Tan, "tan");

src/libasr/pass/intrinsic_function_registry.h

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ the code size.
2727
*/
2828

2929
enum class IntrinsicScalarFunctions : int64_t {
30+
ObjectType,
3031
Sin,
3132
Cos,
3233
Tan,
@@ -100,6 +101,7 @@ enum class IntrinsicScalarFunctions : int64_t {
100101

101102
inline std::string get_intrinsic_name(int x) {
102103
switch (x) {
104+
INTRINSIC_NAME_CASE(ObjectType)
103105
INTRINSIC_NAME_CASE(Sin)
104106
INTRINSIC_NAME_CASE(Cos)
105107
INTRINSIC_NAME_CASE(Tan)
@@ -1160,6 +1162,58 @@ static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x,
11601162

11611163
} // namespace BinaryIntrinsicFunction
11621164

1165+
1166+
namespace ObjectType {
1167+
1168+
static inline void verify_args(const ASR::IntrinsicScalarFunction_t& x, diag::Diagnostics& diagnostics) {
1169+
ASRUtils::require_impl(x.n_args == 1,
1170+
"ASR Verify: type() takes only 1 argument `object`",
1171+
x.base.base.loc, diagnostics);
1172+
}
1173+
1174+
static ASR::expr_t *eval_ObjectType(Allocator &al, const Location &loc,
1175+
ASR::ttype_t* t1, Vec<ASR::expr_t*>& /*args*/) {
1176+
std::string object_type = "<class '";
1177+
switch (t1->type) {
1178+
case ASR::ttypeType::Integer : {
1179+
object_type += "int"; break;
1180+
} case ASR::ttypeType::Real : {
1181+
object_type += "float"; break;
1182+
} case ASR::ttypeType::Character : {
1183+
object_type += "str"; break;
1184+
} case ASR::ttypeType::List : {
1185+
object_type += "list"; break;
1186+
} case ASR::ttypeType::Dict : {
1187+
object_type += "dict"; break;
1188+
} default: {
1189+
LCOMPILERS_ASSERT_MSG(false, "Unsupported type");
1190+
break;
1191+
}
1192+
}
1193+
object_type += "'>";
1194+
return StringConstant(object_type, character(object_type.length()));
1195+
}
1196+
1197+
static inline ASR::asr_t* create_ObjectType(Allocator& al, const Location& loc,
1198+
Vec<ASR::expr_t*>& args,
1199+
const std::function<void (const std::string &, const Location &)> err) {
1200+
if (args.size() != 1) {
1201+
err("type() takes exactly 1 argument `object` for now", loc);
1202+
}
1203+
ASR::expr_t *m_value = nullptr;
1204+
Vec<ASR::expr_t *> arg_values;
1205+
1206+
m_value = eval_ObjectType(al, loc, expr_type(args[0]), arg_values);
1207+
1208+
return ASR::make_IntrinsicScalarFunction_t(al, loc,
1209+
static_cast<int64_t>(IntrinsicScalarFunctions::ObjectType),
1210+
args.p, args.n, 0, ASRUtils::expr_type(m_value), m_value);
1211+
}
1212+
1213+
1214+
} // namespace ObjectType
1215+
1216+
11631217
namespace LogGamma {
11641218

11651219
static inline ASR::expr_t *eval_log_gamma(Allocator &al, const Location &loc,
@@ -3626,6 +3680,8 @@ namespace IntrinsicScalarFunctionRegistry {
36263680
static const std::map<int64_t,
36273681
std::tuple<impl_function,
36283682
verify_function>>& intrinsic_function_by_id_db = {
3683+
{static_cast<int64_t>(IntrinsicScalarFunctions::ObjectType),
3684+
{nullptr, &ObjectType::verify_args}},
36293685
{static_cast<int64_t>(IntrinsicScalarFunctions::LogGamma),
36303686
{&LogGamma::instantiate_LogGamma, &UnaryIntrinsicFunction::verify_args}},
36313687
{static_cast<int64_t>(IntrinsicScalarFunctions::Trunc),
@@ -3753,9 +3809,10 @@ namespace IntrinsicScalarFunctionRegistry {
37533809
};
37543810

37553811
static const std::map<int64_t, std::string>& intrinsic_function_id_to_name = {
3812+
{static_cast<int64_t>(IntrinsicScalarFunctions::ObjectType),
3813+
"type"},
37563814
{static_cast<int64_t>(IntrinsicScalarFunctions::LogGamma),
37573815
"log_gamma"},
3758-
37593816
{static_cast<int64_t>(IntrinsicScalarFunctions::Trunc),
37603817
"trunc"},
37613818
{static_cast<int64_t>(IntrinsicScalarFunctions::Fix),
@@ -3882,6 +3939,7 @@ namespace IntrinsicScalarFunctionRegistry {
38823939
static const std::map<std::string,
38833940
std::tuple<create_intrinsic_function,
38843941
eval_intrinsic_function>>& intrinsic_function_by_name_db = {
3942+
{"type", {&ObjectType::create_ObjectType, &ObjectType::eval_ObjectType}},
38853943
{"log_gamma", {&LogGamma::create_LogGamma, &LogGamma::eval_log_gamma}},
38863944
{"trunc", {&Trunc::create_Trunc, &Trunc::eval_Trunc}},
38873945
{"fix", {&Fix::create_Fix, &Fix::eval_Fix}},

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7586,7 +7586,8 @@ we will have to use something else.
75867586
}
75877587
Vec<ASR::expr_t*> args_; args_.reserve(al, x.n_args);
75887588
visit_expr_list(x.m_args, x.n_args, args_);
7589-
if (ASRUtils::is_array(ASRUtils::expr_type(args_[0])) &&
7589+
7590+
if (x.n_args > 0 && ASRUtils::is_array(ASRUtils::expr_type(args_[0])) &&
75907591
imported_functions[call_name] == "math" ) {
75917592
throw SemanticError("Function '" + call_name + "' does not accept vector values",
75927593
x.base.base.loc);

0 commit comments

Comments
 (0)