Ejemplo n.º 1
0
static VALUE encode(VALUE self, VALUE lat, VALUE lon, VALUE precision)
{
	VALUE geohash;
	char str[15];
	int digits=10;
	
	digits = NUM2INT(precision);
	
	Check_Type(lat, T_FLOAT);
	Check_Type(lon, T_FLOAT);
	if (digits <3 || digits > 12)
		digits = 12;
	
	encode_geohash(RFLOAT(lat)->float_value, RFLOAT(lon)->float_value, digits, str);

	geohash = rb_str_new2(str);
	return geohash;
}
Ejemplo n.º 2
0
static void
set_value(ValueStruct *value, VALUE obj)
{
    VALUE class_path, str;

    if (NIL_P(obj)) {
        ValueIsNil(value);
    }
    else {
        ValueIsNonNil(value);
        switch (TYPE(obj)) {
        case T_TRUE:
        case T_FALSE:
            SetValueBool(value, RTEST(obj) ? TRUE : FALSE);
            break;
        case T_FIXNUM:
            SetValueInteger(value, FIX2INT(obj));
            break;
        case T_BIGNUM:
            SetValueInteger(value, NUM2INT(obj));
            break;
        case T_FLOAT:
            SetValueFloat(value, RFLOAT(obj)->value);
            break;
        case T_STRING:
            switch (ValueType(value)) {
            case GL_TYPE_BYTE:
            case GL_TYPE_BINARY:
                SetValueBinary(value, RSTRING(obj)->ptr, RSTRING(obj)->len);
                break;
            default:
                SetValueStringWithLength(value,
                                         RSTRING(obj)->ptr,
                                         RSTRING(obj)->len,
                                         codeset);
                break;
            }
            break;
        default:
            class_path = rb_class_path(CLASS_OF(obj));
            if (strcasecmp(StringValuePtr(class_path), "BigDecimal") == 0) {
                str = rb_funcall(obj, rb_intern("to_s"), 1, rb_str_new2("F"));
            } else
            if (strcasecmp(StringValuePtr(class_path), "Time") == 0) {
                str = rb_funcall(obj, rb_intern("strftime"), 1, rb_str_new2("%Y%m%d%H%M%S"));
dbgprintf("strftime [%s]",StringValuePtr(str));
            }
            else {
                str = rb_funcall(obj, rb_intern("to_s"), 0);
            }
            SetValueString(value, StringValuePtr(str), codeset);
            break;
        }
    }
}
Ejemplo n.º 3
0
static VALUE rb_gsl_ieee_fprintf_double(int argc, VALUE *argv, VALUE obj)
{
#ifdef RUBY_1_9_LATER
  rb_io_t *fptr = NULL;
#else
  OpenFile *fptr = NULL;
#endif
  FILE *fp = NULL;
  int flag = 0;
  VALUE vtmp;

  switch (argc) {
  case 2:
    switch (TYPE(argv[0])) {
    case T_STRING:
      fp = fopen(RSTRING_PTR(argv[0]), "w");
      flag = 1;
      break;
    case T_FILE:
      GetOpenFile(argv[0], fptr);
      rb_io_check_writable(fptr);
#ifdef RUBY_1_9_LATER
      fp = rb_io_stdio_file(fptr);
#else
      fp = GetWriteFile(fptr);
#endif
      break;
    default:
      rb_raise(rb_eTypeError, "wrong type argument %s (IO or String expected)",
	       rb_class2name(CLASS_OF(argv[0])));
    }
    vtmp = argv[1];
    break;
  case 1:
    vtmp = argv[0];
    fp = stdout;
    break;
  default:
    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
  }
  if (TYPE(vtmp) != T_FLOAT)
    rb_raise(rb_eTypeError, "wrong argument type %s (Float expected)",
	     rb_class2name(CLASS_OF(vtmp)));
#ifdef RUBY_1_9_LATER
  double rbfv = rb_float_value(vtmp);
  gsl_ieee_fprintf_double(fp, &rbfv);
#else
  gsl_ieee_fprintf_double(fp, &(RFLOAT(vtmp)->value));
#endif
  if (fp == stdout) fprintf(stdout, "\n");
  if (flag == 1) fclose(fp);
  return obj;
}
Ejemplo n.º 4
0
void
step_sec_timeval( VALUE secs, struct timeval *t)
{
    switch (TYPE(secs)) {
      case T_FIXNUM:
        t->tv_sec = FIX2LONG(secs), t->tv_usec = 0;
        if (t->tv_sec < 0)
            rb_raise( rb_eArgError, "time interval must be positive");
        break;

      case T_FLOAT:
        if (RFLOAT(secs)->value < 0.0)
            rb_raise( rb_eArgError, "time interval must be positive");
        else {
            double f, d;

            d = modf( RFLOAT(secs)->value, &f);
            t->tv_sec = (time_t) f, t->tv_usec = (time_t) (d*1e6+0.5);
            if (f != t->tv_sec)
                rb_raise( rb_eRangeError, "time interval out of Time range",
                    RFLOAT(secs)->value);
        }
        break;

      case T_BIGNUM:
        t->tv_sec = NUM2LONG(secs), t->tv_usec = 0;
        if (t->tv_sec < 0)
            rb_raise(rb_eArgError, "time interval must be positive");
        break;

      case T_NIL:
        t->tv_sec = 0, t->tv_usec = 0;
        break;

      default:
        rb_raise( rb_eTypeError, "can't convert %s into time interval",
                 rb_obj_classname( secs));
        break;
    }
}
Ejemplo n.º 5
0
/*
  power: x^y
*/
static Term
p_exp(Term t1, Term t2 USES_REGS)
{
  switch (ETypeOfTerm(t1)) {
  case long_int_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      {
	Int i1 = IntegerOfTerm(t1);
	Int i2 = IntegerOfTerm(t2);
	Int pow = ipow(i1,i2);

	if (i2 < 0) {
	  return Yap_ArithError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t2,
		    "%d ^ %d", i1, i2);
	}
#ifdef USE_GMP
	/* two integers */
	if ((i1 && !pow)) {
	  /* overflow */
	  return Yap_gmp_exp_int_int(i1, i2);
	}
#endif
	RINT(pow);
      }
    case double_e:
      {
	/* integer, double */
	Float fl1 = (Float)IntegerOfTerm(t1);
	Float fl2 = FloatOfTerm(t2);
	RFLOAT(pow(fl1,fl2));
      }
    case big_int_e:
#ifdef USE_GMP
      {
	Int i = IntegerOfTerm(t1);
	return Yap_gmp_exp_int_big(i,t2);
      }
#endif
    default:
      RERROR();
    }
    break;
  case double_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      /* float / integer */
      {
	Int i2 = IntegerOfTerm(t2);
	RFLOAT(pow(FloatOfTerm(t1),i2));
      }
    case double_e:
      {
	Float f2 = FloatOfTerm(t2);
	RFLOAT(pow(FloatOfTerm(t1),f2));
      }
    case big_int_e:
#ifdef USE_GMP
      {
	RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2)));
      }
#endif
    default:
      RERROR();
    }
    break;
  case big_int_e:
#ifdef USE_GMP
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      {
	Int i = IntegerOfTerm(t2);
	return Yap_gmp_exp_big_int(t1,i);
      }
    case big_int_e:
      /* two bignums, makes no sense */
      return Yap_gmp_exp_big_big(t1,t2);
    case double_e:
      {
	Float dbl = FloatOfTerm(t2);
	RFLOAT(pow(Yap_gmp_to_float(t1),dbl));
      }
    default:
      RERROR();
    }
#endif
  default:
    RERROR();
  }
  RERROR();
}
Ejemplo n.º 6
0
/*
  power: x^y
*/
static Term
p_power(Term t1, Term t2 USES_REGS)
{
  switch (ETypeOfTerm(t1)) {
  case long_int_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      {
	Int i2 = IntegerOfTerm(t2);

	/* two integers */
	RFLOAT(pow(IntegerOfTerm(t1),i2));
      }
    case double_e:
      {
	/* integer, double */
	Float fl1 = (Float)IntegerOfTerm(t1);
	Float fl2 = FloatOfTerm(t2);
	RFLOAT(pow(fl1,fl2));
      }
    case big_int_e:
#ifdef USE_GMP
      {
	Int i1 = IntegerOfTerm(t1);
	Float f2 = Yap_gmp_to_float(t2);
	RFLOAT(pow(i1,f2));
      }
#endif
    default:
      RERROR();
    }
    break;
  case double_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      /* float / integer */
      {
	Int i2 = IntegerOfTerm(t2);
	RFLOAT(pow(FloatOfTerm(t1),i2));
      }
    case double_e:
      {
	Float f2 = FloatOfTerm(t2);
	RFLOAT(pow(FloatOfTerm(t1),f2));
      }
    case big_int_e:
#ifdef USE_GMP
      {
	RFLOAT(pow(FloatOfTerm(t1),Yap_gmp_to_float(t2)));
      }
#endif
    default:
      RERROR();
    }
    break;
  case big_int_e:
#ifdef USE_GMP
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      {
	Int i = IntegerOfTerm(t2);
	RFLOAT(pow(Yap_gmp_to_float(t1),i));
      }
    case big_int_e:
      /* two bignums */
      RFLOAT(pow(Yap_gmp_to_float(t1),Yap_gmp_to_float(t2)));
    case double_e:
      {
	Float dbl = FloatOfTerm(t2);
	RFLOAT(pow(Yap_gmp_to_float(t1),dbl));
      }
    default:
      RERROR();
    }
#endif
  default:
    RERROR();
  }
  RERROR();
}
Ejemplo n.º 7
0
/*
  atan2: arc tangent x/y
*/
static Term
p_atan2(Term t1, Term t2 USES_REGS)
{
  switch (ETypeOfTerm(t1)) {
  case long_int_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      /* two integers */
      RFLOAT(atan2(IntegerOfTerm(t1),IntegerOfTerm(t2)));
    case double_e:
      RFLOAT(atan2(IntegerOfTerm(t1),FloatOfTerm(t2)));
    case big_int_e:
#ifdef USE_GMP
      {
	Int i1 = IntegerOfTerm(t1);
	Float f2 = Yap_gmp_to_float(t2);
	RFLOAT(atan2(i1,f2));
      }
#endif
    default:
      RERROR();
      break;
    }
  case double_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      /* float / integer */
      {
	Int i2 = IntegerOfTerm(t2);
	RFLOAT(atan2(FloatOfTerm(t1),i2));
      }
    case double_e:
      {
	Float f2 = FloatOfTerm(t2);
	RFLOAT(atan2(FloatOfTerm(t1),f2));
      }
    case big_int_e:
#ifdef USE_GMP
      {
	RFLOAT(atan2(FloatOfTerm(t1),Yap_gmp_to_float(t2)));
      }
#endif
    default:
      RERROR();
    }
    break;
  case big_int_e:
#ifdef USE_GMP
    {
      Float dbl1 = Yap_gmp_to_float(t1);
      switch (ETypeOfTerm(t2)) {
      case long_int_e:
	{
	  Int i = IntegerOfTerm(t2);
	  RFLOAT(atan2(dbl1,i));
	}
      case big_int_e:
	/* two bignums */
	RFLOAT(atan2(dbl1,Yap_gmp_to_float(t2)));
      case double_e:
	{
	  Float dbl = FloatOfTerm(t2);
	  RFLOAT(atan2(dbl1,dbl));
	}
      default:
	RERROR();
      }
    }
#endif
  default:
    RERROR();
  }
  RERROR();
}
Ejemplo n.º 8
0
/*
  Floating point division: /
*/
static Term
p_fdiv(Term t1, Term t2 USES_REGS)
{
  switch (ETypeOfTerm(t1)) {
  case long_int_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      {
	Int i2 = IntegerOfTerm(t2);

	/* two integers */
	RFLOAT((((Float)IntegerOfTerm(t1))/(Float)i2));
      }
    case double_e:
      {
	/* integer, double */
	Float fl1 = (Float)IntegerOfTerm(t1);
	Float fl2 = FloatOfTerm(t2);
	RFLOAT(fl1/fl2);
      }
    case (CELL)big_int_e:
#ifdef USE_GMP
      return Yap_gmp_fdiv_int_big(IntegerOfTerm(t1), t2);
#endif
    default:
      RERROR();
    }
    break;
  case double_e:
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      /* float / integer */
      {
	Int i2 = IntegerOfTerm(t2);
	RFLOAT(FloatOfTerm(t1)/(Float)i2);
      }
    case double_e:
      {
	Float f2 = FloatOfTerm(t2);
	RFLOAT(FloatOfTerm(t1)/f2);
      }
    case big_int_e:
#ifdef USE_GMP
      return Yap_gmp_fdiv_float_big(FloatOfTerm(t1), t2);
#endif
    default:
      RERROR();
    }
    break;
  case big_int_e:
#ifdef USE_GMP
    switch (ETypeOfTerm(t2)) {
    case long_int_e:
      return Yap_gmp_fdiv_big_int(t1, IntegerOfTerm(t2));
    case big_int_e:
      /* two bignums*/
      return Yap_gmp_fdiv_big_big(t1, t2);
    case double_e:
      return Yap_gmp_fdiv_big_float(t1, FloatOfTerm(t2));
    default:
      RERROR();
    }
#endif
  default:
    RERROR();
  }
  RERROR();
}
Ejemplo n.º 9
0
static gpointer marshall_value(CORBA_TypeCode tc, VALUE value, char *pool, int* pool_pos, int out) {
	while (tc->kind == CORBA_tk_alias)
		tc = tc->subtypes[0];

	switch (tc->kind) {
		case CORBA_tk_wchar:
		case CORBA_tk_wstring: {
			rb_raise(eCorbaError, "Wide char unsupported");
			break;
		}
		case CORBA_tk_char:
		case CORBA_tk_octet: {
			char *val = ALLOCATE_FOR(char);
			if(T_FIXNUM == TYPE(value)) {
				*val = (char)NUM2INT(value);
			} else if (cLong == rb_class_of(value)) {
				*val = (char)DATA_PTR(value);
			} else {
				rb_raise(rb_eTypeError, "wrong type argument %s (expected Fixnum or ORBit2::Long)", rb_obj_classname(value));
			}
			return val;
		}
		case CORBA_tk_string: {
			Check_Type(value, T_STRING);
			char **val = ALLOCATE_FOR(char *);
			*val = CORBA_string_dup(STR(value));
			return val;
		}
		case CORBA_tk_ushort:
		case CORBA_tk_short: {
			short *val = ALLOCATE_FOR(short);
			if(T_FIXNUM == TYPE(value)) {
				*(short *)(val) = (short)FIX2INT(value);
			} else if(cLong == rb_class_of(value)){
				*(short *)(val) = (short)(long)DATA_PTR(value);
			} else {
				rb_raise(rb_eTypeError, "wrong type argument %s (expected Fixnum or ORBit2::Long)", rb_obj_classname(value));
			}
			if(!out) return val;
			short **val_ptr = ALLOCATE_FOR(short *);
			*val_ptr = val;
			return val_ptr;
		}
		case CORBA_tk_enum:
		case CORBA_tk_long:
		case CORBA_tk_ulong: {
			long *val = ALLOCATE_FOR(long);
			if(T_FIXNUM == TYPE(value)) {
				*(long *)(val) = FIX2INT(value);
			} else if (cLong == rb_class_of(value)) {
				*(long *)(val) = (long)DATA_PTR(value);
			} else {
				rb_raise(rb_eTypeError, "wrong type argument %s (expected Fixnum or ORBit2::Long)", rb_obj_classname(value));
			}
			if(!out) return val;
			long **val_ptr = ALLOCATE_FOR(long *);
			*val_ptr = val;
			return val_ptr;
		}
		case CORBA_tk_longlong:
		case CORBA_tk_ulonglong: {
			rb_raise(eCorbaError, "Long Long unsupported");
		}
		case CORBA_tk_double: {
			double *val = ALLOCATE_FOR(double);
			if(T_FLOAT == TYPE(value)) {
				*val = RFLOAT(value)->value;
			} else if(T_FIXNUM == TYPE(value)) {
				*val = (double)NUM2INT(value);
			} else if(cLong = rb_class_of(value)) {
				*val = (double)(long)DATA_PTR(value);
			} else {
				rb_raise(rb_eTypeError, "wrong type argument %s (expected Float, Fixnum or ORBit2::Long)", rb_obj_classname(value));
			}
			if(!out) return val;
			double **val_ptr = ALLOCATE_FOR(double *);
			*val_ptr = val;
			return val_ptr;
		}
		case CORBA_tk_longdouble: {
			rb_raise(eCorbaError, "Long double unsupported");
		}
		case CORBA_tk_float: {
			Check_Type(value, T_FLOAT);
			float *val = ALLOCATE_FOR(float);
			*val = (float)RFLOAT(value)->value;
			if(!out) return val;
			float **val_ptr = ALLOCATE_FOR(float *);
			*val_ptr = val;
			return val_ptr;
		}
		case CORBA_tk_null:
		case CORBA_tk_void: {
			return NULL;
			break;
		}
		case CORBA_tk_any: {
			CORBA_any *encoded = ALLOCATE_FOR(CORBA_any);
			encoded->_type = TC_null;
			encoded->_value = NULL;
			encoded->_release = 0;
			if(T_FIXNUM == TYPE(value) || cLong == rb_class_of(value)) {
				encoded->_type = TC_CORBA_long;
				encoded->_value = ALLOCATE_FOR(long);
				if(T_FIXNUM == TYPE(value)) {
					*(long *)(encoded->_value) = FIX2INT(value);
				} else {
					*(long *)(encoded->_value) = (long)DATA_PTR(value);
				}
			} else if (T_STRING == TYPE(value)) {
				encoded->_type = TC_CORBA_string;
				encoded->_value = ALLOCATE_FOR(char *);
				*(char **)(encoded->_value) = STR(value);
			}
Ejemplo n.º 10
0
static Term
eval0(Int fi) {
  CACHE_REGS
  arith0_op fop = fi;
  switch (fop) {
  case op_pi:
    {
      RFLOAT(PI);
    }
  case op_e:
    {
      RFLOAT(M_E);
    }
  case op_epsilon:
    {
      RFLOAT(DBL_EPSILON);
    }
  case op_inf:
    {
#ifdef _MSC_VER /* Microsoft's Visual C++ Compiler */
      Yap_ArithError(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
      P = (yamop *)FAILCODE;
      RERROR();
#else
      if (isoLanguageFlag()) {/* iso */
	Yap_ArithError(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
	P = (yamop *)FAILCODE;
	RERROR();
      } else {
	RFLOAT(INFINITY);
      }
#endif
    }
  case op_nan:
    {
#ifdef _MSC_VER /* Microsoft's Visual C++ Compi<ler */
      Yap_ArithError(TYPE_ERROR_EVALUABLE, TermNil, "evaluating infinity");
      RERROR();
#else
      if (isoLanguageFlag()) {/* iso */
	Yap_ArithError(TYPE_ERROR_EVALUABLE, TermNil, "evaluating not-a-number");
	RERROR();
      } else {
	RFLOAT(NAN);
      }
#endif
    }
  case op_random:
    {
      RFLOAT(Yap_random());
    }
  case op_cputime:
    {
      RFLOAT((Float)Yap_cputime()/1000.0);
    }
  case op_heapused:
    /// - heapused
    ///   Heap (data-base) space used, in bytes.
    ///
    RINT(HeapUsed);
  case op_localsp:
    /// - local
    ///   Local stack in use, in bytes
    ///
#if YAPOR_SBA
    RINT((Int)ASP);
#else
    RINT(LCL0 - ASP);
#endif
  case op_b:
    /// - $b
    ///   current choicepoint
    ///
#if YAPOR_SBA
    RINT((Int)B);
#else
    RINT(LCL0 - (CELL *)B);
#endif
  case op_env:
    /// - $env
    ///   Environment
    ///
#if YAPOR_SBA
    RINT((Int)YENV);
#else
    RINT(LCL0 - YENV);
#endif
  case op_tr:
    /// - $tr
    ///   Trail in use
    ///
#if YAPOR_SBA
    RINT(TR);
#else
    RINT(((CELL *)TR)-LCL0);
#endif
  case op_stackfree:
    /// - $free_stack
    ///   
    /// Not-a-number according to the IEEE Floating-Point standard. Note that evaluating this term will generate a domain error in the `iso` language mode.
    RINT(Unsigned(ASP) - Unsigned(HR));
  case op_globalsp:
    /// - global
    ///   Global stack in use, in bytes.
    ///
#if YAPOR_SBA
    RINT((Int)HR);
#else
    RINT(HR - H0);
#endif
  }
  /// end of switch
  RERROR();
}
Ejemplo n.º 11
0
static void query_bind_one_param(h_query query, int index, VALUE obj) {
	int sql_type;
    RUN(cbind_query_get_par_sql_type(query, index, &sql_type));

    switch (sql_type) {
        case SQL_CHAR:
        case SQL_VARCHAR:
        case SQL_LONGVARCHAR: {
			VALUE str = rb_funcall(obj, rb_intern("to_s"), 0);
            RUN(cbind_query_set_mb_str_par(query, index, STR(str), LEN(str)));
            break;
        }
        case SQL_BINARY:
        case SQL_LONGVARBINARY:
        case SQL_VARBINARY: {
			VALUE str = rb_funcall(obj, rb_intern("to_s"), 0);
            RUN(cbind_query_set_bin_par(query, index, STR(str), LEN(str)));
            break;
        }
        case SQL_TINYINT:
        case SQL_SMALLINT:
        case SQL_INTEGER:
        case SQL_BIGINT:
        case SQL_BIT:
        {
			VALUE num = rb_funcall(obj, rb_intern("to_i"), 0);
            RUN(cbind_query_set_int_par(query, index, NUM2INT(num)));
            break;
        }
        case SQL_FLOAT:
        case SQL_DOUBLE:
        case SQL_REAL:
        case SQL_NUMERIC:
        case SQL_DECIMAL:
        {
			VALUE f = rb_funcall(obj, rb_intern("to_f"), 0);
            RUN(cbind_query_set_double_par(query, index, RFLOAT(f)->value));
            break;
        }
        case SQL_TIME:
        {
			int hour = NUM2INT(CALL(obj, "hour"));
			int minute = NUM2INT(CALL(obj, "min"));
			int second = NUM2INT(CALL(obj, "sec"));
			RUN(cbind_query_set_time_par(query, index, hour, minute, second));
            break;
        }
        case SQL_DATE:
        {
			int year = NUM2INT(CALL(obj, "year"));
			int month = NUM2INT(CALL(obj, "month"));
			int day = NUM2INT(CALL(obj, "day"));
			RUN(cbind_query_set_date_par(query, index, year, month, day));
            break;
        }
        case SQL_TIMESTAMP:
        {
			int year = NUM2INT(CALL(obj, "year"));
			int month = NUM2INT(CALL(obj, "month"));
			int day = NUM2INT(CALL(obj, "day"));
			int hour = NUM2INT(CALL(obj, "hour"));
			int minute = NUM2INT(CALL(obj, "min"));
			int second = NUM2INT(CALL(obj, "sec"));
			int fraction = 0;
		  	RUN(cbind_query_set_timestamp_par(query, index, 
					year, month, day, hour, minute, second, fraction));
            break;
        }

        default:
            rb_raise(cMarshallError, "unknown sql type %d for parameter N %d", sql_type, index);
    }
}
Ejemplo n.º 12
0
void
obj_dump(VALUE obj, yajl_gen gen)
{
  int type;
  yajl_gen_map_open(gen);

  yajl_gen_cstr(gen, "_id");
  yajl_gen_value(gen, obj);

  struct obj_track *tracker = NULL;
  if (st_lookup(objs, (st_data_t)obj, (st_data_t *)&tracker) && BUILTIN_TYPE(obj) != T_NODE) {
    yajl_gen_cstr(gen, "file");
    yajl_gen_cstr(gen, tracker->source);
    yajl_gen_cstr(gen, "line");
    yajl_gen_integer(gen, tracker->line);
  }

  yajl_gen_cstr(gen, "type");
  switch (type=BUILTIN_TYPE(obj)) {
    case T_DATA:
      yajl_gen_cstr(gen, "data");

      if (RBASIC(obj)->klass) {
        yajl_gen_cstr(gen, "class");
        yajl_gen_value(gen, RBASIC(obj)->klass);

        yajl_gen_cstr(gen, "class_name");
        VALUE name = rb_classname(RBASIC(obj)->klass);
        if (RTEST(name))
          yajl_gen_cstr(gen, RSTRING(name)->ptr);
        else
          yajl_gen_cstr(gen, 0);
      }
      break;

    case T_FILE:
      yajl_gen_cstr(gen, "file");
      break;

    case T_FLOAT:
      yajl_gen_cstr(gen, "float");

      yajl_gen_cstr(gen, "data");
      yajl_gen_double(gen, RFLOAT(obj)->value);
      break;

    case T_BIGNUM:
      yajl_gen_cstr(gen, "bignum");

      yajl_gen_cstr(gen, "negative");
      yajl_gen_bool(gen, RBIGNUM(obj)->sign == 0);

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RBIGNUM(obj)->len);

      yajl_gen_cstr(gen, "data");
      yajl_gen_string(gen, RBIGNUM(obj)->digits, RBIGNUM(obj)->len);
      break;

    case T_MATCH:
      yajl_gen_cstr(gen, "match");

      yajl_gen_cstr(gen, "data");
      yajl_gen_value(gen, RMATCH(obj)->str);
      break;

    case T_REGEXP:
      yajl_gen_cstr(gen, "regexp");

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RREGEXP(obj)->len);

      yajl_gen_cstr(gen, "data");
      yajl_gen_cstr(gen, RREGEXP(obj)->str);
      break;

    case T_SCOPE:
      yajl_gen_cstr(gen, "scope");

      struct SCOPE *scope = (struct SCOPE *)obj;
      if (scope->local_tbl) {
        int i = 1;
        int n = scope->local_tbl[0];
        VALUE *list = &scope->local_vars[-1];
        VALUE cur = *list++;

        yajl_gen_cstr(gen, "node");
        yajl_gen_value(gen, cur);

        if (n) {
          yajl_gen_cstr(gen, "variables");
          yajl_gen_map_open(gen);
          while (n--) {
            cur = *list++;
            yajl_gen_cstr(gen, scope->local_tbl[i] == 95 ? "_" : rb_id2name(scope->local_tbl[i]));
            yajl_gen_value(gen, cur);
            i++;
          }
          yajl_gen_map_close(gen);
        }
      }
      break;

    case T_NODE:
      yajl_gen_cstr(gen, "node");

      yajl_gen_cstr(gen, "node_type");
      yajl_gen_cstr(gen, nd_type_str(obj));

      yajl_gen_cstr(gen, "file");
      yajl_gen_cstr(gen, RNODE(obj)->nd_file);

      yajl_gen_cstr(gen, "line");
      yajl_gen_integer(gen, nd_line(obj));

      yajl_gen_cstr(gen, "node_code");
      yajl_gen_integer(gen, nd_type(obj));

      switch (nd_type(obj)) {
        case NODE_SCOPE:
          break;
      }
      break;

    case T_STRING:
      yajl_gen_cstr(gen, "string");

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, RSTRING(obj)->len);

      if (FL_TEST(obj, ELTS_SHARED|FL_USER3)) {
        yajl_gen_cstr(gen, "shared");
        yajl_gen_value(gen, RSTRING(obj)->aux.shared);

        yajl_gen_cstr(gen, "flags");
        yajl_gen_array_open(gen);
        if (FL_TEST(obj, ELTS_SHARED))
          yajl_gen_cstr(gen, "elts_shared");
        if (FL_TEST(obj, FL_USER3))
          yajl_gen_cstr(gen, "str_assoc");
        yajl_gen_array_close(gen);
      } else {
        yajl_gen_cstr(gen, "data");
        yajl_gen_string(gen, (unsigned char *)RSTRING(obj)->ptr, RSTRING(obj)->len);
      }
      break;

    case T_VARMAP:
      yajl_gen_cstr(gen, "varmap");

      struct RVarmap *vars = (struct RVarmap *)obj;

      if (vars->next) {
        yajl_gen_cstr(gen, "next");
        yajl_gen_value(gen, (VALUE)vars->next);
      }

      if (vars->id) {
        yajl_gen_cstr(gen, "data");
        yajl_gen_map_open(gen);
        yajl_gen_cstr(gen, rb_id2name(vars->id));
        yajl_gen_value(gen, vars->val);
        yajl_gen_map_close(gen);
      }
      break;

    case T_CLASS:
    case T_MODULE:
    case T_ICLASS:
      yajl_gen_cstr(gen, type==T_CLASS ? "class" : type==T_MODULE ? "module" : "iclass");

      yajl_gen_cstr(gen, "name");
      VALUE name = rb_classname(obj);
      if (RTEST(name))
        yajl_gen_cstr(gen, RSTRING(name)->ptr);
      else
        yajl_gen_cstr(gen, 0);

      yajl_gen_cstr(gen, "super");
      yajl_gen_value(gen, RCLASS(obj)->super);

      yajl_gen_cstr(gen, "super_name");
      VALUE super_name = rb_classname(RCLASS(obj)->super);
      if (RTEST(super_name))
        yajl_gen_cstr(gen, RSTRING(super_name)->ptr);
      else
        yajl_gen_cstr(gen, 0);

      if (FL_TEST(obj, FL_SINGLETON)) {
        yajl_gen_cstr(gen, "singleton");
        yajl_gen_bool(gen, 1);
      }

      if (RCLASS(obj)->iv_tbl && RCLASS(obj)->iv_tbl->num_entries) {
        yajl_gen_cstr(gen, "ivars");
        yajl_gen_map_open(gen);
        st_foreach(RCLASS(obj)->iv_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }

      if (type != T_ICLASS && RCLASS(obj)->m_tbl && RCLASS(obj)->m_tbl->num_entries) {
        yajl_gen_cstr(gen, "methods");
        yajl_gen_map_open(gen);
        st_foreach(RCLASS(obj)->m_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }
      break;

    case T_OBJECT:
      yajl_gen_cstr(gen, "object");

      yajl_gen_cstr(gen, "class");
      yajl_gen_value(gen, RBASIC(obj)->klass);

      yajl_gen_cstr(gen, "class_name");
      yajl_gen_cstr(gen, rb_obj_classname(obj));

      struct RClass *klass = RCLASS(obj);

      if (klass->iv_tbl && klass->iv_tbl->num_entries) {
        yajl_gen_cstr(gen, "ivars");
        yajl_gen_map_open(gen);
        st_foreach(klass->iv_tbl, each_ivar, (st_data_t)gen);
        yajl_gen_map_close(gen);
      }
      break;

    case T_ARRAY:
      yajl_gen_cstr(gen, "array");

      struct RArray *ary = RARRAY(obj);

      yajl_gen_cstr(gen, "length");
      yajl_gen_integer(gen, ary->len);

      if (FL_TEST(obj, ELTS_SHARED)) {
        yajl_gen_cstr(gen, "shared");
        yajl_gen_value(gen, ary->aux.shared);
      } else if (ary->len) {
        yajl_gen_cstr(gen, "data");
        yajl_gen_array_open(gen);
        int i;
        for(i=0; i < ary->len; i++)
          yajl_gen_value(gen, ary->ptr[i]);
        yajl_gen_array_close(gen);
      }
      break;

    case T_HASH:
      yajl_gen_cstr(gen, "hash");

      struct RHash *hash = RHASH(obj);

      yajl_gen_cstr(gen, "length");
      if (hash->tbl)
        yajl_gen_integer(gen, hash->tbl->num_entries);
      else
        yajl_gen_integer(gen, 0);

      yajl_gen_cstr(gen, "default");
      yajl_gen_value(gen, hash->ifnone);

      if (hash->tbl && hash->tbl->num_entries) {
        yajl_gen_cstr(gen, "data");
        //yajl_gen_map_open(gen);
        yajl_gen_array_open(gen);
        st_foreach(hash->tbl, each_hash_entry, (st_data_t)gen);
        yajl_gen_array_close(gen);
        //yajl_gen_map_close(gen);
      }
      break;

    default:
      yajl_gen_cstr(gen, "unknown");
  }

  yajl_gen_cstr(gen, "code");
  yajl_gen_integer(gen, BUILTIN_TYPE(obj));

  yajl_gen_map_close(gen);
}