@@ -49,13 +49,89 @@ struct IntrinsicNodeHandler {
49
49
const Location &loc) {
50
50
ASR::expr_t *arg = nullptr , *value = nullptr ;
51
51
ASR::ttype_t *type = nullptr ;
52
- if (args.size () > 1 ) {
53
- throw SemanticError (" Either 0 or 1 argument is expected in 'int()' " ,
52
+ if (args.size () > 2 ) {
53
+ throw SemanticError (" 'int()' takes at most 2 arguments ( " + std::to_string (args. size ()) + " given) " ,
54
54
loc);
55
55
}
56
- if (args.size () > 0 ) {
56
+ if (args.size () >= 1 ) {
57
57
arg = args[0 ].m_value ;
58
58
type = ASRUtils::expr_type (arg);
59
+ if (ASRUtils::is_character (*type)) {
60
+ int32_t base;
61
+ if (args.size () == 1 ) {
62
+ base = 10 ;
63
+ } else {
64
+ arg = args[1 ].m_value ;
65
+ type = ASRUtils::expr_type (arg);
66
+ if (ASRUtils::is_integer (*type)) {
67
+ base = ASR::down_cast<ASR::IntegerConstant_t>(
68
+ ASRUtils::expr_value (arg))->m_n ;
69
+ if ((base != 0 && base < 2 ) || base > 36 ) {
70
+ throw SemanticError (" int() base must be >= 2 and <= 36, or 0" , loc);
71
+ }
72
+ } else {
73
+ throw SemanticError (" '" + ASRUtils::type_to_str_python (type) + " ' object cannot be interpreted as an integer" ,
74
+ arg->base .loc );
75
+ }
76
+ }
77
+ arg = args[0 ].m_value ;
78
+ type = ASRUtils::expr_type (arg);
79
+ ASR::ttype_t *to_type = ASRUtils::TYPE (ASR::make_Integer_t (al, loc, 8 ));
80
+ if (ASRUtils::expr_value (arg) != nullptr ) {
81
+ char *c = ASR::down_cast<ASR::StringConstant_t>(
82
+ ASRUtils::expr_value (arg))->m_s ;
83
+ int ival = 0 ;
84
+ bool zero_based = false ;
85
+ char *ch = c;
86
+ if (*ch == ' -' ) {
87
+ ch++;
88
+ }
89
+ if (base == 0 ) {
90
+ zero_based = true ;
91
+ if (*ch == ' 0' ) {
92
+ ch++;
93
+ if (*ch == ' x' || *ch == ' X' ) {
94
+ base = 16 ;
95
+ ch++;
96
+ } else if (*ch == ' o' || *ch == ' O' ) {
97
+ base = 8 ;
98
+ ch++;
99
+ } else if (*ch == ' b' || *ch == ' B' ) {
100
+ base = 2 ;
101
+ ch++;
102
+ }
103
+ } else {
104
+ base = 10 ;
105
+ }
106
+ } else {
107
+ if (*ch == ' 0' &&
108
+ ((base == 16 && (ch[1 ] == ' x' || ch[1 ] == ' X' )) ||
109
+ (base == 8 && (ch[1 ] == ' o' || ch[1 ] == ' O' )) ||
110
+ (base == 2 && (ch[1 ] == ' b' || ch[1 ] == ' B' )))) {
111
+ ch += 2 ;
112
+ }
113
+ }
114
+ while (*ch) {
115
+ if (*ch == ' .' ) {
116
+ throw SemanticError (" invalid literal for int() with base " + std::to_string (zero_based ? 0 : base) + " : '" + std::string (c) + " '" , arg->base .loc );
117
+ }
118
+ if (!((*ch >= ' 0' && (*ch <= std::min ((int )' 9' , ' 0' + base - 1 ))) || (*ch >= ' A' && (*ch < ' A' + base - 10 )) || (*ch >= ' a' && (*ch < ' a' + base - 10 )))) {
119
+ throw SemanticError (" invalid literal for int() with base " + std::to_string (zero_based ? 0 : base) + " : '" + std::string (c) + " '" , arg->base .loc );
120
+ }
121
+ ch++;
122
+ }
123
+ ival = std::stoi (c,0 ,base);
124
+ return (ASR::asr_t *)ASR::down_cast<ASR::expr_t >(ASR::make_IntegerConstant_t (al,
125
+ loc, ival, to_type));
126
+ }
127
+ return (ASR::asr_t *)ASR::down_cast<ASR::expr_t >(ASR::make_Cast_t (
128
+ al, loc, arg, ASR::cast_kindType::CharacterToInteger,
129
+ to_type, value));
130
+ } else {
131
+ if (args.size () == 2 ) {
132
+ throw SemanticError (" int() can't convert non-string with explicit base" , loc);
133
+ }
134
+ }
59
135
}
60
136
ASR::ttype_t *to_type = ASRUtils::TYPE (ASR::make_Integer_t (al, loc, 8 ));
61
137
if (!arg) {
@@ -71,31 +147,6 @@ struct IntrinsicNodeHandler {
71
147
return (ASR::asr_t *)ASR::down_cast<ASR::expr_t >(ASR::make_Cast_t (
72
148
al, loc, arg, ASR::cast_kindType::RealToInteger,
73
149
to_type, value));
74
- } else if (ASRUtils::is_character (*type)) {
75
- if (ASRUtils::expr_value (arg) != nullptr ) {
76
- char *c = ASR::down_cast<ASR::StringConstant_t>(
77
- ASRUtils::expr_value (arg))->m_s ;
78
- int ival = 0 ;
79
- char *ch = c;
80
- if (*ch == ' -' ) {
81
- ch++;
82
- }
83
- while (*ch) {
84
- if (*ch == ' .' ) {
85
- throw SemanticError (" invalid literal for int() with base 10: '" + std::string (c) + " '" , arg->base .loc );
86
- }
87
- if (*ch < ' 0' || *ch > ' 9' ) {
88
- throw SemanticError (" invalid literal for int() with base 10: '" + std::string (c) + " '" , arg->base .loc );
89
- }
90
- ch++;
91
- }
92
- ival = std::stoi (c);
93
- return (ASR::asr_t *)ASR::down_cast<ASR::expr_t >(ASR::make_IntegerConstant_t (al,
94
- loc, ival, to_type));
95
- }
96
- return (ASR::asr_t *)ASR::down_cast<ASR::expr_t >(ASR::make_Cast_t (
97
- al, loc, arg, ASR::cast_kindType::CharacterToInteger,
98
- to_type, value));
99
150
} else if (ASRUtils::is_logical (*type)) {
100
151
if (ASRUtils::expr_value (arg) != nullptr ) {
101
152
int32_t ival = ASR::down_cast<ASR::LogicalConstant_t>(
0 commit comments