diff options
| -rw-r--r-- | include/mrbconf.h | 5 | ||||
| -rw-r--r-- | include/mruby.h | 8 | ||||
| -rw-r--r-- | include/mruby/boxing_nan.h | 4 | ||||
| -rw-r--r-- | include/mruby/boxing_no.h | 8 | ||||
| -rw-r--r-- | include/mruby/boxing_word.h | 16 | ||||
| -rw-r--r-- | include/mruby/class.h | 2 | ||||
| -rw-r--r-- | include/mruby/compile.h | 2 | ||||
| -rw-r--r-- | include/mruby/numeric.h | 6 | ||||
| -rw-r--r-- | include/mruby/value.h | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 18 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 8 | ||||
| -rw-r--r-- | mrblib/float.rb | 9 | ||||
| -rw-r--r-- | mrblib/mrblib.rake | 3 | ||||
| -rw-r--r-- | mrblib/numeric.rb | 12 | ||||
| -rw-r--r-- | src/array.c | 2 | ||||
| -rw-r--r-- | src/class.c | 6 | ||||
| -rw-r--r-- | src/dump.c | 6 | ||||
| -rw-r--r-- | src/etc.c | 12 | ||||
| -rw-r--r-- | src/gc.c | 6 | ||||
| -rw-r--r-- | src/hash.c | 8 | ||||
| -rw-r--r-- | src/kernel.c | 16 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/mruby_core.rake | 1 | ||||
| -rw-r--r-- | src/numeric.c | 135 | ||||
| -rw-r--r-- | src/object.c | 8 | ||||
| -rw-r--r-- | src/range.c | 4 | ||||
| -rw-r--r-- | src/state.c | 2 | ||||
| -rw-r--r-- | src/string.c | 8 | ||||
| -rw-r--r-- | src/vm.c | 55 |
29 files changed, 360 insertions, 20 deletions
diff --git a/include/mrbconf.h b/include/mrbconf.h index b8d603e1c..36008f917 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -28,6 +28,9 @@ /* add -DMRB_USE_FLOAT to use float instead of double for floating point numbers */ //#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 */ //#define MRB_INT16 @@ -45,7 +48,7 @@ # 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 on big endian machines; used by MRB_NAN_BOXING */ diff --git a/include/mruby.h b/include/mruby.h index 316707909..81963908e 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -65,6 +65,7 @@ #include "mrbconf.h" +#ifndef MRB_WITHOUT_FLOAT #ifndef FLT_EPSILON #define FLT_EPSILON (1.19209290e-07f) #endif @@ -80,6 +81,7 @@ #else #define MRB_FLOAT_EPSILON DBL_EPSILON #endif +#endif #include "mruby/common.h" #include <mruby/value.h> @@ -206,7 +208,9 @@ typedef struct mrb_state { struct RClass *hash_class; struct RClass *range_class; +#ifndef MRB_WITHOUT_FLOAT struct RClass *float_class; +#endif struct RClass *fixnum_class; struct RClass *true_class; struct RClass *false_class; @@ -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_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); +#ifndef MRB_WITHOUT_FLOAT 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_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); #define E_REGEXP_ERROR (mrb_exc_get(mrb, "RegexpError")) #define E_NOTIMP_ERROR (mrb_exc_get(mrb, "NotImplementedError")) +#ifndef MRB_WITHOUT_FLOAT #define E_FLOATDOMAIN_ERROR (mrb_exc_get(mrb, "FloatDomainError")) +#endif #define E_KEY_ERROR (mrb_exc_get(mrb, "KeyError")) diff --git a/include/mruby/boxing_nan.h b/include/mruby/boxing_nan.h index 700ea2ed3..3d9bbdc69 100644 --- a/include/mruby/boxing_nan.h +++ b/include/mruby/boxing_nan.h @@ -11,6 +11,10 @@ # error ---->> MRB_NAN_BOXING and MRB_USE_FLOAT conflict <<---- #endif +#ifdef MRB_WITHOUT_FLOAT +# error ---->> MRB_NAN_BOXING and MRB_WITHOUT_FLOAT conflict <<---- +#endif + #ifdef MRB_INT64 # error ---->> MRB_NAN_BOXING and MRB_INT64 conflict <<---- #endif diff --git a/include/mruby/boxing_no.h b/include/mruby/boxing_no.h index 7ee44a934..86ce64555 100644 --- a/include/mruby/boxing_no.h +++ b/include/mruby/boxing_no.h @@ -12,7 +12,9 @@ typedef struct mrb_value { union { +#ifndef MRB_WITHOUT_FLOAT mrb_float f; +#endif void *p; mrb_int i; mrb_sym sym; @@ -20,11 +22,15 @@ typedef struct mrb_value { enum mrb_vtype tt; } mrb_value; +#ifndef MRB_WITHOUT_FLOAT #define mrb_float_pool(mrb,f) mrb_float_value(mrb,f) +#endif #define mrb_ptr(o) (o).value.p #define mrb_cptr(o) mrb_ptr(o) +#ifndef MRB_WITHOUT_FLOAT #define mrb_float(o) (o).value.f +#endif #define mrb_fixnum(o) (o).value.i #define mrb_symbol(o) (o).value.sym #define mrb_type(o) (o).tt @@ -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_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)) +#ifndef MRB_WITHOUT_FLOAT #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_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) diff --git a/include/mruby/boxing_word.h b/include/mruby/boxing_word.h index d1c457fae..b17bfc973 100644 --- a/include/mruby/boxing_word.h +++ b/include/mruby/boxing_word.h @@ -15,10 +15,12 @@ #error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode. #endif +#ifndef MRB_WITHOUT_FLOAT struct RFloat { MRB_OBJECT_HEADER; mrb_float f; }; +#endif struct RCptr { MRB_OBJECT_HEADER; @@ -26,7 +28,11 @@ struct RCptr { }; #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 +#endif enum mrb_special_consts { MRB_Qnil = 0, @@ -51,21 +57,29 @@ typedef union mrb_value { mrb_sym sym : (sizeof(mrb_sym) * CHAR_BIT); }; struct RBasic *bp; +#ifndef MRB_WITHOUT_FLOAT struct RFloat *fp; +#endif struct RCptr *vp; } value; unsigned long w; } mrb_value; 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_pool(struct mrb_state*, mrb_float); +#endif +#ifndef MRB_WITHOUT_FLOAT #define mrb_float_pool(mrb,f) mrb_word_boxing_float_pool(mrb,f) +#endif #define mrb_ptr(o) (o).value.p #define mrb_cptr(o) (o).value.vp->p +#ifndef MRB_WITHOUT_FLOAT #define mrb_float(o) (o).value.fp->f +#endif #define mrb_fixnum(o) ((mrb_int)(o).value.i) #define mrb_symbol(o) (o).value.sym @@ -106,7 +120,9 @@ mrb_type(mrb_value o) }\ } while (0) +#ifndef MRB_WITHOUT_FLOAT #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_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) diff --git a/include/mruby/class.h b/include/mruby/class.h index e9df7764c..1e1d3c136 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -40,8 +40,10 @@ mrb_class(mrb_state *mrb, mrb_value v) return mrb->symbol_class; case MRB_TT_FIXNUM: return mrb->fixnum_class; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: return mrb->float_class; +#endif case MRB_TT_CPTR: return mrb->object_class; case MRB_TT_ENV: diff --git a/include/mruby/compile.h b/include/mruby/compile.h index d1ff0530f..051935ee1 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -165,7 +165,9 @@ struct mrb_parser_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_parse(struct mrb_parser_state*,mrbc_context*); +#ifndef MRB_WITHOUT_FLOAT 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 char const* mrb_parser_get_filename(struct mrb_parser_state*, uint16_t idx); diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index 042311df8..da9225aaa 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -22,13 +22,19 @@ MRB_BEGIN_DECL #define POSFIXABLE(f) TYPED_POSFIXABLE(f,mrb_int) #define NEGFIXABLE(f) TYPED_NEGFIXABLE(f,mrb_int) #define FIXABLE(f) TYPED_FIXABLE(f,mrb_int) +#ifndef MRB_WITHOUT_FLOAT #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); +#endif 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]/ */ +#ifndef MRB_WITHOUT_FLOAT 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); +#endif 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); diff --git a/include/mruby/value.h b/include/mruby/value.h index 98c68d657..f988826ca 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -63,12 +63,14 @@ struct mrb_state; #endif +#ifndef MRB_WITHOUT_FLOAT MRB_API double mrb_float_read(const char*, char**); #ifdef MRB_USE_FLOAT typedef float mrb_float; #else typedef double mrb_float; #endif +#endif #if defined _MSC_VER && _MSC_VER < 1900 # ifndef __cplusplus @@ -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, ...); # 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__) -# if _MSC_VER < 1800 +# if _MSC_VER < 1800 && !defined MRB_WITHOUT_FLOAT # include <float.h> # define isfinite(n) _finite(n) # define isnan _isnan @@ -158,7 +160,9 @@ typedef void mrb_value; #ifndef mrb_bool #define mrb_bool(o) (mrb_type(o) != MRB_TT_FALSE) #endif +#ifndef MRB_WITHOUT_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_array_p(o) (mrb_type(o) == MRB_TT_ARRAY) #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); /* * Returns a float in Ruby. */ +#ifndef MRB_WITHOUT_FLOAT MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) { mrb_value v; @@ -178,6 +183,7 @@ MRB_INLINE mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) SET_FLOAT_VALUE(mrb, v, f); return v; } +#endif static inline mrb_value mrb_cptr_value(struct mrb_state *mrb, void *p) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8f15a9b18..ba8ed2c71 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -460,6 +460,7 @@ new_lit(codegen_scope *s, mrb_value val) return i; } break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: for (i=0; i<s->irep->plen; i++) { pv = &s->irep->pool[i]; @@ -467,6 +468,7 @@ new_lit(codegen_scope *s, mrb_value val) if (mrb_float(*pv) == mrb_float(val)) return i; } break; +#endif case MRB_TT_FIXNUM: for (i=0; i<s->irep->plen; i++) { pv = &s->irep->pool[i]; @@ -492,11 +494,13 @@ new_lit(codegen_scope *s, mrb_value val) *pv = mrb_str_pool(s->mrb, val); break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING *pv = mrb_float_pool(s->mrb, mrb_float(val)); break; #endif +#endif case MRB_TT_FIXNUM: *pv = val; break; @@ -1163,6 +1167,7 @@ raise_error(codegen_scope *s, const char *msg) genop(s, MKOP_ABx(OP_ERR, 1, idx)); } +#ifndef MRB_WITHOUT_FLOAT static double 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; } +#endif static mrb_int 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) mrb_bool overflow; i = readint_mrb_int(s, p, base, FALSE, &overflow); +#ifndef MRB_WITHOUT_FLOAT if (overflow) { double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(s->mrb, f)); @@ -2244,6 +2251,7 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } else { +#endif if (i < MAXARG_sBx && i > -MAXARG_sBx) { co = MKOP_AsBx(OP_LOADI, cursp(), i); } @@ -2252,11 +2260,14 @@ codegen(codegen_scope *s, node *tree, int val) co = MKOP_ABx(OP_LOADL, cursp(), off); } genop(s, co); +#ifndef MRB_WITHOUT_FLOAT } +#endif push(); } break; +#ifndef MRB_WITHOUT_FLOAT case NODE_FLOAT: if (val) { char *p = (char*)tree; @@ -2267,12 +2278,14 @@ codegen(codegen_scope *s, node *tree, int val) push(); } break; +#endif case NODE_NEGATE: { nt = nint(tree->car); tree = tree->cdr; switch (nt) { +#ifndef MRB_WITHOUT_FLOAT case NODE_FLOAT: if (val) { char *p = (char*)tree; @@ -2283,6 +2296,7 @@ codegen(codegen_scope *s, node *tree, int val) push(); } break; +#endif case NODE_INT: if (val) { @@ -2293,6 +2307,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_bool overflow; i = readint_mrb_int(s, p, base, TRUE, &overflow); +#ifndef MRB_WITHOUT_FLOAT if (overflow) { double f = readint_float(s, p, base); int off = new_lit(s, mrb_float_value(s->mrb, -f)); @@ -2300,6 +2315,7 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); } else { +#endif if (i < MAXARG_sBx && i > -MAXARG_sBx) { co = MKOP_AsBx(OP_LOADI, cursp(), i); } @@ -2308,7 +2324,9 @@ codegen(codegen_scope *s, node *tree, int val) co = MKOP_ABx(OP_LOADL, cursp(), off); } genop(s, co); +#ifndef MRB_WITHOUT_FLOAT } +#endif push(); } break; diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 82e4c7bdd..b4a70873d 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -740,12 +740,14 @@ new_int(parser_state *p, const char *s, int base) return list3((node*)NODE_INT, (node*)strdup(s), nint(base)); } +#ifndef MRB_WITHOUT_FLOAT /* (:float . i) */ static node* new_float(parser_state *p, const char *s) { return cons((node*)NODE_FLOAT, (node*)strdup(s)); } +#endif /* (:str . (s . len)) */ static node* @@ -4962,6 +4964,11 @@ parser_yylex(parser_state *p) } tokfix(p); 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; char *endp; @@ -4976,6 +4983,7 @@ parser_yylex(parser_state *p) } pylval.nd = new_float(p, tok(p)); return tFLOAT; +#endif } pylval.nd = new_int(p, tok(p), 10); return tINTEGER; diff --git a/mrblib/float.rb b/mrblib/float.rb new file mode 100644 index 000000000..6343b9b85 --- /dev/null +++ b/mrblib/float.rb @@ -0,0 +1,9 @@ +## +# 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 diff --git a/mrblib/mrblib.rake b/mrblib/mrblib.rake index 19fd00d66..fe4aae1f7 100644 --- a/mrblib/mrblib.rake +++ b/mrblib/mrblib.rake @@ -8,6 +8,9 @@ MRuby.each_target do 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| _, _, *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) open(t.name, 'w') do |f| _pp "GEN", "*.rb", "#{t.name.relative_path}" diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb index 89401a084..1b11e92ad 100644 --- a/mrblib/numeric.rb +++ b/mrblib/numeric.rb @@ -104,7 +104,7 @@ module Integral raise ArgumentError, "step can't be 0" if step == 0 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 while true block.call(i) @@ -161,13 +161,3 @@ class Integer # ISO 15.2.8.3.26 alias truncate floor 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 diff --git a/src/array.c b/src/array.c index 8f33defe6..7bd630638 100644 --- a/src/array.c +++ b/src/array.c @@ -767,9 +767,11 @@ aget_index(mrb_state *mrb, mrb_value index) if (mrb_fixnum_p(index)) { return mrb_fixnum(index); } +#ifndef MRB_WITHOUT_FLOAT else if (mrb_float_p(index)) { return (mrb_int)mrb_float(index); } +#endif else { mrb_int i, argc; mrb_value *argv; diff --git a/src/class.c b/src/class.c index f220106cd..33d6d7b92 100644 --- a/src/class.c +++ b/src/class.c @@ -804,6 +804,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; +#ifndef MRB_WITHOUT_FLOAT case 'f': { mrb_float *p; @@ -816,6 +817,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; +#endif case 'i': { mrb_int *p; @@ -826,6 +828,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) case MRB_TT_FIXNUM: *p = mrb_fixnum(ARGV[arg_i]); break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: { mrb_float f = mrb_float(ARGV[arg_i]); @@ -836,6 +839,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) *p = (mrb_int)f; } break; +#endif case MRB_TT_STRING: mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); break; @@ -1277,9 +1281,11 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v) return mrb_obj_value(mrb->object_class); case MRB_TT_SYMBOL: case MRB_TT_FIXNUM: +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); return mrb_nil_value(); /* not reached */ +#endif default: break; } diff --git a/src/dump.c b/src/dump.c index 71d2f7184..df1e171e4 100644 --- a/src/dump.c +++ b/src/dump.c @@ -15,11 +15,13 @@ #define FLAG_BYTEORDER_NATIVE 2 #define FLAG_BYTEORDER_NONATIVE 0 +#ifndef MRB_WITHOUT_FLOAT #ifdef MRB_USE_FLOAT #define MRB_FLOAT_FMT "%.8e" #else #define MRB_FLOAT_FMT "%.16e" #endif +#endif 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) } break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: 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) size += (size_t)len; } break; +#endif case MRB_TT_STRING: { @@ -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); break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: cur += uint8_to_bin(IREP_TT_FLOAT, cur); /* data type */ str = mrb_float_to_str(mrb, irep->pool[pool_no], MRB_FLOAT_FMT); break; +#endif case MRB_TT_STRING: cur += uint8_to_bin(IREP_TT_STRING, cur); /* data type */ @@ -87,14 +87,20 @@ mrb_obj_to_sym(mrb_state *mrb, mrb_value name) } MRB_API mrb_int +#ifdef MRB_WITHOUT_FLOAT +mrb_fixnum_id(mrb_int f) +#else mrb_float_id(mrb_float f) +#endif { const char *p = (const char*)&f; int len = sizeof(f); uint32_t id = 0; +#ifndef MRB_WITHOUT_FLOAT /* normalize -0.0 to 0.0 */ if (f == 0) f = 0.0; +#endif while (len--) { id = id*65599 + *p; p++; @@ -125,9 +131,13 @@ mrb_obj_id(mrb_value obj) case MRB_TT_SYMBOL: return MakeID(mrb_symbol(obj)); 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); case MRB_TT_FLOAT: return MakeID(mrb_float_id(mrb_float(obj))); +#endif case MRB_TT_STRING: case MRB_TT_OBJECT: case MRB_TT_CLASS: @@ -148,6 +158,7 @@ mrb_obj_id(mrb_value obj) } #ifdef MRB_WORD_BOXING +#ifndef MRB_WITHOUT_FLOAT MRB_API mrb_value 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) nf->f = f; return mrb_obj_value(nf); } +#endif /* MRB_WITHOUT_FLOAT */ MRB_API mrb_value mrb_word_boxing_cptr_value(mrb_state *mrb, void *p) @@ -114,7 +114,9 @@ typedef struct { struct RException exc; struct RBreak brk; #ifdef MRB_WORD_BOXING +#ifndef MRB_WITHOUT_FLOAT struct RFloat floatv; +#endif struct RCptr cptr; #endif } as; @@ -741,12 +743,14 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) /* cannot happen */ return; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING break; #else return; #endif +#endif case MRB_TT_OBJECT: mrb_gc_free_iv(mrb, (struct RObject*)obj); @@ -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->range_class); +#ifndef MRB_WITHOUT_FLOAT 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->true_class); mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class); diff --git a/src/hash.c b/src/hash.c index 53ef2b818..27d481947 100644 --- a/src/hash.c +++ b/src/hash.c @@ -12,8 +12,10 @@ #include <mruby/string.h> #include <mruby/variable.h> +#ifndef MRB_WITHOUT_FLOAT /* a function to get hash value of a float number */ mrb_int mrb_float_id(mrb_float f); +#endif static inline khint_t 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_SYMBOL: case MRB_TT_FIXNUM: +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: +#endif h = (khint_t)mrb_obj_id(key); break; @@ -60,12 +64,15 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) switch (mrb_type(b)) { case MRB_TT_FIXNUM: return mrb_fixnum(a) == mrb_fixnum(b); +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: return (mrb_float)mrb_fixnum(a) == mrb_float(b); +#endif default: return FALSE; } +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: switch (mrb_type(b)) { case MRB_TT_FIXNUM: @@ -75,6 +82,7 @@ mrb_hash_ht_hash_equal(mrb_state *mrb, mrb_value a, mrb_value b) default: return FALSE; } +#endif default: return mrb_eql(mrb, a, b); diff --git a/src/kernel.c b/src/kernel.c index 33d142184..c9b4e9619 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -426,7 +426,9 @@ mrb_obj_freeze(mrb_state *mrb, mrb_value self) case MRB_TT_TRUE: case MRB_TT_FIXNUM: case MRB_TT_SYMBOL: +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: +#endif return self; default: break; @@ -449,7 +451,9 @@ mrb_obj_frozen(mrb_state *mrb, mrb_value self) case MRB_TT_TRUE: case MRB_TT_FIXNUM: case MRB_TT_SYMBOL: +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: +#endif return mrb_true_value(); default: break; @@ -878,6 +882,16 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) 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 */ /* * call-seq: @@ -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, "__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_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); } diff --git a/src/load.c b/src/load.c index 8ae607ffa..58427424d 100644 --- a/src/load.c +++ b/src/load.c @@ -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); break; +#ifndef MRB_WITHOUT_FLOAT case IREP_TT_FLOAT: irep->pool[i] = mrb_float_pool(mrb, mrb_str_to_dbl(mrb, s, FALSE)); break; +#endif case IREP_TT_STRING: irep->pool[i] = mrb_str_pool(mrb, s); diff --git a/src/mruby_core.rake b/src/mruby_core.rake index 4558493d9..bb3d7b633 100644 --- a/src/mruby_core.rake +++ b/src/mruby_core.rake @@ -5,6 +5,7 @@ MRuby.each_target do objs = Dir.glob("#{current_dir}/*.c").map { |f| 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")) }.compact diff --git a/src/numeric.c b/src/numeric.c index 8c7d448bd..dd3aa558c 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -4,9 +4,11 @@ ** See Copyright Notice in mruby.h */ +#ifndef MRB_WITHOUT_FLOAT #include <float.h> -#include <limits.h> #include <math.h> +#endif +#include <limits.h> #include <stdlib.h> #include <mruby.h> @@ -15,6 +17,7 @@ #include <mruby/string.h> #include <mruby/class.h> +#ifndef MRB_WITHOUT_FLOAT #ifdef MRB_USE_FLOAT #define trunc(f) truncf(f) #define floor(f) floorf(f) @@ -24,7 +27,9 @@ #else #define MRB_FLO_TO_STR_FMT "%.14g" #endif +#endif +#ifndef MRB_WITHOUT_FLOAT MRB_API mrb_float 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); } +#endif /* * call-seq: @@ -52,7 +58,9 @@ static mrb_value num_pow(mrb_state *mrb, mrb_value x) { mrb_value y; +#ifndef MRB_WITHOUT_FLOAT mrb_float d; +#endif mrb_get_args(mrb, "o", &y); if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) { @@ -61,24 +69,37 @@ num_pow(mrb_state *mrb, mrb_value x) mrb_int exp = mrb_fixnum(y); 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 (;;) { if (exp & 1) { if (mrb_int_mul_overflow(result, base, &result)) { +#ifndef MRB_WITHOUT_FLOAT goto float_pow; +#endif } } exp >>= 1; if (exp == 0) break; if (mrb_int_mul_overflow(base, base, &base)) { +#ifndef MRB_WITHOUT_FLOAT goto float_pow; +#endif } } return mrb_fixnum_value(result); } +#ifdef MRB_WITHOUT_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); +#else float_pow: d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y)); return mrb_float_value(mrb, d); +#endif } /* 15.2.8.3.4 */ @@ -95,7 +116,14 @@ num_pow(mrb_state *mrb, mrb_value x) mrb_value 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)); +#endif } /* 15.2.9.3.19(x) */ @@ -109,12 +137,23 @@ mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) static mrb_value 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_get_args(mrb, "f", &y); return mrb_float_value(mrb, mrb_to_flo(mrb, x) / y); +#endif } +#ifndef MRB_WITHOUT_FLOAT /******************************************************************** * * Document-class: Float @@ -231,6 +270,7 @@ flo_mod(mrb_state *mrb, mrb_value x) flodivmod(mrb, mrb_float(x), mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); } +#endif /* 15.2.8.3.16 */ /* @@ -254,6 +294,7 @@ fix_eql(mrb_state *mrb, mrb_value x) return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); } +#ifndef MRB_WITHOUT_FLOAT static mrb_value flo_eql(mrb_state *mrb, mrb_value x) { @@ -648,6 +689,7 @@ flo_nan_p(mrb_state *mrb, mrb_value num) { return mrb_bool_value(isnan(mrb_float(num))); } +#endif /* * Document-class: Integer @@ -685,11 +727,17 @@ mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) if (a == 0) return x; b = mrb_fixnum(y); if (mrb_int_mul_overflow(a, b, &c)) { +#ifndef MRB_WITHOUT_FLOAT return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b); +#endif } 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)); +#endif } /* 15.2.8.3.3 */ @@ -761,17 +809,26 @@ fix_mod(mrb_state *mrb, mrb_value x) mrb_int b, mod; if ((b=mrb_fixnum(y)) == 0) { +#ifdef MRB_WITHOUT_FLOAT + /* ZeroDivisionError */ + return mrb_fixnum_value(0); +#else return mrb_float_value(mrb, NAN); +#endif } fixdivmod(mrb, a, b, 0, &mod); return mrb_fixnum_value(mod); } +#ifdef MRB_WITHOUT_FLOAT + mrb_raise(mrb, E_TYPE_ERROR, "non fixnum value"); +#else else { mrb_float mod; flodivmod(mrb, (mrb_float)a, mrb_to_flo(mrb, y), 0, &mod); return mrb_float_value(mrb, mod); } +#endif } /* @@ -791,14 +848,21 @@ fix_divmod(mrb_state *mrb, mrb_value x) mrb_int div, mod; 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) ? mrb_float_value(mrb, NAN): mrb_float_value(mrb, INFINITY)), mrb_float_value(mrb, NAN)); +#endif } fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &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 { mrb_float div, mod; mrb_value a, b; @@ -808,8 +872,10 @@ fix_divmod(mrb_state *mrb, mrb_value x) b = mrb_float_value(mrb, mod); return mrb_assoc_new(mrb, a, b); } +#endif } +#ifndef MRB_WITHOUT_FLOAT static mrb_value 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); return mrb_assoc_new(mrb, a, b); } +#endif /* 15.2.8.3.7 */ /* @@ -846,8 +913,10 @@ fix_equal(mrb_state *mrb, mrb_value x) switch (mrb_type(y)) { case MRB_TT_FIXNUM: return mrb_bool_value(mrb_fixnum(x) == mrb_fixnum(y)); +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: return mrb_bool_value((mrb_float)mrb_fixnum(x) == mrb_float(y)); +#endif default: return mrb_false_value(); } @@ -872,6 +941,11 @@ fix_rev(mrb_state *mrb, mrb_value num) 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_or(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); 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)));\ } while(0) +#endif /* 15.2.8.3.9 */ /* @@ -937,23 +1012,36 @@ static mrb_value lshift(mrb_state *mrb, mrb_int val, mrb_int width) { if (width < 0) { /* mrb_int overflow */ +#ifdef MRB_WITHOUT_FLOAT + return mrb_fixnum_value(0); +#else return mrb_float_value(mrb, INFINITY); +#endif } if (val > 0) { if ((width > NUMERIC_SHIFT_WIDTH_MAX) || (val > (MRB_INT_MAX >> width))) { +#ifdef MRB_WITHOUT_FLOAT + return mrb_fixnum_value(-1); +#else goto bit_overflow; +#endif } return mrb_fixnum_value(val << width); } else { if ((width > NUMERIC_SHIFT_WIDTH_MAX) || (val < (MRB_INT_MIN >> width))) { +#ifdef MRB_WITHOUT_FLOAT + return mrb_fixnum_value(0); +#else goto bit_overflow; +#endif } return mrb_fixnum_value(val * ((mrb_int)1 << width)); } +#ifndef MRB_WITHOUT_FLOAT bit_overflow: { mrb_float f = (mrb_float)val; @@ -962,6 +1050,7 @@ bit_overflow: } return mrb_float_value(mrb, f); } +#endif } static mrb_value @@ -1038,6 +1127,7 @@ fix_rshift(mrb_state *mrb, mrb_value x) * */ +#ifndef MRB_WITHOUT_FLOAT static mrb_value fix_to_f(mrb_state *mrb, mrb_value num) { @@ -1085,6 +1175,7 @@ mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) } return mrb_fixnum_value(z); } +#endif mrb_value 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; b = mrb_fixnum(y); if (mrb_int_add_overflow(a, b, &c)) { +#ifndef MRB_WITHOUT_FLOAT return mrb_float_value(mrb, (mrb_float)a + (mrb_float)b); +#endif } 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)); +#endif } /* 15.2.8.3.1 */ @@ -1134,11 +1231,17 @@ mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) b = mrb_fixnum(y); if (mrb_int_sub_overflow(a, b, &c)) { +#ifndef MRB_WITHOUT_FLOAT return mrb_float_value(mrb, (mrb_float)a - (mrb_float)b); +#endif } 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)); +#endif } /* 15.2.8.3.2 */ @@ -1230,18 +1333,32 @@ static mrb_value num_cmp(mrb_state *mrb, mrb_value self) { mrb_value other; +#ifdef MRB_WITHOUT_FLOAT + mrb_int x, y; +#else mrb_float x, y; +#endif mrb_get_args(mrb, "o", &other); +#ifdef MRB_WITHOUT_FLOAT + x = mrb_fixnum(self); +#else x = mrb_to_flo(mrb, self); +#endif switch (mrb_type(other)) { case MRB_TT_FIXNUM: +#ifdef MRB_WITHOUT_FLOAT + y = mrb_fixnum(other); +#else y = (mrb_float)mrb_fixnum(other); +#endif break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: y = mrb_float(other); break; +#endif default: return mrb_nil_value(); } @@ -1262,6 +1379,7 @@ num_cmp(mrb_state *mrb, mrb_value self) * Returns a new float which is the sum of <code>float</code> * and <code>other</code>. */ +#ifndef MRB_WITHOUT_FLOAT static mrb_value 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); return mrb_float_value(mrb, mrb_float(x) + mrb_to_flo(mrb, y)); } +#endif /* ------------------------------------------------------------------------*/ void 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 = mrb_define_class(mrb, "Numeric", mrb->object_class); /* 15.2.7 */ @@ -1291,10 +1413,12 @@ mrb_init_numeric(mrb_state *mrb) 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_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, "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, "truncate", int_to_i, MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */ +#endif /* Fixnum Class */ mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer); @@ -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_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 */ +#ifndef MRB_WITHOUT_FLOAT 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, "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) */ +#ifndef MRB_WITHOUT_FLOAT /* Float Class */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); @@ -1352,4 +1479,6 @@ mrb_init_numeric(mrb_state *mrb) #ifdef NAN mrb_define_const(mrb, fl, "NAN", mrb_float_value(mrb, NAN)); #endif +#endif + mrb_define_module(mrb, "Integral"); } diff --git a/src/object.c b/src/object.c index 388a34b44..df2e8b5ab 100644 --- a/src/object.c +++ b/src/object.c @@ -24,8 +24,10 @@ mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) case MRB_TT_SYMBOL: return (mrb_symbol(v1) == mrb_symbol(v2)); +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: return (mrb_float(v1) == mrb_float(v2)); +#endif default: return (mrb_ptr(v1) == mrb_ptr(v2)); @@ -373,7 +375,9 @@ static const struct types { {MRB_TT_ICLASS, "iClass"}, /* internal use: mixed-in module holder */ {MRB_TT_SCLASS, "SClass"}, {MRB_TT_PROC, "Proc"}, +#ifndef MRB_WITHOUT_FLOAT {MRB_TT_FLOAT, "Float"}, +#endif {MRB_TT_ARRAY, "Array"}, {MRB_TT_HASH, "Hash"}, {MRB_TT_STRING, "String"}, @@ -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"); } switch (mrb_type(val)) { +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: if (base != 0) goto arg_error; else { @@ -541,6 +546,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, mrb_int base) } } return mrb_flo_to_fixnum(mrb, val); +#endif case MRB_TT_FIXNUM: if (base != 0) goto arg_error; @@ -575,6 +581,7 @@ mrb_Integer(mrb_state *mrb, mrb_value val) return mrb_convert_to_integer(mrb, val, 0); } +#ifndef MRB_WITHOUT_FLOAT MRB_API mrb_value 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"); } } +#endif MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj) diff --git a/src/range.c b/src/range.c index c6a5ea924..0360b48ae 100644 --- a/src/range.c +++ b/src/range.c @@ -30,8 +30,12 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b) ta = mrb_type(a); 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) && (tb == MRB_TT_FIXNUM || tb == MRB_TT_FLOAT)) { +#endif return; } diff --git a/src/state.c b/src/state.c index 2f66e494b..9b33d6ad9 100644 --- a/src/state.c +++ b/src/state.c @@ -164,7 +164,7 @@ mrb_irep_free(mrb_state *mrb, mrb_irep *irep) mrb_gc_free_str(mrb, RSTRING(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) { mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); } diff --git a/src/string.c b/src/string.c index 2616d0e72..62dc4b583 100644 --- a/src/string.c +++ b/src/string.c @@ -8,7 +8,9 @@ # define _CRT_NONSTDC_NO_DEPRECATE #endif +#ifndef MRB_WITHOUT_FLOAT #include <float.h> +#endif #include <limits.h> #include <stddef.h> #include <stdlib.h> @@ -2284,6 +2286,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self) return mrb_str_to_inum(mrb, self, base, FALSE); } +#ifndef MRB_WITHOUT_FLOAT MRB_API double 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) { return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE)); } +#endif /* 15.2.10.5.40 */ /* @@ -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, "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 */ +#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_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()); @@ -2799,6 +2805,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); } +#ifndef MRB_WITHOUT_FLOAT /* * Source code for the "strtod" library procedure. * @@ -3043,3 +3050,4 @@ done: } return fraction; } +#endif @@ -670,7 +670,9 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self) switch (mrb_type(self)) { case MRB_TT_SYMBOL: case MRB_TT_FIXNUM: +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: +#endif c = 0; break; default: @@ -1005,9 +1007,11 @@ RETRY_TRY_BLOCK: int bx = GETARG_Bx(i); #ifdef MRB_WORD_BOXING mrb_value val = pool[bx]; +#ifndef MRB_WITHOUT_FLOAT if (mrb_float_p(val)) { val = mrb_float_value(mrb, mrb_float(val)); } +#endif regs[a] = val; #else regs[a] = pool[bx]; @@ -2187,12 +2191,15 @@ RETRY_TRY_BLOCK: x = mrb_fixnum(regs_a[0]); y = mrb_fixnum(regs_a[1]); 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); break; +#endif } SET_INT_VALUE(regs[a], z); } break; +#ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); @@ -2222,6 +2229,7 @@ RETRY_TRY_BLOCK: OP_MATH_BODY(+,mrb_float,mrb_float); #endif break; +#endif case TYPES2(MRB_TT_STRING,MRB_TT_STRING): regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); break; @@ -2245,12 +2253,15 @@ RETRY_TRY_BLOCK: x = mrb_fixnum(regs[a]); y = mrb_fixnum(regs[a+1]); if (mrb_int_sub_overflow(x, y, &z)) { +#ifndef MRB_WITHOUT_FLOAT SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); break; +#endif } SET_INT_VALUE(regs[a], z); } break; +#ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); @@ -2280,6 +2291,7 @@ RETRY_TRY_BLOCK: OP_MATH_BODY(-,mrb_float,mrb_float); #endif break; +#endif default: goto L_SEND; } @@ -2299,12 +2311,15 @@ RETRY_TRY_BLOCK: x = mrb_fixnum(regs[a]); y = mrb_fixnum(regs[a+1]); if (mrb_int_mul_overflow(x, y, &z)) { +#ifndef MRB_WITHOUT_FLOAT SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); break; +#endif } SET_INT_VALUE(regs[a], z); } break; +#ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); @@ -2334,6 +2349,7 @@ RETRY_TRY_BLOCK: OP_MATH_BODY(*,mrb_float,mrb_float); #endif break; +#endif default: goto L_SEND; } @@ -2350,6 +2366,9 @@ RETRY_TRY_BLOCK: { mrb_int x = mrb_fixnum(regs[a]); mrb_int y = mrb_fixnum(regs[a+1]); +#ifdef MRB_WITHOUT_FLOAT + SET_INT_VALUE(regs[a], y ? x / y : 0); +#else double f; if (y == 0) { if (x > 0) f = INFINITY; @@ -2360,8 +2379,10 @@ RETRY_TRY_BLOCK: f = (mrb_float)x / (mrb_float)y; } SET_FLOAT_VALUE(mrb, regs[a], f); +#endif } break; +#ifndef MRB_WITHOUT_FLOAT case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): { mrb_int x = mrb_fixnum(regs[a]); @@ -2398,6 +2419,7 @@ RETRY_TRY_BLOCK: OP_MATH_BODY(/,mrb_float,mrb_float); #endif break; +#endif default: goto L_SEND; } @@ -2423,12 +2445,15 @@ RETRY_TRY_BLOCK: mrb_int 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); break; +#endif } SET_INT_VALUE(regs[a], z); } break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING { @@ -2439,6 +2464,7 @@ RETRY_TRY_BLOCK: mrb_float(regs[a]) += GETARG_C(i); #endif break; +#endif default: SET_INT_VALUE(regs[a+1], GETARG_C(i)); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); @@ -2461,13 +2487,15 @@ RETRY_TRY_BLOCK: mrb_int 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); + break; +#endif } - else { - SET_INT_VALUE(regs_a[0], z); - } + SET_INT_VALUE(regs_a[0], z); } break; +#ifndef MRB_WITHOUT_FLOAT case MRB_TT_FLOAT: #ifdef MRB_WORD_BOXING { @@ -2478,6 +2506,7 @@ RETRY_TRY_BLOCK: mrb_float(regs_a[0]) -= GETARG_C(i); #endif break; +#endif default: SET_INT_VALUE(regs_a[1], GETARG_C(i)); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); @@ -2488,6 +2517,25 @@ RETRY_TRY_BLOCK: #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 {\ int result;\ /* need to check if - is overridden */\ @@ -2514,6 +2562,7 @@ RETRY_TRY_BLOCK: SET_FALSE_VALUE(regs[a]);\ }\ } while(0) +#endif CASE(OP_EQ) { /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/ |
