@@ -1708,9 +1708,11 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
1708
1708
right_type->type != ASR::ttypeType::Complex) &&
1709
1709
x.m_ops != AST::cmpopType::Eq && x.m_ops != AST::cmpopType::NotEq) &&
1710
1710
(left_type->type != ASR::ttypeType::Character ||
1711
- right_type->type != ASR::ttypeType::Character))) {
1711
+ right_type->type != ASR::ttypeType::Character)) &&
1712
+ (left_type->type != ASR::ttypeType::Logical ||
1713
+ right_type->type != ASR::ttypeType::Logical)) {
1712
1714
throw SemanticError (
1713
- " Compare: only Integer, Real, or String can be on the LHS and RHS."
1715
+ " Compare: only Integer, Real, Logical, or String can be on the LHS and RHS."
1714
1716
" If operator is Eq or NotEq then Complex type is also acceptable" ,
1715
1717
x.base .base .loc );
1716
1718
}
@@ -1810,6 +1812,27 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
1810
1812
value = ASR::down_cast<ASR::expr_t >(ASR::make_ConstantLogical_t (
1811
1813
al, x.base .base .loc , result, type));
1812
1814
1815
+ } else if (ASRUtils::is_logical (*source_type)) {
1816
+ bool left_value = ASR::down_cast<ASR::ConstantLogical_t>(
1817
+ ASRUtils::expr_value (left))->m_value ;
1818
+ bool right_value = ASR::down_cast<ASR::ConstantLogical_t>(
1819
+ ASRUtils::expr_value (right))->m_value ;
1820
+ bool result;
1821
+ switch (asr_op) {
1822
+ case (ASR::cmpopType::Eq): { result = left_value == right_value; break ; }
1823
+ case (ASR::cmpopType::Gt): { result = left_value > right_value; break ; }
1824
+ case (ASR::cmpopType::GtE): { result = left_value >= right_value; break ; }
1825
+ case (ASR::cmpopType::Lt): { result = left_value < right_value; break ; }
1826
+ case (ASR::cmpopType::LtE): { result = left_value <= right_value; break ; }
1827
+ case (ASR::cmpopType::NotEq): { result = left_value != right_value; break ; }
1828
+ default : {
1829
+ throw SemanticError (" Comparison operator not implemented" ,
1830
+ x.base .base .loc );
1831
+ }
1832
+ }
1833
+ value = ASR::down_cast<ASR::expr_t >(ASR::make_ConstantLogical_t (
1834
+ al, x.base .base .loc , result, type));
1835
+
1813
1836
} else if (ASRUtils::is_character (*source_type)) {
1814
1837
char * left_value = ASR::down_cast<ASR::ConstantString_t>(
1815
1838
ASRUtils::expr_value (left))->m_s ;
@@ -2271,130 +2294,6 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
2271
2294
throw SemanticError (call_name + " () must have one integer argument" ,
2272
2295
x.base .base .loc );
2273
2296
}
2274
- } else if (call_name == " abs" ) {
2275
- if (args.size () != 1 ) {
2276
- throw SemanticError (call_name + " () takes exactly one argument (" +
2277
- std::to_string (args.size ()) + " given)" , x.base .base .loc );
2278
- }
2279
- std::string rl_path = get_runtime_library_dir ();
2280
- SymbolTable *st = current_scope;
2281
- while (st->parent != nullptr ) {
2282
- st = st->parent ;
2283
- }
2284
- bool ltypes;
2285
- std::string msym = " lpython_builtin" ;
2286
- ASR::symbol_t *t = (ASR::symbol_t *)(load_module (al, st,
2287
- msym, x.base .base .loc , true , rl_path, ltypes,
2288
- [&](const std::string &msg, const Location &loc) { throw SemanticError (msg, loc); }
2289
- ));
2290
- LFORTRAN_ASSERT (!ltypes)
2291
- if (!t) {
2292
- throw SemanticError (" The module '" + msym + " ' cannot be loaded" ,
2293
- x.base .base .loc );
2294
- }
2295
-
2296
- ASR::Module_t *m = ASR::down_cast<ASR::Module_t>(t);
2297
-
2298
- std::string local_sym = " abs" ;
2299
- t = m->m_symtab ->resolve_symbol (local_sym);
2300
- if (!t) {
2301
- throw SemanticError (" ICE: The symbol '" + local_sym + " ' not found in the module '" + msym + " '" ,
2302
- x.base .base .loc );
2303
- }
2304
- if (ASR::is_a<ASR::Function_t>(*t)) {
2305
- if (current_scope->scope .find (local_sym) != current_scope->scope .end ()) {
2306
- throw SemanticError (" Function already defined" ,
2307
- x.base .base .loc );
2308
- }
2309
- ASR::Function_t *mfn = ASR::down_cast<ASR::Function_t>(t);
2310
- // `mfn` is the Function in a module. Now we construct
2311
- // an ExternalSymbol that points to it.
2312
- Str name;
2313
- name.from_str (al, local_sym);
2314
- char *cname = name.c_str (al);
2315
- ASR::asr_t *fn = ASR::make_ExternalSymbol_t (
2316
- al, mfn->base .base .loc ,
2317
- /* a_symtab */ current_scope,
2318
- /* a_name */ cname,
2319
- (ASR::symbol_t *)mfn,
2320
- m->m_name , nullptr , 0 , mfn->m_name ,
2321
- ASR::accessType::Public
2322
- );
2323
- current_scope->scope [local_sym] = ASR::down_cast<ASR::symbol_t >(fn);
2324
-
2325
- ASR::ttype_t *a_type = ASRUtils::TYPE (ASR::make_Real_t (al,
2326
- x.base .base .loc , 8 , nullptr , 0 ));
2327
- tmp = ASR::make_FunctionCall_t (al, x.base .base .loc , ASR::down_cast<ASR::symbol_t >(fn),
2328
- nullptr , args.p , args.size (), nullptr , 0 , a_type, nullptr , nullptr );
2329
- return ;
2330
- } else {
2331
- throw SemanticError (" ICE: Abs expected to be a function" , x.base .base .loc );
2332
- }
2333
- // Compile time value implementation:
2334
- /*
2335
- ASR::expr_t* arg = ASRUtils::expr_value(args[0]);
2336
- ASR::ttype_t* t = ASRUtils::expr_type(arg);
2337
- ASR::ttype_t* real_type = ASRUtils::TYPE(ASR::make_Real_t(al,
2338
- x.base.base.loc, 8, nullptr, 0));
2339
- ASR::ttype_t *int_type = ASRUtils::TYPE(ASR::make_Integer_t(al,
2340
- x.base.base.loc, 4, nullptr, 0));
2341
- if (ASRUtils::is_real(*t)) {
2342
- double rv = ASR::down_cast<ASR::ConstantReal_t>(arg)->m_r;
2343
- double val = std::abs(rv);
2344
- tmp = ASR::make_ConstantReal_t(al, x.base.base.loc, val, t);
2345
- } else if (ASRUtils::is_integer(*t)) {
2346
- int64_t rv = ASR::down_cast<ASR::ConstantInteger_t>(arg)->m_n;
2347
- int64_t val = std::abs(rv);
2348
- tmp = ASR::make_ConstantInteger_t(al, x.base.base.loc, val, t);
2349
- } else if (ASRUtils::is_complex(*t)) {
2350
- double re = ASR::down_cast<ASR::ConstantComplex_t>(arg)->m_re;
2351
- double im = ASR::down_cast<ASR::ConstantComplex_t>(arg)->m_im;
2352
- std::complex<double> c(re, im);
2353
- double result = std::abs(c);
2354
- tmp = ASR::make_ConstantReal_t(al, x.base.base.loc, result, real_type);
2355
- } else if (ASRUtils::is_logical(*t)) {
2356
- bool rv = ASR::down_cast<ASR::ConstantLogical_t>(arg)->m_value;
2357
- int8_t val = rv ? 1 : 0;
2358
- tmp = ASR::make_ConstantInteger_t(al, x.base.base.loc, val, int_type);
2359
- } else {
2360
- throw SemanticError(call_name + "() must have one real, integer, complex, or logical argument",
2361
- x.base.base.loc);
2362
- }
2363
- return;
2364
- */
2365
- } else if (call_name == " bool" ) {
2366
- if (args.size () != 1 ) {
2367
- throw SemanticError (call_name + " () takes exactly one argument (" +
2368
- std::to_string (args.size ()) + " given)" , x.base .base .loc );
2369
- }
2370
- ASR::ttype_t *type = ASRUtils::TYPE (ASR::make_Logical_t (al, x.base .base .loc ,
2371
- 1 , nullptr , 0 ));
2372
- ASR::expr_t * arg = ASRUtils::expr_value (args[0 ]);
2373
- ASR::ttype_t * t = ASRUtils::expr_type (arg);
2374
- bool result;
2375
- if (ASRUtils::is_real (*t)) {
2376
- double rv = ASR::down_cast<ASR::ConstantReal_t>(arg)->m_r ;
2377
- result = rv ? true : false ;
2378
- } else if (ASRUtils::is_integer (*t)) {
2379
- int64_t rv = ASR::down_cast<ASR::ConstantInteger_t>(arg)->m_n ;
2380
- result = rv ? true : false ;
2381
- } else if (ASRUtils::is_complex (*t)) {
2382
- double re = ASR::down_cast<ASR::ConstantComplex_t>(arg)->m_re ;
2383
- double im = ASR::down_cast<ASR::ConstantComplex_t>(arg)->m_im ;
2384
- std::complex<double > c (re, im);
2385
- result = (re || im) ? true : false ;
2386
- } else if (ASRUtils::is_logical (*t)) {
2387
- bool rv = ASR::down_cast<ASR::ConstantLogical_t>(arg)->m_value ;
2388
- result = rv;
2389
- } else if (ASRUtils::is_character (*t)) {
2390
- char * c = ASR::down_cast<ASR::ConstantString_t>(ASRUtils::expr_value (arg))->m_s ;
2391
- result = strlen (s2c (al, std::string (c))) ? true : false ;
2392
- } else {
2393
- throw SemanticError (call_name + " () must have one real, integer, character,"
2394
- " complex, or logical argument" , x.base .base .loc );
2395
- }
2396
- tmp = ASR::make_ConstantLogical_t (al, x.base .base .loc , result, type);
2397
- return ;
2398
2297
} else if (call_name == " callable" ) {
2399
2298
if (args.size () != 1 ) {
2400
2299
throw SemanticError (call_name + " () takes exactly one argument (" +
@@ -2482,40 +2381,6 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
2482
2381
ASRUtils::type_to_str (float_type) + " '" , x.base .base .loc );
2483
2382
}
2484
2383
return ;
2485
- } else if (call_name == " str" ) {
2486
- ASR::ttype_t * str_type = ASRUtils::TYPE (ASR::make_Character_t (al,
2487
- x.base .base .loc , 1 , 1 , nullptr , nullptr , 0 ));
2488
- if (args.size () == 0 ) { // create an empty string
2489
- tmp = ASR::make_ConstantString_t (al, x.base .base .loc , s2c (al, " " ), str_type);
2490
- return ;
2491
- }
2492
- ASR::expr_t * arg = ASRUtils::expr_value (args[0 ]);
2493
- ASR::ttype_t * arg_type = ASRUtils::expr_type (arg);
2494
- if (arg == nullptr ) {
2495
- throw SemanticError (" runtime str(x) is not supported, only compile time for now" ,
2496
- x.base .base .loc );
2497
- }
2498
- if (ASRUtils::is_integer (*arg_type)) {
2499
- int64_t ival = ASR::down_cast<ASR::ConstantInteger_t>(arg)->m_n ;
2500
- std::string s = std::to_string (ival);
2501
- tmp = ASR::make_ConstantString_t (al, x.base .base .loc , s2c (al, s), str_type);
2502
- } else if (ASRUtils::is_real (*arg_type)) {
2503
- double rval = ASR::down_cast<ASR::ConstantReal_t>(arg)->m_r ;
2504
- std::string s = std::to_string (rval);
2505
- tmp = ASR::make_ConstantString_t (al, x.base .base .loc , s2c (al, s), str_type);
2506
- } else if (ASRUtils::is_logical (*arg_type)) {
2507
- bool rv = ASR::down_cast<ASR::ConstantLogical_t>(arg)->m_value ;
2508
- std::string s = rv ? " True" : " False" ;
2509
- tmp = ASR::make_ConstantString_t (al, x.base .base .loc , s2c (al, s), str_type);
2510
- } else if (ASRUtils::is_character (*arg_type)) {
2511
- char * c = ASR::down_cast<ASR::ConstantString_t>(arg)->m_s ;
2512
- std::string s = std::string (c);
2513
- tmp = ASR::make_ConstantString_t (al, x.base .base .loc , s2c (al, s), str_type);
2514
- } else {
2515
- throw SemanticError (" str() argument must be real, integer, logical, or a string, not '" +
2516
- ASRUtils::type_to_str (arg_type) + " '" , x.base .base .loc );
2517
- }
2518
- return ;
2519
2384
} else if (call_name == " divmod" ) {
2520
2385
if (args.size () != 2 ) {
2521
2386
throw SemanticError (call_name + " () takes exactly two arguments (" +
0 commit comments