/** @brief Encode a ball position and heading into a char array for transmission */ static void serialise_ball(char *buf, const GameState *state) { Vector pos = state->ballPos; Vector heading = state->ballHeading; /* Translate to opponent co-ords */ flip_coords(&pos); heading.x *= -1; heading.y *= -1; /* Encode */ ASSERT(0 <= pos.x && pos.x <= 9); ASSERT(pos.y == 5); buf[0] = '0' + pos.x; if (vector_equal(heading, headings[0])) { buf[1] = '0'; } else if (vector_equal(heading, headings[1])) { buf[1] = '1'; } else if (vector_equal(heading, headings[2])) { buf[1] = '2'; } else { TRACE("Invalid ball heading.\n"); buf[0] = buf[1] = 'x'; return; } }
int hormodular::Orientation::getRelativeOrientation(int connector, hormodular::Orientation localOrient, hormodular::Orientation remoteOrient) { //-- Create rotation matrices for local orientation: Eigen::AngleAxisd rollAngle( deg2rad(localOrient.getRoll()), Eigen::Vector3d::UnitZ()); Eigen::AngleAxisd pitchAngle( deg2rad(localOrient.getPitch()), Eigen::Vector3d::UnitY()); Eigen::AngleAxisd yawAngle( deg2rad(localOrient.getYaw()), Eigen::Vector3d::UnitX()); Eigen::Quaterniond q0 = yawAngle * pitchAngle * rollAngle ; Eigen::Matrix3d rotationMatrix = q0.matrix(); //-- Create rotation matrices for the other orientation: Eigen::AngleAxisd otherRollAngle( deg2rad(remoteOrient.getRoll()), Eigen::Vector3d::UnitZ()); Eigen::AngleAxisd otherPitchAngle( deg2rad(remoteOrient.getPitch()), Eigen::Vector3d::UnitY()); Eigen::AngleAxisd otherYawAngle( deg2rad(remoteOrient.getYaw()), Eigen::Vector3d::UnitX()); Eigen::Quaterniond q1 = otherYawAngle * otherPitchAngle * otherRollAngle; Eigen::Matrix3d otherRotationMatrix = q1.matrix(); Eigen::Matrix3d relativeRotation = rotationMatrix.inverse() * otherRotationMatrix; Eigen::Vector3d new_z = relativeRotation * Eigen::Vector3d::UnitZ(); // std::cout << "New_z: " << std::endl << new_z << std::endl << std::endl; //-- Get connector base vector for the rotations: Eigen::Vector3d base_vector; if ( connector == 0 || connector == 2) { //-- Y axis base_vector = Eigen::Vector3d::UnitY(); } else if ( connector == 1 || connector == 3) { //-- X axis base_vector = Eigen::Vector3d::UnitX(); } //-- Try for rotations to fit the vector for ( int i = 0; i < 4; i++) { Eigen::AngleAxisd rotAngle( deg2rad(i*90), base_vector); Eigen::Matrix3d rotMatrix = rotAngle.matrix(); Eigen::Vector3d result_vector = rotMatrix * Eigen::Vector3d::UnitZ(); // std::cout << "i = " << i << std::endl << result_vector << std::endl << std::endl; if ( vector_equal(result_vector, new_z) ) return i; } return -1; }
/** * Tests if the two stacks are equal. */ bool_t stack_equal(const cstl_stack_t* cpsk_first, const cstl_stack_t* cpsk_second) { assert(cpsk_first != NULL); assert(cpsk_second != NULL); #if defined (CSTL_STACK_VECTOR_SEQUENCE) return vector_equal(&cpsk_first->_t_sequence, &cpsk_second->_t_sequence); #elif defined (CSTL_STACK_LIST_SEQUENCE) return list_equal(&cpsk_first->_t_sequence, &cpsk_second->_t_sequence); #else return deque_equal(&cpsk_first->_t_sequence, &cpsk_second->_t_sequence); #endif }
/** * Assign vector element with an exist vector container. */ void vector_assign(vector_t* pvec_dest, const vector_t* cpvec_src) { assert(pvec_dest != NULL); assert(cpvec_src != NULL); assert(_vector_is_inited(pvec_dest)); assert(_vector_is_inited(cpvec_src)); assert(_vector_same_type(pvec_dest, cpvec_src)); if(vector_equal(pvec_dest, cpvec_src)) { return; } vector_assign_range(pvec_dest, vector_begin(cpvec_src), vector_end(cpvec_src)); }
/** * Swap vector datas. */ void vector_swap(vector_t* pvec_first, vector_t* pvec_second) { vector_t vec_swap; /* the swap temporary vector */ /* test the two vector has the same type */ assert(pvec_first != NULL); assert(pvec_second != NULL); assert(_vector_is_inited(pvec_first)); assert(_vector_is_inited(pvec_second)); assert(_vector_same_type(pvec_first, pvec_second)); if(vector_equal(pvec_first, pvec_second)) { return; } vec_swap = *pvec_first; *pvec_first = *pvec_second; *pvec_second = vec_swap; }
void advanceBall(GameState *state) { const Vector old_pos = state->ballPos; /* Save some typing */ Vector new_pos = vector_add(old_pos, state->ballHeading); /* Ball is going off the bottom of the display: change mode. */ if (new_pos.y <= -1) { state->mode = LOST_ROUND; } /* Ball is going off the top of the display: change mode. */ else if(new_pos.y > 4) { state->mode = WAITING; } /* Ball is staying on the display. */ else { /* Ball is bouncing off the side of the display: change heading. */ if(new_pos.x < 0 || new_pos.x > 6) { state->ballHeading.x *= -1; } /* Ball is going to either bounce off the paddle or enter the bottom * row: possibly change heading. */ if (new_pos.y == 0 && state->ballHeading.y == -1) { /* Ball is bouncing off center of paddle (same for every heading). */ if (old_pos.x == state->paddlePos + 1) { state->ballHeading.y *= -1; } /* Ball is going straight down. */ else if (vector_equal(state->ballHeading, DOWN)) { /* Ball is bouncing off left of paddle. */ if (old_pos.x == state->paddlePos){ /* Paddle is in left corner => bounce off to the right. */ if (old_pos.x == 0){ state->ballHeading = UP_RIGHT; } /* Bounce off to the left. */ else { state->ballHeading = UP_LEFT; } } /* Ball is bouncing off right of paddle. */ else if (old_pos.x == state->paddlePos + 2) { /* Paddle is in right corner => bounce off to the left. */ if (old_pos.x == 6){ state->ballHeading = UP_LEFT; } /* Bounce off to the right. */ else { state->ballHeading = UP_RIGHT; } } } /* Ball is going down and right. */ else if (vector_equal(state->ballHeading, DOWN_RIGHT)) { /* Ball is bouncing off left corner of paddle. */ if (old_pos.x == state->paddlePos - 1) { if (old_pos.x == 0) { state->ballHeading = UP_RIGHT; } else { state->ballHeading = UP_LEFT; } } /* Ball is bouncing off left of paddle. */ else if (old_pos.x == state->paddlePos){ state->ballHeading = UP; } /* Ball is bouncing off right of paddle. */ else if (old_pos.x == state->paddlePos + 2) { /* Paddle is in right corner => bounce off to the left. */ if (old_pos.x == 6){ state->ballHeading = UP_LEFT; } /* Bounce off to the right. */ else { state->ballHeading = UP_RIGHT; } } } /* Ball is going down and left. */ else if (vector_equal(state->ballHeading, DOWN_LEFT)) { /* Ball is bouncing off left of paddle. */ if (old_pos.x == state->paddlePos) { /* Paddle is in left corner => bounce off to the right. */ if (state->paddlePos == 0) { state->ballHeading = UP_RIGHT; } /* Bounce off to the left. */ else { state->ballHeading = UP_LEFT; } } /* Ball is bouncing off right of paddle. */ else if (old_pos.x == state->paddlePos + 2) { state->ballHeading = UP; } /* Ball is bouncing off right corner of paddle. */ else if (old_pos.x == state->paddlePos + 3) { /* Paddle is in right corner => bounce off to the left. */ if (old_pos.x == 6) { state->ballHeading = UP_LEFT; } /* Bounce off to the right. */ else { state->ballHeading = UP_RIGHT; } } } } /* Move the ball from the old position according to the (potentially * changed) heading. */ new_pos = vector_add(old_pos, state->ballHeading); state->ballPos = new_pos; } }
int is_equal (Scheme_Object *obj1, Scheme_Object *obj2, Equal_Info *eql) { Scheme_Type t1, t2; int cmp; top: if (eql->next_next) { if (eql->next) { Scheme_Object *a[2]; a[0] = obj1; a[1] = obj2; obj1 = _scheme_apply(eql->next, 2, a); return SCHEME_TRUEP(obj1); } eql->next = eql->next_next; } cmp = is_eqv(obj1, obj2); if (cmp > -1) return cmp; if (eql->for_chaperone && SCHEME_CHAPERONEP(obj1) && (!(SCHEME_CHAPERONE_FLAGS((Scheme_Chaperone *)obj1) & SCHEME_CHAPERONE_IS_IMPERSONATOR) || (eql->for_chaperone > 1))) { obj1 = ((Scheme_Chaperone *)obj1)->prev; goto top; } t1 = SCHEME_TYPE(obj1); t2 = SCHEME_TYPE(obj2); if (NOT_SAME_TYPE(t1, t2)) { if (!eql->for_chaperone) { if (SCHEME_CHAPERONEP(obj1)) { obj1 = ((Scheme_Chaperone *)obj1)->val; goto top; } if (SCHEME_CHAPERONEP(obj2)) { obj2 = ((Scheme_Chaperone *)obj2)->val; goto top; } } return 0; } else if (t1 == scheme_pair_type) { # include "mzeqchk.inc" if ((eql->car_depth > 2) || !scheme_is_list(obj1)) { if (union_check(obj1, obj2, eql)) return 1; } eql->car_depth += 2; if (is_equal(SCHEME_CAR(obj1), SCHEME_CAR(obj2), eql)) { eql->car_depth -= 2; obj1 = SCHEME_CDR(obj1); obj2 = SCHEME_CDR(obj2); goto top; } else return 0; } else if (t1 == scheme_mutable_pair_type) { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; if (is_equal(SCHEME_CAR(obj1), SCHEME_CAR(obj2), eql)) { obj1 = SCHEME_CDR(obj1); obj2 = SCHEME_CDR(obj2); goto top; } else return 0; } else if ((t1 == scheme_vector_type) || (t1 == scheme_fxvector_type)) { # include "mzeqchk.inc" if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; if (union_check(obj1, obj2, eql)) return 1; return vector_equal(obj1, obj2, eql); } else if (t1 == scheme_flvector_type) { intptr_t l1, l2, i; l1 = SCHEME_FLVEC_SIZE(obj1); l2 = SCHEME_FLVEC_SIZE(obj2); if (l1 == l2) { for (i = 0; i < l1; i++) { if (!double_eqv(SCHEME_FLVEC_ELS(obj1)[i], SCHEME_FLVEC_ELS(obj2)[i])) return 0; } return 1; } return 0; } else if ((t1 == scheme_byte_string_type) || ((t1 >= scheme_unix_path_type) && (t1 <= scheme_windows_path_type))) { intptr_t l1, l2; if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; l1 = SCHEME_BYTE_STRTAG_VAL(obj1); l2 = SCHEME_BYTE_STRTAG_VAL(obj2); return ((l1 == l2) && !memcmp(SCHEME_BYTE_STR_VAL(obj1), SCHEME_BYTE_STR_VAL(obj2), l1)); } else if (t1 == scheme_char_string_type) { intptr_t l1, l2; if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; l1 = SCHEME_CHAR_STRTAG_VAL(obj1); l2 = SCHEME_CHAR_STRTAG_VAL(obj2); return ((l1 == l2) && !memcmp(SCHEME_CHAR_STR_VAL(obj1), SCHEME_CHAR_STR_VAL(obj2), l1 * sizeof(mzchar))); } else if (t1 == scheme_regexp_type) { if (scheme_regexp_is_byte(obj1) != scheme_regexp_is_byte(obj2)) return 0; if (scheme_regexp_is_pregexp(obj1) != scheme_regexp_is_pregexp(obj2)) return 0; obj1 = scheme_regexp_source(obj1); obj2 = scheme_regexp_source(obj2); goto top; } else if ((t1 == scheme_structure_type) || (t1 == scheme_proc_struct_type)) { Scheme_Struct_Type *st1, *st2; Scheme_Object *procs1, *procs2; st1 = SCHEME_STRUCT_TYPE(obj1); st2 = SCHEME_STRUCT_TYPE(obj2); if (eql->for_chaperone == 1) procs1 = NULL; else procs1 = scheme_struct_type_property_ref(scheme_impersonator_of_property, (Scheme_Object *)st1); if (procs1) procs1 = apply_impersonator_of(eql->for_chaperone, procs1, obj1); if (eql->for_chaperone) procs2 = NULL; else { procs2 = scheme_struct_type_property_ref(scheme_impersonator_of_property, (Scheme_Object *)st2); if (procs2) procs2 = apply_impersonator_of(eql->for_chaperone, procs2, obj2); } if (procs1 || procs2) { /* impersonator-of property trumps other forms of checking */ if (procs1) obj1 = procs1; if (procs2) obj2 = procs2; goto top; } else { procs1 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st1); if (procs1 && (st1 != st2)) { procs2 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st2); if (!procs2 || !SAME_OBJ(SCHEME_VEC_ELS(procs1)[0], SCHEME_VEC_ELS(procs2)[0])) procs1 = NULL; } if (procs1) { /* Has an equality property: */ Scheme_Object *a[3], *recur; Equal_Info *eql2; # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; /* Create/cache closure to use for recursive equality checks: */ if (eql->recur) { recur = eql->recur; eql2 = (Equal_Info *)SCHEME_PRIM_CLOSURE_ELS(recur)[0]; } else { eql2 = (Equal_Info *)scheme_malloc(sizeof(Equal_Info)); a[0] = (Scheme_Object *)eql2; recur = scheme_make_prim_closure_w_arity(equal_recur, 1, a, "equal?/recur", 2, 2); eql->recur = recur; } memcpy(eql2, eql, sizeof(Equal_Info)); a[0] = obj1; a[1] = obj2; a[2] = recur; procs1 = SCHEME_VEC_ELS(procs1)[1]; recur = _scheme_apply(procs1, 3, a); memcpy(eql, eql2, sizeof(Equal_Info)); return SCHEME_TRUEP(recur); } else if (st1 != st2) { return 0; } else if ((eql->for_chaperone == 1) && !(MZ_OPT_HASH_KEY(&st1->iso) & STRUCT_TYPE_ALL_IMMUTABLE)) { return 0; } else { /* Same types, but doesn't have an equality property (or checking for chaperone), so check transparency: */ Scheme_Object *insp; insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); if (scheme_inspector_sees_part(obj1, insp, -2) && scheme_inspector_sees_part(obj2, insp, -2)) { # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; return struct_equal(obj1, obj2, eql); } else return 0; } } } else if (t1 == scheme_box_type) { SCHEME_USE_FUEL(1); if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; if (union_check(obj1, obj2, eql)) return 1; obj1 = SCHEME_BOX_VAL(obj1); obj2 = SCHEME_BOX_VAL(obj2); goto top; } else if (t1 == scheme_hash_table_type) { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; return scheme_hash_table_equal_rec((Scheme_Hash_Table *)obj1, (Scheme_Hash_Table *)obj2, eql); } else if (t1 == scheme_hash_tree_type) { # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; return scheme_hash_tree_equal_rec((Scheme_Hash_Tree *)obj1, (Scheme_Hash_Tree *)obj2, eql); } else if (t1 == scheme_bucket_table_type) { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; return scheme_bucket_table_equal_rec((Scheme_Bucket_Table *)obj1, (Scheme_Bucket_Table *)obj2, eql); } else if (t1 == scheme_cpointer_type) { return (((char *)SCHEME_CPTR_VAL(obj1) + SCHEME_CPTR_OFFSET(obj1)) == ((char *)SCHEME_CPTR_VAL(obj2) + SCHEME_CPTR_OFFSET(obj2))); } else if (t1 == scheme_wrap_chunk_type) { return vector_equal(obj1, obj2, eql); } else if (t1 == scheme_resolved_module_path_type) { obj1 = SCHEME_PTR_VAL(obj1); obj2 = SCHEME_PTR_VAL(obj2); goto top; } else if (t1 == scheme_place_bi_channel_type) { Scheme_Place_Bi_Channel *bc1, *bc2; bc1 = (Scheme_Place_Bi_Channel *)obj1; bc2 = (Scheme_Place_Bi_Channel *)obj2; return (SAME_OBJ(bc1->recvch, bc2->recvch) && SAME_OBJ(bc1->sendch, bc2->sendch)); } else if (!eql->for_chaperone && ((t1 == scheme_chaperone_type) || (t1 == scheme_proc_chaperone_type))) { /* both chaperones */ obj1 = ((Scheme_Chaperone *)obj1)->val; obj2 = ((Scheme_Chaperone *)obj2)->val; goto top; } else { Scheme_Equal_Proc eqlp = scheme_type_equals[t1]; if (eqlp) { if (union_check(obj1, obj2, eql)) return 1; return eqlp(obj1, obj2, eql); } else return 0; } }
/** * Test the first vector is greater than or equal to the second vector. */ bool_t vector_greater_equal(const vector_t* cpvec_first, const vector_t* cpvec_second) { return (vector_greater(cpvec_first, cpvec_second) || vector_equal(cpvec_first, cpvec_second)) ? true : false; }
/** * Test the two vectors are unequal. */ bool_t vector_not_equal(const vector_t* cpvec_first, const vector_t* cpvec_second) { return !vector_equal(cpvec_first, cpvec_second); }
/* * Computes clusters' centroids. */ static void compute_centroids(void) { int i, j; /* Loop indexes. */ int population; /* Centroid population. */ start = timer_get(); memcpy(lcentroids, CENTROID(rank*(ncentroids/nprocs)), lncentroids[rank]*dimension*sizeof(float)); memset(&has_changed[rank*NUM_THREADS], 0, NUM_THREADS*sizeof(int)); memset(centroids, 0, (ncentroids + DELTA*nprocs)*dimension*sizeof(float)); memset(ppopulation, 0, (ncentroids + nprocs*DELTA)*sizeof(int)); /* Compute partial centroids. */ #pragma omp parallel for schedule(static) default(shared) private(i, j) for (i = 0; i < lnpoints; i++) { j = map[i]%NUM_THREADS; omp_set_lock(&lock[j]); vector_add(CENTROID(map[i]), POINT(i)); ppopulation[map[i]]++; omp_unset_lock(&lock[j]); } end = timer_get(); total += timer_diff(start, end); sync_pcentroids(); sync_ppopulation(); start = timer_get(); /* Compute centroids. */ #pragma omp parallel for schedule(static) default(shared) private(i, j, population) for (j = 0; j < lncentroids[rank]; j++) { population = 0; for (i = 0; i < nprocs; i++) { if (*POPULATION(i, j) == 0) continue; population += *POPULATION(i, j); if (i == rank) continue; vector_add(PCENTROID(rank, j), PCENTROID(i, j)); } if (population > 1) vector_mult(PCENTROID(rank, j), 1.0/population); /* Cluster mean has changed. */ if (!vector_equal(PCENTROID(rank, j), LCENTROID(j))) { has_changed[rank*NUM_THREADS + omp_get_thread_num()] = 1; vector_assign(LCENTROID(j), PCENTROID(rank, j)); } } end = timer_get(); total += timer_diff(start, end); sync_centroids(); sync_status(); }
int t_vector() { c_vector vt; __c_vector(&vt, int_comparer); printf("1.test create vector\n"); create_with_push_back(&vt); print_vector(&vt); reverse_print_vector(&vt); clear_vector(&vt); printf("\n\n2.test vector assign\n"); create_with_push_back(&vt); vector_assign(&vt); clear_vector(&vt); printf("\n\n3.test erase vector\n"); erase_vector(); printf("\n\n4.test reserve vector\n"); create_with_push_back(&vt); vector_reserve(&vt); clear_vector(&vt); printf("\n\n5.test front back\n"); create_with_push_back(&vt); vector_front_back(&vt); clear_vector(&vt); printf("\n\n6.test swap\n"); create_with_push_back(&vt); vector_swap(&vt); clear_vector(&vt); printf("\n\n7.test insert\n"); vector_insert(&vt); clear_vector(&vt); printf("\n\n8.test insert2\n"); create_with_push_back(&vt); vector_insert2(&vt); clear_vector(&vt); printf("\n\n9.test fill insert\n"); create_with_push_back(&vt); vector_fill_insert(&vt); clear_vector(&vt); printf("\n\n10.test resize\n"); create_with_push_back(&vt); vector_resize(&vt); clear_vector(&vt); printf("\n\n11.test equal\n"); create_with_push_back(&vt); vector_equal(&vt); clear_vector(&vt); printf("\n\n12.test less\n"); create_with_push_back(&vt); vector_less(&vt); clear_vector(&vt); __c_rotcev(&vt); printf("\n\nfinish testing vector!\n"); return 0; }
int is_equal (Scheme_Object *obj1, Scheme_Object *obj2, Equal_Info *eql) { Scheme_Type t1, t2; int cmp; Scheme_Object *orig_obj1, *orig_obj2; top: orig_obj1 = obj1; orig_obj2 = obj2; if (eql->next_next) { if (eql->next) { Scheme_Object *a[2]; a[0] = obj1; a[1] = obj2; obj1 = _scheme_apply(eql->next, 2, a); return SCHEME_TRUEP(obj1); } eql->next = eql->next_next; } top_after_next: cmp = is_fast_equal(obj1, obj2, eql->for_chaperone == 1); if (cmp > -1) return cmp; if (eql->for_chaperone && SCHEME_CHAPERONEP(obj2) && scheme_is_noninterposing_chaperone(obj2)) { obj2 = ((Scheme_Chaperone *)obj2)->prev; goto top_after_next; } if (eql->for_chaperone && SCHEME_CHAPERONEP(obj1) && (!(SCHEME_CHAPERONE_FLAGS((Scheme_Chaperone *)obj1) & SCHEME_CHAPERONE_IS_IMPERSONATOR) || (eql->for_chaperone > 1))) { /* `obj1` and `obj2` are not eq, otherwise is_fast_equal() would have returned true */ if (SCHEME_CHAPERONEP(obj2)) { /* for immutable hashes, it's ok for the two objects to not be eq, as long as the interpositions are the same and the underlying values are `{impersonator,chaperone}-of?`: */ if (SCHEME_HASHTRP(((Scheme_Chaperone *)obj1)->val) && SCHEME_HASHTRP(((Scheme_Chaperone *)obj2)->val) /* eq redirects means redirects were propagated: */ && SAME_OBJ(((Scheme_Chaperone *)obj1)->redirects, ((Scheme_Chaperone *)obj2)->redirects)) obj2 = ((Scheme_Chaperone *)obj2)->prev; } obj1 = ((Scheme_Chaperone *)obj1)->prev; goto top_after_next; } t1 = SCHEME_TYPE(obj1); t2 = SCHEME_TYPE(obj2); if (NOT_SAME_TYPE(t1, t2)) { if (!eql->for_chaperone) { if (SCHEME_CHAPERONEP(obj1)) { obj1 = ((Scheme_Chaperone *)obj1)->val; goto top_after_next; } else if (t1 == scheme_hash_tree_indirection_type) { obj1 = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)obj1); goto top_after_next; } if (SCHEME_CHAPERONEP(obj2)) { obj2 = ((Scheme_Chaperone *)obj2)->val; goto top_after_next; } else if (t2 == scheme_hash_tree_indirection_type) { obj2 = (Scheme_Object *)scheme_hash_tree_resolve_placeholder((Scheme_Hash_Tree *)obj2); goto top_after_next; } } return 0; } else { switch (t1) { case scheme_pair_type: { # include "mzeqchk.inc" if ((eql->car_depth > 2) || !scheme_is_list(obj1)) { if (union_check(obj1, obj2, eql)) return 1; } eql->car_depth += 2; if (is_equal(SCHEME_CAR(obj1), SCHEME_CAR(obj2), eql)) { eql->car_depth -= 2; obj1 = SCHEME_CDR(obj1); obj2 = SCHEME_CDR(obj2); goto top; } else return 0; } case scheme_mutable_pair_type: { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; if (is_equal(SCHEME_CAR(obj1), SCHEME_CAR(obj2), eql)) { obj1 = SCHEME_CDR(obj1); obj2 = SCHEME_CDR(obj2); goto top; } else return 0; } case scheme_vector_type: case scheme_fxvector_type: { # include "mzeqchk.inc" if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; if (union_check(obj1, obj2, eql)) return 1; return vector_equal(obj1, orig_obj1, obj2, orig_obj2, eql); } case scheme_byte_string_type: case scheme_unix_path_type: case scheme_windows_path_type: { intptr_t l1, l2; if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; l1 = SCHEME_BYTE_STRTAG_VAL(obj1); l2 = SCHEME_BYTE_STRTAG_VAL(obj2); return ((l1 == l2) && !memcmp(SCHEME_BYTE_STR_VAL(obj1), SCHEME_BYTE_STR_VAL(obj2), l1)); } case scheme_char_string_type: { intptr_t l1, l2; if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; l1 = SCHEME_CHAR_STRTAG_VAL(obj1); l2 = SCHEME_CHAR_STRTAG_VAL(obj2); return ((l1 == l2) && !memcmp(SCHEME_CHAR_STR_VAL(obj1), SCHEME_CHAR_STR_VAL(obj2), l1 * sizeof(mzchar))); } case scheme_regexp_type: { if (scheme_regexp_is_byte(obj1) != scheme_regexp_is_byte(obj2)) return 0; if (scheme_regexp_is_pregexp(obj1) != scheme_regexp_is_pregexp(obj2)) return 0; obj1 = scheme_regexp_source(obj1); obj2 = scheme_regexp_source(obj2); goto top; } case scheme_structure_type: case scheme_proc_struct_type: { Scheme_Struct_Type *st1, *st2; Scheme_Object *procs1, *procs2; st1 = SCHEME_STRUCT_TYPE(obj1); st2 = SCHEME_STRUCT_TYPE(obj2); if (eql->for_chaperone == 1) procs1 = NULL; else procs1 = scheme_struct_type_property_ref(scheme_impersonator_of_property, (Scheme_Object *)st1); if (procs1) procs1 = scheme_apply_impersonator_of(eql->for_chaperone, procs1, obj1); if (eql->for_chaperone) procs2 = NULL; else { procs2 = scheme_struct_type_property_ref(scheme_impersonator_of_property, (Scheme_Object *)st2); if (procs2) procs2 = scheme_apply_impersonator_of(eql->for_chaperone, procs2, obj2); } if (procs1 || procs2) { /* impersonator-of property trumps other forms of checking */ if (procs1) { obj1 = procs1; orig_obj1 = obj1; } if (procs2) { obj2 = procs2; orig_obj2 = obj2; } goto top_after_next; } else { procs1 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st1); if (procs1 && (st1 != st2)) { procs2 = scheme_struct_type_property_ref(scheme_equal_property, (Scheme_Object *)st2); if (!procs2 || !SAME_OBJ(SCHEME_VEC_ELS(procs1)[0], SCHEME_VEC_ELS(procs2)[0])) procs1 = NULL; } if (procs1) { /* Has an equality property: */ Scheme_Object *a[3], *recur; Equal_Info *eql2; # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; /* Create/cache closure to use for recursive equality checks: */ if (eql->recur) { recur = eql->recur; eql2 = (Equal_Info *)SCHEME_PRIM_CLOSURE_ELS(recur)[0]; } else { eql2 = (Equal_Info *)scheme_malloc(sizeof(Equal_Info)); a[0] = (Scheme_Object *)eql2; recur = scheme_make_prim_closure_w_arity(equal_recur, 1, a, "equal?/recur", 2, 2); eql->recur = recur; } memcpy(eql2, eql, sizeof(Equal_Info)); a[0] = orig_obj1; a[1] = orig_obj2; a[2] = recur; procs1 = SCHEME_VEC_ELS(procs1)[1]; recur = _scheme_apply(procs1, 3, a); memcpy(eql, eql2, sizeof(Equal_Info)); return SCHEME_TRUEP(recur); } else if (st1 != st2) { return 0; } else if ((eql->for_chaperone == 1) && !(MZ_OPT_HASH_KEY(&st1->iso) & STRUCT_TYPE_ALL_IMMUTABLE)) { return 0; } else { /* Same types, but doesn't have an equality property (or checking for chaperone), so check transparency: */ Scheme_Object *insp; if (scheme_struct_is_transparent(obj1)) insp = NULL; else { insp = scheme_get_param(scheme_current_config(), MZCONFIG_INSPECTOR); } if (!insp || scheme_inspector_sees_part(obj1, insp, -2)) { # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; return struct_equal(obj1, orig_obj1, obj2, orig_obj2, eql); } else return 0; } } } case scheme_box_type: { SCHEME_USE_FUEL(1); if ((eql->for_chaperone == 1) && (!SCHEME_IMMUTABLEP(obj1) || !SCHEME_IMMUTABLEP(obj2))) return 0; if (union_check(obj1, obj2, eql)) return 1; if (SAME_OBJ(obj1, orig_obj1)) obj1 = SCHEME_BOX_VAL(obj1); else obj1 = scheme_unbox(orig_obj1); if (SAME_OBJ(obj2, orig_obj2)) obj2 = SCHEME_BOX_VAL(obj2); else obj2 = scheme_unbox(orig_obj2); goto top; } case scheme_hash_table_type: { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; return scheme_hash_table_equal_rec((Scheme_Hash_Table *)obj1, orig_obj1, (Scheme_Hash_Table *)obj2, orig_obj2, eql); } case scheme_hash_tree_type: case scheme_eq_hash_tree_type: case scheme_eqv_hash_tree_type: case scheme_hash_tree_indirection_type: { # include "mzeqchk.inc" if (union_check(obj1, obj2, eql)) return 1; return scheme_hash_tree_equal_rec((Scheme_Hash_Tree *)obj1, orig_obj1, (Scheme_Hash_Tree *)obj2, orig_obj2, eql); } case scheme_bucket_table_type: { # include "mzeqchk.inc" if (eql->for_chaperone == 1) return 0; if (union_check(obj1, obj2, eql)) return 1; return scheme_bucket_table_equal_rec((Scheme_Bucket_Table *)obj1, orig_obj1, (Scheme_Bucket_Table *)obj2, orig_obj2, eql); } case scheme_wrap_chunk_type: { return vector_equal(obj1, obj1, obj2, obj2, eql); } case scheme_resolved_module_path_type: { obj1 = SCHEME_PTR_VAL(obj1); obj2 = SCHEME_PTR_VAL(obj2); goto top; } case scheme_module_index_type: { Scheme_Modidx *midx1, *midx2; # include "mzeqchk.inc" midx1 = (Scheme_Modidx *)obj1; midx2 = (Scheme_Modidx *)obj2; if (eql->eq_for_modidx && (SCHEME_FALSEP(midx1->path) || SCHEME_FALSEP(midx2->path))) return 0; else if (is_equal(midx1->path, midx2->path, eql)) { obj1 = midx1->base; obj2 = midx2->base; goto top; } } case scheme_scope_table_type: { Scheme_Scope_Table *mt1 = (Scheme_Scope_Table *)obj1; Scheme_Scope_Table *mt2 = (Scheme_Scope_Table *)obj2; if (!is_equal((Scheme_Object *)mt1->simple_scopes, (Scheme_Object *)mt2->simple_scopes, eql)) return 0; obj1 = mt1->multi_scopes; obj2 = mt2->multi_scopes; goto top; } default: if (!eql->for_chaperone && ((t1 == scheme_chaperone_type) || (t1 == scheme_proc_chaperone_type))) { /* both chaperones */ obj1 = ((Scheme_Chaperone *)obj1)->val; obj2 = ((Scheme_Chaperone *)obj2)->val; goto top_after_next; } else { Scheme_Equal_Proc eqlp = scheme_type_equals[t1]; if (eqlp) { if (union_check(obj1, obj2, eql)) return 1; return eqlp(obj1, obj2, eql); } else return 0; } } } }