Changeset 1592b9 in git
- Timestamp:
- Sep 19, 2012, 4:49:01 PM (11 years ago)
- Branches:
- (u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'a800fe4b3e9d37a38c5a10cc0ae9dfa0c15a4ee6')
- Children:
- abe5c8b5ebdd2be025cd137e4a089c3780efb8a3
- Parents:
- 6b81068b7df492eba0593f871f54cb7afc957691
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/countedref.cc
r6b8106 r1592b9 6 6 * @date 2012-08-15 7 7 * 8 * This file defines reference countes interpreter objects and adds the 8 * This file defines reference countes interpreter objects and adds the 9 9 * @c blackbox operations for high-level types 'reference' and 'shared'. 10 10 * 11 11 * @note This works was supported by the "Industrial Algebra" project. 12 * 12 * 13 13 * @par Copyright: 14 14 * (c) 2012 by The Singular Team, see LICENSE file … … 81 81 m_back.invalidate(); 82 82 else 83 m_data.clearid(root()); 83 m_data.clearid(root()); 84 84 } 85 85 } … … 90 90 /// Gerenate weak (but managed) reference to @c *this 91 91 back_ptr weakref() { 92 if (m_back.unassigned()) 92 if (m_back.unassigned()) 93 93 m_back = this; 94 94 return m_back; … … 118 118 /// Check whether identifier became invalid 119 119 BOOLEAN broken() const { 120 if (!m_back.unassigned() && !m_back) 121 return complain("Back-reference broken"); 120 if (!m_back.unassigned() && !m_back) 121 return complain("Back-reference broken"); 122 122 123 123 if (m_ring) { 124 if (m_ring != currRing) 125 return complain("Referenced identifier not from current ring"); 124 if (m_ring != currRing) 125 return complain("Referenced identifier not from current ring"); 126 126 127 127 return m_data.isid() && m_data.brokenid(currRing->idroot) && 128 complain("Referenced identifier not available in ring anymore"); 128 complain("Referenced identifier not available in ring anymore"); 129 129 } 130 130 131 131 if (!m_data.isid()) return FALSE; 132 132 return m_data.brokenid(IDROOT) && … … 136 136 137 137 /// Reassign actual object 138 BOOLEAN assign(leftv result, leftv arg) { 138 BOOLEAN assign(leftv result, leftv arg) { 139 139 140 140 if (!m_data.isid()) { … … 147 147 BOOLEAN retrieve(leftv res) { return m_data.retrieve(res); } 148 148 149 /// Check whether data is all-zero 149 /// Check whether data is all-zero 150 150 BOOLEAN unassigned() const { return m_data.unassigned(); } 151 151 152 152 private: 153 153 /// Raise error message and return @c TRUE 154 BOOLEAN complain(const char* text) const { 155 Werror(text); 154 BOOLEAN complain(const char* text) const 155 { 156 WerrorS(text); 156 157 return TRUE; 157 158 } 158 159 159 160 /// Store ring for ring-dependent objects 160 static ring parent(leftv rhs) { 161 return (rhs->RingDependend()? currRing: NULL); 161 static ring parent(leftv rhs) 162 { 163 return (rhs->RingDependend()? currRing: NULL); 162 164 } 163 165 … … 169 171 ring_ptr m_ring; 170 172 171 /// Reference to actual object for wrap structures 173 /// Reference to actual object for wrap structures 172 174 back_ptr m_back; 173 175 }; … … 214 216 } 215 217 216 /// Reference given Singular data 218 /// Reference given Singular data 217 219 explicit CountedRef(leftv arg): m_data(new data_type(arg)) { } 218 220 … … 254 256 255 257 /// Construct raw reference data 256 data_type* outcast() { 258 data_type* outcast() { 257 259 m_data.reclaim(); 258 260 return m_data; … … 287 289 /// Check for likewise identifiers 288 290 BOOLEAN likewise(leftv res, leftv arg) { 289 return resolve(arg) || construct(res, operator*()->data == arg->data); 291 return resolve(arg) || construct(res, operator*()->data == arg->data); 290 292 } 291 293 292 294 /// Check for identical reference objects 293 BOOLEAN same(leftv res, leftv arg) { 295 BOOLEAN same(leftv res, leftv arg) { 294 296 return construct(res, m_data == arg->Data()); 295 297 } 296 298 297 299 /// Get type of references data 298 BOOLEAN type(leftv res) { 300 BOOLEAN type(leftv res) { 299 301 return construct(res, Tok2Cmdname(operator*()->Typ())); 300 302 }; … … 363 365 /// blackbox support - copy element 364 366 void* countedref_Copy(blackbox*b, void* ptr) 365 { 367 { 366 368 if (ptr) return CountedRef::cast(ptr).outcast(); 367 369 return NULL; … … 374 376 if (result->Data() != NULL) { 375 377 CountedRef ref = CountedRef::cast(result); 376 return CountedRef::resolve(arg) || ref.assign(result, arg); 377 } 378 378 return CountedRef::resolve(arg) || ref.assign(result, arg); 379 } 380 379 381 // Case: copy reference 380 382 if (result->Typ() == arg->Typ()) … … 385 387 return CountedRef(arg).outcast(result); 386 388 387 Werror ("Can only take reference from identifier");389 WerrorS("Can only take reference from identifier"); 388 390 return TRUE; 389 391 } … … 393 395 if (arg->Data() != NULL) return FALSE; 394 396 res->rtyp = NONE; 395 Werror ("Noninitialized access");397 WerrorS("Noninitialized access"); 396 398 return TRUE; 397 399 } 398 400 399 401 /// blackbox support - unary operations 400 402 BOOLEAN countedref_Op1(int op, leftv res, leftv head) … … 404 406 405 407 if (countedref_CheckInit(res, head)) return TRUE; 406 407 if ((op == DEF_CMD) || (op == head->Typ())) { 408 409 if ((op == DEF_CMD) || (op == head->Typ())) 410 { 408 411 res->rtyp = head->Typ(); 409 412 return iiAssign(res, head); … … 420 423 static BOOLEAN countedref_Op2_(int op, leftv res, leftv head, leftv arg) 421 424 { 422 if (CountedRef::is_ref(arg)) { 425 if (CountedRef::is_ref(arg)) 426 { 423 427 CountedRef ref = CountedRef::cast(arg); 424 428 return ref.dereference(arg) || iiExprArith2(res, head, op, arg); … … 430 434 { 431 435 if (countedref_CheckInit(res, head)) return TRUE; 432 if (CountedRef::is_ref(head)) { 436 if (CountedRef::is_ref(head)) 437 { 433 438 CountedRef ref = CountedRef::cast(head); 434 439 return ref.dereference(head) || countedref_Op2_(op, res, head, arg); … … 440 445 { 441 446 442 if (CountedRef::is_ref(arg2)) { 447 if (CountedRef::is_ref(arg2)) 448 { 443 449 CountedRef ref = CountedRef::cast(arg2); 444 450 return ref.dereference(arg2) || iiExprArith3(res, op, head, arg1, arg2); … … 449 455 static BOOLEAN countedref_Op3_(int op, leftv res, leftv head, leftv arg1, leftv arg2) 450 456 { 451 if (CountedRef::is_ref(arg1)) { 457 if (CountedRef::is_ref(arg1)) 458 { 452 459 CountedRef ref = CountedRef::cast(arg1); 453 460 return ref.dereference(arg1) || countedref_Op3__(op, res, head, arg1, arg2); … … 461 468 { 462 469 if (countedref_CheckInit(res, head)) return TRUE; 463 if (CountedRef::is_ref(head)) { 470 if (CountedRef::is_ref(head)) 471 { 464 472 CountedRef ref = CountedRef::cast(head); 465 473 return ref.dereference(head) || countedref_Op3_(op, res, head, arg1, arg2); … … 477 485 478 486 class CountedRefShared: 479 public CountedRef { 487 public CountedRef 488 { 480 489 typedef CountedRefShared self; 481 490 typedef CountedRef base; … … 494 503 explicit CountedRefShared(leftv arg): base(new data_type(arg, data_type::copy_tag())) { } 495 504 496 /// Construct new reference to internal data 505 /// Construct new reference to internal data 497 506 CountedRefShared(const self& rhs): base(rhs) { } 498 507 499 /// Desctruct 508 /// Desctruct 500 509 ~CountedRefShared() { } 501 510 502 /// Change reference to shared data 511 /// Change reference to shared data 503 512 self& operator=(const self& rhs) { 504 513 return static_cast<self&>(base::operator=(rhs)); … … 518 527 519 528 /// Recover more information (e.g. subexpression data) from computed result 520 BOOLEAN retrieve(leftv res, int typ) { 529 BOOLEAN retrieve(leftv res, int typ) 530 { 521 531 return (m_data->retrieve(res) && outcast(res, typ)); 522 532 } 523 533 }; 524 534 525 /// Blackbox support - generate initialized, but all-zero - shared data 535 /// Blackbox support - generate initialized, but all-zero - shared data 526 536 void* countedref_InitShared(blackbox*) 527 537 { … … 537 547 if (countedref_CheckInit(res, head)) return TRUE; 538 548 539 if ((op == DEF_CMD) || (op == head->Typ())) { 549 if ((op == DEF_CMD) || (op == head->Typ())) 550 { 540 551 res->rtyp = head->Typ(); 541 552 return iiAssign(res, head); … … 544 555 CountedRefShared ref = CountedRefShared::cast(head); 545 556 546 if ((op == LINK_CMD) ) { 557 if ((op == LINK_CMD) ) 558 { 547 559 if (ref.dereference(head)) return TRUE; 548 560 res->Copy(head); … … 562 574 if (countedref_CheckInit(res, head)) return TRUE; 563 575 564 if (CountedRefShared::is_ref(head)) { 576 if (CountedRefShared::is_ref(head)) 577 { 565 578 CountedRefShared wrap = CountedRefShared::cast(head).wrapid(); 566 579 int typ = head->Typ(); … … 577 590 if (args->Data() == NULL) return FALSE; 578 591 579 if(op == SYSTEM_CMD) { 580 if (args->next) { 592 if(op == SYSTEM_CMD) 593 { 594 if (args->next) 595 { 581 596 leftv next = args->next; 582 597 args->next = NULL; 583 598 584 char* name = (next->Typ() == STRING_CMD? 599 char* name = (next->Typ() == STRING_CMD? 585 600 (char*) next->Data(): (char*)next->Name()); 586 601 next = next->next; 587 602 588 if (strcmp(name, "help") == 0) { 603 if (strcmp(name, "help") == 0) 604 { 589 605 PrintS("system(<ref>, ...): extended functionality for reference/shared data <ref>\n"); 590 606 PrintS(" system(<ref>, count) - number of references pointing to <ref>\n"); … … 596 612 return CountedRef::construct(res); 597 613 } 598 if (strncmp(name, "undef", 5) == 0) { 599 return CountedRef::construct(res, args->Data()? 614 if (strncmp(name, "undef", 5) == 0) 615 { 616 return CountedRef::construct(res, args->Data()? 600 617 (CountedRef::cast(args).unassigned()? 1: 2): 0); 601 618 } 602 619 603 620 CountedRef obj = CountedRef::cast(args); 604 if (next) { 621 if (next) 622 { 605 623 if (strcmp(name, "same") == 0) return obj.same(res, next); 606 624 // likewise may be hard to interprete, so we not not document it above 607 if (strncmp(name, "like", 4) == 0) return obj.likewise(res, next); 625 if (strncmp(name, "like", 4) == 0) return obj.likewise(res, next); 608 626 } 609 627 if (strncmp(name, "count", 5) == 0) return obj.count(res); … … 614 632 return TRUE; 615 633 } 616 if (op == LIST_CMD){ 634 if (op == LIST_CMD) 635 { 617 636 res->rtyp = op; 618 637 return jjLIST_PL(res, args); … … 628 647 if ((result->Data() != NULL) && !CountedRefShared::cast(result).unassigned()) { 629 648 CountedRef ref = CountedRef::cast(result); 630 return CountedRef::resolve(arg) || ref.assign(result, arg); 631 } 632 649 return CountedRef::resolve(arg) || ref.assign(result, arg); 650 } 651 633 652 /// Case: new reference to already shared data 634 if (result->Typ() == arg->Typ()) { 635 if (result->Data() != NULL) 653 if (result->Typ() == arg->Typ()) 654 { 655 if (result->Data() != NULL) 636 656 CountedRefShared::cast(result).destruct(); 637 657 return CountedRefShared::cast(arg).outcast(result); 638 } 639 if(CountedRefShared::cast(result).unassigned()) { 640 return CountedRefShared::cast(result).assign(result, arg); 641 642 return FALSE; 643 } 644 658 } 659 if(CountedRefShared::cast(result).unassigned()) 660 { 661 return CountedRefShared::cast(result).assign(result, arg); 662 } 663 645 664 /// Case: new shared data 646 665 return CountedRefShared(arg).outcast(result);
Note: See TracChangeset
for help on using the changeset viewer.