Mercurial > octave
comparison libinterp/octave-value/ov.cc @ 28519:d4563c5d4060
handle all dispatching for colon operator in do_colon_op function
* ov.cc (do_colon_op): Handle all dispatching here, but using lookup
based on argument vector passed to feval instead of determining
dispatch type separately.
* pt-colon.cc (tree_colon_expression::evaluate): Simply evaluate
arguments and pass them to do_colon_op.
* test/colon-op: New test directory.
* test/module.mk: Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Mon, 29 Jun 2020 23:45:19 -0400 |
parents | b743a63e2dab |
children | ee9b1081471f |
comparison
equal
deleted
inserted
replaced
28518:b8ab8b58547d | 28519:d4563c5d4060 |
---|---|
2504 { | 2504 { |
2505 octave_value retval; | 2505 octave_value retval; |
2506 | 2506 |
2507 if (base.isobject () || increment.isobject () || limit.isobject ()) | 2507 if (base.isobject () || increment.isobject () || limit.isobject ()) |
2508 { | 2508 { |
2509 std::string dispatch_type; | 2509 octave_value_list tmp1; |
2510 | |
2511 if (base.isobject ()) | |
2512 dispatch_type = base.class_name (); | |
2513 else if (increment.is_defined () && increment.isobject ()) | |
2514 dispatch_type = increment.class_name (); | |
2515 else | |
2516 dispatch_type = limit.class_name (); | |
2517 | |
2518 octave::symbol_table& symtab = octave::__get_symbol_table__ ("do_colon_op"); | |
2519 | |
2520 octave_value meth = symtab.find_method ("colon", dispatch_type); | |
2521 | |
2522 if (! meth.is_defined ()) | |
2523 error ("colon method not defined for %s class", dispatch_type.c_str ()); | |
2524 | |
2525 octave_value_list args; | |
2526 | 2510 |
2527 if (increment.is_defined ()) | 2511 if (increment.is_defined ()) |
2528 { | 2512 { |
2529 args(2) = limit; | 2513 tmp1(2) = limit; |
2530 args(1) = increment; | 2514 tmp1(1) = increment; |
2515 tmp1(0) = base; | |
2531 } | 2516 } |
2532 else | 2517 else |
2533 args(1) = limit; | 2518 { |
2534 | 2519 tmp1(1) = limit; |
2535 args(0) = base; | 2520 tmp1(0) = base; |
2536 | 2521 } |
2537 octave_value_list tmp = octave::feval (meth.function_value (), args, 1); | 2522 |
2538 | 2523 octave::interpreter& interp = octave::__get_interpreter__ ("do_colon_op"); |
2539 if (tmp.length () > 0) | 2524 |
2540 retval = tmp(0); | 2525 octave::symbol_table& symtab = interp.get_symbol_table (); |
2541 } | 2526 |
2527 octave_value fcn = symtab.find_function ("colon", tmp1); | |
2528 | |
2529 if (fcn.is_defined ()) | |
2530 { | |
2531 octave_value_list tmp2 = interp.feval (fcn, tmp1, 1); | |
2532 | |
2533 return tmp2 (0); | |
2534 } | |
2535 } | |
2536 | |
2537 bool result_is_str = (base.is_string () && limit.is_string ()); | |
2538 bool dq_str = (base.is_dq_string () || limit.is_dq_string ()); | |
2539 | |
2540 if (base.numel () > 1 || limit.numel () > 1 | |
2541 || (increment.is_defined () && increment.numel () > 1)) | |
2542 warning_with_id ("Octave:colon-nonscalar-argument", | |
2543 "colon arguments should be scalars"); | |
2544 | |
2545 if (base.iscomplex () || limit.iscomplex () | |
2546 || (increment.is_defined () && increment.iscomplex ())) | |
2547 warning_with_id ("Octave:colon-complex-argument", | |
2548 "imaginary part of complex colon arguments is ignored"); | |
2549 | |
2550 Matrix m_base, m_limit, m_increment; | |
2551 | |
2552 try | |
2553 { | |
2554 m_base = base.matrix_value (true); | |
2555 } | |
2556 catch (octave::execution_exception& e) | |
2557 { | |
2558 error (e, "invalid base value in colon expression"); | |
2559 } | |
2560 | |
2561 try | |
2562 { | |
2563 m_limit = limit.matrix_value (true); | |
2564 } | |
2565 catch (octave::execution_exception& e) | |
2566 { | |
2567 error (e, "invalid limit value in colon expression"); | |
2568 } | |
2569 | |
2570 try | |
2571 { | |
2572 m_increment = (increment.is_defined () | |
2573 ? increment.matrix_value (true) | |
2574 : Matrix (1, 1, 1.0)); | |
2575 } | |
2576 catch (octave::execution_exception& e) | |
2577 { | |
2578 error (e, "invalid increment value in colon expression"); | |
2579 } | |
2580 | |
2581 bool base_empty = m_base.isempty (); | |
2582 bool limit_empty = m_limit.isempty (); | |
2583 bool increment_empty = m_increment.isempty (); | |
2584 | |
2585 if (base_empty || limit_empty || increment_empty) | |
2586 retval = Range (); | |
2542 else | 2587 else |
2543 { | 2588 { |
2544 bool result_is_str = (base.is_string () && limit.is_string ()); | 2589 Range r (m_base(0), m_limit(0), m_increment(0)); |
2545 bool dq_str = (base.is_dq_string () || limit.is_dq_string ()); | 2590 |
2546 | 2591 // For compatibility with Matlab, don't allow the range used in |
2547 if (base.numel () > 1 || limit.numel () > 1 | 2592 // a FOR loop expression to be converted to a Matrix. |
2548 || (increment.is_defined () && increment.numel () > 1)) | 2593 |
2549 warning_with_id ("Octave:colon-nonscalar-argument", | 2594 retval = octave_value (r, is_for_cmd_expr); |
2550 "colon arguments should be scalars"); | 2595 |
2551 | 2596 if (result_is_str) |
2552 if (base.iscomplex () || limit.iscomplex () | 2597 retval = (retval.convert_to_str (false, true, dq_str ? '"' : '\'')); |
2553 || (increment.is_defined () && increment.iscomplex ())) | |
2554 warning_with_id ("Octave:colon-complex-argument", | |
2555 "imaginary part of complex colon arguments is ignored"); | |
2556 | |
2557 Matrix m_base, m_limit, m_increment; | |
2558 | |
2559 try | |
2560 { | |
2561 m_base = base.matrix_value (true); | |
2562 } | |
2563 catch (octave::execution_exception& e) | |
2564 { | |
2565 error (e, "invalid base value in colon expression"); | |
2566 } | |
2567 | |
2568 try | |
2569 { | |
2570 m_limit = limit.matrix_value (true); | |
2571 } | |
2572 catch (octave::execution_exception& e) | |
2573 { | |
2574 error (e, "invalid limit value in colon expression"); | |
2575 } | |
2576 | |
2577 try | |
2578 { | |
2579 m_increment = (increment.is_defined () | |
2580 ? increment.matrix_value (true) | |
2581 : Matrix (1, 1, 1.0)); | |
2582 } | |
2583 catch (octave::execution_exception& e) | |
2584 { | |
2585 error (e, "invalid increment value in colon expression"); | |
2586 } | |
2587 | |
2588 bool base_empty = m_base.isempty (); | |
2589 bool limit_empty = m_limit.isempty (); | |
2590 bool increment_empty = m_increment.isempty (); | |
2591 | |
2592 if (base_empty || limit_empty || increment_empty) | |
2593 retval = Range (); | |
2594 else | |
2595 { | |
2596 Range r (m_base(0), m_limit(0), m_increment(0)); | |
2597 | |
2598 // For compatibility with Matlab, don't allow the range used in | |
2599 // a FOR loop expression to be converted to a Matrix. | |
2600 | |
2601 retval = octave_value (r, is_for_cmd_expr); | |
2602 | |
2603 if (result_is_str) | |
2604 retval = (retval.convert_to_str (false, true, dq_str ? '"' : '\'')); | |
2605 } | |
2606 } | 2598 } |
2607 | 2599 |
2608 return retval; | 2600 return retval; |
2609 } | 2601 } |
2610 | 2602 |