LISP_OBJ_PTR mult(LISP_OBJ_PTR args) { LISP_OBJ_PTR res = alloc_obj(); int int_res = 1; float float_res = 1; BOOLEAN is_float = FALSE; while (args != nil_ptr) { // check to see if we should be adding floats if (is_float(car(args)) && !is_float) { float_res = int_res; is_float = TRUE; } // grab the proper number if (is_float(car(args))) { float_res *= float_value(car(args)); } else if (!is_float) int_res *= int_value(car(args)); else float_res *= int_value(car(args)); args = cdr(args); } if (is_float) { form(res) = FLOAT_FORM; float_value(res) = float_res; } else { form(res) = INT_FORM; int_value(res) = int_res; } return res; }
LISP_OBJ_PTR eq(LISP_OBJ_PTR args) { LISP_OBJ_PTR current = car(args); LISP_OBJ_PTR to_test; BOOLEAN res = TRUE; args = cdr(args); while (args != nil_ptr) { to_test = car(args); if (is_int(current) && is_int(to_test)) res = (int_value(current) == int_value(to_test)); else if (is_int(current) && is_float(to_test)) res = (int_value(current) == float_value(to_test)); else if (is_float(current) && is_int(to_test)) res = (float_value(current) == int_value(to_test)); else res = (float_value(current) == float_value(to_test)); if (!res) { return false_ptr; } current = to_test; args = cdr(args); } return true_ptr; }
LISP_OBJ_PTR divide(LISP_OBJ_PTR args) { LISP_OBJ_PTR res = alloc_obj(); float float_res = 0; // for now, this always coerces to a float form(res) = FLOAT_FORM; if (is_float(car(args))) { float_res = float_value(car(args)); } else float_res = int_value(car(args)); args = cdr(args); if (args == nil_ptr) { float_value(res) = 1 / float_res; return res; } // TODO: check for zero division while (args != nil_ptr) { if (is_float(car(args))) float_res /= float_value(car(args)); else float_res /= int_value(car(args)); args = cdr(args); } float_value(res) = float_res; return res; }
/* Unbox a float. */ Float float_unbox(Boxed reference) { assert(reference); assert(is_float(reference)); Float value = float_value(reference); boxed_free(reference); return value; }
void kitten_trace(Boxed stack, Boxed definitions) { assert(stack); assert(is_quotation(stack)); printf("[ "); int i; for (i = 0; i < quotation_size(stack); ++i) { Boxed current = quotation_data(stack)[i]; switch (boxed_type(current)) { case FLOAT: printf("%p:%fF ", current, float_value(current)); break; case INTEGER: printf("%p:%ldI ", current, integer_value(current)); break; case WORD: printf("%p:%dW ", current, word_value(current)); break; case QUOTATION: printf("%p:", current); kitten_trace(current, definitions); break; } } printf("] "); }
FloatLiteral (Token _token, std::string _value) : Expression(_token, nullptr, Kind::FloatLit, nullptr) { type = std::unique_ptr<Type>(new BaseType(_token, float_type(_value))); bool positive = num_is_positive(_value); value = float_value(_value); if (!positive) { value = -value; } }
ObjFileHandler::ObjFileHandler(std::string filename) { _points = new std::vector<Point>(); _connections = new std::vector<std::vector<int>* >(); std::string line; std::vector<std::string> tokens; std::ifstream file(filename.c_str()); if (file.is_open()) { while (file.good()) { // Parse valid lines while(std::getline(file, line)) { // Ignore blank lines if(line.length() == 0) break; tokens = split(line, ' '); // Parse vertice if(tokens.at(0) == "v") { Point p(float_value(tokens.at(1)), float_value(tokens.at(2)), float_value(tokens.at(3)) ); _points->push_back(p); } // Parse face else if(tokens.at(0) == "f") { std::vector<int>* aux = new std::vector<int>(); for(unsigned int i = 1; i < tokens.size(); i++) { std::vector<std::string> values = split(tokens.at(i), '/'); aux->push_back(int_value(values.at(0))); } _connections->push_back(aux); } } } file.close(); } }
LISP_OBJ_PTR greater_than(LISP_OBJ_PTR args) { LISP_OBJ_PTR current = car(args); args = cdr(args); // TODO: make this a lot less ugly. while (args != nil_ptr) { switch (form(current)) { case INT_FORM: switch (form(car(args))) { case INT_FORM: if (int_value(current) <= int_value(car(args))) return false_ptr; break; case FLOAT_FORM: if (int_value(current) <= float_value(car(args))) return false_ptr; break; } break; case FLOAT_FORM: switch (form(car(args))) { case INT_FORM: if (float_value(current) <= int_value(car(args))) return false_ptr; break; case FLOAT_FORM: if (float_value(current) <= float_value(car(args))) return false_ptr; break; } break; } current = car(args); args = cdr(args); } return true_ptr; }
void display(LISP_OBJ_PTR objp) { switch (objp->form) { case INT_FORM: fprintf(out_stream, "%d", int_value(objp)); break; case FLOAT_FORM: fprintf(out_stream, "%g", float_value(objp)); break; case CHAR_FORM: fprintf(out_stream, "%c", char_value(objp)); break; case STRING_FORM: fprintf(out_stream, "%s", string_value(objp)); break; case SYMBOL_FORM: fprintf(out_stream, "%s", symbol_value(objp)); break; case PROCEDURE_FORM: fprintf(out_stream, "<PROCEDURE>"); break; case BOOLEAN_FORM: fprintf(out_stream, "#%c", bool_value(objp) ? 't' : 'f'); break; case CONS_FORM: fprintf(out_stream, "("); while (TRUE) { print_lispobj(car(objp)); objp = cdr(objp); if (objp == nil_ptr) break; if (!(is_pair(objp))) { printf(" . "); print_lispobj(objp); break; } fprintf(out_stream, " "); } fprintf(out_stream, ")"); break; case NO_FORM: fprintf(out_stream, "no form, boss"); break; default: fprintf(out_stream, "dunno that form %d", form(objp)); } }
/* Make a deeper copy of a boxed reference. References within quotations are cloned using boxed_copy() rather than boxed_clone(). */ Boxed boxed_clone(Boxed reference) { trace("boxed_clone(%p)\n", reference); if (!reference) return NULL; switch (boxed_type(reference)) { case FLOAT: return float_new(float_value(reference)); case INTEGER: return integer_new(integer_value(reference)); case QUOTATION: { Boxed result = quotation_new(0); quotation_append(result, reference); return result; } case WORD: return word_new(word_value(reference)); } return NULL; }
TEST(EventToStringTest, ScalarType) { IntValue int_value(-42); std::string int_str; EXPECT_TRUE(ToString(&int_value, &int_str)); EXPECT_STREQ("-42", int_str.c_str()); UIntValue uint_value(42); std::string uint_str; EXPECT_TRUE(ToString(&uint_value, &uint_str)); EXPECT_STREQ("42", uint_str.c_str()); LongValue long_value(-42); std::string long_str; EXPECT_TRUE(ToString(&long_value, &long_str)); EXPECT_STREQ("-42", long_str.c_str()); ULongValue ulong_value(42); std::string ulong_str; EXPECT_TRUE(ToString(&ulong_value, &ulong_str)); EXPECT_STREQ("42", ulong_str.c_str()); FloatValue float_value(.5); std::string float_str; EXPECT_TRUE(ToString(&float_value, &float_str)); EXPECT_STREQ("0.5", float_str.c_str()); DoubleValue double_value(.25); std::string double_str; EXPECT_TRUE(ToString(&double_value, &double_str)); EXPECT_STREQ("0.25", double_str.c_str()); StringValue string_value("dummy"); std::string string_str; EXPECT_TRUE(ToString(&string_value, &string_str)); EXPECT_STREQ("\"dummy\"", string_str.c_str()); }
/* FLOAT 型の value を作成する */ value* float_new(double val) { value* res = value_new(); *res = float_value(val); return res; }
CS_IMPLEMENT_APPLICATION int main (int argc, char *argv[]) { iObjectRegistry* objreg = csInitializer::CreateEnvironment (argc, argv); if (! objreg) { csFPrintf (stderr, "Failed to create environment!\n"); return 1; } bool ok = csInitializer::RequestPlugins (objreg, CS_REQUEST_REPORTER, CS_REQUEST_REPORTERLISTENER, CS_REQUEST_PLUGIN ("crystalspace.script.perl5", iScript), CS_REQUEST_END); if (! ok) { csFPrintf (stderr, "Failed to load plugins!\n"); return 2; } if (csCommandLineHelper::CheckHelp (objreg)) { csCommandLineHelper::Help (objreg); return 0; } { csRef<iScript> script = csQueryRegistry<iScript> (objreg); if (! script) { csFPrintf (stderr, "Failed to find perl5 plugin!\n"); return 3; } ok = script->LoadModule ("cspace"); //ok = script->LoadModule ("scripts/perl5", "cspace.pm"); if (! ok) { csFPrintf (stderr, "Failed to load perl5 cspace module!\n"); return 4; } csInitializer::OpenApplication (objreg); //====================================================================// csPrintf ("Testing RValue/Store/Retrieve:\n"); int test_int = 3; float test_float = 3.0; double test_double = 3.0; bool test_bool = true; const char *test_str = "hello"; csPrintf (" Int: "); csRef<iScriptValue> int_value (script->RValue (test_int)); ok = script->Store("i", int_value); int_value.AttachNew (script->Retrieve ("i")); csPrintf ("%d == %d\n", test_int, int_value->GetInt ()); csPrintf (" Float: "); csRef<iScriptValue> float_value (script->RValue (test_float)); ok = script->Store("f", float_value); float_value.AttachNew (script->Retrieve ("f")); csPrintf ("%f == %f\n", test_float, float_value->GetFloat ()); csPrintf (" Double: "); csRef<iScriptValue> double_value (script->RValue (test_double)); ok = script->Store("d", double_value); double_value.AttachNew (script->Retrieve ("d")); csPrintf ("%lf == %lf\n", test_double, double_value->GetDouble ()); csPrintf (" String: "); csRef<iScriptValue> str_value (script->RValue (test_str)); ok = script->Store("s", str_value); str_value.AttachNew (script->Retrieve ("s")); csPrintf ("%s == %s\n", test_str, str_value->GetString ()->GetData ()); csPrintf (" Bool: "); csRef<iScriptValue> bool_value (script->RValue (test_bool)); ok = script->Store("b", bool_value); bool_value.AttachNew (script->Retrieve ("b")); csPrintf ("%s == %s\n\n", test_bool ? "true" : "false", bool_value->GetBool () ? "true" : "false"); //====================================================================// csPrintf ("Testing Remove:\n"); ok = script->Remove ("i") && script->Remove ("f") && script->Remove ("d") && script->Remove ("s") && script->Remove ("b"); csPrintf (" %s\n", ok ? "ok" : "failed"); int_value.AttachNew (script->Retrieve ("i")); csPrintf (" %s\n", int_value.IsValid () ? "failed" : "ok"); //====================================================================// csPrintf ("Testing New(csVector3):\n"); csRef<iScriptObject> obj (script->New ("csVector3")); csPrintf (" %s\n", obj.IsValid () ? "ok" : "failed"); //====================================================================// csPrintf ("Testing GetClass/IsA:\n"); csRef<iString> classname (obj->GetClass ()); csPrintf (" %s\n", classname->GetData ()); csPrintf (" %s\n", obj->IsA ("csVector3") ? "ok" : "failed"); //====================================================================// csPrintf ("Testing Set/Get:\n"); csPrintf (" %f == ", float_value->GetFloat ()); ok = obj->Set ("x", float_value); float_value.AttachNew (obj->Get ("x")); csPrintf ("%f\n", float_value->GetFloat ()); //====================================================================// csPrintf ("Testing Call(csVector3::Set):\n"); csRefArray<iScriptValue> args; args.Push (float_value); csRef<iScriptValue> ret (obj->Call ("Set", args)); csPrintf (" %f\n", float_value->GetFloat ()); //====================================================================// csPrintf ("Testing Call(csVector3::Norm):\n"); ret.AttachNew (obj->Call ("Norm")); csPrintf (" %f\n", ret->GetFloat ()); //====================================================================// csPrintf ("Testing GetPointer:\n"); csVector3 &vector = * (csVector3 *) obj->GetPointer (); vector.Normalize (); csPrintf (" %f %f %f\n", vector[0], vector[1], vector[2]); csPrintf (" ok\n"); csPrintf ("All Done!\n"); } csInitializer::DestroyApplication (objreg); return 0; }
void seek_live(term_t *tp, apr_memnode_t *newest, heap_t *hp) { term_t t = *tp; apr_memnode_t *node; term_box_t *ptr; // newest node - the node last generation the term may belong to // the node chain starts with the newest and goes to hp->gc_spot if (is_immed(t)) return; ptr = peel(t); node = newest; while (node != hp->gc_spot) { if (node_contains(node, ptr)) { // the term belongs to the newer generation // of terms; recurse to find possible references // to live terms in hp->gc_spot // only tuples, conses, funs (frozen) // and binaries (data, parent) contain references // order of popularity: // cons - tuple - binary - fun if (is_cons(t)) { seek_live(&ptr->cons.head, node, hp); seek_live(&ptr->cons.tail, node, hp); } else if (is_tuple(t)) { int i; int n = ptr->tuple.size; for (i = 0; i < n; i++) seek_live(&ptr->tuple.elts[i], node, hp); } else if (is_binary(t)) { if (ptr->binary.parent != noval) { term_box_t *parent; seek_live(&ptr->binary.parent, node, hp); parent = peel(ptr->binary.parent); ptr->binary.data = parent->binary.data + ptr->binary.offset; } } else if (is_fun(t)) { seek_live(&ptr->fun.frozen, node, hp); } return; } node = node->next; } if (node_contains(hp->gc_spot, ptr)) { // the term should be recreated // the term may have already been moved // and the term value has been replaced with // the buried reference to the new location if (is_grave(t)) { *tp = ptr->grave.skeleton; return; } // list - tuple - binary - fun - bignum - pid - float if (is_list(t)) { term_t cons = heap_cons2(hp, ptr->cons.head, ptr->cons.tail); term_box_t *box = peel(cons); seek_live(&box->cons.head, hp->gc_spot, hp); seek_live(&box->cons.tail, hp->gc_spot, hp); *tp = cons; } else if (is_tuple(t)) { term_t tuple = heap_tuple(hp, ptr->tuple.size); term_box_t *box = peel(tuple); int i; for (i = 0; i < ptr->tuple.size; i++) { box->tuple.elts[i] = ptr->tuple.elts[i]; seek_live(&box->tuple.elts[i], hp->gc_spot, hp); } *tp = tuple; } else if (is_binary(t)) { term_t parent = ptr->binary.parent; term_t b; if (parent == noval) b = heap_binary(hp, ptr->binary.bit_size, ptr->binary.data); else { apr_byte_t *data; seek_live(&parent, hp->gc_spot, hp); data = peel(parent)->binary.data + ptr->binary.offset; b = heap_binary_shared(hp, ptr->binary.bit_size, data, parent); } *tp = b; } else if (is_fun(t)) { term_t f = heap_fun(hp, ptr->fun.module, ptr->fun.function, ptr->fun.arity, ptr->fun.uniq, ptr->fun.index, ptr->fun.frozen); seek_live(&peel(f)->fun.frozen, hp->gc_spot, hp); *tp = f; } else if (is_bignum(t)) { mp_int ma = bignum_to_mp(t); *tp = heap_bignum(hp, SIGN(&ma), USED(&ma), DIGITS(&ma)); } else if (is_long_id(t)) { *tp = heap_long_id(hp, ptr->long_id.node, ptr->long_id.serial, ptr->long_id.tag_creation); } else // if (is_float(t)) { assert(is_float(t)); *tp = heap_float(hp, float_value(t)); } // bury the term ptr->grave.cross = MAGIC_CROSS; ptr->grave.skeleton = *tp; return; } else { // the term belong to the older generation or // to the literal pool of the module -- ignore return; } }
static bool assign_xml_value_to_protobuf_field(const std::string &value, xmltype xtype, ::google::protobuf::Message* msg, const ::google::protobuf::FieldDescriptor* field) { if (xtype==duration) return assign_xml_duration_value_to_protobuf_field(value,msg,field); // handle xmltype 'automatic' const ::google::protobuf::Reflection* reflection = msg->GetReflection(); switch (field->cpp_type()) { case ::google::protobuf::FieldDescriptor::CPPTYPE_INT32: { long longval; if (long_value(value,longval)) reflection->SetInt32(msg, field, longval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_INT64: { long longval; if (long_value(value,longval)) reflection->SetInt64(msg, field, longval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_UINT32: { unsigned long ulongval; if (ulong_value(value,ulongval)) reflection->SetUInt32(msg, field, ulongval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_UINT64: { unsigned long ulongval; if (ulong_value(value,ulongval)) reflection->SetUInt64(msg, field, ulongval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE: { double doubleval; if (double_value(value,doubleval)) reflection->SetDouble(msg, field, doubleval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_FLOAT: { double floatval; if (float_value(value,floatval)) reflection->SetFloat(msg, field, floatval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_BOOL: { bool boolval; if (bool_value(value,boolval)) reflection->SetBool(msg, field, boolval); else printf("ERROR:\n"); break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_ENUM: { const ::google::protobuf::EnumDescriptor *enu = field->enum_type(); const ::google::protobuf::EnumValueDescriptor *enuval = enu->FindValueByName(value); if (!enuval) { printf("ERROR: '%s' not a valid value for %s !\n",value.c_str(),enu->name().c_str()); } else { //printf("SUCCESS: '%s' is a valid value for %s !\n",value.c_str(),enu->name().c_str()); reflection->SetEnum(msg, field, enuval); } break; } case ::google::protobuf::FieldDescriptor::CPPTYPE_STRING: reflection->SetString(msg, field, value); break; case ::google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: printf("ERROR: element should not contain text data but we got '%s' !\n",value.c_str()); return false; default: printf("ERROR: Unsupported field type '%d' !\n", field->cpp_type()); return false; } return true; }
int are_terms_equal(term_t a, term_t b, int exact) { assert(a != b); // should be checked elsewhere if (is_immed(a) || is_immed(b)) { if (exact) return 0; if (is_int(a) && is_boxed(b)) { uint32_t *term_data = peel_boxed(b); return (boxed_tag(term_data) == SUBTAG_FLOAT) && (double)int_value(a) == float_value(term_data); } else if (is_boxed(a) && is_int(b)) { uint32_t *term_data = peel_boxed(a); return (boxed_tag(term_data) == SUBTAG_FLOAT) && (float_value(term_data) == (double)int_value(b)); } return 0; } if (is_cons(a)) { if (is_cons(b)) { do { uint32_t *cons1 = peel_cons(a); uint32_t *cons2 = peel_cons(b); if (cons1[0] != cons2[0] && !are_terms_equal(cons1[0], cons2[0], exact)) return 0; a = cons1[1]; b = cons2[1]; } while (is_cons(a) && is_cons(b)); return (a == b) || are_terms_equal(a, b, exact); } else return 0; } else if (is_tuple(a)) { if (is_tuple(b)) { uint32_t *data1 = peel_tuple(a); uint32_t *data2 = peel_tuple(b); if (data1[0] != data2[0]) return 0; for (int i = 1; i <= data1[0]; i++) if (data1[i] != data2[i] && !are_terms_equal(data1[i], data2[i], exact)) return 0; return 1; } else return 0; } else { assert(is_boxed(a)); if (!is_boxed(b)) return 0; uint32_t *term_data1 = peel_boxed(a); uint32_t *term_data2 = peel_boxed(b); uint32_t subtag = boxed_tag(term_data1); if (!exact && subtag == SUBTAG_FLOAT && is_bignum(term_data2)) return float_value(term_data1) == bignum_to_double((bignum_t *)term_data2); if (!exact && is_bignum(term_data1) && boxed_tag(term_data2) == SUBTAG_FLOAT) return bignum_to_double((bignum_t *)term_data1) == float_value(term_data2); if (subtag != boxed_tag(term_data2) && !(is_binary(term_data1) && is_binary(term_data2))) return 0; switch (subtag) { case SUBTAG_POS_BIGNUM: case SUBTAG_NEG_BIGNUM: { bignum_t *bn1 = (bignum_t *)term_data1; bignum_t *bn2 = (bignum_t *)term_data2; return bignum_compare(bn1, bn2) == 0; } case SUBTAG_FUN: { t_fun_t *f1 = (t_fun_t *)term_data1; t_fun_t *f2 = (t_fun_t *)term_data2; if (f1->module != f2->module || f1->index != f2->index || f1->old_uniq != f2->old_uniq) return 0; int num_free = fun_num_free(term_data1); assert(num_free == fun_num_free(term_data2)); for (int i = 0; i < num_free; i++) { term_t v1 = f1->frozen[i]; term_t v2 = f2->frozen[i]; if (v1 != v2 && !are_terms_equal(v1, v2, exact)) return 0; } return 1; } case SUBTAG_EXPORT: { export_t *e1 = ((t_export_t *)term_data1)->e; export_t *e2 = ((t_export_t *)term_data2)->e; return e1->module == e2->module && e1->function == e2->function && e1->arity == e2->arity; } case SUBTAG_PID: { t_long_pid_t *pid1 = (t_long_pid_t *)term_data1; t_long_pid_t *pid2 = (t_long_pid_t *)term_data2; return pid1->node == pid2->node && pid1->serial == pid2->serial && opr_hdr_id(pid1) == opr_hdr_id(pid2) && opr_hdr_creat(pid1) == opr_hdr_creat(pid2); } case SUBTAG_OID: { t_long_oid_t *oid1 = (t_long_oid_t *)term_data1; t_long_oid_t *oid2 = (t_long_oid_t *)term_data2; return oid1->node == oid2->node && opr_hdr_id(oid1) == opr_hdr_id(oid2) && opr_hdr_creat(oid1) == opr_hdr_creat(oid2); } case SUBTAG_REF: { t_long_ref_t *ref1 = (t_long_ref_t *)term_data1; t_long_ref_t *ref2 = (t_long_ref_t *)term_data2; return ref1->node == ref2->node && ref1->id1 == ref2->id1 && ref1->id2 == ref2->id2 && opr_hdr_id(ref1) == opr_hdr_id(ref2) && opr_hdr_creat(ref1) == opr_hdr_creat(ref2); } case SUBTAG_PROC_BIN: case SUBTAG_HEAP_BIN: case SUBTAG_MATCH_CTX: case SUBTAG_SUB_BIN: { bits_t bs1, bs2; bits_get_real(term_data1, &bs1); bits_get_real(term_data2, &bs2); return (bits_compare(&bs1, &bs2) == 0); } default: assert(subtag == SUBTAG_FLOAT); return float_value(term_data1) == float_value(term_data2); } return 1; } }
int is_term_smaller(term_t a, term_t b) { if (a == b) return 0; if (are_both_immed(a, b)) { if (are_both_int(a, b)) return int_value(a) < int_value(b); if (is_int(a)) // !is_int(b) return 1; if (is_nil(a)) // !is_nil(b) return 0; if (is_nil(b)) // !is_nil(a) return 1; if (is_atom(a)) { if (is_int(b)) return 0; else if (is_atom(b)) { uint8_t *print1 = atoms_get(atom_index(a)); uint8_t *print2 = atoms_get(atom_index(b)); int short_len = (print1[0] < print2[0]) ? print1[0] : print2[0]; int d = memcmp(print1+1, print2+1, short_len); if (d == 0) return print1[0] < print2[0]; return d < 0; } else return 1; } else if (is_short_oid(a)) { if (is_int(b) || is_atom(b)) return 0; else if (is_short_oid(b)) return short_oid_id(a) < short_oid_id(b); else return 1; } else if (is_short_pid(a)) { if (is_int(b) || is_atom(b) || is_short_oid(b)) return 0; else { assert(is_short_pid(b)); return short_pid_id(a) < short_pid_id(b); } } } //TODO: comparison of bignum and float: docs mention the // number 9007199254740992.0 and a loss of transitivity if (!is_immed(a) && !is_immed(b) && primary_tag(a) == primary_tag(b)) { if (is_cons(a)) return is_term_smaller_1(a, b); else if (is_tuple(a)) return is_term_smaller_2(a, b); else { assert(is_boxed(a) && is_boxed(b)); uint32_t *adata = peel_boxed(a); uint32_t *bdata = peel_boxed(b); if (boxed_tag(adata) == boxed_tag(bdata) || (is_binary(adata) && is_binary(bdata)) || (is_bignum(adata) && is_bignum(bdata))) { switch(boxed_tag(adata)) { case SUBTAG_POS_BIGNUM: case SUBTAG_NEG_BIGNUM: return bignum_compare((bignum_t *)adata, (bignum_t *)bdata) < 0; case SUBTAG_FUN: return fun_compare((t_fun_t *)adata, (t_fun_t *)bdata) < 0; case SUBTAG_EXPORT: return export_compare((t_export_t *)adata, (t_export_t *)bdata) < 0; case SUBTAG_PID: return pid_compare((t_long_pid_t *)adata, (t_long_pid_t *)bdata) < 0; case SUBTAG_OID: return oid_compare((t_long_oid_t *)adata, (t_long_oid_t *)bdata) < 0; case SUBTAG_REF: return ref_compare((t_long_ref_t *)adata, (t_long_ref_t *)bdata) < 0; case SUBTAG_PROC_BIN: case SUBTAG_HEAP_BIN: case SUBTAG_MATCH_CTX: case SUBTAG_SUB_BIN: return is_term_smaller_3(adata, bdata); default: assert(boxed_tag(adata) == SUBTAG_FLOAT); return float_value(adata) < float_value(bdata); } } } } // Number comparison with (mandatory) coercion // int use_float = (is_boxed(a) && boxed_tag(peel_boxed(a)) == SUBTAG_FLOAT) || (is_boxed(b) && boxed_tag(peel_boxed(b)) == SUBTAG_FLOAT); if (use_float) { if (is_int(a)) // b is always float return (double)int_value(a) < float_value(peel_boxed(b)); else if (is_boxed(a)) { uint32_t *adata = peel_boxed(a); if (is_bignum(adata)) // b is always float return bignum_to_double((bignum_t *)adata) < float_value(peel_boxed(b)); if (boxed_tag(adata) == SUBTAG_FLOAT) { if (is_int(b)) return float_value(adata) < (double)int_value(b); if (is_boxed(b)) { uint32_t *bdata = peel_boxed(b); if (is_bignum(bdata)) return float_value(adata) < bignum_to_double((bignum_t *)bdata); } } } } else // use integer { if (is_int(a)) { if (is_boxed(b)) { uint32_t *bdata = peel_boxed(b); if (is_bignum(bdata)) { bignum_t *bbn = (bignum_t *)bdata; return !bignum_is_neg(bbn); } assert(boxed_tag(bdata) != SUBTAG_FLOAT); } } else if (is_boxed(a)) { uint32_t *adata = peel_boxed(a); if (is_bignum(adata)) { bignum_t *abn = (bignum_t *)adata; if (is_int(b)) return bignum_is_neg(abn); if (is_boxed(b)) { uint32_t *bdata = peel_boxed(b); if (is_bignum(bdata)) return bignum_compare(abn, (bignum_t *)bdata); assert(boxed_tag(bdata) != SUBTAG_FLOAT); } } assert(boxed_tag(adata) != SUBTAG_FLOAT); } } // a and b are quaranteed to have different types // return term_order(a) < term_order(b); }
//cons - tuple - binary - fun term_t heap_marshal(term_t t, heap_t *hp) { term_box_t *box; if (is_immed(t)) return t; box = peel(t); if (is_cons(t)) { term_t first = nil; term_t last = nil; do { term_box_t *cb = peel(t); term_t v = heap_marshal(cb->cons.head, hp); cons_up(first, last, v, hp); t = cb->cons.tail; } while (is_cons(t)); if (t != nil) peel(last)->cons.tail = heap_marshal(t, hp); return first; } else if (is_tuple(t)) { int n = box->tuple.size; term_t tuple = heap_tuple(hp, n); term_box_t *tb = peel(tuple); int i; for (i = 0; i < n; i++) tb->tuple.elts[i] = heap_marshal(box->tuple.elts[i], hp); return tuple; } else if (is_binary(t)) { //NB: for shared binaries parent not copied; shared becomes root term_t binary = heap_binary(hp, box->binary.bit_size, box->binary.data); return binary; } else if (is_bignum(t)) { bignum_t *bb = (bignum_t *)peel(t); term_t biggie = heap_bignum(hp, bb->sign, bb->used, bb->dp); return biggie; } else if (is_float(t)) { term_t f = heap_float(hp, float_value(t)); return f; } else if (is_fun(t)) { term_t fun = heap_fun(hp, box->fun.module, box->fun.function, box->fun.arity, box->fun.uniq, box->fun.index, heap_marshal(box->fun.frozen, hp)); return fun; } else // long_id { term_t id; assert(is_long_id(t)); id = heap_long_id(hp, box->long_id.node, box->long_id.serial, box->long_id.tag_creation); return id; } }