summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-11-04 12:33:07 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-11-04 12:33:07 +0900
commitd6cb4f9cf2027eb20f67238aa6c051448602e7e6 (patch)
treec025d53534298097aadc3d7699de964bd8a7225f
parent388d26d77027feaa3e107abf7209e2681868bbe6 (diff)
parenta751f7f196e35cf85ac6f5c0d855edeb68b2bf53 (diff)
downloadmruby-d6cb4f9cf2027eb20f67238aa6c051448602e7e6.tar.gz
mruby-d6cb4f9cf2027eb20f67238aa6c051448602e7e6.zip
Merge branch 'pandax381-mrb_without_float'
-rw-r--r--AUTHORS1
-rw-r--r--include/mrbconf.h5
-rw-r--r--include/mruby.h8
-rw-r--r--include/mruby/boxing_nan.h4
-rw-r--r--include/mruby/boxing_no.h8
-rw-r--r--include/mruby/boxing_word.h16
-rw-r--r--include/mruby/class.h2
-rw-r--r--include/mruby/compile.h2
-rw-r--r--include/mruby/numeric.h6
-rw-r--r--include/mruby/value.h8
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c4
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c18
-rw-r--r--mrbgems/mruby-compiler/core/parse.y8
-rw-r--r--mrbgems/mruby-kernel-ext/src/kernel.c4
-rw-r--r--mrbgems/mruby-kernel-ext/test/kernel.rb4
-rw-r--r--mrbgems/mruby-numeric-ext/test/numeric.rb2
-rw-r--r--mrbgems/mruby-object-ext/src/object.c6
-rw-r--r--mrbgems/mruby-object-ext/test/nil.rb2
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c10
-rw-r--r--mrbgems/mruby-sprintf/test/sprintf.rb7
-rw-r--r--mrbgems/mruby-string-ext/src/string.c2
-rw-r--r--mrbgems/mruby-test/driver.c2
-rw-r--r--mrbgems/mruby-test/mrbgem.rake4
-rw-r--r--mrblib/float.rb9
-rw-r--r--mrblib/mrblib.rake3
-rw-r--r--mrblib/numeric.rb12
-rw-r--r--src/array.c2
-rw-r--r--src/class.c6
-rw-r--r--src/dump.c6
-rw-r--r--src/etc.c12
-rw-r--r--src/fmt_fp.c2
-rw-r--r--src/gc.c8
-rw-r--r--src/hash.c8
-rw-r--r--src/kernel.c16
-rw-r--r--src/load.c2
-rw-r--r--src/mruby_core.rake1
-rw-r--r--src/numeric.c135
-rw-r--r--src/object.c8
-rw-r--r--src/range.c4
-rw-r--r--src/state.c2
-rw-r--r--src/string.c8
-rw-r--r--src/symbol.c2
-rw-r--r--src/vm.c62
-rw-r--r--test/t/array.rb2
-rw-r--r--test/t/class.rb2
-rw-r--r--test/t/hash.rb2
-rw-r--r--test/t/integer.rb53
-rw-r--r--test/t/numeric.rb2
-rw-r--r--test/t/range.rb2
-rw-r--r--test/t/string.rb11
50 files changed, 454 insertions, 61 deletions
diff --git a/AUTHORS b/AUTHORS
index a918ecdaa..4265f7f58 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -37,3 +37,4 @@ Original Authors "mruby developers" are:
Tomasz DÄ…browski
Christopher Aue
Masahiro Wakame
+ YAMAMOTO Masaya
diff --git a/include/mrbconf.h b/include/mrbconf.h
index b8d603e1c..eb2d69187 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_WITHOUT_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_WITHOUT_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 1dc2eaf10..1413d604e 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;
@@ -1059,7 +1063,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);
@@ -1149,7 +1155,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-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index 7e5fd392f..8084e8af3 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -528,6 +528,10 @@ done:
/* no evaluation of code */
}
else {
+ if (0 < parser->nwarn) {
+ /* warning */
+ printf("line %d: %s\n", parser->warn_buffer[0].lineno, parser->warn_buffer[0].message);
+ }
if (0 < parser->nerr) {
/* syntax error */
printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message);
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index da29077b0..fce5ac490 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -481,6 +481,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];
@@ -488,6 +489,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];
@@ -513,11 +515,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;
@@ -1184,6 +1188,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)
{
@@ -1209,6 +1214,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)
@@ -2258,6 +2264,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));
@@ -2265,6 +2272,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);
}
@@ -2273,11 +2281,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;
@@ -2288,12 +2299,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;
@@ -2304,6 +2317,7 @@ codegen(codegen_scope *s, node *tree, int val)
push();
}
break;
+#endif
case NODE_INT:
if (val) {
@@ -2314,6 +2328,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));
@@ -2321,6 +2336,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);
}
@@ -2329,7 +2345,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 e5017b677..01269d8da 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/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c
index 94a8ac320..32d86376a 100644
--- a/mrbgems/mruby-kernel-ext/src/kernel.c
+++ b/mrbgems/mruby-kernel-ext/src/kernel.c
@@ -114,6 +114,7 @@ mrb_f_integer(mrb_state *mrb, mrb_value self)
return mrb_convert_to_integer(mrb, arg, base);
}
+#ifndef MRB_WITHOUT_FLOAT
/*
* call-seq:
* Float(arg) -> float
@@ -134,6 +135,7 @@ mrb_f_float(mrb_state *mrb, mrb_value self)
mrb_get_args(mrb, "o", &arg);
return mrb_Float(mrb, arg);
}
+#endif
/*
* call-seq:
@@ -247,7 +249,9 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
+#ifndef MRB_WITHOUT_FLOAT
mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
+#endif
mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1));
diff --git a/mrbgems/mruby-kernel-ext/test/kernel.rb b/mrbgems/mruby-kernel-ext/test/kernel.rb
index 89cedaf27..206b7ac74 100644
--- a/mrbgems/mruby-kernel-ext/test/kernel.rb
+++ b/mrbgems/mruby-kernel-ext/test/kernel.rb
@@ -49,7 +49,7 @@ assert('Kernel#__method__') do
end
assert('Kernel#Integer') do
- assert_equal(123, Integer(123.999))
+ assert_equal(123, Integer(123.999)) if class_defined?("Float")
assert_equal(26, Integer("0x1a"))
assert_equal(930, Integer("0930", 10))
assert_equal(7, Integer("111", 2))
@@ -63,7 +63,7 @@ assert('Kernel#Float') do
assert_equal(123.456, Float(123.456))
assert_equal(123.456, Float("123.456"))
assert_raise(TypeError) { Float(nil) }
-end
+end if class_defined?("Float")
assert('Kernel#String') do
assert_equal("main", String(self))
diff --git a/mrbgems/mruby-numeric-ext/test/numeric.rb b/mrbgems/mruby-numeric-ext/test/numeric.rb
index 8bead2489..6ea0c14e7 100644
--- a/mrbgems/mruby-numeric-ext/test/numeric.rb
+++ b/mrbgems/mruby-numeric-ext/test/numeric.rb
@@ -15,7 +15,7 @@ end
assert('Float#div') do
assert_float 52, 365.2425.div(7)
-end
+end if class_defined?("Float")
assert('Integer#zero?') do
assert_equal true, 0.zero?
diff --git a/mrbgems/mruby-object-ext/src/object.c b/mrbgems/mruby-object-ext/src/object.c
index 35a07b584..b076b3ec0 100644
--- a/mrbgems/mruby-object-ext/src/object.c
+++ b/mrbgems/mruby-object-ext/src/object.c
@@ -16,6 +16,7 @@ nil_to_a(mrb_state *mrb, mrb_value obj)
return mrb_ary_new(mrb);
}
+#ifndef MRB_WITHOUT_FLOAT
/*
* call-seq:
* nil.to_f -> 0.0
@@ -28,6 +29,7 @@ nil_to_f(mrb_state *mrb, mrb_value obj)
{
return mrb_float_value(mrb, 0.0);
}
+#endif
/*
* call-seq:
@@ -77,7 +79,9 @@ mrb_obj_instance_exec(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 = NULL;
break;
default:
@@ -94,7 +98,9 @@ mrb_mruby_object_ext_gem_init(mrb_state* mrb)
struct RClass * n = mrb->nil_class;
mrb_define_method(mrb, n, "to_a", nil_to_a, MRB_ARGS_NONE());
+#ifndef MRB_WITHOUT_FLOAT
mrb_define_method(mrb, n, "to_f", nil_to_f, MRB_ARGS_NONE());
+#endif
mrb_define_method(mrb, n, "to_i", nil_to_i, MRB_ARGS_NONE());
mrb_define_method(mrb, mrb->kernel_module, "instance_exec", mrb_obj_instance_exec, MRB_ARGS_ANY() | MRB_ARGS_BLOCK());
diff --git a/mrbgems/mruby-object-ext/test/nil.rb b/mrbgems/mruby-object-ext/test/nil.rb
index 5cd1cf4ed..7f773637a 100644
--- a/mrbgems/mruby-object-ext/test/nil.rb
+++ b/mrbgems/mruby-object-ext/test/nil.rb
@@ -4,7 +4,7 @@ end
assert('NilClass#to_f') do
assert_equal 0.0, nil.to_f
-end
+end if class_defined?("Float")
assert('NilClass#to_i') do
assert_equal 0, nil.to_i
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index efa0b3d34..7eea1a1f3 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -12,7 +12,9 @@
#include <mruby/string.h>
#include <mruby/hash.h>
#include <mruby/numeric.h>
+#ifndef MRB_WITHOUT_FLOAT
#include <math.h>
+#endif
#include <ctype.h>
#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */
@@ -20,7 +22,9 @@
#define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n)))
mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value);
+#ifndef MRB_WITHOUT_FLOAT
static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int);
+#endif
static char*
remove_sign_bits(char *str, int base)
@@ -814,10 +818,12 @@ retry:
bin_retry:
switch (mrb_type(val)) {
+#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
val = mrb_flo_to_fixnum(mrb, val);
if (mrb_fixnum_p(val)) goto bin_retry;
break;
+#endif
case MRB_TT_STRING:
val = mrb_str_to_inum(mrb, val, 0, TRUE);
goto bin_retry;
@@ -990,6 +996,7 @@ retry:
}
break;
+#ifndef MRB_WITHOUT_FLOAT
case 'f':
case 'g':
case 'G':
@@ -1069,6 +1076,7 @@ retry:
blen += n;
}
break;
+#endif
}
flags = FNONE;
}
@@ -1088,6 +1096,7 @@ retry:
return result;
}
+#ifndef MRB_WITHOUT_FLOAT
static void
fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec)
{
@@ -1114,3 +1123,4 @@ fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec)
*buf++ = c;
*buf = '\0';
}
+#endif
diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb
index e3b66ef9c..a5fd4e638 100644
--- a/mrbgems/mruby-sprintf/test/sprintf.rb
+++ b/mrbgems/mruby-sprintf/test/sprintf.rb
@@ -3,7 +3,8 @@
assert('String#%') do
assert_equal "one=1", "one=%d" % 1
- assert_equal "1 one 1.0", "%d %s %3.1f" % [ 1, "one", 1.01 ]
+ assert_equal "1 one", "%d %s" % [ 1, "one" ]
+ assert_equal "1.0", "%3.1f" % 1.01 if class_defined?("Float")
assert_equal "123 < 456", "%{num} < %<str>s" % { num: 123, str: "456" }
assert_equal 15, ("%b" % (1<<14)).size
end
@@ -34,7 +35,7 @@ assert('String#% with inf') do
assert_equal " Inf", "% 3f" % inf
assert_equal " Inf", "% 4f" % inf
assert_equal " Inf", "% 5f" % inf
-end
+end if class_defined?("Float")
assert('String#% with nan') do
nan = Float::NAN
@@ -62,7 +63,7 @@ assert('String#% with nan') do
assert_equal " NaN", "% 3f" % nan
assert_equal " NaN", "% 4f" % nan
assert_equal " NaN", "% 5f" % nan
-end
+end if class_defined?("Float")
assert("String#% with invalid chr") do
begin
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 5195a7ba0..ddceb03ff 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -68,9 +68,11 @@ mrb_str_byteslice(mrb_state *mrb, mrb_value str)
}
return mrb_nil_value();
}
+#ifndef MRB_WITHOUT_FLOAT
case MRB_TT_FLOAT:
a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
/* fall through */
+#endif
case MRB_TT_FIXNUM:
return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
default:
diff --git a/mrbgems/mruby-test/driver.c b/mrbgems/mruby-test/driver.c
index df9df9e42..434d1fee5 100644
--- a/mrbgems/mruby-test/driver.c
+++ b/mrbgems/mruby-test/driver.c
@@ -95,11 +95,13 @@ mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose)
mrb_define_const(mrb, mrbtest, "FIXNUM_MIN", mrb_fixnum_value(MRB_INT_MIN));
mrb_define_const(mrb, mrbtest, "FIXNUM_BIT", mrb_fixnum_value(MRB_INT_BIT));
+#ifndef MRB_WITHOUT_FLOAT
#ifdef MRB_USE_FLOAT
mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-6));
#else
mrb_define_const(mrb, mrbtest, "FLOAT_TOLERANCE", mrb_float_value(mrb, 1e-12));
#endif
+#endif
if (verbose) {
mrb_gv_set(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"), mrb_true_value());
diff --git a/mrbgems/mruby-test/mrbgem.rake b/mrbgems/mruby-test/mrbgem.rake
index ae4c2f131..49714078b 100644
--- a/mrbgems/mruby-test/mrbgem.rake
+++ b/mrbgems/mruby-test/mrbgem.rake
@@ -7,6 +7,10 @@ MRuby::Gem::Specification.new('mruby-test') do |spec|
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
spec.test_rbfiles = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb")
+ if build.cc.defines.flatten.include?("MRB_WITHOUT_FLOAT")
+ spec.test_rbfiles.delete("#{MRUBY_ROOT}/test/t/float.rb")
+ end
+
clib = "#{build_dir}/mrbtest.c"
mlib = clib.ext(exts.object)
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 30faa85e9..fb394cc89 100644
--- a/src/class.c
+++ b/src/class.c
@@ -827,6 +827,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
break;
+#ifndef MRB_WITHOUT_FLOAT
case 'f':
{
mrb_float *p;
@@ -839,6 +840,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
break;
+#endif
case 'i':
{
mrb_int *p;
@@ -849,6 +851,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]);
@@ -859,6 +862,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;
@@ -1300,9 +1304,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 */
diff --git a/src/etc.c b/src/etc.c
index ccf4f3992..1b8d44a53 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -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)
diff --git a/src/fmt_fp.c b/src/fmt_fp.c
index 0a8b22b41..f8a8f7904 100644
--- a/src/fmt_fp.c
+++ b/src/fmt_fp.c
@@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <mruby.h>
#include <mruby/string.h>
+#ifndef MRB_WITHOUT_FLOAT
struct fmt_args {
mrb_state *mrb;
mrb_value str;
@@ -370,3 +371,4 @@ mrb_float_to_str(mrb_state *mrb, mrb_value flo, const char *fmt)
}
return f.str;
}
+#endif
diff --git a/src/gc.c b/src/gc.c
index 4b83f454b..794a22e9e 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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;
@@ -412,7 +414,7 @@ gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p)
#else
if (gc->arena_idx >= gc->arena_capa) {
/* extend arena */
- gc->arena_capa = (int)(gc->arena_capa * 1.5);
+ gc->arena_capa = (int)(gc->arena_capa * 3 / 2);
gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa);
}
#endif
@@ -735,12 +737,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);
@@ -871,7 +875,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 ec95b04ba..4a20e18c1 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -442,7 +442,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;
@@ -465,7 +467,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;
@@ -894,6 +898,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:
@@ -1252,6 +1266,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 b381bd206..44e3d9836 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();
}
@@ -1276,6 +1393,7 @@ num_infinite_p(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)
{
@@ -1284,12 +1402,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 */
@@ -1307,10 +1429,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);
@@ -1326,11 +1450,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);
@@ -1368,4 +1495,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 f4e63ab84..18d104555 100644
--- a/src/state.c
+++ b/src/state.c
@@ -154,7 +154,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 c1e248dd9..8f0db681c 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>
@@ -2256,6 +2258,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)
{
@@ -2359,6 +2362,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 */
/*
@@ -2760,7 +2764,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());
@@ -2771,6 +2777,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.
*
@@ -3015,3 +3022,4 @@ done:
}
return fraction;
}
+#endif
diff --git a/src/symbol.c b/src/symbol.c
index a3ab05c85..5e1f9f561 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -68,7 +68,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit)
sym = ++mrb->symidx;
if (mrb->symcapa < sym) {
if (mrb->symcapa == 0) mrb->symcapa = 100;
- else mrb->symcapa = (size_t)(mrb->symcapa * 1.2);
+ else mrb->symcapa = (size_t)(mrb->symcapa * 6 / 5);
mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1));
}
sname = &mrb->symtbl[sym];
diff --git a/src/vm.c b/src/vm.c
index 37b7b3c4d..8d5bbc6d8 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -667,7 +667,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:
@@ -990,9 +992,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];
@@ -2175,12 +2179,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]);
@@ -2210,6 +2217,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;
@@ -2233,12 +2241,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]);
@@ -2268,6 +2279,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(-,mrb_float,mrb_float);
#endif
break;
+#endif
default:
goto L_SEND;
}
@@ -2287,12 +2299,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]);
@@ -2322,6 +2337,7 @@ RETRY_TRY_BLOCK:
OP_MATH_BODY(*,mrb_float,mrb_float);
#endif
break;
+#endif
default:
goto L_SEND;
}
@@ -2331,11 +2347,21 @@ RETRY_TRY_BLOCK:
CASE(OP_DIV) {
/* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
int a = GETARG_A(i);
+#ifndef MRB_WITHOUT_FLOAT
double x, y, f;
+#endif
/* need to check if op is overridden */
switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
+#ifdef MRB_WITHOUT_FLOAT
+ {
+ mrb_int x = mrb_fixnum(regs[a]);
+ mrb_int y = mrb_fixnum(regs[a+1]);
+ SET_INT_VALUE(regs[a], y ? x / y : 0);
+ }
+ break;
+#else
x = (mrb_float)mrb_fixnum(regs[a]);
y = (mrb_float)mrb_fixnum(regs[a+1]);
break;
@@ -2351,10 +2377,12 @@ RETRY_TRY_BLOCK:
x = mrb_float(regs[a]);
y = mrb_float(regs[a+1]);
break;
+#endif
default:
goto L_SEND;
}
+#ifndef MRB_WITHOUT_FLOAT
if (y == 0) {
if (x > 0) f = INFINITY;
else if (x < 0) f = -INFINITY;
@@ -2364,6 +2392,7 @@ RETRY_TRY_BLOCK:
f = x / y;
}
SET_FLOAT_VALUE(mrb, regs[a], f);
+#endif
NEXT;
}
@@ -2380,12 +2409,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
{
@@ -2396,6 +2428,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);
@@ -2418,13 +2451,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
{
@@ -2435,6 +2470,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);
@@ -2445,6 +2481,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 */\
@@ -2471,6 +2526,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)*/
diff --git a/test/t/array.rb b/test/t/array.rb
index 7c11265a4..d2edd0189 100644
--- a/test/t/array.rb
+++ b/test/t/array.rb
@@ -55,7 +55,7 @@ assert('Array#[]', '15.2.12.5.4') do
assert_equal(nil, [1,2,3].[](-4))
a = [ "a", "b", "c", "d", "e" ]
- assert_equal("b", a[1.1])
+ assert_equal("b", a[1.1]) if class_defined?("Float")
assert_equal(["b", "c"], a[1,2])
assert_equal(["b", "c", "d"], a[1..-2])
end
diff --git a/test/t/class.rb b/test/t/class.rb
index eb077fce6..a5118fa93 100644
--- a/test/t/class.rb
+++ b/test/t/class.rb
@@ -358,7 +358,7 @@ assert('singleton tests') do
7
end
end
- end
+ end if class_defined?("Float")
end
assert('clone Class') do
diff --git a/test/t/hash.rb b/test/t/hash.rb
index c63b8c009..5403a5901 100644
--- a/test/t/hash.rb
+++ b/test/t/hash.rb
@@ -8,7 +8,7 @@ end
assert('Hash#==', '15.2.13.4.1') do
assert_true({ 'abc' => 'abc' } == { 'abc' => 'abc' })
assert_false({ 'abc' => 'abc' } == { 'cba' => 'cba' })
- assert_true({ :equal => 1 } == { :equal => 1.0 })
+ assert_true({ :equal => 1 } == { :equal => 1.0 }) if class_defined?("Float")
assert_false({ :a => 1 } == true)
end
diff --git a/test/t/integer.rb b/test/t/integer.rb
index d4ef8b519..cea97a1e6 100644
--- a/test/t/integer.rb
+++ b/test/t/integer.rb
@@ -7,56 +7,65 @@ end
assert('Integer#+', '15.2.8.3.1') do
a = 1+1
- b = 1+1.0
+ b = 1+1.0 if class_defined?("Float")
assert_equal 2, a
- assert_equal 2.0, b
+ assert_equal 2.0, b if class_defined?("Float")
assert_raise(TypeError){ 0+nil }
assert_raise(TypeError){ 1+nil }
c = Mrbtest::FIXNUM_MAX + 1
d = Mrbtest::FIXNUM_MAX.__send__(:+, 1)
- e = Mrbtest::FIXNUM_MAX + 1.0
- assert_equal Float, c.class
- assert_equal Float, d.class
- assert_float e, c
- assert_float e, d
+
+ if class_defined?("Float")
+ e = Mrbtest::FIXNUM_MAX + 1.0
+ assert_equal Float, c.class
+ assert_equal Float, d.class
+ assert_float e, c
+ assert_float e, d
+ end
end
assert('Integer#-', '15.2.8.3.2') do
a = 2-1
- b = 2-1.0
+ b = 2-1.0 if class_defined?("Float")
assert_equal 1, a
- assert_equal 1.0, b
+ assert_equal 1.0, b if class_defined?("Float")
c = Mrbtest::FIXNUM_MIN - 1
d = Mrbtest::FIXNUM_MIN.__send__(:-, 1)
- e = Mrbtest::FIXNUM_MIN - 1.0
- assert_equal Float, c.class
- assert_equal Float, d.class
- assert_float e, c
- assert_float e, d
+
+ if class_defined?("Float")
+ e = Mrbtest::FIXNUM_MIN - 1.0
+ assert_equal Float, c.class
+ assert_equal Float, d.class
+ assert_float e, c
+ assert_float e, d
+ end
end
assert('Integer#*', '15.2.8.3.3') do
a = 1*1
- b = 1*1.0
+ b = 1*1.0 if class_defined?("Float")
assert_equal 1, a
- assert_equal 1.0, b
+ assert_equal 1.0, b if class_defined?("Float")
assert_raise(TypeError){ 0*nil }
assert_raise(TypeError){ 1*nil }
c = Mrbtest::FIXNUM_MAX * 2
d = Mrbtest::FIXNUM_MAX.__send__(:*, 2)
- e = Mrbtest::FIXNUM_MAX * 2.0
- assert_equal Float, c.class
- assert_equal Float, d.class
- assert_float e, c
- assert_float e, d
+
+ if class_defined?("Float")
+ e = Mrbtest::FIXNUM_MAX * 2.0
+ assert_equal Float, c.class
+ assert_equal Float, d.class
+ assert_float e, c
+ assert_float e, d
+ end
end
assert('Integer#/', '15.2.8.3.4') do
@@ -218,7 +227,7 @@ end
assert('Integer#to_f', '15.2.8.3.23') do
assert_equal 1.0, 1.to_f
-end
+end if class_defined?("Float")
assert('Integer#to_i', '15.2.8.3.24') do
assert_equal 1, 1.to_i
diff --git a/test/t/numeric.rb b/test/t/numeric.rb
index 120cc960d..38c62a669 100644
--- a/test/t/numeric.rb
+++ b/test/t/numeric.rb
@@ -15,7 +15,7 @@ end
assert('Numeric#abs', '15.2.7.4.3') do
assert_equal(1, 1.abs)
- assert_equal(1.0, -1.abs)
+ assert_equal(1.0, -1.abs) if class_defined?("Float")
end
assert('Numeric#pow') do
diff --git a/test/t/range.rb b/test/t/range.rb
index 5391369de..3e67fcc1c 100644
--- a/test/t/range.rb
+++ b/test/t/range.rb
@@ -8,7 +8,7 @@ end
assert('Range#==', '15.2.14.4.1') do
assert_true (1..10) == (1..10)
assert_false (1..10) == (1..100)
- assert_true (1..10) == Range.new(1.0, 10.0)
+ assert_true (1..10) == Range.new(1.0, 10.0) if class_defined?("Float")
end
assert('Range#===', '15.2.14.4.2') do
diff --git a/test/t/string.rb b/test/t/string.rb
index a4139622a..c9041469e 100644
--- a/test/t/string.rb
+++ b/test/t/string.rb
@@ -154,10 +154,11 @@ assert('String#[]=') do
d[-10] = 'X'
end
- e = 'abc'
- e[1.1] = 'X'
- assert_equal 'aXc', e
-
+ if class_defined?("Float")
+ e = 'abc'
+ e[1.1] = 'X'
+ assert_equal 'aXc', e
+ end
# length of args is 2
a1 = 'abc'
@@ -629,7 +630,7 @@ assert('String#to_f', '15.2.10.5.38') do
assert_float(12345.6789, c)
assert_float(0, d)
assert_float(Float::INFINITY, e)
-end
+end if class_defined?("Float")
assert('String#to_i', '15.2.10.5.39') do
a = ''.to_i