Commit acdc2d1f authored by YAMAMOTO Masaya's avatar YAMAMOTO Masaya

Add MRB_WITHOUT_FLOAT

parent 679dfd75
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
/* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */ /* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */
//#define MRB_USE_FLOAT //#define MRB_USE_FLOAT
/* exclude floating point numbers */
//#define MRB_WITUOUT_FLOAT
/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */ /* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT64 */
//#define MRB_INT16 //#define MRB_INT16
...@@ -45,7 +48,7 @@ ...@@ -45,7 +48,7 @@
# endif # endif
#endif #endif
/* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT */ /* represent mrb_value in boxed double; conflict with MRB_USE_FLOAT and MRB_WITUOUT_FLOAT */
//#define MRB_NAN_BOXING //#define MRB_NAN_BOXING
/* define on big endian machines; used by MRB_NAN_BOXING */ /* define on big endian machines; used by MRB_NAN_BOXING */
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include "mrbconf.h" #include "mrbconf.h"
#ifndef MRB_WITHOUT_FLOAT
#ifndef FLT_EPSILON #ifndef FLT_EPSILON
#define FLT_EPSILON (1.19209290e-07f) #define FLT_EPSILON (1.19209290e-07f)
#endif #endif
...@@ -80,6 +81,7 @@ ...@@ -80,6 +81,7 @@
#else #else
#define MRB_FLOAT_EPSILON DBL_EPSILON #define MRB_FLOAT_EPSILON DBL_EPSILON
#endif #endif
#endif
#include "mruby/common.h" #include "mruby/common.h"
#include <mruby/value.h> #include <mruby/value.h>
...@@ -206,7 +208,9 @@ typedef struct mrb_state { ...@@ -206,7 +208,9 @@ typedef struct mrb_state {
struct RClass *hash_class; struct RClass *hash_class;
struct RClass *range_class; struct RClass *range_class;
#ifndef MRB_WITHOUT_FLOAT
struct RClass *float_class; struct RClass *float_class;
#endif
struct RClass *fixnum_class; struct RClass *fixnum_class;
struct RClass *true_class; struct RClass *true_class;
struct RClass *false_class; struct RClass *false_class;
...@@ -1056,7 +1060,9 @@ MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value); ...@@ -1056,7 +1060,9 @@ MRB_API mrb_bool mrb_obj_equal(mrb_state*, mrb_value, mrb_value);
MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base); MRB_API mrb_value mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base);
MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_Integer(mrb_state *mrb, mrb_value val);
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_Float(mrb_state *mrb, mrb_value val);
#endif
MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj);
MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2);
...@@ -1146,7 +1152,9 @@ MRB_API void mrb_print_error(mrb_state *mrb); ...@@ -1146,7 +1152,9 @@ MRB_API void mrb_print_error(mrb_state *mrb);
#define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError")) #define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError"))
#define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) #define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError"))
#ifndef MRB_WITHOUT_FLOAT
#define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) #define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError"))
#endif
#define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError")) #define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError"))
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
# error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<---- # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<----
#endif #endif
#ifdef MRB_WITHOUT_FLOAT
# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<----
#endif
#ifdef MRB_INT64 #ifdef MRB_INT64
# error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<---- # error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<----
#endif #endif
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
typedef struct mrb_value { typedef struct mrb_value {
union { union {
#ifndef MRB_WITHOUT_FLOAT
mrb_float f; mrb_float f;
#endif
void *p; void *p;
mrb_int i; mrb_int i;
mrb_sym sym; mrb_sym sym;
...@@ -20,11 +22,15 @@ typedef struct mrb_value { ...@@ -20,11 +22,15 @@ typedef struct mrb_value {
enum mrb_vtype tt; enum mrb_vtype tt;
} mrb_value; } mrb_value;
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) #define mrb_float_pool(mrb,f) mrb_float_value(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p #define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) mrb_ptr(o) #define mrb_cptr(o) mrb_ptr(o)
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.f #define mrb_float(o) (o).value.f
#endif
#define mrb_fixnum(o) (o).value.i #define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym #define mrb_symbol(o) (o).value.sym
#define mrb_type(o) (o).tt #define mrb_type(o) (o).tt
...@@ -39,7 +45,9 @@ typedef struct mrb_value { ...@@ -39,7 +45,9 @@ typedef struct mrb_value {
#define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1) #define SET_TRUE_VALUE(r) BOXNIX_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
#define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1) #define SET_BOOL_VALUE(r,b) BOXNIX_SET_VALUE(r, b ? MRB_TT_TRUE : MRB_TT_FALSE, value.i, 1)
#define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n)) #define SET_INT_VALUE(r,n) BOXNIX_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#ifndef MRB_WITHOUT_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v)) #define SET_FLOAT_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
#endif
#define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v)) #define SET_SYM_VALUE(r,v) BOXNIX_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
#define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v)) #define SET_OBJ_VALUE(r,v) BOXNIX_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
#define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v) #define SET_CPTR_VALUE(mrb,r,v) BOXNIX_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
......
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode. #error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
#endif #endif
#ifndef MRB_WITHOUT_FLOAT
struct RFloat { struct RFloat {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
mrb_float f; mrb_float f;
}; };
#endif
struct RCptr { struct RCptr {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
...@@ -26,7 +28,11 @@ struct RCptr { ...@@ -26,7 +28,11 @@ struct RCptr {
}; };
#define MRB_FIXNUM_SHIFT 1 #define MRB_FIXNUM_SHIFT 1
#ifdef MRB_WITHOUT_FLOAT
#define MRB_TT_HAS_BASIC MRB_TT_CPTR
#else
#define MRB_TT_HAS_BASIC MRB_TT_FLOAT #define MRB_TT_HAS_BASIC MRB_TT_FLOAT
#endif
enum mrb_special_consts { enum mrb_special_consts {
MRB_Qnil = 0, MRB_Qnil = 0,
...@@ -51,21 +57,29 @@ typedef union mrb_value { ...@@ -51,21 +57,29 @@ typedef union mrb_value {
mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT); mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT);
}; };
struct RBasic *bp; struct RBasic *bp;
#ifndef MRB_WITHOUT_FLOAT
struct RFloat *fp; struct RFloat *fp;
#endif
struct RCptr *vp; struct RCptr *vp;
} value; } value;
unsigned long w; unsigned long w;
} mrb_value; } mrb_value;
MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*); MRB_API mrb_value mrb_word_boxing_cptr_value(struct mrb_state*, void*);
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float); MRB_API mrb_value mrb_word_boxing_float_value(struct mrb_state*, mrb_float);
MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float); MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#endif
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f) #define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f)
#endif
#define mrb_ptr(o) (o).value.p #define mrb_ptr(o) (o).value.p
#define mrb_cptr(o) (o).value.vp->p #define mrb_cptr(o) (o).value.vp->p
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float(o) (o).value.fp->f #define mrb_float(o) (o).value.fp->f
#endif
#define mrb_fixnum(o) ((mrb_int)(o).value.i) #define mrb_fixnum(o) ((mrb_int)(o).value.i)
#define mrb_symbol(o) (o).value.sym #define mrb_symbol(o) (o).value.sym
...@@ -106,7 +120,9 @@ mrb_type(mrb_value o) ...@@ -106,7 +120,9 @@ mrb_type(mrb_value o)
}\ }\
} while (0) } while (0)
#ifndef MRB_WITHOUT_FLOAT
#define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v) #define SET_FLOAT_VALUE(mrb,r,v) r = mrb_word_boxing_float_value(mrb, v)
#endif
#define SET_CPTR_VALUE(mrb,r,v) r = mrb_word_boxing_cptr_value(mrb, v) #define SET_CPTR_VALUE(mrb,r,v) r = mrb_word_boxing_cptr_value(mrb, v)
#define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0) #define SET_NIL_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
#define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1) #define SET_FALSE_VALUE(r) BOXWORD_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
......
...@@ -40,8 +40,10 @@ mrb_class(mrb_state *mrb, mrb_value v) ...@@ -40,8 +40,10 @@ mrb_class(mrb_state *mrb, mrb_value v)
return mrb->symbol_class; return mrb->symbol_class;
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
return mrb->fixnum_class; return mrb->fixnum_class;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
return mrb->float_class; return mrb->float_class;
#endif
case MRB_TT_CPTR: case MRB_TT_CPTR:
return mrb->object_class; return mrb->object_class;
case MRB_TT_ENV: case MRB_TT_ENV:
......
...@@ -165,7 +165,9 @@ struct mrb_parser_state { ...@@ -165,7 +165,9 @@ struct mrb_parser_state {
MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*); MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
MRB_API void mrb_parser_free(struct mrb_parser_state*); MRB_API void mrb_parser_free(struct mrb_parser_state*);
MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*); MRB_API void mrb_parser_parse(struct mrb_parser_state*,mrbc_context*);
#ifndef MRB_WITHOUT_FLOAT
MRB_API double mrb_float_read(const char*, char**); MRB_API double mrb_float_read(const char*, char**);
#endif
MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*); MRB_API void mrb_parser_set_filename(struct mrb_parser_state*, char const*);
MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx);
......
...@@ -22,13 +22,19 @@ MRB_BEGIN_DECL ...@@ -22,13 +22,19 @@ MRB_BEGIN_DECL
#define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int) #define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int)
#define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int) #define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int)
#define FIXABLE(f) TYPED_FIXABLE(f,mrb_int) #define FIXABLE(f) TYPED_FIXABLE(f,mrb_int)
#ifndef MRB_WITHOUT_FLOAT
#define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,double) #define FIXABLE_FLOAT(f) TYPED_FIXABLE(f,double)
#endif
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val); MRB_API mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val);
#endif
MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base); MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */ /* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt); MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x); MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
#endif
mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y);
mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y);
......
...@@ -63,12 +63,14 @@ struct mrb_state; ...@@ -63,12 +63,14 @@ struct mrb_state;
#endif #endif
#ifndef MRB_WITHOUT_FLOAT
MRB_API double mrb_float_read(const char*, char**); MRB_API double mrb_float_read(const char*, char**);
#ifdef MRB_USE_FLOAT #ifdef MRB_USE_FLOAT
typedef float mrb_float; typedef float mrb_float;
#else #else
typedef double mrb_float; typedef double mrb_float;
#endif #endif
#endif
#if defined _MSC_VER && _MSC_VER < 1900 #if defined _MSC_VER && _MSC_VER < 1900
# ifndef __cplusplus # ifndef __cplusplus
...@@ -79,7 +81,7 @@ MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list ar ...@@ -79,7 +81,7 @@ MRB_API int mrb_msvc_vsnprintf(char *s, size_t n, const char *format, va_list ar
MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...); MRB_API int mrb_msvc_snprintf(char *s, size_t n, const char *format, ...);
# define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg) # define vsnprintf(s, n, format, arg) mrb_msvc_vsnprintf(s, n, format, arg)
# define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__) # define snprintf(s, n, format, ...) mrb_msvc_snprintf(s, n, format, __VA_ARGS__)
# if _MSC_VER < 1800 # if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT
# include <float.h> # include <float.h>
# define isfinite(n) _finite(n) # define isfinite(n) _finite(n)
# define isnan _isnan # define isnan _isnan
...@@ -158,7 +160,9 @@ typedef void mrb_value; ...@@ -158,7 +160,9 @@ typedef void mrb_value;
#ifndef mrb_bool #ifndef mrb_bool
#define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE)
#endif #endif
#ifndef MRB_WITHOUT_FLOAT
#define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT) #define mrb_float_p(o) (mrb_type(o) == MRB_TT_FLOAT)
#endif
#define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL) #define mrb_symbol_p(o) (mrb_type(o) == MRB_TT_SYMBOL)
#define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY) #define mrb_array_p(o) (mrb_type(o) == MRB_TT_ARRAY)
#define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING) #define mrb_string_p(o) (mrb_type(o) == MRB_TT_STRING)
...@@ -171,6 +175,7 @@ MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value); ...@@ -171,6 +175,7 @@ MRB_API mrb_bool mrb_regexp_p(struct mrb_state*, mrb_value);
/* /*
* Returns a float in Ruby. * Returns a float in Ruby.
*/ */
#ifndef MRB_WITHOUT_FLOAT
MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
{ {
mrb_value v; mrb_value v;
...@@ -178,6 +183,7 @@ MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) ...@@ -178,6 +183,7 @@ MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f)
SET_FLOAT_VALUE(mrb, v, f); SET_FLOAT_VALUE(mrb, v, f);
return v; return v;
} }
#endif
static inline mrb_value static inline mrb_value
mrb_cptr_value(struct mrb_state *mrb, void *p) mrb_cptr_value(struct mrb_state *mrb, void *p)
......
...@@ -460,6 +460,7 @@ new_lit(codegen_scope *s, mrb_value val) ...@@ -460,6 +460,7 @@ new_lit(codegen_scope *s, mrb_value val)
return i; return i;
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
for (i=0; i<s->irep->plen; i++) { for (i=0; i<s->irep->plen; i++) {
pv = &s->irep->pool[i]; pv = &s->irep->pool[i];
...@@ -467,6 +468,7 @@ new_lit(codegen_scope *s, mrb_value val) ...@@ -467,6 +468,7 @@ new_lit(codegen_scope *s, mrb_value val)
if (mrb_float(*pv) == mrb_float(val)) return i; if (mrb_float(*pv) == mrb_float(val)) return i;
} }
break; break;
#endif
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
for (i=0; i<s->irep->plen; i++) { for (i=0; i<s->irep->plen; i++) {
pv = &s->irep->pool[i]; pv = &s->irep->pool[i];
...@@ -492,10 +494,12 @@ new_lit(codegen_scope *s, mrb_value val) ...@@ -492,10 +494,12 @@ new_lit(codegen_scope *s, mrb_value val)
*pv = mrb_str_pool(s->mrb, val); *pv = mrb_str_pool(s->mrb, val);
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
*pv = mrb_float_pool(s->mrb, mrb_float(val)); *pv = mrb_float_pool(s->mrb, mrb_float(val));
break; break;
#endif
#endif #endif
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
*pv = val; *pv = val;
...@@ -1163,6 +1167,7 @@ raise_error(codegen_scope *s, const char *msg) ...@@ -1163,6 +1167,7 @@ raise_error(codegen_scope *s, const char *msg)
genop(s, MKOP_ABx(OP_ERR, 1, idx)); genop(s, MKOP_ABx(OP_ERR, 1, idx));
} }
#ifndef MRB_WITHOUT_FLOAT
static double static double
readint_float(codegen_scope *s, const char *p, int base) readint_float(codegen_scope *s, const char *p, int base)
{ {
...@@ -1188,6 +1193,7 @@ readint_float(codegen_scope *s, const char *p, int base) ...@@ -1188,6 +1193,7 @@ readint_float(codegen_scope *s, const char *p, int base)
} }
return f; return f;
} }
#endif
static mrb_int static mrb_int
readint_mrb_int(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow) readint_mrb_int(codegen_scope *s, const char *p, int base, mrb_bool neg, mrb_bool *overflow)
...@@ -2237,6 +2243,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2237,6 +2243,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_bool overflow; mrb_bool overflow;
i = readint_mrb_int(s, p, base, FALSE, &overflow); i = readint_mrb_int(s, p, base, FALSE, &overflow);
#ifndef MRB_WITHOUT_FLOAT
if (overflow) { if (overflow) {
double f = readint_float(s, p, base); double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(s->mrb, f)); int off = new_lit(s, mrb_float_value(s->mrb, f));
...@@ -2244,6 +2251,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2244,6 +2251,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
} }
else { else {
#endif
if (i < MAXARG_sBx && i > -MAXARG_sBx) { if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i); co = MKOP_AsBx(OP_LOADI, cursp(), i);
} }
...@@ -2252,11 +2260,14 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2252,11 +2260,14 @@ codegen(codegen_scope *s, node *tree, int val)
co = MKOP_ABx(OP_LOADL, cursp(), off); co = MKOP_ABx(OP_LOADL, cursp(), off);
} }
genop(s, co); genop(s, co);
#ifndef MRB_WITHOUT_FLOAT
} }
#endif
push(); push();
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case NODE_FLOAT: case NODE_FLOAT:
if (val) { if (val) {
char *p = (char*)tree; char *p = (char*)tree;
...@@ -2267,12 +2278,14 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2267,12 +2278,14 @@ codegen(codegen_scope *s, node *tree, int val)
push(); push();
} }
break; break;
#endif
case NODE_NEGATE: case NODE_NEGATE:
{ {
nt = nint(tree->car); nt = nint(tree->car);
tree = tree->cdr; tree = tree->cdr;
switch (nt) { switch (nt) {
#ifndef MRB_WITHOUT_FLOAT
case NODE_FLOAT: case NODE_FLOAT:
if (val) { if (val) {
char *p = (char*)tree; char *p = (char*)tree;
...@@ -2283,6 +2296,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2283,6 +2296,7 @@ codegen(codegen_scope *s, node *tree, int val)
push(); push();
} }
break; break;
#endif
case NODE_INT: case NODE_INT:
if (val) { if (val) {
...@@ -2293,6 +2307,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2293,6 +2307,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_bool overflow; mrb_bool overflow;
i = readint_mrb_int(s, p, base, TRUE, &overflow); i = readint_mrb_int(s, p, base, TRUE, &overflow);
#ifndef MRB_WITHOUT_FLOAT
if (overflow) { if (overflow) {
double f = readint_float(s, p, base); double f = readint_float(s, p, base);
int off = new_lit(s, mrb_float_value(s->mrb, -f)); int off = new_lit(s, mrb_float_value(s->mrb, -f));
...@@ -2300,6 +2315,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2300,6 +2315,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
} }
else { else {
#endif
if (i < MAXARG_sBx && i > -MAXARG_sBx) { if (i < MAXARG_sBx && i > -MAXARG_sBx) {
co = MKOP_AsBx(OP_LOADI, cursp(), i); co = MKOP_AsBx(OP_LOADI, cursp(), i);
} }
...@@ -2308,7 +2324,9 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2308,7 +2324,9 @@ codegen(codegen_scope *s, node *tree, int val)
co = MKOP_ABx(OP_LOADL, cursp(), off); co = MKOP_ABx(OP_LOADL, cursp(), off);
} }
genop(s, co); genop(s, co);
#ifndef MRB_WITHOUT_FLOAT
} }
#endif
push(); push();
} }
break; break;
......
...@@ -740,12 +740,14 @@ new_int(parser_state *p, const char *s, int base) ...@@ -740,12 +740,14 @@ new_int(parser_state *p, const char *s, int base)
return list3((node*)NODE_INT, (node*)strdup(s), nint(base)); return list3((node*)NODE_INT, (node*)strdup(s), nint(base));
} }
#ifndef MRB_WITHOUT_FLOAT
/* (:float . i) */ /* (:float . i) */
static node* static node*
new_float(parser_state *p, const char *s) new_float(parser_state *p, const char *s)
{ {
return cons((node*)NODE_FLOAT, (node*)strdup(s)); return cons((node*)NODE_FLOAT, (node*)strdup(s));
} }
#endif
/* (:str . (s . len)) */ /* (:str . (s . len)) */
static node* static node*
...@@ -4962,6 +4964,11 @@ parser_yylex(parser_state *p) ...@@ -4962,6 +4964,11 @@ parser_yylex(parser_state *p)
} }
tokfix(p); tokfix(p);
if (is_float) { if (is_float) {
#ifdef MRB_WITHOUT_FLOAT
yywarning_s(p, "floating point numbers are not supported", tok(p));
pylval.nd = new_int(p, "0", 10);
return tINTEGER;
#else
double d; double d;
char *endp; char *endp;
...@@ -4976,6 +4983,7 @@ parser_yylex(parser_state *p) ...@@ -4976,6 +4983,7 @@ parser_yylex(parser_state *p)
} }
pylval.nd = new_float(p, tok(p)); pylval.nd = new_float(p, tok(p));
return tFLOAT; return tFLOAT;
#endif
} }
pylval.nd = new_int(p, tok(p), 10); pylval.nd = new_int(p, tok(p), 10);
return tINTEGER; return tINTEGER;
......
##
# Float
#
# ISO 15.2.9
class Float
# mruby special - since mruby integers may be upgraded to floats,
# floats should be compatible to integers.
include Integral
end
...@@ -8,6 +8,9 @@ MRuby.each_target do ...@@ -8,6 +8,9 @@ MRuby.each_target do
file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c" file objfile("#{current_build_dir}/mrblib") => "#{current_build_dir}/mrblib.c"
file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t| file "#{current_build_dir}/mrblib.c" => [mrbcfile, __FILE__] + Dir.glob("#{current_dir}/*.rb").sort do |t|
_, _, *rbfiles = t.prerequisites _, _, *rbfiles = t.prerequisites
if self.cc.defines.flatten.include?("MRB_WITHOUT_FLOAT")
rbfiles.delete("#{current_dir}/float.rb")
end
FileUtils.mkdir_p File.dirname(t.name) FileUtils.mkdir_p File.dirname(t.name)
open(t.name, 'w') do |f| open(t.name, 'w') do |f|
_pp "GEN", "*.rb", "#{t.name.relative_path}" _pp "GEN", "*.rb", "#{t.name.relative_path}"
......
...@@ -104,7 +104,7 @@ module Integral ...@@ -104,7 +104,7 @@ module Integral
raise ArgumentError, "step can't be 0" if step == 0 raise ArgumentError, "step can't be 0" if step == 0
return to_enum(:step, num, step) unless block return to_enum(:step, num, step) unless block
i = if num.kind_of? Float then self.to_f else self end i = if class_defined?("Float") && num.kind_of?(Float) then self.to_f else self end
if num == nil if num == nil
while true while true
block.call(i) block.call(i)
...@@ -161,13 +161,3 @@ class Integer ...@@ -161,13 +161,3 @@ class Integer
# ISO 15.2.8.3.26 # ISO 15.2.8.3.26
alias truncate floor alias truncate floor
end end
##
# Float
#
# ISO 15.2.9
class Float
# mruby special - since mruby integers may be upgraded to floats,
# floats should be compatible to integers.
include Integral
end
...@@ -767,9 +767,11 @@ aget_index(mrb_state *mrb, mrb_value index) ...@@ -767,9 +767,11 @@ aget_index(mrb_state *mrb, mrb_value index)
if (mrb_fixnum_p(index)) { if (mrb_fixnum_p(index)) {
return mrb_fixnum(index); return mrb_fixnum(index);
} }
#ifndef MRB_WITHOUT_FLOAT
else if (mrb_float_p(index)) { else if (mrb_float_p(index)) {
return (mrb_int)mrb_float(index); return (mrb_int)mrb_float(index);
} }
#endif
else { else {
mrb_int i, argc; mrb_int i, argc;
mrb_value *argv; mrb_value *argv;
......
...@@ -804,6 +804,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -804,6 +804,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
} }
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case 'f': case 'f':
{ {
mrb_float *p; mrb_float *p;
...@@ -816,6 +817,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -816,6 +817,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
} }
} }
break; break;
#endif
case 'i': case 'i':
{ {
mrb_int *p; mrb_int *p;
...@@ -826,6 +828,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -826,6 +828,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
*p = mrb_fixnum(ARGV[arg_i]); *p = mrb_fixnum(ARGV[arg_i]);
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
{ {
mrb_float f = mrb_float(ARGV[arg_i]); mrb_float f = mrb_float(ARGV[arg_i]);
...@@ -836,6 +839,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ...@@ -836,6 +839,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
*p = (mrb_int)f; *p = (mrb_int)f;
} }
break; break;
#endif
case MRB_TT_STRING: case MRB_TT_STRING:
mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
break; break;
...@@ -1277,9 +1281,11 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v) ...@@ -1277,9 +1281,11 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v)
return mrb_obj_value(mrb->object_class); return mrb_obj_value(mrb->object_class);
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
return mrb_nil_value(); /* not reached */ return mrb_nil_value(); /* not reached */
#endif
default: default:
break; break;
} }
......
...@@ -15,11 +15,13 @@ ...@@ -15,11 +15,13 @@
#define FLAG_BYTEORDER_NATIVE 2 #define FLAG_BYTEORDER_NATIVE 2
#define FLAG_BYTEORDER_NONATIVE 0 #define FLAG_BYTEORDER_NONATIVE 0
#ifndef MRB_WITHOUT_FLOAT
#ifdef MRB_USE_FLOAT #ifdef MRB_USE_FLOAT
#define MRB_FLOAT_FMT "%.8e" #define MRB_FLOAT_FMT "%.8e"
#else #else
#define MRB_FLOAT_FMT "%.16e" #define MRB_FLOAT_FMT "%.16e"
#endif #endif
#endif
static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep);
...@@ -131,6 +133,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) ...@@ -131,6 +133,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
{ {
...@@ -139,6 +142,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) ...@@ -139,6 +142,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
size += (size_t)len; size += (size_t)len;
} }
break; break;
#endif
case MRB_TT_STRING: case MRB_TT_STRING:
{ {
...@@ -177,10 +181,12 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) ...@@ -177,10 +181,12 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf)
str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10);
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */
str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT);
break; break;
#endif
case MRB_TT_STRING: case MRB_TT_STRING:
cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */
......
...@@ -87,14 +87,20 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) ...@@ -87,14 +87,20 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name)
} }
MRB_API mrb_int MRB_API mrb_int
#ifdef MRB_WITHOUT_FLOAT
mrb_fixnum_id(mrb_int f)
#else
mrb_float_id(mrb_float f) mrb_float_id(mrb_float f)
#endif
{ {
const char *p = (const char*)&f; const char *p = (const char*)&f;
int len = sizeof(f); int len = sizeof(f);
uint32_t id = 0; uint32_t id = 0;
#ifndef MRB_WITHOUT_FLOAT
/* normalize -0.0 to 0.0 */ /* normalize -0.0 to 0.0 */
if (f == 0) f = 0.0; if (f == 0) f = 0.0;
#endif
while (len--) { while (len--) {
id = id*65599 + *p; id = id*65599 + *p;
p++; p++;
...@@ -125,9 +131,13 @@ mrb_obj_id(mrb_value obj) ...@@ -125,9 +131,13 @@ mrb_obj_id(mrb_value obj)
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
return MakeID(mrb_symbol(obj)); return MakeID(mrb_symbol(obj));
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifdef MRB_WITHOUT_FLOAT
return MakeID(mrb_fixnum_id(mrb_fixnum(obj)));
#else
return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT); return MakeID2(mrb_float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
return MakeID(mrb_float_id(mrb_float(obj))); return MakeID(mrb_float_id(mrb_float(obj)));
#endif
case MRB_TT_STRING: case MRB_TT_STRING:
case MRB_TT_OBJECT: case MRB_TT_OBJECT:
case MRB_TT_CLASS: case MRB_TT_CLASS:
...@@ -148,6 +158,7 @@ mrb_obj_id(mrb_value obj) ...@@ -148,6 +158,7 @@ mrb_obj_id(mrb_value obj)
} }
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value MRB_API mrb_value
mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f) mrb_word_boxing_float_value(mrb_state *mrb, mrb_float f)
{ {
...@@ -167,6 +178,7 @@ mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f) ...@@ -167,6 +178,7 @@ mrb_word_boxing_float_pool(mrb_state *mrb, mrb_float f)
nf->f = f; nf->f = f;
return mrb_obj_value(nf); return mrb_obj_value(nf);
} }
#endif /* MRB_WITHOUT_FLOAT */
MRB_API mrb_value MRB_API mrb_value
mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) mrb_word_boxing_cptr_value(mrb_state *mrb, void *p)
......
...@@ -114,7 +114,9 @@ typedef struct { ...@@ -114,7 +114,9 @@ typedef struct {
struct RException exc; struct RException exc;
struct RBreak brk; struct RBreak brk;
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
#ifndef MRB_WITHOUT_FLOAT
struct RFloat floatv; struct RFloat floatv;
#endif
struct RCptr cptr; struct RCptr cptr;
#endif #endif
} as; } as;
...@@ -741,11 +743,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) ...@@ -741,11 +743,13 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
/* cannot happen */ /* cannot happen */
return; return;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
break; break;
#else #else
return; return;
#endif
#endif #endif
case MRB_TT_OBJECT: case MRB_TT_OBJECT:
...@@ -877,7 +881,9 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) ...@@ -877,7 +881,9 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc)
mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->range_class);
#ifndef MRB_WITHOUT_FLOAT
mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
#endif
mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class);
......
...@@ -12,8 +12,10 @@ ...@@ -12,8 +12,10 @@
#include <mruby/string.h> #include <mruby/string.h>
#include <mruby/variable.h> #include <mruby/variable.h>
#ifndef MRB_WITHOUT_FLOAT
/* a function to get hash value of a float number */ /* a function to get hash value of a float number */
mrb_int mrb_float_id(mrb_float f); mrb_int mrb_float_id(mrb_float f);
#endif
static inline khint_t static inline khint_t
mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
...@@ -31,7 +33,9 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) ...@@ -31,7 +33,9 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
case MRB_TT_FALSE: case MRB_TT_FALSE:
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#endif
h = (khint_t)mrb_obj_id(key); h = (khint_t)mrb_obj_id(key);
break; break;
...@@ -60,12 +64,15 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -60,12 +64,15 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
switch (mrb_type(b)) { switch (mrb_type(b)) {
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
return mrb_fixnum(a) == mrb_fixnum(b); return mrb_fixnum(a) == mrb_fixnum(b);
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
return (mrb_float)mrb_fixnum(a) == mrb_float(b); return (mrb_float)mrb_fixnum(a) == mrb_float(b);
#endif
default: default:
return FALSE; return FALSE;
} }
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
switch (mrb_type(b)) { switch (mrb_type(b)) {
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
...@@ -75,6 +82,7 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -75,6 +82,7 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b)
default: default:
return FALSE; return FALSE;
} }
#endif
default: default:
return mrb_eql(mrb, a, b); return mrb_eql(mrb, a, b);
......
...@@ -426,7 +426,9 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self) ...@@ -426,7 +426,9 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self)
case MRB_TT_TRUE: case MRB_TT_TRUE:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#endif
return self; return self;
default: default:
break; break;
...@@ -449,7 +451,9 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self) ...@@ -449,7 +451,9 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self)
case MRB_TT_TRUE: case MRB_TT_TRUE:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#endif
return mrb_true_value(); return mrb_true_value();
default: default:
break; break;
...@@ -878,6 +882,16 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) ...@@ -878,6 +882,16 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
return mrb_nil_value(); /* not reached */ return mrb_nil_value(); /* not reached */
} }
static mrb_value
mrb_krn_class_defined(mrb_state *mrb, mrb_value self)
{
mrb_value str;
mrb_get_args(mrb, "S", &str);
return mrb_bool_value(mrb_class_defined(mrb, RSTRING_PTR(str)));
}
/* 15.3.1.3.41 */ /* 15.3.1.3.41 */
/* /*
* call-seq: * call-seq:
...@@ -1233,6 +1247,8 @@ mrb_init_kernel(mrb_state *mrb) ...@@ -1233,6 +1247,8 @@ mrb_init_kernel(mrb_state *mrb)
mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */
mrb_define_method(mrb, krn, "class_defined?", mrb_krn_class_defined, MRB_ARGS_REQ(1));
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone"));
} }
...@@ -130,9 +130,11 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag ...@@ -130,9 +130,11 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag
irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE); irep->pool[i] = mrb_str_to_inum(mrb, s, 10, FALSE);
break; break;
#ifndef MRB_WITHOUT_FLOAT
case IREP_TT_FLOAT: case IREP_TT_FLOAT:
irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE));
break; break;
#endif
case IREP_TT_STRING: case IREP_TT_STRING:
irep->pool[i] = mrb_str_pool(mrb, s); irep->pool[i] = mrb_str_pool(mrb, s);
......
...@@ -5,6 +5,7 @@ MRuby.each_target do ...@@ -5,6 +5,7 @@ MRuby.each_target do
objs = Dir.glob("#{current_dir}/*.c").map { |f| objs = Dir.glob("#{current_dir}/*.c").map { |f|
next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/ next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/
next nil if self.cc.defines.flatten.include?("MRB_WITHOUT_FLOAT") and f =~ /fmt_fp.c$/
objfile(f.pathmap("#{current_build_dir}/%n")) objfile(f.pathmap("#{current_build_dir}/%n"))
}.compact }.compact
......
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
** See Copyright Notice in mruby.h ** See Copyright Notice in mruby.h
*/ */
#ifndef MRB_WITHOUT_FLOAT
#include <float.h> #include <float.h>
#include <limits.h>
#include <math.h> #include <math.h>
#endif
#include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <mruby.h> #include <mruby.h>
...@@ -15,6 +17,7 @@ ...@@ -15,6 +17,7 @@
#include <mruby/string.h> #include <mruby/string.h>
#include <mruby/class.h> #include <mruby/class.h>
#ifndef MRB_WITHOUT_FLOAT
#ifdef MRB_USE_FLOAT #ifdef MRB_USE_FLOAT
#define trunc(f) truncf(f) #define trunc(f) truncf(f)
#define floor(f) floorf(f) #define floor(f) floorf(f)
...@@ -24,7 +27,9 @@ ...@@ -24,7 +27,9 @@
#else #else
#define MRB_FLO_TO_STR_FMT "%.14g" #define MRB_FLO_TO_STR_FMT "%.14g"
#endif #endif
#endif
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_float MRB_API mrb_float
mrb_to_flo(mrb_state *mrb, mrb_value val) mrb_to_flo(mrb_state *mrb, mrb_value val)
{ {
...@@ -38,6 +43,7 @@ mrb_to_flo(mrb_state *mrb, mrb_value val) ...@@ -38,6 +43,7 @@ mrb_to_flo(mrb_state *mrb, mrb_value val)
} }
return mrb_float(val); return mrb_float(val);
} }
#endif
/* /*
* call-seq: * call-seq:
...@@ -52,7 +58,9 @@ static mrb_value ...@@ -52,7 +58,9 @@ static mrb_value
num_pow(mrb_state *mrb, mrb_value x) num_pow(mrb_state *mrb, mrb_value x)
{ {
mrb_value y; mrb_value y;
#ifndef MRB_WITHOUT_FLOAT
mrb_float d; mrb_float d;
#endif
mrb_get_args(mrb, "o", &y); mrb_get_args(mrb, "o", &y);
if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) { if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) {
...@@ -61,24 +69,37 @@ num_pow(mrb_state *mrb, mrb_value x) ...@@ -61,24 +69,37 @@ num_pow(mrb_state *mrb, mrb_value x)
mrb_int exp = mrb_fixnum(y); mrb_int exp = mrb_fixnum(y);
mrb_int result = 1; mrb_int result = 1;
if (exp < 0) goto float_pow; if (exp < 0)
#ifdef MRB_WITHOUT_FLOAT
return mrb_fixnum_value(0);
#else
goto float_pow;
#endif
for (;;) { for (;;) {
if (exp & 1) { if (exp & 1) {
if (mrb_int_mul_overflow(result, base, &result)) { if (mrb_int_mul_overflow(result, base, &result)) {
#ifndef MRB_WITHOUT_FLOAT
goto float_pow; goto float_pow;
#endif
} }
} }
exp >>= 1; exp >>= 1;
if (exp == 0) break; if (exp == 0) break;
if (mrb_int_mul_overflow(base, base, &base)) { if (mrb_int_mul_overflow(base, base, &base)) {
#ifndef MRB_WITHOUT_FLOAT
goto float_pow; goto float_pow;
#endif
} }
} }
return mrb_fixnum_value(result); return mrb_fixnum_value(result);
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
float_pow: float_pow:
d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
return mrb_float_value(mrb, d); return mrb_float_value(mrb, d);
#endif
} }
/* 15.2.8.3.4 */ /* 15.2.8.3.4 */
...@@ -95,7 +116,14 @@ num_pow(mrb_state *mrb, mrb_value x) ...@@ -95,7 +116,14 @@ num_pow(mrb_state *mrb, mrb_value x)
mrb_value mrb_value
mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
{ {
#ifdef MRB_WITHOUT_FLOAT
if (!mrb_fixnum_p(y)) {
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
}
return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
#else
return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y));
#endif
} }
/* 15.2.9.3.19(x) */ /* 15.2.9.3.19(x) */
...@@ -109,12 +137,23 @@ mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) ...@@ -109,12 +137,23 @@ mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y)
static mrb_value static mrb_value
num_div(mrb_state *mrb, mrb_value x) num_div(mrb_state *mrb, mrb_value x)
{ {
#ifdef MRB_WITHOUT_FLOAT
mrb_value y;
mrb_get_args(mrb, "o", &y);
if (!mrb_fixnum_p(y)) {
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
}
return mrb_fixnum_value(mrb_fixnum(x) / mrb_fixnum(y));
#else
mrb_float y; mrb_float y;
mrb_get_args(mrb, "f", &y); mrb_get_args(mrb, "f", &y);
return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y);
#endif
} }
#ifndef MRB_WITHOUT_FLOAT
/******************************************************************** /********************************************************************
* *
* Document-class: Float * Document-class: Float
...@@ -231,6 +270,7 @@ flo_mod(mrb_state *mrb, mrb_value x) ...@@ -231,6 +270,7 @@ flo_mod(mrb_state *mrb, mrb_value x)
flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod);
return mrb_float_value(mrb, mod); return mrb_float_value(mrb, mod);
} }
#endif
/* 15.2.8.3.16 */ /* 15.2.8.3.16 */
/* /*
...@@ -254,6 +294,7 @@ fix_eql(mrb_state *mrb, mrb_value x) ...@@ -254,6 +294,7 @@ fix_eql(mrb_state *mrb, mrb_value x)
return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
} }
#ifndef MRB_WITHOUT_FLOAT
static mrb_value static mrb_value
flo_eql(mrb_state *mrb, mrb_value x) flo_eql(mrb_state *mrb, mrb_value x)
{ {
...@@ -648,6 +689,7 @@ flo_nan_p(mrb_state *mrb, mrb_value num) ...@@ -648,6 +689,7 @@ flo_nan_p(mrb_state *mrb, mrb_value num)
{ {
return mrb_bool_value(isnan(mrb_float(num))); return mrb_bool_value(isnan(mrb_float(num)));
} }
#endif
/* /*
* Document-class: Integer * Document-class: Integer
...@@ -685,11 +727,17 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) ...@@ -685,11 +727,17 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
if (a == 0) return x; if (a == 0) return x;
b = mrb_fixnum(y); b = mrb_fixnum(y);
if (mrb_int_mul_overflow(a, b, &c)) { if (mrb_int_mul_overflow(a, b, &c)) {
#ifndef MRB_WITHOUT_FLOAT
return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b);
#endif
} }
return mrb_fixnum_value(c); return mrb_fixnum_value(c);
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y)); return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
#endif
} }
/* 15.2.8.3.3 */ /* 15.2.8.3.3 */
...@@ -761,17 +809,26 @@ fix_mod(mrb_state *mrb, mrb_value x) ...@@ -761,17 +809,26 @@ fix_mod(mrb_state *mrb, mrb_value x)
mrb_int b, mod; mrb_int b, mod;
if ((b=mrb_fixnum(y)) == 0) { if ((b=mrb_fixnum(y)) == 0) {
#ifdef MRB_WITHOUT_FLOAT
/* ZeroDivisionError */
return mrb_fixnum_value(0);
#else
return mrb_float_value(mrb, NAN); return mrb_float_value(mrb, NAN);
#endif
} }
fixdivmod(mrb, a, b, 0, &mod); fixdivmod(mrb, a, b, 0, &mod);
return mrb_fixnum_value(mod); return mrb_fixnum_value(mod);
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
else { else {
mrb_float mod; mrb_float mod;
flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod);
return mrb_float_value(mrb, mod); return mrb_float_value(mrb, mod);
} }
#endif
} }
/* /*
...@@ -791,14 +848,21 @@ fix_divmod(mrb_state *mrb, mrb_value x) ...@@ -791,14 +848,21 @@ fix_divmod(mrb_state *mrb, mrb_value x)
mrb_int div, mod; mrb_int div, mod;
if (mrb_fixnum(y) == 0) { if (mrb_fixnum(y) == 0) {
#ifdef MRB_WITHOUT_FLOAT
return mrb_assoc_new(mrb, mrb_fixnum_value(0), mrb_fixnum_value(0));
#else
return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ? return mrb_assoc_new(mrb, ((mrb_fixnum(x) == 0) ?
mrb_float_value(mrb, NAN): mrb_float_value(mrb, NAN):
mrb_float_value(mrb, INFINITY)), mrb_float_value(mrb, INFINITY)),
mrb_float_value(mrb, NAN)); mrb_float_value(mrb, NAN));
#endif
} }
fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod);
return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod));
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
else { else {
mrb_float div, mod; mrb_float div, mod;
mrb_value a, b; mrb_value a, b;
...@@ -808,8 +872,10 @@ fix_divmod(mrb_state *mrb, mrb_value x) ...@@ -808,8 +872,10 @@ fix_divmod(mrb_state *mrb, mrb_value x)
b = mrb_float_value(mrb, mod); b = mrb_float_value(mrb, mod);
return mrb_assoc_new(mrb, a, b); return mrb_assoc_new(mrb, a, b);
} }
#endif
} }
#ifndef MRB_WITHOUT_FLOAT
static mrb_value static mrb_value
flo_divmod(mrb_state *mrb, mrb_value x) flo_divmod(mrb_state *mrb, mrb_value x)
{ {
...@@ -824,6 +890,7 @@ flo_divmod(mrb_state *mrb, mrb_value x) ...@@ -824,6 +890,7 @@ flo_divmod(mrb_state *mrb, mrb_value x)
b = mrb_float_value(mrb, mod); b = mrb_float_value(mrb, mod);
return mrb_assoc_new(mrb, a, b); return mrb_assoc_new(mrb, a, b);
} }
#endif
/* 15.2.8.3.7 */ /* 15.2.8.3.7 */
/* /*
...@@ -846,8 +913,10 @@ fix_equal(mrb_state *mrb, mrb_value x) ...@@ -846,8 +913,10 @@ fix_equal(mrb_state *mrb, mrb_value x)
switch (mrb_type(y)) { switch (mrb_type(y)) {
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y));
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y));
#endif
default: default:
return mrb_false_value(); return mrb_false_value();
} }
...@@ -872,6 +941,11 @@ fix_rev(mrb_state *mrb, mrb_value num) ...@@ -872,6 +941,11 @@ fix_rev(mrb_state *mrb, mrb_value num)
return mrb_fixnum_value(~val); return mrb_fixnum_value(~val);
} }
#ifdef MRB_WITHOUT_FLOAT
#define bit_op(x,y,op1,op2) do {\
return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
} while(0)
#else
static mrb_value flo_and(mrb_state *mrb, mrb_value x); static mrb_value flo_and(mrb_state *mrb, mrb_value x);
static mrb_value flo_or(mrb_state *mrb, mrb_value x); static mrb_value flo_or(mrb_state *mrb, mrb_value x);
static mrb_value flo_xor(mrb_state *mrb, mrb_value x); static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
...@@ -879,6 +953,7 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x); ...@@ -879,6 +953,7 @@ static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\ if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\ return flo_ ## op1(mrb, mrb_float_value(mrb, (mrb_float)mrb_fixnum(x)));\
} while(0) } while(0)
#endif
/* 15.2.8.3.9 */ /* 15.2.8.3.9 */
/* /*
...@@ -937,23 +1012,36 @@ static mrb_value ...@@ -937,23 +1012,36 @@ static mrb_value
lshift(mrb_state *mrb, mrb_int val, mrb_int width) lshift(mrb_state *mrb, mrb_int val, mrb_int width)
{ {
if (width < 0) { /* mrb_int overflow */ if (width < 0) { /* mrb_int overflow */
#ifdef MRB_WITHOUT_FLOAT
return mrb_fixnum_value(0);
#else
return mrb_float_value(mrb, INFINITY); return mrb_float_value(mrb, INFINITY);
#endif
} }
if (val > 0) { if (val > 0) {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) || if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val > (MRB_INT_MAX >> width))) { (val > (MRB_INT_MAX >> width))) {
#ifdef MRB_WITHOUT_FLOAT
return mrb_fixnum_value(-1);
#else
goto bit_overflow; goto bit_overflow;
#endif
} }
return mrb_fixnum_value(val << width); return mrb_fixnum_value(val << width);
} }
else { else {
if ((width > NUMERIC_SHIFT_WIDTH_MAX) || if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
(val < (MRB_INT_MIN >> width))) { (val < (MRB_INT_MIN >> width))) {
#ifdef MRB_WITHOUT_FLOAT
return mrb_fixnum_value(0);
#else
goto bit_overflow; goto bit_overflow;
#endif
} }
return mrb_fixnum_value(val * ((mrb_int)1 << width)); return mrb_fixnum_value(val * ((mrb_int)1 << width));
} }
#ifndef MRB_WITHOUT_FLOAT
bit_overflow: bit_overflow:
{ {
mrb_float f = (mrb_float)val; mrb_float f = (mrb_float)val;
...@@ -962,6 +1050,7 @@ bit_overflow: ...@@ -962,6 +1050,7 @@ bit_overflow:
} }
return mrb_float_value(mrb, f); return mrb_float_value(mrb, f);
} }
#endif
} }
static mrb_value static mrb_value
...@@ -1038,6 +1127,7 @@ fix_rshift(mrb_state *mrb, mrb_value x) ...@@ -1038,6 +1127,7 @@ fix_rshift(mrb_state *mrb, mrb_value x)
* *
*/ */
#ifndef MRB_WITHOUT_FLOAT
static mrb_value static mrb_value
fix_to_f(mrb_state *mrb, mrb_value num) fix_to_f(mrb_state *mrb, mrb_value num)
{ {
...@@ -1085,6 +1175,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) ...@@ -1085,6 +1175,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
} }
return mrb_fixnum_value(z); return mrb_fixnum_value(z);
} }
#endif
mrb_value mrb_value
mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
...@@ -1098,11 +1189,17 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) ...@@ -1098,11 +1189,17 @@ mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y)
if (a == 0) return y; if (a == 0) return y;
b = mrb_fixnum(y); b = mrb_fixnum(y);
if (mrb_int_add_overflow(a, b, &c)) { if (mrb_int_add_overflow(a, b, &c)) {
#ifndef MRB_WITHOUT_FLOAT
return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b);
#endif
} }
return mrb_fixnum_value(c); return mrb_fixnum_value(c);
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y)); return mrb_float_value(mrb, (mrb_float)a + mrb_to_flo(mrb, y));
#endif
} }
/* 15.2.8.3.1 */ /* 15.2.8.3.1 */
...@@ -1134,11 +1231,17 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) ...@@ -1134,11 +1231,17 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y)
b = mrb_fixnum(y); b = mrb_fixnum(y);
if (mrb_int_sub_overflow(a, b, &c)) { if (mrb_int_sub_overflow(a, b, &c)) {
#ifndef MRB_WITHOUT_FLOAT
return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b);
#endif
} }
return mrb_fixnum_value(c); return mrb_fixnum_value(c);
} }
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value");
#else
return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y)); return mrb_float_value(mrb, (mrb_float)a - mrb_to_flo(mrb, y));
#endif
} }
/* 15.2.8.3.2 */ /* 15.2.8.3.2 */
...@@ -1230,18 +1333,32 @@ static mrb_value ...@@ -1230,18 +1333,32 @@ static mrb_value
num_cmp(mrb_state *mrb, mrb_value self) num_cmp(mrb_state *mrb, mrb_value self)
{ {
mrb_value other; mrb_value other;
#ifdef MRB_WITHOUT_FLOAT
mrb_int x, y;
#else
mrb_float x, y; mrb_float x, y;
#endif
mrb_get_args(mrb, "o", &other); mrb_get_args(mrb, "o", &other);
#ifdef MRB_WITHOUT_FLOAT
x = mrb_fixnum(self);
#else
x = mrb_to_flo(mrb, self); x = mrb_to_flo(mrb, self);
#endif
switch (mrb_type(other)) { switch (mrb_type(other)) {
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifdef MRB_WITHOUT_FLOAT
y = mrb_fixnum(other);
#else
y = (mrb_float)mrb_fixnum(other); y = (mrb_float)mrb_fixnum(other);
#endif
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
y = mrb_float(other); y = mrb_float(other);
break; break;
#endif
default: default:
return mrb_nil_value(); return mrb_nil_value();
} }
...@@ -1262,6 +1379,7 @@ num_cmp(mrb_state *mrb, mrb_value self) ...@@ -1262,6 +1379,7 @@ num_cmp(mrb_state *mrb, mrb_value self)
* Returns a new float which is the sum of <code>float</code> * Returns a new float which is the sum of <code>float</code>
* and <code>other</code>. * and <code>other</code>.
*/ */
#ifndef MRB_WITHOUT_FLOAT
static mrb_value static mrb_value
flo_plus(mrb_state *mrb, mrb_value x) flo_plus(mrb_state *mrb, mrb_value x)
{ {
...@@ -1270,12 +1388,16 @@ flo_plus(mrb_state *mrb, mrb_value x) ...@@ -1270,12 +1388,16 @@ flo_plus(mrb_state *mrb, mrb_value x)
mrb_get_args(mrb, "o", &y); mrb_get_args(mrb, "o", &y);
return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y));
} }
#endif
/* ------------------------------------------------------------------------*/ /* ------------------------------------------------------------------------*/
void void
mrb_init_numeric(mrb_state *mrb) mrb_init_numeric(mrb_state *mrb)
{ {
struct RClass *numeric, *integer, *fixnum, *fl; struct RClass *numeric, *integer, *fixnum;
#ifndef MRB_WITHOUT_FLOAT
struct RClass *fl;
#endif
/* Numeric Class */ /* Numeric Class */
numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ numeric = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */
...@@ -1291,10 +1413,12 @@ mrb_init_numeric(mrb_state *mrb) ...@@ -1291,10 +1413,12 @@ mrb_init_numeric(mrb_state *mrb)
mrb_undef_class_method(mrb, integer, "new"); mrb_undef_class_method(mrb, integer, "new");
mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */
mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE());
#ifndef MRB_WITHOUT_FLOAT
mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */ mrb_define_method(mrb, integer, "ceil", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */ mrb_define_method(mrb, integer, "floor", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */ mrb_define_method(mrb, integer, "round", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */
mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ mrb_define_method(mrb, integer, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */
#endif
/* Fixnum Class */ /* Fixnum Class */
mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer); mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer);
...@@ -1310,11 +1434,14 @@ mrb_init_numeric(mrb_state *mrb) ...@@ -1310,11 +1434,14 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, fixnum, "<<", fix_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */ mrb_define_method(mrb, fixnum, "<<", fix_lshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */ mrb_define_method(mrb, fixnum, ">>", fix_rshift, MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */ mrb_define_method(mrb, fixnum, "eql?", fix_eql, MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
#ifndef MRB_WITHOUT_FLOAT
mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */ mrb_define_method(mrb, fixnum, "to_f", fix_to_f, MRB_ARGS_NONE()); /* 15.2.8.3.23 */
#endif
mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */ mrb_define_method(mrb, fixnum, "to_s", fix_to_s, MRB_ARGS_NONE()); /* 15.2.8.3.25 */
mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, fixnum, "inspect", fix_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ mrb_define_method(mrb, fixnum, "divmod", fix_divmod, MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
#ifndef MRB_WITHOUT_FLOAT
/* Float Class */ /* Float Class */
mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */
MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT);
...@@ -1352,4 +1479,6 @@ mrb_init_numeric(mrb_state *mrb) ...@@ -1352,4 +1479,6 @@ mrb_init_numeric(mrb_state *mrb)
#ifdef NAN #ifdef NAN
mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN));
#endif #endif
#endif
mrb_define_module(mrb, "Integral");
} }
...@@ -24,8 +24,10 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) ...@@ -24,8 +24,10 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2)
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
return (mrb_symbol(v1) == mrb_symbol(v2)); return (mrb_symbol(v1) == mrb_symbol(v2));
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
return (mrb_float(v1) == mrb_float(v2)); return (mrb_float(v1) == mrb_float(v2));
#endif
default: default:
return (mrb_ptr(v1) == mrb_ptr(v2)); return (mrb_ptr(v1) == mrb_ptr(v2));
...@@ -373,7 +375,9 @@ static const struct types { ...@@ -373,7 +375,9 @@ static const struct types {
{MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */ {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */
{MRB_TT_SCLASS, "SClass"}, {MRB_TT_SCLASS, "SClass"},
{MRB_TT_PROC, "Proc"}, {MRB_TT_PROC, "Proc"},
#ifndef MRB_WITHOUT_FLOAT
{MRB_TT_FLOAT, "Float"}, {MRB_TT_FLOAT, "Float"},
#endif
{MRB_TT_ARRAY, "Array"}, {MRB_TT_ARRAY, "Array"},
{MRB_TT_HASH, "Hash"}, {MRB_TT_HASH, "Hash"},
{MRB_TT_STRING, "String"}, {MRB_TT_STRING, "String"},
...@@ -532,6 +536,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) ...@@ -532,6 +536,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base)
mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer"); mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
} }
switch (mrb_type(val)) { switch (mrb_type(val)) {
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
else { else {
...@@ -541,6 +546,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) ...@@ -541,6 +546,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base)
} }
} }
return mrb_flo_to_fixnum(mrb, val); return mrb_flo_to_fixnum(mrb, val);
#endif
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
if (base != 0) goto arg_error; if (base != 0) goto arg_error;
...@@ -575,6 +581,7 @@ mrb_Integer(mrb_state *mrb, mrb_value val) ...@@ -575,6 +581,7 @@ mrb_Integer(mrb_state *mrb, mrb_value val)
return mrb_convert_to_integer(mrb, val, 0); return mrb_convert_to_integer(mrb, val, 0);
} }
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value MRB_API mrb_value
mrb_Float(mrb_state *mrb, mrb_value val) mrb_Float(mrb_state *mrb, mrb_value val)
{ {
...@@ -595,6 +602,7 @@ mrb_Float(mrb_state *mrb, mrb_value val) ...@@ -595,6 +602,7 @@ mrb_Float(mrb_state *mrb, mrb_value val)
return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f"); return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
} }
} }
#endif
MRB_API mrb_value MRB_API mrb_value
mrb_inspect(mrb_state *mrb, mrb_value obj) mrb_inspect(mrb_state *mrb, mrb_value obj)
......
...@@ -30,8 +30,12 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -30,8 +30,12 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b)
ta = mrb_type(a); ta = mrb_type(a);
tb = mrb_type(b); tb = mrb_type(b);
#ifdef MRB_WITHOUT_FLOAT
if (ta == MRB_TT_FIXNUM && tb == MRB_TT_FIXNUM ) {
#else
if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) && if ((ta == MRB_TT_FIXNUM || ta == MRB_TT_FLOAT) &&
(tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) { (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) {
#endif
return; return;
} }
......
...@@ -164,7 +164,7 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) ...@@ -164,7 +164,7 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
} }
#ifdef MRB_WORD_BOXING #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
} }
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
# define _CRT_NONSTDC_NO_DEPRECATE # define _CRT_NONSTDC_NO_DEPRECATE
#endif #endif
#ifndef MRB_WITHOUT_FLOAT
#include <float.h> #include <float.h>
#endif
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -2284,6 +2286,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self) ...@@ -2284,6 +2286,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self)
return mrb_str_to_inum(mrb, self, base, FALSE); return mrb_str_to_inum(mrb, self, base, FALSE);
} }
#ifndef MRB_WITHOUT_FLOAT
MRB_API double MRB_API double
mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck)
{ {
...@@ -2387,6 +2390,7 @@ mrb_str_to_f(mrb_state *mrb, mrb_value self) ...@@ -2387,6 +2390,7 @@ mrb_str_to_f(mrb_state *mrb, mrb_value self)
{ {
return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE)); return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE));
} }
#endif
/* 15.2.10.5.40 */ /* 15.2.10.5.40 */
/* /*
...@@ -2788,7 +2792,9 @@ mrb_init_string(mrb_state *mrb) ...@@ -2788,7 +2792,9 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */ mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY()); /* 15.2.10.5.34 */
mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */ mrb_define_method(mrb, s, "split", mrb_str_split_m, MRB_ARGS_ANY()); /* 15.2.10.5.35 */
#ifndef MRB_WITHOUT_FLOAT
mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */ mrb_define_method(mrb, s, "to_f", mrb_str_to_f, MRB_ARGS_NONE()); /* 15.2.10.5.38 */
#endif
mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */ mrb_define_method(mrb, s, "to_i", mrb_str_to_i, MRB_ARGS_ANY()); /* 15.2.10.5.39 */
mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */ mrb_define_method(mrb, s, "to_s", mrb_str_to_s, MRB_ARGS_NONE()); /* 15.2.10.5.40 */
mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "to_str", mrb_str_to_s, MRB_ARGS_NONE());
...@@ -2799,6 +2805,7 @@ mrb_init_string(mrb_state *mrb) ...@@ -2799,6 +2805,7 @@ mrb_init_string(mrb_state *mrb)
mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE());
} }
#ifndef MRB_WITHOUT_FLOAT
/* /*
* Source code for the "strtod" library procedure. * Source code for the "strtod" library procedure.
* *
...@@ -3043,3 +3050,4 @@ done: ...@@ -3043,3 +3050,4 @@ done:
} }
return fraction; return fraction;
} }
#endif
...@@ -670,7 +670,9 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) ...@@ -670,7 +670,9 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
switch (mrb_type(self)) { switch (mrb_type(self)) {
case MRB_TT_SYMBOL: case MRB_TT_SYMBOL:
case MRB_TT_FIXNUM: case MRB_TT_FIXNUM:
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#endif
c = 0; c = 0;
break; break;
default: default:
...@@ -1005,9 +1007,11 @@ RETRY_TRY_BLOCK: ...@@ -1005,9 +1007,11 @@ RETRY_TRY_BLOCK:
int bx = GETARG_Bx(i); int bx = GETARG_Bx(i);
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
mrb_value val = pool[bx]; mrb_value val = pool[bx];
#ifndef MRB_WITHOUT_FLOAT
if (mrb_float_p(val)) { if (mrb_float_p(val)) {
val = mrb_float_value(mrb, mrb_float(val)); val = mrb_float_value(mrb, mrb_float(val));
} }
#endif
regs[a] = val; regs[a] = val;
#else #else
regs[a] = pool[bx]; regs[a] = pool[bx];
...@@ -2187,12 +2191,15 @@ RETRY_TRY_BLOCK: ...@@ -2187,12 +2191,15 @@ RETRY_TRY_BLOCK:
x = mrb_fixnum(regs_a[0]); x = mrb_fixnum(regs_a[0]);
y = mrb_fixnum(regs_a[1]); y = mrb_fixnum(regs_a[1]);
if (mrb_int_add_overflow(x, y, &z)) { if (mrb_int_add_overflow(x, y, &z)) {
#ifndef MRB_WITHOUT_FLOAT
SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
break; break;
#endif
} }
SET_INT_VALUE(regs[a], z); SET_INT_VALUE(regs[a], z);
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ {
mrb_int x = mrb_fixnum(regs[a]); mrb_int x = mrb_fixnum(regs[a]);
...@@ -2222,6 +2229,7 @@ RETRY_TRY_BLOCK: ...@@ -2222,6 +2229,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(+,mrb_float,mrb_float); OP_MATH_BODY(+,mrb_float,mrb_float);
#endif #endif
break; break;
#endif
case TYPES2(MRB_TT_STRING,MRB_TT_STRING): case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
break; break;
...@@ -2245,12 +2253,15 @@ RETRY_TRY_BLOCK: ...@@ -2245,12 +2253,15 @@ RETRY_TRY_BLOCK:
x = mrb_fixnum(regs[a]); x = mrb_fixnum(regs[a]);
y = mrb_fixnum(regs[a+1]); y = mrb_fixnum(regs[a+1]);
if (mrb_int_sub_overflow(x, y, &z)) { if (mrb_int_sub_overflow(x, y, &z)) {
#ifndef MRB_WITHOUT_FLOAT
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
break; break;
#endif
} }
SET_INT_VALUE(regs[a], z); SET_INT_VALUE(regs[a], z);
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ {
mrb_int x = mrb_fixnum(regs[a]); mrb_int x = mrb_fixnum(regs[a]);
...@@ -2280,6 +2291,7 @@ RETRY_TRY_BLOCK: ...@@ -2280,6 +2291,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(-,mrb_float,mrb_float); OP_MATH_BODY(-,mrb_float,mrb_float);
#endif #endif
break; break;
#endif
default: default:
goto L_SEND; goto L_SEND;
} }
...@@ -2299,12 +2311,15 @@ RETRY_TRY_BLOCK: ...@@ -2299,12 +2311,15 @@ RETRY_TRY_BLOCK:
x = mrb_fixnum(regs[a]); x = mrb_fixnum(regs[a]);
y = mrb_fixnum(regs[a+1]); y = mrb_fixnum(regs[a+1]);
if (mrb_int_mul_overflow(x, y, &z)) { if (mrb_int_mul_overflow(x, y, &z)) {
#ifndef MRB_WITHOUT_FLOAT
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
break; break;
#endif
} }
SET_INT_VALUE(regs[a], z); SET_INT_VALUE(regs[a], z);
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ {
mrb_int x = mrb_fixnum(regs[a]); mrb_int x = mrb_fixnum(regs[a]);
...@@ -2334,6 +2349,7 @@ RETRY_TRY_BLOCK: ...@@ -2334,6 +2349,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(*,mrb_float,mrb_float); OP_MATH_BODY(*,mrb_float,mrb_float);
#endif #endif
break; break;
#endif
default: default:
goto L_SEND; goto L_SEND;
} }
...@@ -2350,6 +2366,9 @@ RETRY_TRY_BLOCK: ...@@ -2350,6 +2366,9 @@ RETRY_TRY_BLOCK:
{ {
mrb_int x = mrb_fixnum(regs[a]); mrb_int x = mrb_fixnum(regs[a]);
mrb_int y = mrb_fixnum(regs[a+1]); mrb_int y = mrb_fixnum(regs[a+1]);
#ifdef MRB_WITHOUT_FLOAT
SET_INT_VALUE(regs[a], y ? x / y : 0);
#else
double f; double f;
if (y == 0) { if (y == 0) {
if (x > 0) f = INFINITY; if (x > 0) f = INFINITY;
...@@ -2360,8 +2379,10 @@ RETRY_TRY_BLOCK: ...@@ -2360,8 +2379,10 @@ RETRY_TRY_BLOCK:
f = (mrb_float)x / (mrb_float)y; f = (mrb_float)x / (mrb_float)y;
} }
SET_FLOAT_VALUE(mrb, regs[a], f); SET_FLOAT_VALUE(mrb, regs[a], f);
#endif
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
{ {
mrb_int x = mrb_fixnum(regs[a]); mrb_int x = mrb_fixnum(regs[a]);
...@@ -2398,6 +2419,7 @@ RETRY_TRY_BLOCK: ...@@ -2398,6 +2419,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(/,mrb_float,mrb_float); OP_MATH_BODY(/,mrb_float,mrb_float);
#endif #endif
break; break;
#endif
default: default:
goto L_SEND; goto L_SEND;
} }
...@@ -2423,12 +2445,15 @@ RETRY_TRY_BLOCK: ...@@ -2423,12 +2445,15 @@ RETRY_TRY_BLOCK:
mrb_int z; mrb_int z;
if (mrb_int_add_overflow(x, y, &z)) { if (mrb_int_add_overflow(x, y, &z)) {
#ifndef MRB_WITHOUT_FLOAT
SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
break; break;
#endif
} }
SET_INT_VALUE(regs[a], z); SET_INT_VALUE(regs[a], z);
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
{ {
...@@ -2439,6 +2464,7 @@ RETRY_TRY_BLOCK: ...@@ -2439,6 +2464,7 @@ RETRY_TRY_BLOCK:
mrb_float(regs[a]) += GETARG_C(i); mrb_float(regs[a]) += GETARG_C(i);
#endif #endif
break; break;
#endif
default: default:
SET_INT_VALUE(regs[a+1], GETARG_C(i)); SET_INT_VALUE(regs[a+1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
...@@ -2461,13 +2487,15 @@ RETRY_TRY_BLOCK: ...@@ -2461,13 +2487,15 @@ RETRY_TRY_BLOCK:
mrb_int z; mrb_int z;
if (mrb_int_sub_overflow(x, y, &z)) { if (mrb_int_sub_overflow(x, y, &z)) {
#ifndef MRB_WITHOUT_FLOAT
SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
break;
#endif
} }
else { SET_INT_VALUE(regs_a[0], z);
SET_INT_VALUE(regs_a[0], z);
}
} }
break; break;
#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT: case MRB_TT_FLOAT:
#ifdef MRB_WORD_BOXING #ifdef MRB_WORD_BOXING
{ {
...@@ -2478,6 +2506,7 @@ RETRY_TRY_BLOCK: ...@@ -2478,6 +2506,7 @@ RETRY_TRY_BLOCK:
mrb_float(regs_a[0]) -= GETARG_C(i); mrb_float(regs_a[0]) -= GETARG_C(i);
#endif #endif
break; break;
#endif
default: default:
SET_INT_VALUE(regs_a[1], GETARG_C(i)); SET_INT_VALUE(regs_a[1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
...@@ -2488,6 +2517,25 @@ RETRY_TRY_BLOCK: ...@@ -2488,6 +2517,25 @@ RETRY_TRY_BLOCK:
#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
#ifdef MRB_WITHOUT_FLOAT
#define OP_CMP(op) do {\
int result;\
/* need to check if - is overridden */\
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\
break;\
default:\
goto L_SEND;\
}\
if (result) {\
SET_TRUE_VALUE(regs[a]);\
}\
else {\
SET_FALSE_VALUE(regs[a]);\
}\
} while(0)
#else
#define OP_CMP(op) do {\ #define OP_CMP(op) do {\
int result;\ int result;\
/* need to check if - is overridden */\ /* need to check if - is overridden */\
...@@ -2514,6 +2562,7 @@ RETRY_TRY_BLOCK: ...@@ -2514,6 +2562,7 @@ RETRY_TRY_BLOCK:
SET_FALSE_VALUE(regs[a]);\ SET_FALSE_VALUE(regs[a]);\
}\ }\
} while(0) } while(0)
#endif
CASE(OP_EQ) { CASE(OP_EQ) {
/* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/ /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment