示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
文件: types.c 项目: bawerd/kitten
/* Unbox a float. */
Float float_unbox(Boxed reference) {
  assert(reference);
  assert(is_float(reference));
  Float value = float_value(reference);
  boxed_free(reference);
  return value;
}
示例#5
0
文件: kitten.c 项目: bawerd/kitten
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("] ");
}
示例#6
0
 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;
     }
 }
示例#7
0
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();
  }
}
示例#8
0
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;
}
示例#9
0
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));
  }
}
示例#10
0
文件: types.c 项目: bawerd/kitten
/* 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;
}
示例#11
0
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());
}
示例#12
0
文件: value.c 项目: dyama/supoo
/* FLOAT 型の value を作成する */
value* float_new(double val)
{
  value* res = value_new();
  *res = float_value(val);
  return res;
}
示例#13
0
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;
}
示例#14
0
文件: heap_gc.c 项目: aidanhs/teeterl
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;
	}
}
示例#15
0
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;
}
示例#16
0
文件: compare.c 项目: MCRedJay/ling
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;
	}
}
示例#17
0
文件: compare.c 项目: MCRedJay/ling
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);
}
示例#18
0
文件: heap.c 项目: aidanhs/teeterl
//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;
	}
}