/* ============================================================================= * delete_node * ============================================================================= */ static node_t* delete_node (rbtree_t* s, node_t* p) { /* * If strictly internal, copy successor's element to p and then make p * point to successor */ if (LDNODE(p, l) != NULL && LDNODE(p, r) != NULL) { node_t* s = SUCCESSOR(p); STF(p, k, LDNODE(s, k)); STF(p, v, LDNODE(s, v)); p = s; } /* p has 2 children */ /* Start fixup at replacement node, if it exists */ node_t* replacement = ((LDNODE(p, l) != NULL) ? LDNODE(p, l) : LDNODE(p, r)); if (replacement != NULL) { /* Link replacement to parent */ /* TODO: precompute pp = p->p and substitute below ... */ STF (replacement, p, LDNODE(p, p)); node_t* pp = LDNODE(p, p); if (pp == NULL) { STF(s, root, replacement); } else if (p == LDNODE(pp, l)) { STF(pp, l, replacement); } else { STF(pp, r, replacement); } /* Null out links so they are OK to use by fixAfterDeletion */ STF(p, l, NULL); STF(p, r, NULL); STF(p, p, NULL); /* Fix replacement */ if (LDF(p,c) == BLACK) { FIX_AFTER_DELETION(s, replacement); } } else if (LDNODE(p, p) == NULL) { /* return if we are the only node */ STF(s, root, NULL); } else { /* No children. Use self as phantom replacement and unlink */ if (LDF(p, c) == BLACK) { FIX_AFTER_DELETION(s, p); } node_t* pp = LDNODE(p, p); if (pp != NULL) { if (p == LDNODE(pp, l)) { STF(pp,l, NULL); } else if (p == LDNODE(pp, r)) { STF(pp, r, NULL); } STF(p, p, NULL); } } return p; }
/* ============================================================================= * fixAfterInsertion * ============================================================================= */ static void fixAfterInsertion (rbtree_t* s, node_t* x) { STF(x, c, RED); while (x != NULL && x != LDNODE(s, root)) { node_t* xp = LDNODE(x, p); if (LDF(xp, c) != RED) { break; } /* TODO: cache g = ppx = PARENT_OF(PARENT_OF(x)) */ if (PARENT_OF(x) == LEFT_OF(PARENT_OF(PARENT_OF(x)))) { node_t* y = RIGHT_OF(PARENT_OF(PARENT_OF(x))); if (COLOR_OF(y) == RED) { SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(y, BLACK); SET_COLOR(PARENT_OF(PARENT_OF(x)), RED); x = PARENT_OF(PARENT_OF(x)); } else { if (x == RIGHT_OF(PARENT_OF(x))) { x = PARENT_OF(x); ROTATE_LEFT(s, x); } SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(PARENT_OF(PARENT_OF(x)), RED); if (PARENT_OF(PARENT_OF(x)) != NULL) { ROTATE_RIGHT(s, PARENT_OF(PARENT_OF(x))); } } } else { node_t* y = LEFT_OF(PARENT_OF(PARENT_OF(x))); if (COLOR_OF(y) == RED) { SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(y, BLACK); SET_COLOR(PARENT_OF(PARENT_OF(x)), RED); x = PARENT_OF(PARENT_OF(x)); } else { if (x == LEFT_OF(PARENT_OF(x))) { x = PARENT_OF(x); ROTATE_RIGHT(s, x); } SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(PARENT_OF(PARENT_OF(x)), RED); if (PARENT_OF(PARENT_OF(x)) != NULL) { ROTATE_LEFT(s, PARENT_OF(PARENT_OF(x))); } } } } node_t* ro = LDNODE(s, root); if (LDF(ro, c) != BLACK) { STF(ro, c, BLACK); } }
/* ============================================================================= * rbtree_get * ============================================================================= */ void* rbtree_get (rbtree_t* r, void* key) { node_t* n = LOOKUP(r, key); if (n != NULL) { void* val = LDF(n, v); return val; } return NULL; }
/* ============================================================================= * insert * ============================================================================= */ static node_t* insert (rbtree_t* s, void* k, void* v, node_t* n) { node_t* t = LDNODE(s, root); if (t == NULL) { if (n == NULL) { return NULL; } /* Note: the following STs don't really need to be transactional */ STF(n, l, NULL); STF(n, r, NULL); STF(n, p, NULL); STF(n, k, k); STF(n, v, v); STF(n, c, BLACK); STF(s, root, n); return NULL; } long int (*compare)(const void*, const void*) = s->compare->compare_notm; for (;;) { long cmp = compare(k, LDF(t, k)); if (cmp == 0) { return t; } else if (cmp < 0) { node_t* tl = LDNODE(t, l); if (tl != NULL) { t = tl; } else { STF(n, l, NULL); STF(n, r, NULL); STF(n, k, k); STF(n, v, v); STF(n, p, t); STF(t, l, n); FIX_AFTER_INSERTION(s, n); return NULL; } } else { /* cmp > 0 */ node_t* tr = LDNODE(t, r); if (tr != NULL) { t = tr; } else { STF(n, l, NULL); STF(n, r, NULL); STF(n, k, k); STF(n, v, v); STF(n, p, t); STF(t, r, n); FIX_AFTER_INSERTION(s, n); return NULL; } } } }
/* ============================================================================= * lookup * ============================================================================= */ static node_t* lookup (rbtree_t* s, void* k) { node_t* p = LDNODE(s, root); long int (*compare)(const void*, const void*) = s->compare->compare_notm; while (p != NULL) { long cmp = compare(k, LDF(p, k)); if (cmp == 0) { return p; } p = ((cmp < 0) ? LDNODE(p, l) : LDNODE(p, r)); } return NULL; }
/* ============================================================================= * fixAfterDeletion * ============================================================================= */ static void fixAfterDeletion (rbtree_t* s, node_t* x) { while (x != LDNODE(s,root) && COLOR_OF(x) == BLACK) { if (x == LEFT_OF(PARENT_OF(x))) { node_t* sib = RIGHT_OF(PARENT_OF(x)); if (COLOR_OF(sib) == RED) { SET_COLOR(sib, BLACK); SET_COLOR(PARENT_OF(x), RED); ROTATE_LEFT(s, PARENT_OF(x)); sib = RIGHT_OF(PARENT_OF(x)); } if (COLOR_OF(LEFT_OF(sib)) == BLACK && COLOR_OF(RIGHT_OF(sib)) == BLACK) { SET_COLOR(sib, RED); x = PARENT_OF(x); } else { if (COLOR_OF(RIGHT_OF(sib)) == BLACK) { SET_COLOR(LEFT_OF(sib), BLACK); SET_COLOR(sib, RED); ROTATE_RIGHT(s, sib); sib = RIGHT_OF(PARENT_OF(x)); } SET_COLOR(sib, COLOR_OF(PARENT_OF(x))); SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(RIGHT_OF(sib), BLACK); ROTATE_LEFT(s, PARENT_OF(x)); /* TODO: consider break ... */ x = LDNODE(s,root); } } else { /* symmetric */ node_t* sib = LEFT_OF(PARENT_OF(x)); if (COLOR_OF(sib) == RED) { SET_COLOR(sib, BLACK); SET_COLOR(PARENT_OF(x), RED); ROTATE_RIGHT(s, PARENT_OF(x)); sib = LEFT_OF(PARENT_OF(x)); } if (COLOR_OF(RIGHT_OF(sib)) == BLACK && COLOR_OF(LEFT_OF(sib)) == BLACK) { SET_COLOR(sib, RED); x = PARENT_OF(x); } else { if (COLOR_OF(LEFT_OF(sib)) == BLACK) { SET_COLOR(RIGHT_OF(sib), BLACK); SET_COLOR(sib, RED); ROTATE_LEFT(s, sib); sib = LEFT_OF(PARENT_OF(x)); } SET_COLOR(sib, COLOR_OF(PARENT_OF(x))); SET_COLOR(PARENT_OF(x), BLACK); SET_COLOR(LEFT_OF(sib), BLACK); ROTATE_RIGHT(s, PARENT_OF(x)); /* TODO: consider break ... */ x = LDNODE(s, root); } } } if (x != NULL && LDF(x,c) != BLACK) { STF(x, c, BLACK); } }
Elem & Machine::execute(std::ostream &out) { Instruction *command; std::shared_ptr<Elem> command_ptr; Elem *ADD(new Instruction("ADD")); Elem *MUL(new Instruction("MUL")); Elem *SUB(new Instruction("SUB")); Elem *DIV(new Instruction("DIV")); Elem *REM(new Instruction("REM")); Elem *EQ(new Instruction("EQ")); Elem *LEQ(new Instruction("LEQ")); Elem *SEL(new Instruction("SEL")); Elem *LD(new Instruction("LD")); Elem *LDC(new Instruction("LDC")); Elem *LDF(new Instruction("LDF")); Elem *CAR(new Instruction("CAR")); Elem *CDR(new Instruction("CDR")); Elem *CONS(new Instruction("CONS")); Elem *NIL(new Instruction("NIL")); Elem *DUM(new Instruction("DUM")); Elem *AP(new Instruction("AP")); Elem *RAP(new Instruction("RAP")); Elem *RTN(new Instruction("RTN")); Elem *JOIN(new Instruction("JOIN")); Elem *STOP(new Instruction("STOP")); while (!C->empty()) { if (out != 0x0) { print_S(out); print_E(out); print_C(out); out << std::endl; } command_ptr = C->pop_ret(); command = dynamic_cast<Instruction*>(&*command_ptr); if (command == nullptr) throw Exception("Execute", "FatalError"); if (*command == *ADD) this->ADD(); else if (*command == *MUL) this->MUL(); else if (*command == *SUB) this->SUB(); else if (*command == *DIV) this->DIV(); else if (*command == *REM) this->REM(); else if (*command == *EQ) this->EQ(); else if (*command == *LEQ) this->LEQ(); else if (*command == *SEL) this->SEL(); else if (*command == *LD) this->LD(); else if (*command == *LDC) this->LDC(); else if (*command == *LDF) this->LDF(); else if (*command == *CAR) this->CAR(); else if (*command == *CDR) this->CDR(); else if (*command == *CONS) this->CONS(); else if (*command == *NIL) this->NIL(); else if (*command == *DUM) this->DUM(); else if (*command == *AP) this->AP(); else if (*command == *RAP) this->RAP(); else if (*command == *RTN) this->RTN(); else if (*command == *JOIN) this->JOIN(); else if (*command == *STOP) { return (*(this->STOP()));} else throw Exception("Execute", "Expected 'instruction' but greeted constant."); } throw Exception("Execute", "FatalError"); }
int main(int argc, char *argv[]) { E_RT_init(argc, argv); JMP(begin); Label0: R005=ADD(R000,2); STI(R001, R000); R000=SUB(R000,1); MOVI(R000, R001); LDI(R005, R008); R005=ADD(R005,1); LDF(R005, F001); R005=ADD(R005,1); MOVIF(R008, F003); MOVIF(R008, F006); F005=FADD(F006,F001); MOVF(F005, F008); R010=ADD(R008,1); MOVI(R010, R011); MOVI(R010, R012); MOVIF(R008, F010); MOVF(F005, F011); while_1_start: JMPC(GT(1000, R008), while_1_begin); JMP(while_1_end); while_1_begin: MOVIF(R008, F013); MOVIF(R008, F014); F008=FADD(F014,F001); F001=FMUL(F001,2.0); R008=ADD(R008,100); JMP(while_1_start); while_1_end: PRTF(F008); PRTS(R007); MOVI(R008, R002); JMP(Label1); Label1: MOVI(R001, R000); R000=ADD(R000,1); LDI(R000, R001); R000=ADD(R000,1); LDI(R000, R004); R000=ADD(R000,2); JMPI(R004); eventLabel_a: INI(R010); INF(F013); STI(R010, R000); R000=SUB(R000,1); STF(F013, R000); R000=SUB(R000,1); STF(F013, R000); R000=SUB(R000,1); STI(R010, R000); R000=SUB(R000,1); MOVL(Label2, R004); STI(R004, R000); R000=SUB(R000,1); JMP(Label0); Label2: MOVI(R002, R006); R000=ADD(R000,1); LDF(R000, F013); R000=ADD(R000,1); LDI(R000, R010); JMP(EventMStart); begin: MOVI(10000, R000); MOVI(0, R006); MOVS("\n", R007); IN(R010); IN(R010); IN(R010); EventMStart: IN(R010); JMPC(GT(64, R010), EventMOut); JMPC(EQ(97, R010), eventLabel_a); JMP(EventMStart); EventMOut: PRTS("\nDone\n"); E_RT_exit(); return 0; }