comparison libinterp/parse-tree/pt-idx.cc @ 20590:1a0a433c8263

eliminate more simple uses of error_state * dirfns.cc, oct-map.cc, oct-stream.cc, regexp.cc, ov-base-mat.cc, ov-cell.cc, pt-idx.cc, pt-mat.cc: Eliminate simple uses of error_state.
author John W. Eaton <jwe@octave.org>
date Mon, 05 Oct 2015 21:13:12 -0400
parents dd6345fd8a97
children 729a85dafba8
comparison
equal deleted inserted replaced
20589:b10432a40432 20590:1a0a433c8263
155 octave_value_list arg_values; 155 octave_value_list arg_values;
156 156
157 if (args) 157 if (args)
158 arg_values = args->convert_to_const_vector (); 158 arg_values = args->convert_to_const_vector ();
159 159
160 if (! error_state) 160 int n = arg_values.length ();
161 { 161
162 int n = arg_values.length (); 162 if (n > 0)
163 163 {
164 if (n > 0) 164 arg_values.stash_name_tags (arg_nm);
165 { 165
166 arg_values.stash_name_tags (arg_nm); 166 retval.resize (dim_vector (1, n));
167 167
168 retval.resize (dim_vector (1, n)); 168 for (int i = 0; i < n; i++)
169 169 retval(0,i) = arg_values(i);
170 for (int i = 0; i < n; i++)
171 retval(0,i) = arg_values(i);
172 }
173 } 170 }
174 171
175 return retval; 172 return retval;
176 } 173 }
177 174
187 gripe_invalid_inquiry_subscript (); 184 gripe_invalid_inquiry_subscript ();
188 else 185 else
189 retval = args->convert_to_const_vector (object); 186 retval = args->convert_to_const_vector (object);
190 } 187 }
191 188
192 if (! error_state) 189 octave_idx_type n = retval.length ();
193 { 190
194 octave_idx_type n = retval.length (); 191 if (n > 0)
195 192 retval.stash_name_tags (arg_nm);
196 if (n > 0)
197 retval.stash_name_tags (arg_nm);
198 }
199 193
200 return retval; 194 return retval;
201 } 195 }
202 196
203 std::string 197 std::string
213 207
214 if (df) 208 if (df)
215 { 209 {
216 octave_value t = df->rvalue1 (); 210 octave_value t = df->rvalue1 ();
217 211
218 if (! error_state) 212 if (t.is_string () && t.rows () == 1)
219 { 213 fn = t.string_value ();
220 if (t.is_string () && t.rows () == 1) 214 else
221 fn = t.string_value (); 215 error ("dynamic structure field names must be strings");
222 else
223 error ("dynamic structure field names must be strings");
224 }
225 } 216 }
226 else 217 else
227 panic_impossible (); 218 panic_impossible ();
228 } 219 }
229 220
262 253
263 default: 254 default:
264 panic_impossible (); 255 panic_impossible ();
265 } 256 }
266 257
267 if (error_state)
268 return m;
269
270 p_args++; 258 p_args++;
271 p_arg_nm++; 259 p_arg_nm++;
272 p_dyn_field++; 260 p_dyn_field++;
273 } 261 }
274 262
301 octave_value_list 289 octave_value_list
302 tree_index_expression::rvalue (int nargout, 290 tree_index_expression::rvalue (int nargout,
303 const std::list<octave_lvalue> *lvalue_list) 291 const std::list<octave_lvalue> *lvalue_list)
304 { 292 {
305 octave_value_list retval; 293 octave_value_list retval;
306
307 if (error_state)
308 return retval;
309 294
310 octave_value first_expr_val; 295 octave_value first_expr_val;
311 296
312 octave_value_list first_args; 297 octave_value_list first_args;
313 298
328 string_vector anm = *(arg_nm.begin ()); 313 string_vector anm = *(arg_nm.begin ());
329 have_args = true; 314 have_args = true;
330 first_args = al -> convert_to_const_vector (); 315 first_args = al -> convert_to_const_vector ();
331 first_args.stash_name_tags (anm); 316 first_args.stash_name_tags (anm);
332 317
333 if (! error_state) 318 first_expr_val = id->do_lookup (first_args);
334 first_expr_val = id->do_lookup (first_args);
335 } 319 }
336 } 320 }
337 } 321 }
338 322
339 if (! error_state) 323 if (first_expr_val.is_undefined ())
340 { 324 first_expr_val = expr->rvalue1 ();
341 if (first_expr_val.is_undefined ()) 325
342 first_expr_val = expr->rvalue1 (); 326 octave_value tmp = first_expr_val;
343 327 octave_idx_type tmpi = 0;
344 octave_value tmp = first_expr_val; 328
345 octave_idx_type tmpi = 0; 329 std::list<octave_value_list> idx;
346 330
347 std::list<octave_value_list> idx; 331 int n = args.size ();
348 332
349 int n = args.size (); 333 std::list<tree_argument_list *>::iterator p_args = args.begin ();
350 334 std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
351 std::list<tree_argument_list *>::iterator p_args = args.begin (); 335 std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
352 std::list<string_vector>::iterator p_arg_nm = arg_nm.begin (); 336
353 std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin (); 337 for (int i = 0; i < n; i++)
354 338 {
355 for (int i = 0; i < n; i++) 339 if (i > 0)
356 { 340 {
357 if (i > 0) 341 tree_argument_list *al = *p_args;
342
343 // In Matlab, () can only be followed by . In Octave, we do not
344 // enforce this for rvalue expressions, but we'll split the
345 // evaluation at this point. This will, hopefully, allow Octave's
346 // looser rules apply smoothly for Matlab overloaded subsref
347 // codes.
348 bool force_split = type[i-1] == '(' && type[i] != '.';
349
350 if (force_split || (al && al->has_magic_end ()))
358 { 351 {
359 tree_argument_list *al = *p_args; 352 // (we have force_split, or) we have an expression like
360 353 //
361 // In Matlab, () can only be followed by . In Octave, we do not 354 // x{end}.a(end)
362 // enforce this for rvalue expressions, but we'll split the 355 //
363 // evaluation at this point. This will, hopefully, allow Octave's 356 // and we are looking at the argument list that
364 // looser rules apply smoothly for Matlab overloaded subsref 357 // contains the second (or third, etc.) "end" token,
365 // codes. 358 // so we must evaluate everything up to the point of
366 bool force_split = type[i-1] == '(' && type[i] != '.'; 359 // that argument list so we can pass the appropriate
367 360 // value to the built-in end function.
368 if (force_split || (al && al->has_magic_end ())) 361
362 try
369 { 363 {
370 // (we have force_split, or) we have an expression like 364 octave_value_list tmp_list
371 // 365 =tmp.subsref (type.substr (tmpi, i-tmpi), idx, nargout);
372 // x{end}.a(end) 366
373 // 367 tmp = tmp_list.length () ? tmp_list(0) : octave_value ();
374 // and we are looking at the argument list that 368 tmpi = i;
375 // contains the second (or third, etc.) "end" token, 369 idx.clear ();
376 // so we must evaluate everything up to the point of 370
377 // that argument list so we can pass the appropriate 371 if (tmp.is_cs_list ())
378 // value to the built-in end function. 372 gripe_indexed_cs_list ();
379 373
380 try 374 if (tmp.is_function ())
381 { 375 {
382 octave_value_list tmp_list 376 octave_function *fcn = tmp.function_value (true);
383 =tmp.subsref (type.substr (tmpi, i-tmpi), idx, nargout); 377
384 378 if (fcn && ! fcn->is_postfix_index_handled (type[i]))
385 tmp = tmp_list.length () ? tmp_list(0) : octave_value ();
386 tmpi = i;
387 idx.clear ();
388
389 if (tmp.is_cs_list ())
390 gripe_indexed_cs_list ();
391
392 if (error_state)
393 break;
394
395 if (tmp.is_function ())
396 { 379 {
397 octave_function *fcn = tmp.function_value (true); 380 octave_value_list empty_args;
398 381
399 if (fcn && ! fcn->is_postfix_index_handled (type[i])) 382 tmp_list = tmp.do_multi_index_op (1, empty_args);
400 { 383 tmp = (tmp_list.length ()
401 octave_value_list empty_args; 384 ? tmp_list(0) : octave_value ());
402 385
403 tmp_list = tmp.do_multi_index_op (1, empty_args); 386 if (tmp.is_cs_list ())
404 tmp = (tmp_list.length () 387 gripe_indexed_cs_list ();
405 ? tmp_list(0) : octave_value ());
406
407 if (tmp.is_cs_list ())
408 gripe_indexed_cs_list ();
409
410 if (error_state)
411 break;
412 }
413 } 388 }
414 } 389 }
415 catch (index_exception& e) // problems with index range, type etc. 390 }
416 { 391 catch (index_exception& e) // problems with index range, type etc.
417 final_index_error (e, expr); 392 {
418 } 393 final_index_error (e, expr);
419 } 394 }
420 } 395 }
421 396 }
422 switch (type[i]) 397
398 switch (type[i])
399 {
400 case '(':
401 if (have_args)
423 { 402 {
424 case '(': 403 idx.push_back (first_args);
425 if (have_args) 404 have_args = false;
426 {
427 idx.push_back (first_args);
428 have_args = false;
429 }
430 else
431 idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
432 break;
433
434 case '{':
435 idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
436 break;
437
438 case '.':
439 idx.push_back (octave_value (get_struct_index (p_arg_nm,
440 p_dyn_field)));
441 break;
442
443 default:
444 panic_impossible ();
445 } 405 }
446 406 else
447 if (error_state) 407 idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
448 break; 408 break;
449 409
450 p_args++; 410 case '{':
451 p_arg_nm++; 411 idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
452 p_dyn_field++; 412 break;
413
414 case '.':
415 idx.push_back (octave_value (get_struct_index (p_arg_nm,
416 p_dyn_field)));
417 break;
418
419 default:
420 panic_impossible ();
453 } 421 }
454 422
455 if (! error_state) 423 p_args++;
424 p_arg_nm++;
425 p_dyn_field++;
426 }
427
428 try
429 {
430 retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout,
431 lvalue_list);
432 }
433 catch (index_exception& e) // problems with range, invalid index type etc.
434 {
435 final_index_error (e, expr);
436 }
437
438 octave_value val = retval.length () ? retval(0) : octave_value ();
439
440 if (val.is_function ())
441 {
442 octave_function *fcn = val.function_value (true);
443
444 if (fcn)
445 {
446 octave_value_list empty_args;
447
448 retval = (lvalue_list
449 ? val.do_multi_index_op (nargout, empty_args,
450 lvalue_list)
451 : val.do_multi_index_op (nargout, empty_args));
452 }
453 }
454
455 return retval;
456 }
457
458 octave_value
459 tree_index_expression::rvalue1 (int nargout)
460 {
461 octave_value retval;
462
463 const octave_value_list tmp = rvalue (nargout);
464
465 if (! tmp.empty ())
466 retval = tmp(0);
467
468 return retval;
469 }
470
471 octave_lvalue
472 tree_index_expression::lvalue (void)
473 {
474 octave_lvalue retval;
475
476 std::list<octave_value_list> idx;
477 std::string tmp_type;
478
479 int n = args.size ();
480
481 std::list<tree_argument_list *>::iterator p_args = args.begin ();
482 std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
483 std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
484
485 retval = expr->lvalue ();
486
487 octave_value tmp = retval.value ();
488
489 octave_idx_type tmpi = 0;
490 std::list<octave_value_list> tmpidx;
491
492 for (int i = 0; i < n; i++)
493 {
494 if (retval.numel () != 1)
495 gripe_indexed_cs_list ();
496 else if (tmpi < i)
456 { 497 {
457 try 498 try
458 { 499 {
459 retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout, 500 tmp = tmp.subsref (type.substr (tmpi, i-tmpi), tmpidx, true);
460 lvalue_list);
461 } 501 }
462 catch (index_exception& e) // problems with range, invalid index type etc. 502 catch (index_exception& e) // problems with range, invalid type etc.
463 { 503 {
464 final_index_error (e, expr); 504 final_index_error (e, expr);
465 } 505 }
466 506 tmpidx.clear ();
467 octave_value val = retval.length () ? retval(0) : octave_value ();
468
469 if (! error_state && val.is_function ())
470 {
471 octave_function *fcn = val.function_value (true);
472
473 if (fcn)
474 {
475 octave_value_list empty_args;
476
477 retval = (lvalue_list
478 ? val.do_multi_index_op (nargout, empty_args,
479 lvalue_list)
480 : val.do_multi_index_op (nargout, empty_args));
481 }
482 }
483 } 507 }
484 } 508
485 509 switch (type[i])
486 return retval;
487 }
488
489 octave_value
490 tree_index_expression::rvalue1 (int nargout)
491 {
492 octave_value retval;
493
494 const octave_value_list tmp = rvalue (nargout);
495
496 if (! tmp.empty ())
497 retval = tmp(0);
498
499 return retval;
500 }
501
502 octave_lvalue
503 tree_index_expression::lvalue (void)
504 {
505 octave_lvalue retval;
506
507 std::list<octave_value_list> idx;
508 std::string tmp_type;
509
510 int n = args.size ();
511
512 std::list<tree_argument_list *>::iterator p_args = args.begin ();
513 std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
514 std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
515
516 retval = expr->lvalue ();
517
518 if (! error_state)
519 {
520 octave_value tmp = retval.value ();
521
522 octave_idx_type tmpi = 0;
523 std::list<octave_value_list> tmpidx;
524
525 for (int i = 0; i < n; i++)
526 { 510 {
527 if (retval.numel () != 1) 511 case '(':
528 gripe_indexed_cs_list (); 512 {
529 else if (tmpi < i) 513 octave_value_list tidx
530 { 514 = make_value_list (*p_args, *p_arg_nm, &tmp, false);
531 try 515
532 { 516 idx.push_back (tidx);
533 tmp = tmp.subsref (type.substr (tmpi, i-tmpi), tmpidx, true); 517
534 } 518 if (i < n - 1)
535 catch (index_exception& e) // problems with range, invalid type etc.
536 {
537 final_index_error (e, expr);
538 }
539 tmpidx.clear ();
540 }
541
542 if (error_state)
543 break;
544
545 switch (type[i])
546 {
547 case '(':
548 { 519 {
549 octave_value_list tidx 520 if (type[i+1] == '.')
550 = make_value_list (*p_args, *p_arg_nm, &tmp, false);
551
552 idx.push_back (tidx);
553
554 if (i < n - 1)
555 { 521 {
556 if (type[i+1] == '.') 522 tmpidx.push_back (tidx);
557 { 523 tmpi = i+1;
558 tmpidx.push_back (tidx);
559 tmpi = i+1;
560 }
561 else
562 error ("() must be followed by . or close the index chain");
563 } 524 }
525 else
526 error ("() must be followed by . or close the index chain");
564 } 527 }
565 break; 528 }
566 529 break;
567 case '{': 530
531 case '{':
532 {
533 octave_value_list tidx
534 = make_value_list (*p_args, *p_arg_nm, &tmp, false);
535
536 if (tmp.is_undefined ())
568 { 537 {
569 octave_value_list tidx 538 if (tidx.has_magic_colon ())
570 = make_value_list (*p_args, *p_arg_nm, &tmp, false); 539 gripe_invalid_inquiry_subscript ();
571 540 else
541 tmp = Cell ();
542 }
543 else if (tmp.is_zero_by_zero ()
544 && (tmp.is_matrix_type () || tmp.is_string ()))
545 {
546 tmp = Cell ();
547 }
548
549 retval.numel (tmp.numel (tidx));
550
551 idx.push_back (tidx);
552 tmpidx.push_back (tidx);
553 tmpi = i;
554 }
555 break;
556
557 case '.':
558 {
559 octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field);
560
561 bool autoconv = (tmp.is_zero_by_zero ()
562 && (tmp.is_matrix_type () || tmp.is_string ()
563 || tmp.is_cell ()));
564
565 if (i > 0 && type[i-1] == '(')
566 {
567 octave_value_list pidx = idx.back ();
568
569 // Use octave_map, not octave_scalar_map so that the
570 // dimensions are 0x0, not 1x1.
572 if (tmp.is_undefined ()) 571 if (tmp.is_undefined ())
573 { 572 {
574 if (tidx.has_magic_colon ()) 573 if (pidx.has_magic_colon ())
575 gripe_invalid_inquiry_subscript (); 574 gripe_invalid_inquiry_subscript ();
576 else 575 else
577 tmp = Cell (); 576 tmp = octave_map ();
578 } 577 }
579 else if (tmp.is_zero_by_zero () 578 else if (autoconv)
580 && (tmp.is_matrix_type () || tmp.is_string ())) 579 tmp = octave_map ();
580
581 retval.numel (tmp.numel (pidx));
582
583 tmpi = i-1;
584 tmpidx.push_back (tidx);
585 }
586 else
587 {
588 if (tmp.is_undefined () || autoconv)
581 { 589 {
582 tmp = Cell (); 590 tmpi = i+1;
583 } 591 tmp = octave_value ();
584
585 retval.numel (tmp.numel (tidx));
586
587 if (error_state)
588 break;
589
590 idx.push_back (tidx);
591 tmpidx.push_back (tidx);
592 tmpi = i;
593 }
594 break;
595
596 case '.':
597 {
598 octave_value tidx = get_struct_index (p_arg_nm, p_dyn_field);
599 if (error_state)
600 break;
601
602 bool autoconv = (tmp.is_zero_by_zero ()
603 && (tmp.is_matrix_type () || tmp.is_string ()
604 || tmp.is_cell ()));
605
606 if (i > 0 && type[i-1] == '(')
607 {
608 octave_value_list pidx = idx.back ();
609
610 // Use octave_map, not octave_scalar_map so that the
611 // dimensions are 0x0, not 1x1.
612 if (tmp.is_undefined ())
613 {
614 if (pidx.has_magic_colon ())
615 gripe_invalid_inquiry_subscript ();
616 else
617 tmp = octave_map ();
618 }
619 else if (autoconv)
620 tmp = octave_map ();
621
622 retval.numel (tmp.numel (pidx));
623
624 tmpi = i-1;
625 tmpidx.push_back (tidx);
626 } 592 }
627 else 593 else
628 { 594 {
629 if (tmp.is_undefined () || autoconv) 595 retval.numel (tmp.numel (octave_value_list ()));
630 { 596
631 tmpi = i+1; 597 tmpi = i;
632 tmp = octave_value (); 598 tmpidx.push_back (tidx);
633 }
634 else
635 {
636 retval.numel (tmp.numel (octave_value_list ()));
637
638 tmpi = i;
639 tmpidx.push_back (tidx);
640 }
641 } 599 }
642
643 if (error_state)
644 break;
645
646 idx.push_back (tidx);
647 } 600 }
648 break; 601
649 602 idx.push_back (tidx);
650 default: 603 }
651 panic_impossible (); 604 break;
652 } 605
653 606 default:
654 if (idx.back ().empty ()) 607 panic_impossible ();
655 error ("invalid empty index list");
656
657 if (error_state)
658 break;
659
660 p_args++;
661 p_arg_nm++;
662 p_dyn_field++;
663 } 608 }
664 609
665 if (! error_state) 610 if (idx.back ().empty ())
666 retval.set_index (type, idx); 611 error ("invalid empty index list");
667 612
668 } 613 p_args++;
614 p_arg_nm++;
615 p_dyn_field++;
616 }
617
618 retval.set_index (type, idx);
669 619
670 return retval; 620 return retval;
671 } 621 }
672 622
673 /* 623 /*