summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/array.c72
-rw-r--r--src/class.c127
-rw-r--r--src/codegen.c138
-rw-r--r--src/crc.c2
-rw-r--r--src/dump.c5
-rw-r--r--src/error.c93
-rw-r--r--src/gc.c52
-rw-r--r--src/hash.c47
-rw-r--r--src/init.c4
-rw-r--r--src/kernel.c104
-rw-r--r--src/keywords78
-rw-r--r--src/lex.def92
-rw-r--r--src/load.c3
-rw-r--r--src/node.h5
-rw-r--r--src/numeric.c157
-rw-r--r--src/object.c19
-rw-r--r--src/opcode.h25
-rw-r--r--src/parse.y1907
-rw-r--r--src/print.c23
-rw-r--r--src/range.c95
-rw-r--r--src/state.c9
-rw-r--r--src/string.c242
-rw-r--r--src/symbol.c208
-rw-r--r--src/value_array.h27
-rw-r--r--src/variable.c81
-rw-r--r--src/vm.c326
26 files changed, 2145 insertions, 1796 deletions
diff --git a/src/array.c b/src/array.c
index 5d7b0e690..ba289997f 100644
--- a/src/array.c
+++ b/src/array.c
@@ -9,6 +9,7 @@
#include <string.h>
#include "mruby/string.h"
#include "mruby/class.h"
+#include "value_array.h"
/* SIZE_MAX is not supported by VC++. */
#ifndef SIZE_MAX
@@ -301,7 +302,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1)
a1 = RARRAY(ary1); a2 = RARRAY(ary2);
if (a1->len == a2->len && a1->ptr == a2->ptr) return mrb_fixnum_value(0);
else {
- mrb_sym cmp = mrb_intern(mrb, "<=>");
+ mrb_sym cmp = mrb_intern2(mrb, "<=>", 3);
len = RARRAY_LEN(ary1);
if (len > RARRAY_LEN(ary2)) {
@@ -519,7 +520,7 @@ mrb_ary_unshift(mrb_state *mrb, mrb_value self, mrb_value item)
ary_modify(mrb, a);
if (a->aux.capa < a->len + 1)
ary_expand_capa(mrb, a, a->len + 1);
- memmove(a->ptr + 1, a->ptr, sizeof(mrb_value)*a->len);
+ value_move(a->ptr + 1, a->ptr, a->len);
a->ptr[0] = item;
}
a->len++;
@@ -546,7 +547,7 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self)
if (len == 0) return self;
if (a->aux.capa < a->len + len)
ary_expand_capa(mrb, a, a->len + len);
- memmove(a->ptr + len, a->ptr, sizeof(mrb_value)*a->len);
+ value_move(a->ptr + len, a->ptr, a->len);
}
array_copy(a->ptr, vals, len);
a->len += len;
@@ -631,7 +632,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val
ary_fill_with_nil(a->ptr + a->len, (int)(head - a->len));
}
else if (head < a->len) {
- memmove(a->ptr + head + argc, a->ptr + tail, sizeof(mrb_value)*(a->len - tail));
+ value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail);
}
for(i = 0; i < argc; i++) {
@@ -702,6 +703,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self)
default:
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
+ break;
}
return mrb_nil_value(); /* dummy to avoid warning : not reach here */
@@ -877,7 +879,7 @@ mrb_ary_empty_p(mrb_state *mrb, mrb_value self)
{
struct RArray *a = mrb_ary_ptr(self);
- return ((a->len == 0)? mrb_true_value(): mrb_false_value());
+ return mrb_bool_value(a->len == 0);
}
mrb_value
@@ -917,7 +919,7 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
mrb_str_buf_cat(mrb, arystr, head, sizeof(head));
for(i=0; i<RARRAY_LEN(ary); i++) {
- mrb_int ai = mrb_gc_arena_save(mrb);
+ int ai = mrb_gc_arena_save(mrb);
if (i > 0) {
mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
@@ -1058,31 +1060,39 @@ static mrb_value
mrb_ary_equal(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
+ mrb_bool equal_p;
mrb_get_args(mrb, "o", &ary2);
- if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
- if (mrb_special_const_p(ary2)) return mrb_false_value();
- if (!mrb_array_p(ary2)) {
- if (!mrb_respond_to(mrb, ary2, mrb_intern(mrb, "to_ary"))) {
- return mrb_false_value();
- }
- if (mrb_equal(mrb, ary2, ary1)){
- return mrb_true_value();
+ if (mrb_obj_equal(mrb, ary1, ary2)) {
+ equal_p = 1;
+ }
+ else if (mrb_special_const_p(ary2)) {
+ equal_p = 0;
+ }
+ else if (!mrb_array_p(ary2)) {
+ if (!mrb_respond_to(mrb, ary2, mrb_intern2(mrb, "to_ary", 6))) {
+ equal_p = 0;
}
else {
- return mrb_false_value();
+ equal_p = mrb_equal(mrb, ary2, ary1);
}
}
- if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
+ else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
+ equal_p = 0;
+ }
else {
mrb_int i;
+ equal_p = 1;
for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
- return mrb_false_value();
+ if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
+ equal_p = 0;
+ break;
+ }
}
- return mrb_true_value();
}
+
+ return mrb_bool_value(equal_p);
}
/* 15.2.12.5.34 (x) */
@@ -1098,20 +1108,30 @@ static mrb_value
mrb_ary_eql(mrb_state *mrb, mrb_value ary1)
{
mrb_value ary2;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &ary2);
- if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value();
- if (!mrb_array_p(ary2)) return mrb_false_value();
- if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value();
+ if (mrb_obj_equal(mrb, ary1, ary2)) {
+ eql_p = 1;
+ }
+ else if (!mrb_array_p(ary2)) {
+ eql_p = 0;
+ }
+ else if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) {
+ eql_p = 0;
+ }
else {
mrb_int i;
-
+ eql_p = 1;
for (i=0; i<RARRAY_LEN(ary1); i++) {
- if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i)))
- return mrb_false_value();
+ if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) {
+ eql_p = 0;
+ break;
+ }
}
- return mrb_true_value();
}
+
+ return mrb_bool_value(eql_p);
}
void
diff --git a/src/class.c b/src/class.c
index a3defc2ae..c421376b8 100644
--- a/src/class.c
+++ b/src/class.c
@@ -7,6 +7,7 @@
#include "mruby.h"
#include <stdarg.h>
#include <ctype.h>
+#include <string.h>
#include "mruby/class.h"
#include "mruby/proc.h"
#include "mruby/string.h"
@@ -53,7 +54,7 @@ void
mrb_name_class(mrb_state *mrb, struct RClass *c, mrb_sym name)
{
mrb_obj_iv_set(mrb, (struct RObject*)c,
- mrb_intern(mrb, "__classid__"), mrb_symbol_value(name));
+ mrb_intern2(mrb, "__classid__", 11), mrb_symbol_value(name));
}
#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
@@ -87,7 +88,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
o->c = sc;
mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o);
- mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern(mrb, "__attached__"), mrb_obj_value(o));
+ mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern2(mrb, "__attached__", 12), mrb_obj_value(o));
}
struct RClass*
@@ -114,7 +115,7 @@ setup_class(mrb_state *mrb, mrb_value outer, struct RClass *c, mrb_sym id)
mrb_name_class(mrb, c, id);
mrb_const_set(mrb, outer, id, mrb_obj_value(c));
mrb_obj_iv_set(mrb, (struct RObject*)c,
- mrb_intern(mrb, "__outer__"), outer);
+ mrb_intern2(mrb, "__outer__", 9), outer);
}
struct RClass*
@@ -122,7 +123,7 @@ mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
{
mrb_value outer;
- outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__outer__"));
+ outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern2(mrb, "__outer__", 9));
if (mrb_nil_p(outer)) return 0;
return mrb_class_ptr(outer);
}
@@ -203,6 +204,12 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
return c;
}
+int
+mrb_class_defined(mrb_state *mrb, const char *name)
+{
+ return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_intern(mrb, name));
+}
+
static struct RClass *
class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
{
@@ -290,17 +297,19 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro
}
void
-mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, int aspec)
+mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
{
struct RProc *p;
+ int ai = mrb_gc_arena_save(mrb);
p = mrb_proc_new_cfunc(mrb, func);
p->target_class = c;
mrb_define_method_raw(mrb, c, mid, p);
+ mrb_gc_arena_restore(mrb, ai);
}
void
-mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec)
+mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
{
mrb_define_method_id(mrb, c, mrb_intern(mrb, name), func, aspec);
}
@@ -400,6 +409,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
if (argc <= i && !opt) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
}
+ break;
}
switch (c) {
@@ -912,26 +922,26 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v)
default:
break;
}
- obj = mrb_object(v);
+ obj = mrb_basic_ptr(v);
prepare_singleton_class(mrb, obj);
return mrb_obj_value(obj->c);
}
void
-mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, int aspec)
+mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
{
prepare_singleton_class(mrb, (struct RBasic*)o);
mrb_define_method_id(mrb, o->c, mrb_intern(mrb, name), func, aspec);
}
void
-mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec)
+mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
{
mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
}
void
-mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, int aspec)
+mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
{
mrb_define_class_method(mrb, c, name, func, aspec);
mrb_define_method(mrb, c, name, func, aspec);
@@ -1080,9 +1090,7 @@ mrb_bob_init(mrb_state *mrb, mrb_value cv)
static mrb_value
mrb_bob_not(mrb_state *mrb, mrb_value cv)
{
- if (mrb_test(cv))
- return mrb_false_value();
- return mrb_true_value();
+ return mrb_bool_value(!mrb_test(cv));
}
/* 15.3.1.3.30 */
@@ -1130,8 +1138,13 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod)
mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol");
}
- inspect = mrb_funcall(mrb, mod, "inspect", 0);
- if (RSTRING_LEN(inspect) > 64) {
+ if (mrb_respond_to(mrb,mod,mrb_intern2(mrb,"inspect",7))){
+ inspect = mrb_funcall(mrb, mod, "inspect", 0);
+ if (RSTRING_LEN(inspect) > 64) {
+ inspect = mrb_any_to_s(mrb, mod);
+ }
+ }
+ else {
inspect = mrb_any_to_s(mrb, mod);
}
@@ -1176,9 +1189,10 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
{
mrb_value path;
const char *name;
- int len;
+ size_t len;
+ mrb_sym classpath = mrb_intern2(mrb, "__classpath__", 13);
- path = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"));
+ path = mrb_obj_iv_get(mrb, (struct RObject*)c, classpath);
if (mrb_nil_p(path)) {
struct RClass *outer = mrb_class_outer_module(mrb, c);
mrb_sym sym = mrb_class_sym(mrb, c, outer);
@@ -1195,7 +1209,7 @@ mrb_class_path(mrb_state *mrb, struct RClass *c)
name = mrb_sym2name_len(mrb, sym, &len);
path = mrb_str_new(mrb, name, len);
}
- mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern(mrb, "__classpath__"), path);
+ mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
}
return path;
}
@@ -1214,10 +1228,9 @@ mrb_class_name(mrb_state *mrb, struct RClass* c)
{
mrb_value path = mrb_class_path(mrb, c);
if (mrb_nil_p(path)) {
- char buf[32];
-
- snprintf(buf, 32, "#<Class:%p>", c);
- path = mrb_str_new_cstr(mrb, buf);
+ path = mrb_str_new(mrb, "#<Class:", 8);
+ mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
+ mrb_str_cat(mrb, path, ">", 1);
}
return mrb_str_ptr(path)->ptr;
}
@@ -1336,51 +1349,54 @@ mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const
static mrb_value
mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
{
+ mrb_value str;
+
if (mrb_type(klass) == MRB_TT_SCLASS) {
- mrb_value s = mrb_str_new(mrb, "#<", 2);
- mrb_value v = mrb_iv_get(mrb, klass, mrb_intern(mrb, "__attached__"));
+ mrb_value v = mrb_iv_get(mrb, klass, mrb_intern2(mrb, "__attached__", 12));
+
+ str = mrb_str_new(mrb, "#<Class:", 8);
- mrb_str_cat2(mrb, s, "Class:");
switch (mrb_type(v)) {
case MRB_TT_CLASS:
case MRB_TT_MODULE:
case MRB_TT_SCLASS:
- mrb_str_append(mrb, s, mrb_inspect(mrb, v));
+ mrb_str_append(mrb, str, mrb_inspect(mrb, v));
break;
default:
- mrb_str_append(mrb, s, mrb_any_to_s(mrb, v));
+ mrb_str_append(mrb, str, mrb_any_to_s(mrb, v));
break;
}
- mrb_str_cat2(mrb, s, ">");
-
- return s;
+ mrb_str_cat(mrb, str, ">", 1);
}
else {
+ str = mrb_str_buf_new(mrb, 32);
struct RClass *c = mrb_class_ptr(klass);
- const char *cn = mrb_class_name(mrb, c);
-
- if (!cn) {
- char buf[256];
- int n = 0;
+ mrb_value path = mrb_class_path(mrb, c);
+ if (mrb_nil_p(path)) {
switch (mrb_type(klass)) {
case MRB_TT_CLASS:
- n = snprintf(buf, sizeof(buf), "#<Class:%p>", c);
+ mrb_str_cat(mrb, str, "#<Class:", 8);
break;
case MRB_TT_MODULE:
- n = snprintf(buf, sizeof(buf), "#<Module:%p>", c);
+ mrb_str_cat(mrb, str, "#<Module:", 9);
break;
default:
+ /* Shouldn't be happened? */
+ mrb_str_cat(mrb, str, "#<??????:", 9);
break;
}
- return mrb_str_dup(mrb, mrb_str_new(mrb, buf, n));
+ mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c));
+ mrb_str_cat(mrb, str, ">", 1);
}
else {
- return mrb_str_dup(mrb, mrb_str_new_cstr(mrb, cn));
+ str = path;
}
}
+
+ return str;
}
mrb_value
@@ -1453,7 +1469,7 @@ static void
check_cv_name(mrb_state *mrb, mrb_sym id)
{
const char *s;
- int len;
+ size_t len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 3 || !(s[0] == '@' && s[1] == '@')) {
@@ -1480,12 +1496,12 @@ static mrb_value
mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod)
{
mrb_sym id;
+ mrb_bool defined_p;
mrb_get_args(mrb, "n", &id);
check_cv_name(mrb, id);
- if(mrb_cv_defined(mrb, mod, id))
- return mrb_true_value();
- return mrb_false_value();
+ defined_p = mrb_cv_defined(mrb, mod, id);
+ return mrb_bool_value(defined_p);
}
/* 15.2.2.4.17 */
@@ -1621,12 +1637,11 @@ static mrb_value
mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
{
mrb_sym id;
+ mrb_bool method_defined_p;
mrb_get_args(mrb, "n", &id);
- if (mrb_obj_respond_to(mrb_class_ptr(mod), id)) {
- return mrb_true_value();
- }
- return mrb_false_value();
+ method_defined_p = mrb_obj_respond_to(mrb_class_ptr(mod), id);
+ return mrb_bool_value(method_defined_p);
}
static void
@@ -1675,7 +1690,7 @@ static void
check_const_name(mrb_state *mrb, mrb_sym id)
{
const char *s;
- int len;
+ size_t len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 1 || !ISUPPER(*s)) {
@@ -1687,13 +1702,13 @@ mrb_value
mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
{
mrb_sym id;
+ mrb_bool const_defined_p;
mrb_get_args(mrb, "n", &id);
check_const_name(mrb, id);
- if(mrb_const_defined(mrb, mod, id)) {
- return mrb_true_value();
- }
- return mrb_false_value();
+ const_defined_p = mrb_const_defined(mrb, mod, id);
+
+ return mrb_bool_value(const_defined_p);
}
mrb_value
@@ -1737,11 +1752,12 @@ static mrb_value
mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
{
mrb_value obj;
+ mrb_bool eqq;
mrb_get_args(mrb, "o", &obj);
- if (!mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod)))
- return mrb_false_value();
- return mrb_true_value();
+ eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
+
+ return mrb_bool_value(eqq);
}
void
@@ -1789,6 +1805,7 @@ mrb_init_class(mrb_state *mrb)
mrb_define_method(mrb, cls, "new", mrb_instance_new, ARGS_ANY()); /* 15.2.3.3.3 */
mrb_define_method(mrb, cls, "inherited", mrb_bob_init, ARGS_REQ(1));
+ MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, ARGS_REQ(1)); /* 15.2.2.4.16 */
mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, ARGS_REQ(1)); /* 15.2.2.4.17 */
mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, ARGS_REQ(2)); /* 15.2.2.4.18 */
diff --git a/src/codegen.c b/src/codegen.c
index ed44f1792..5b86c90a9 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -4,8 +4,6 @@
** See Copyright Notice in mruby.h
*/
-#define CODEGEN_DUMP
-
#include "mruby.h"
#include "mruby/string.h"
#include "mruby/irep.h"
@@ -49,7 +47,7 @@ typedef struct scope {
int pc;
int lastlabel;
int ainfo:15;
- int mscope:1;
+ mrb_bool mscope:1;
struct loopinfo *loop;
int ensure_level;
@@ -379,6 +377,7 @@ dispatch(codegen_scope *s, int pc)
fprintf(stderr, "bug: dispatch on non JMP op\n");
#endif
scope_error(s);
+ break;
}
s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
}
@@ -540,11 +539,11 @@ for_body(codegen_scope *s, node *tree)
// generate loop variable
n2 = tree->car;
if (n2->car && !n2->car->cdr && !n2->cdr) {
- genop(s, MKOP_Ax(OP_ENTER, 1<<18));
+ genop(s, MKOP_Ax(OP_ENTER, 0x40000));
gen_assignment(s, n2->car->car, 1, NOVAL);
}
else {
- genop(s, MKOP_Ax(OP_ENTER, 1<<18));
+ genop(s, MKOP_Ax(OP_ENTER, 0x40000));
gen_vmassignment(s, n2, 1, VAL);
}
codegen(s, tree->cdr->cdr->car, VAL);
@@ -559,7 +558,7 @@ for_body(codegen_scope *s, node *tree)
s = prev;
genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx - base, OP_L_BLOCK));
pop();
- idx = new_msym(s, mrb_intern(s->mrb, "each"));
+ idx = new_msym(s, mrb_intern2(s->mrb, "each", 4));
genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
}
@@ -579,7 +578,8 @@ lambda_body(codegen_scope *s, node *tree, int blk)
}
tree = tree->cdr;
if (tree->car) {
- int ma, oa, ra, pa, ka, kd, ba, a;
+ int32_t a;
+ int ma, oa, ra, pa, ka, kd, ba;
int pos, i;
node *n, *opt;
@@ -594,8 +594,8 @@ lambda_body(codegen_scope *s, node *tree, int blk)
ka = kd = 0;
ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0;
- a = ((ma & 0x1f) << 18)
- | ((oa & 0x1f) << 13)
+ a = ((int32_t)(ma & 0x1f) << 18)
+ | ((int32_t)(oa & 0x1f) << 13)
| ((ra & 1) << 12)
| ((pa & 0x1f) << 7)
| ((ka & 0x1f) << 2)
@@ -690,7 +690,7 @@ static mrb_sym
attrsym(codegen_scope *s, mrb_sym a)
{
const char *name;
- int len;
+ size_t len;
char *name2;
name = mrb_sym2name_len(s->mrb, a, &len);
@@ -789,7 +789,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
}
pop_n(n+1);
{
- int len;
+ size_t len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
if (!noop && len == 1 && name[0] == '+') {
@@ -955,6 +955,68 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
}
static void
+gen_send_intern(codegen_scope *s)
+{
+ pop();
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "intern", 6)), 0));
+ push();
+}
+static void
+gen_literal_array(codegen_scope *s, node *tree, int sym, int val)
+{
+ if (val) {
+ int i = 0, j = 0;
+
+ while (tree) {
+ switch ((intptr_t)tree->car->car) {
+ case NODE_STR:
+ if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
+ break;
+ /* fall through */
+ case NODE_BEGIN:
+ codegen(s, tree->car, VAL);
+ ++j;
+ break;
+
+ case NODE_LITERAL_DELIM:
+ if (j > 0) {
+ j = 0;
+ ++i;
+ if (sym)
+ gen_send_intern(s);
+ }
+ break;
+ }
+ if (j >= 2) {
+ pop(); pop();
+ genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
+ push();
+ j = 1;
+ }
+ tree = tree->cdr;
+ }
+ if (j > 0) {
+ j = 0;
+ ++i;
+ if (sym)
+ gen_send_intern(s);
+ }
+ pop_n(i);
+ genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
+ push();
+ }
+ else {
+ while (tree) {
+ switch ((intptr_t)tree->car->car) {
+ case NODE_BEGIN: case NODE_BLOCK:
+ codegen(s, tree->car, NOVAL);
+ }
+ tree = tree->cdr;
+ }
+ }
+}
+
+static void
raise_error(codegen_scope *s, const char *msg)
{
int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
@@ -1088,12 +1150,12 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n4->car, VAL);
}
else {
- genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern(s->mrb, "StandardError"))));
+ genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern2(s->mrb, "StandardError", 13))));
push();
}
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
pop();
- genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1));
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
pos2 = tmp;
@@ -1297,7 +1359,7 @@ codegen(codegen_scope *s, node *tree, int val)
if (head) {
genop(s, MKOP_AB(OP_MOVE, cursp(), head));
pop();
- genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1));
}
else {
pop();
@@ -1491,7 +1553,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_OP_ASGN:
{
mrb_sym sym = sym(tree->cdr->car);
- int len;
+ size_t len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
int idx;
@@ -1638,7 +1700,7 @@ codegen(codegen_scope *s, node *tree, int val)
}
pop_n(n+1);
if (sendv) n = CALL_MAXARGS;
- genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "call")), n));
+ genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "call", 4)), n));
if (val) push();
}
break;
@@ -1905,7 +1967,7 @@ codegen(codegen_scope *s, node *tree, int val)
default:
{
- int sym = new_msym(s, mrb_intern(s->mrb, "-"));
+ int sym = new_msym(s, mrb_intern2(s->mrb, "-", 1));
genop(s, MKOP_ABx(OP_LOADI, cursp(), 0));
push();
@@ -1932,9 +1994,7 @@ codegen(codegen_scope *s, node *tree, int val)
break;
case NODE_HEREDOC:
- /*if(tree == NULL){printf("heredoc error 1\n");exit(11);}*/
tree = ((struct mrb_parser_heredoc_info *)tree)->doc;
- /*if(tree == NULL){printf("heredoc error 2\n");exit(12);}*/
/* fall through */
case NODE_DSTR:
if (val) {
@@ -1962,6 +2022,34 @@ codegen(codegen_scope *s, node *tree, int val)
}
break;
+ case NODE_WORDS:
+ gen_literal_array(s, tree, FALSE, val);
+ break;
+
+ case NODE_SYMBOLS:
+ gen_literal_array(s, tree, TRUE, val);
+ break;
+
+ case NODE_XSTR:
+ if (val) {
+ char *p = (char*)tree->car;
+ size_t len = (intptr_t)tree->cdr;
+ int ai = mrb_gc_arena_save(s->mrb);
+ int sym = new_sym(s, mrb_intern2(s->mrb, "Kernel", 6));
+ int off = new_lit(s, mrb_str_new(s->mrb, p, len));
+
+ genop(s, MKOP_A(OP_OCLASS, cursp()));
+ genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
+ push();
+ genop(s, MKOP_ABx(OP_STRING, cursp(), off));
+ pop();
+ sym = new_sym(s, mrb_intern2(s->mrb, "`", 1));
+ genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
+ mrb_gc_arena_restore(s->mrb, ai);
+ push();
+ }
+ break;
+
case NODE_REGX:
if (val) {
char *p1 = (char*)tree->car;
@@ -1983,7 +2071,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
}
pop();
- sym = new_sym(s, mrb_intern(s->mrb, "compile"));
+ sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
mrb_gc_arena_restore(s->mrb, ai);
push();
@@ -2031,7 +2119,7 @@ codegen(codegen_scope *s, node *tree, int val)
pop();
}
pop();
- sym = new_sym(s, mrb_intern(s->mrb, "compile"));
+ sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7));
genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
mrb_gc_arena_restore(s->mrb, ai);
push();
@@ -2060,9 +2148,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_DSYM:
codegen(s, tree, val);
if (val) {
- pop();
- genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "intern")), 0));
- push();
+ gen_send_intern(s);
}
break;
@@ -2098,7 +2184,7 @@ codegen(codegen_scope *s, node *tree, int val)
{
int a = new_msym(s, sym(tree->car));
int b = new_msym(s, sym(tree->cdr));
- int c = new_msym(s, mrb_intern(s->mrb, "alias_method"));
+ int c = new_msym(s, mrb_intern2(s->mrb, "alias_method", 12));
genop(s, MKOP_A(OP_TCLASS, cursp()));
push();
@@ -2117,7 +2203,7 @@ codegen(codegen_scope *s, node *tree, int val)
case NODE_UNDEF:
{
- int undef = new_msym(s, mrb_intern(s->mrb, "undef_method"));
+ int undef = new_msym(s, mrb_intern2(s->mrb, "undef_method", 12));
int num = 0;
node *t = tree;
diff --git a/src/crc.c b/src/crc.c
index c150f966b..a54909fdb 100644
--- a/src/crc.c
+++ b/src/crc.c
@@ -13,7 +13,7 @@
// carry
#define CRC_16_CCITT 0x11021ul //x^16+x^12+x^5+1
#define CRC_XOR_PATTERN (CRC_16_CCITT << 8)
-#define CRC_CARRY_BIT (1 << 24)
+#define CRC_CARRY_BIT (0x01000000)
uint16_t
calc_crc_16_ccitt(unsigned char *src, int nbytes)
diff --git a/src/dump.c b/src/dump.c
index ba5a69a56..9666f7562 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -279,7 +279,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type)
size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */
if (irep->syms[sym_no] != 0) {
- int len;
+ size_t len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
nlen = str_dump_len((char*)name, len, type);
@@ -421,9 +421,10 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type)
uint16_t nlen =0;
if (irep->syms[sym_no] != 0) {
- int len;
+ size_t len;
name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len);
+ if (len > UINT16_MAX) goto error_exit;
nlen = str_dump_len((char*)name, len, type);
if ( nlen > buf_size - 1) {
buf_size = nlen + 1;
diff --git a/src/error.c b/src/error.c
index ed30173bc..f46887465 100644
--- a/src/error.c
+++ b/src/error.c
@@ -5,7 +5,9 @@
*/
#include "mruby.h"
+#include <errno.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
#include "error.h"
@@ -42,7 +44,7 @@ exc_initialize(mrb_state *mrb, mrb_value exc)
mrb_value mesg;
if (mrb_get_args(mrb, "|o", &mesg) == 1) {
- mrb_iv_set(mrb, exc, mrb_intern(mrb, "mesg"), mesg);
+ mrb_iv_set(mrb, exc, mrb_intern2(mrb, "mesg", 4), mesg);
}
return exc;
}
@@ -71,7 +73,7 @@ exc_exception(mrb_state *mrb, mrb_value self)
if (argc == 0) return self;
if (mrb_obj_equal(mrb, self, a)) return self;
exc = mrb_obj_clone(mrb, self);
- mrb_iv_set(mrb, exc, mrb_intern(mrb, "mesg"), a);
+ mrb_iv_set(mrb, exc, mrb_intern2(mrb, "mesg", 4), a);
return exc;
}
@@ -87,9 +89,9 @@ exc_exception(mrb_state *mrb, mrb_value self)
static mrb_value
exc_to_s(mrb_state *mrb, mrb_value exc)
{
- mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg"));
+ mrb_value mesg = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "mesg", 4));
- if (mrb_nil_p(mesg)) return mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
+ if (mrb_nil_p(mesg)) return mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
return mesg;
}
@@ -121,32 +123,32 @@ exc_inspect(mrb_state *mrb, mrb_value exc)
{
mrb_value str, mesg, file, line;
- mesg = mrb_attr_get(mrb, exc, mrb_intern(mrb, "mesg"));
- file = mrb_attr_get(mrb, exc, mrb_intern(mrb, "file"));
- line = mrb_attr_get(mrb, exc, mrb_intern(mrb, "line"));
+ mesg = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "mesg", 4));
+ file = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "file", 4));
+ line = mrb_attr_get(mrb, exc, mrb_intern2(mrb, "line", 4));
if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
str = file;
- mrb_str_cat2(mrb, str, ":");
+ mrb_str_cat(mrb, str, ":", 1);
mrb_str_append(mrb, str, line);
- mrb_str_cat2(mrb, str, ": ");
+ mrb_str_cat(mrb, str, ": ", 2);
if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
mrb_str_append(mrb, str, mesg);
- mrb_str_cat2(mrb, str, " (");
+ mrb_str_cat(mrb, str, " (", 2);
}
- mrb_str_cat2(mrb, str, mrb_obj_classname(mrb, exc));
+ mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
- mrb_str_cat2(mrb, str, ")");
+ mrb_str_cat(mrb, str, ")", 1);
}
}
else {
- str = mrb_str_new2(mrb, mrb_obj_classname(mrb, exc));
+ str = mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc));
if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) {
- mrb_str_cat2(mrb, str, ": ");
+ mrb_str_cat(mrb, str, ": ", 2);
mrb_str_append(mrb, str, mesg);
} else {
- mrb_str_cat2(mrb, str, ": ");
- mrb_str_cat2(mrb, str, mrb_obj_classname(mrb, exc));
+ mrb_str_cat(mrb, str, ": ", 2);
+ mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
}
}
return str;
@@ -158,25 +160,29 @@ exc_equal(mrb_state *mrb, mrb_value exc)
{
mrb_value obj;
mrb_value mesg;
- mrb_sym id_mesg = mrb_intern(mrb, "mesg");
+ mrb_bool equal_p;
+ mrb_sym id_mesg = mrb_intern2(mrb, "mesg", 4);
mrb_get_args(mrb, "o", &obj);
- if (mrb_obj_equal(mrb, exc, obj)) return mrb_true_value();
-
- if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
- if (mrb_respond_to(mrb, obj, mrb_intern(mrb, "message"))) {
- mesg = mrb_funcall(mrb, obj, "message", 0);
- }
- else
- return mrb_false_value();
+ if (mrb_obj_equal(mrb, exc, obj)) {
+ equal_p = 1;
}
else {
- mesg = mrb_attr_get(mrb, obj, id_mesg);
+ if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
+ if (mrb_respond_to(mrb, obj, mrb_intern2(mrb, "message", 7))) {
+ mesg = mrb_funcall(mrb, obj, "message", 0);
+ }
+ else
+ return mrb_false_value();
+ }
+ else {
+ mesg = mrb_attr_get(mrb, obj, id_mesg);
+ }
+
+ equal_p = mrb_equal(mrb, mrb_attr_get(mrb, exc, id_mesg), mesg);
}
- if (!mrb_equal(mrb, mrb_attr_get(mrb, exc, id_mesg), mesg))
- return mrb_false_value();
- return mrb_true_value();
+ return mrb_bool_value(equal_p);
}
static void
@@ -185,15 +191,15 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
mrb_callinfo *ci = mrb->ci;
mrb_code *pc = ci->pc;
- mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->cibase));
+ mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->cibase));
ci--;
while (ci >= mrb->cibase) {
if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
mrb_irep *irep = ci->proc->body.irep;
if (irep->filename && irep->lines && irep->iseq <= pc && pc < irep->iseq + irep->ilen) {
- mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "file"), mrb_str_new_cstr(mrb, irep->filename));
- mrb_obj_iv_set(mrb, exc, mrb_intern(mrb, "line"), mrb_fixnum_value(irep->lines[pc - irep->iseq - 1]));
+ mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "file", 4), mrb_str_new_cstr(mrb, irep->filename));
+ mrb_obj_iv_set(mrb, exc, mrb_intern2(mrb, "line", 4), mrb_fixnum_value(irep->lines[pc - irep->iseq - 1]));
return;
}
}
@@ -205,7 +211,7 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc)
void
mrb_exc_raise(mrb_state *mrb, mrb_value exc)
{
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
exc_debug_info(mrb, mrb->exc);
if (!mrb->jmp) {
mrb_p(mrb, exc);
@@ -218,7 +224,7 @@ void
mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
{
mrb_value mesg;
- mesg = mrb_str_new2(mrb, msg);
+ mesg = mrb_str_new_cstr(mrb, msg);
mrb_exc_raise(mrb, mrb_exc_new3(mrb, c, mesg));
}
@@ -329,7 +335,7 @@ mrb_bug_errno(const char *mesg, int errno_arg)
int
sysexit_status(mrb_state *mrb, mrb_value err)
{
- mrb_value st = mrb_iv_get(mrb, err, mrb_intern(mrb, "status"));
+ mrb_value st = mrb_iv_get(mrb, err, mrb_intern2(mrb, "status", 6));
return mrb_fixnum(st);
}
@@ -367,7 +373,7 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
n = 1;
exception_call:
{
- mrb_sym exc = mrb_intern(mrb, "exception");
+ mrb_sym exc = mrb_intern2(mrb, "exception", 9);
if (mrb_respond_to(mrb, argv[0], exc)) {
mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
}
@@ -401,7 +407,20 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv)
void
mrb_sys_fail(mrb_state *mrb, const char *mesg)
{
- mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ struct RClass *sce;
+ mrb_int no;
+
+ no = (mrb_int)errno;
+ if (mrb_class_defined(mrb, "SystemCallError")) {
+ sce = mrb_class_get(mrb, "SystemCallError");
+ if (mesg != NULL) {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg));
+ } else {
+ mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no));
+ }
+ } else {
+ mrb_raise(mrb, E_RUNTIME_ERROR, mesg);
+ }
}
void
diff --git a/src/gc.c b/src/gc.c
index da6844fa5..f8d25e5ec 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -197,7 +197,7 @@ struct heap_page {
struct heap_page *next;
struct heap_page *free_next;
struct heap_page *free_prev;
- unsigned int old:1;
+ mrb_bool old:1;
RVALUE objects[MRB_HEAP_PAGE_SIZE];
};
@@ -322,7 +322,7 @@ void
mrb_gc_protect(mrb_state *mrb, mrb_value obj)
{
if (mrb_special_const_p(obj)) return;
- gc_protect(mrb, mrb_basic(obj));
+ gc_protect(mrb, mrb_basic_ptr(obj));
}
struct RBasic*
@@ -542,7 +542,9 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
static void
root_scan_phase(mrb_state *mrb)
{
- int i, j, e;
+ int j;
+ size_t i;
+ size_t e;
mrb_callinfo *ci;
if (!is_minor_gc(mrb)) {
@@ -982,8 +984,8 @@ gc_enable(mrb_state *mrb, mrb_value obj)
int old = mrb->gc_disabled;
mrb->gc_disabled = FALSE;
- if (old) return mrb_true_value();
- return mrb_false_value();
+
+ return mrb_bool_value(old);
}
/*
@@ -1004,8 +1006,8 @@ gc_disable(mrb_state *mrb, mrb_value obj)
int old = mrb->gc_disabled;
mrb->gc_disabled = TRUE;
- if (old) return mrb_true_value();
- return mrb_false_value();
+
+ return mrb_bool_value(old);
}
/*
@@ -1101,10 +1103,7 @@ change_gen_gc_mode(mrb_state *mrb, mrb_int enable)
static mrb_value
gc_generational_mode_get(mrb_state *mrb, mrb_value self)
{
- if (mrb->is_generational_gc_mode)
- return mrb_true_value();
- else
- return mrb_false_value();
+ return mrb_bool_value(mrb->is_generational_gc_mode);
}
/*
@@ -1124,10 +1123,7 @@ gc_generational_mode_set(mrb_state *mrb, mrb_value self)
if (mrb->is_generational_gc_mode != enable)
change_gen_gc_mode(mrb, enable);
- if (enable)
- return mrb_true_value();
- else
- return mrb_false_value();
+ return mrb_bool_value(enable);
}
#ifdef GC_TEST
@@ -1168,8 +1164,8 @@ test_mrb_field_write_barrier(void)
puts("test_mrb_field_write_barrier");
mrb->is_generational_gc_mode = FALSE;
- obj = mrb_basic(mrb_ary_new(mrb));
- value = mrb_basic(mrb_str_new_cstr(mrb, "value"));
+ obj = mrb_basic_ptr(mrb_ary_new(mrb));
+ value = mrb_basic_ptr(mrb_str_new_cstr(mrb, "value"));
paint_black(obj);
paint_partial_white(mrb,value);
@@ -1210,15 +1206,15 @@ test_mrb_field_write_barrier(void)
{
puts("test_mrb_field_write_barrier_value");
- obj = mrb_basic(mrb_ary_new(mrb));
+ obj = mrb_basic_ptr(mrb_ary_new(mrb));
mrb_value value = mrb_str_new_cstr(mrb, "value");
paint_black(obj);
- paint_partial_white(mrb, mrb_basic(value));
+ paint_partial_white(mrb, mrb_basic_ptr(value));
mrb->gc_state = GC_STATE_MARK;
mrb_field_write_barrier_value(mrb, obj, value);
- gc_assert(is_gray(mrb_basic(value)));
+ gc_assert(is_gray(mrb_basic_ptr(value)));
}
mrb_close(mrb);
@@ -1231,7 +1227,7 @@ test_mrb_write_barrier(void)
struct RBasic *obj;
puts("test_mrb_write_barrier");
- obj = mrb_basic(mrb_ary_new(mrb));
+ obj = mrb_basic_ptr(mrb_ary_new(mrb));
paint_black(obj);
puts(" in GC_STATE_MARK");
@@ -1260,12 +1256,12 @@ test_add_gray_list(void)
puts("test_add_gray_list");
change_gen_gc_mode(mrb, FALSE);
gc_assert(mrb->gray_list == NULL);
- obj1 = mrb_basic(mrb_str_new_cstr(mrb, "test"));
+ obj1 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj1);
gc_assert(mrb->gray_list == obj1);
gc_assert(is_gray(obj1));
- obj2 = mrb_basic(mrb_str_new_cstr(mrb, "test"));
+ obj2 = mrb_basic_ptr(mrb_str_new_cstr(mrb, "test"));
add_gray_list(mrb, obj2);
gc_assert(mrb->gray_list == obj2);
gc_assert(mrb->gray_list->gcnext == obj1);
@@ -1294,12 +1290,12 @@ test_gc_gray_mark(void)
puts(" in MRB_TT_ARRAY");
obj_v = mrb_ary_new(mrb);
value_v = mrb_str_new_cstr(mrb, "test");
- paint_gray(mrb_basic(obj_v));
- paint_partial_white(mrb, mrb_basic(value_v));
+ paint_gray(mrb_basic_ptr(obj_v));
+ paint_partial_white(mrb, mrb_basic_ptr(value_v));
mrb_ary_push(mrb, obj_v, value_v);
- gray_num = gc_gray_mark(mrb, mrb_basic(obj_v));
- gc_assert(is_black(mrb_basic(obj_v)));
- gc_assert(is_gray(mrb_basic(value_v)));
+ gray_num = gc_gray_mark(mrb, mrb_basic_ptr(obj_v));
+ gc_assert(is_black(mrb_basic_ptr(obj_v)));
+ gc_assert(is_gray(mrb_basic_ptr(value_v)));
gc_assert(gray_num == 1);
mrb_close(mrb);
diff --git a/src/hash.c b/src/hash.c
index 728fc0f2f..8de7b55c8 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -15,7 +15,7 @@
static inline khint_t
mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key)
{
- khint_t h = mrb_type(key) << 24;
+ khint_t h = (khint_t)mrb_type(key) << 24;
mrb_value h2;
h2 = mrb_funcall(mrb, key, "hash", 0, 0);
@@ -52,11 +52,15 @@ mrb_gc_mark_ht(mrb_state *mrb, struct RHash *hash)
khash_t(ht) *h = hash->ht;
if (!h) return;
- for (k = kh_begin(h); k != kh_end(h); k++)
+ for (k = kh_begin(h); k != kh_end(h); k++) {
if (kh_exist(h, k)) {
- mrb_gc_mark_value(mrb, kh_key(h, k));
- mrb_gc_mark_value(mrb, kh_value(h, k));
+ mrb_value key = kh_key(h, k);
+ mrb_value val = kh_value(h, k);
+
+ mrb_gc_mark_value(mrb, key);
+ mrb_gc_mark_value(mrb, val);
}
+ }
}
size_t
@@ -258,7 +262,7 @@ mrb_hash_init_core(mrb_state *mrb, mrb_value hash)
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
ifnone = block;
}
- mrb_iv_set(mrb, hash, mrb_intern(mrb, "ifnone"), ifnone);
+ mrb_iv_set(mrb, hash, mrb_intern2(mrb, "ifnone", 6), ifnone);
return hash;
}
@@ -423,7 +427,7 @@ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
mrb_get_args(mrb, "o", &ifnone);
mrb_hash_modify(mrb, hash);
- mrb_iv_set(mrb, hash, mrb_intern(mrb, "ifnone"), ifnone);
+ mrb_iv_set(mrb, hash, mrb_intern2(mrb, "ifnone", 6), ifnone);
RHASH(hash)->flags &= ~(MRB_HASH_PROC_DEFAULT);
return ifnone;
@@ -474,7 +478,7 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
mrb_get_args(mrb, "o", &ifnone);
mrb_hash_modify(mrb, hash);
- mrb_iv_set(mrb, hash, mrb_intern(mrb, "ifnone"), ifnone);
+ mrb_iv_set(mrb, hash, mrb_intern2(mrb, "ifnone", 6), ifnone);
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
return ifnone;
@@ -755,7 +759,7 @@ mrb_hash_replace(mrb_state *mrb, mrb_value hash)
else {
ifnone = RHASH_IFNONE(hash2);
}
- mrb_iv_set(mrb, hash, mrb_intern(mrb, "ifnone"), ifnone);
+ mrb_iv_set(mrb, hash, mrb_intern2(mrb, "ifnone", 6), ifnone);
return hash;
}
@@ -797,13 +801,16 @@ static mrb_value
mrb_hash_empty_p(mrb_state *mrb, mrb_value self)
{
khash_t(ht) *h = RHASH_TBL(self);
+ mrb_bool empty_p;
if (h) {
- if (kh_size(h) == 0)
- return mrb_true_value();
- return mrb_false_value();
+ empty_p = (kh_size(h) == 0);
}
- return mrb_true_value();
+ else {
+ empty_p = 1;
+ }
+
+ return mrb_bool_value(empty_p);
}
/* 15.2.13.4.11 */
@@ -887,7 +894,7 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur)
ai = mrb_gc_arena_save(mrb);
- if (RSTRING_LEN(str) > 1) mrb_str_cat2(mrb, str, ", ");
+ if (RSTRING_LEN(str) > 1) mrb_str_cat(mrb, str, ", ", 2);
str2 = mrb_inspect(mrb, kh_key(h,k));
mrb_str_append(mrb, str, str2);
@@ -1006,14 +1013,17 @@ mrb_hash_has_keyWithKey(mrb_state *mrb, mrb_value hash, mrb_value key)
{
khash_t(ht) *h = RHASH_TBL(hash);
khiter_t k;
+ mrb_bool result;
if (h) {
k = kh_get(ht, h, key);
- if (k != kh_end(h))
- return mrb_true_value();
+ result = (k != kh_end(h));
+ }
+ else {
+ result = 0;
}
- return mrb_false_value();
+ return mrb_bool_value(result);
}
/* 15.2.13.4.13 */
@@ -1094,7 +1104,7 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
if (!mrb_hash_p(hash2)) {
- if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
+ if (!mrb_respond_to(mrb, hash2, mrb_intern2(mrb, "to_hash", 7))) {
return mrb_false_value();
}
if (eql)
@@ -1105,8 +1115,7 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
h1 = RHASH_TBL(hash1);
h2 = RHASH_TBL(hash2);
if (!h1) {
- if (!h2) return mrb_true_value();
- return mrb_false_value();
+ return mrb_bool_value(!h2);
}
if (!h2) return mrb_false_value();
if (kh_size(h1) != kh_size(h2)) return mrb_false_value();
diff --git a/src/init.c b/src/init.c
index 0d1a24881..e97c72d68 100644
--- a/src/init.c
+++ b/src/init.c
@@ -21,7 +21,6 @@ void mrb_init_hash(mrb_state*);
void mrb_init_numeric(mrb_state*);
void mrb_init_range(mrb_state*);
void mrb_init_gc(mrb_state*);
-void mrb_init_print(mrb_state*);
void mrb_init_math(mrb_state*);
void mrb_init_mrblib(mrb_state*);
void mrb_init_mrbgems(mrb_state*);
@@ -48,9 +47,6 @@ mrb_init_core(mrb_state *mrb)
mrb_init_numeric(mrb); DONE;
mrb_init_range(mrb); DONE;
mrb_init_gc(mrb); DONE;
-#ifdef ENABLE_STDIO
- mrb_init_print(mrb); DONE;
-#endif
mrb_init_mrblib(mrb); DONE;
#ifndef DISABLE_GEMS
mrb_init_mrbgems(mrb); DONE;
diff --git a/src/kernel.c b/src/kernel.c
index 7187a125d..0c746d987 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -29,7 +29,7 @@ typedef enum {
int
mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
{
- struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern(mrb, "to_s"));
+ struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern2(mrb, "to_s", 4));
if (me && MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
return TRUE;
return FALSE;
@@ -96,28 +96,24 @@ static mrb_value
mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &arg);
- if (mrb_obj_equal(mrb, self, arg)) {
- return mrb_true_value();
- }
- else {
- return mrb_false_value();
- }
+ eql_p = mrb_obj_equal(mrb, self, arg);
+
+ return mrb_bool_value(eql_p);
}
static mrb_value
mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &arg);
- if (mrb_equal(mrb, self, arg)) {
- return mrb_false_value();
- }
- else {
- return mrb_true_value();
- }
+ eql_p = mrb_obj_equal(mrb, self, arg);
+
+ return mrb_bool_value(!eql_p);
}
/* 15.3.1.3.2 */
@@ -133,14 +129,12 @@ static mrb_value
mrb_equal_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
+ mrb_bool equal_p;
mrb_get_args(mrb, "o", &arg);
- if (mrb_equal(mrb, self, arg)){
- return mrb_true_value();
- }
- else {
- return mrb_false_value();
- }
+ equal_p = mrb_equal(mrb, self, arg);
+
+ return mrb_bool_value(equal_p);
}
/* 15.3.1.3.3 */
@@ -225,21 +219,28 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
{
mrb_callinfo *ci = mrb->ci;
mrb_value *bp;
+ mrb_bool given_p;
bp = mrb->stbase + ci->stackidx + 1;
ci--;
- if (ci <= mrb->cibase) return mrb_false_value();
- /* block_given? called within block; check upper scope */
- if (ci->proc->env && ci->proc->env->stack) {
- if (ci->proc->env->stack == mrb->stbase || mrb_nil_p(ci->proc->env->stack[1]))
- return mrb_false_value();
- return mrb_true_value();
+ if (ci <= mrb->cibase) {
+ given_p = 0;
}
- if (ci->argc > 0) {
- bp += ci->argc;
+ else {
+ /* block_given? called within block; check upper scope */
+ if (ci->proc->env && ci->proc->env->stack) {
+ given_p = !(ci->proc->env->stack == mrb->stbase ||
+ mrb_nil_p(ci->proc->env->stack[1]));
+ }
+ else {
+ if (ci->argc > 0) {
+ bp += ci->argc;
+ }
+ given_p = !mrb_nil_p(*bp);
+ }
}
- if (mrb_nil_p(*bp)) return mrb_false_value();
- return mrb_true_value();
+
+ return mrb_bool_value(given_p);
}
/* 15.3.1.3.7 */
@@ -263,7 +264,7 @@ mrb_obj_class_m(mrb_state *mrb, mrb_value self)
struct RClass*
mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
{
- struct RClass *klass = mrb_basic(obj)->c;
+ struct RClass *klass = mrb_basic_ptr(obj)->c;
if (klass->tt != MRB_TT_SCLASS)
return klass;
@@ -282,7 +283,7 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
clone->super = klass->super;
if (klass->iv) {
mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
- mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern(mrb, "__attached__"), obj);
+ mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern2(mrb, "__attached__", 12), obj);
}
if (klass->mt) {
clone->mt = kh_copy(mt, mrb, klass->mt);
@@ -518,6 +519,7 @@ mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
default:
cv = mrb_singleton_class(mrb, self);
c = mrb_class_ptr(cv);
+ break;
}
return mrb_yield_internal(mrb, b, 0, 0, self, c);
}
@@ -541,21 +543,19 @@ static mrb_value
obj_is_instance_of(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
+ mrb_bool instance_of_p;
mrb_get_args(mrb, "o", &arg);
- if (mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))){
- return mrb_true_value();
- }
- else {
- return mrb_false_value();
- }
+ instance_of_p = mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg));
+
+ return mrb_bool_value(instance_of_p);
}
static void
check_iv_name(mrb_state *mrb, mrb_sym id)
{
const char *s;
- int len;
+ size_t len;
s = mrb_sym2name_len(mrb, id, &len);
if (len < 2 || !(s[0] == '@' && s[1] != '@')) {
@@ -585,12 +585,13 @@ mrb_value
mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
{
mrb_sym mid;
+ mrb_bool defined_p;
mrb_get_args(mrb, "n", &mid);
check_iv_name(mrb, mid);
- if (mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid))
- return mrb_true_value();
- return mrb_false_value();
+ defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid);
+
+ return mrb_bool_value(defined_p);
}
/* 15.3.1.3.21 */
@@ -687,14 +688,12 @@ mrb_value
mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
{
mrb_value arg;
+ mrb_bool kind_of_p;
mrb_get_args(mrb, "o", &arg);
- if (mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))) {
- return mrb_true_value();
- }
- else {
- return mrb_false_value();
- }
+ kind_of_p = mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg));
+
+ return mrb_bool_value(kind_of_p);
}
static void
@@ -929,8 +928,9 @@ mrb_f_raise(mrb_state *mrb, mrb_value self)
/* fall through */
default:
exc = mrb_make_exception(mrb, argc, a);
- mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern(mrb, "lastpc"), mrb_voidp_value(mrb->ci->pc));
+ mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(mrb->ci->pc));
mrb_exc_raise(mrb, exc);
+ break;
}
return mrb_nil_value(); /* not reached */
}
@@ -1000,15 +1000,17 @@ obj_respond_to(mrb_state *mrb, mrb_value self)
int argc;
mrb_value mid, priv;
mrb_sym id;
+ mrb_bool respond_to_p;
mrb_get_args(mrb, "*", &argv, &argc);
mid = argv[0];
if (argc > 1) priv = argv[1];
else priv = mrb_nil_value();
id = mrb_to_id(mrb, mid);
- if (basic_obj_respond_to(mrb, self, id, !mrb_test(priv)))
- return mrb_true_value();
- return mrb_false_value();
+
+ respond_to_p = basic_obj_respond_to(mrb, self, id, !mrb_test(priv));
+
+ return mrb_bool_value(respond_to_p);
}
/* 15.3.1.3.45 */
diff --git a/src/keywords b/src/keywords
index be5324875..9cb86608c 100644
--- a/src/keywords
+++ b/src/keywords
@@ -8,43 +8,43 @@ static const struct kwtable *reserved_word(const char *, unsigned int);
struct kwtable;
%%
__ENCODING__, {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END
-__LINE__, {keyword__LINE__, keyword__LINE__}, EXPR_END
-__FILE__, {keyword__FILE__, keyword__FILE__}, EXPR_END
-BEGIN, {keyword_BEGIN, keyword_BEGIN}, EXPR_END
-END, {keyword_END, keyword_END}, EXPR_END
-alias, {keyword_alias, keyword_alias}, EXPR_FNAME
-and, {keyword_and, keyword_and}, EXPR_VALUE
-begin, {keyword_begin, keyword_begin}, EXPR_BEG
-break, {keyword_break, keyword_break}, EXPR_MID
-case, {keyword_case, keyword_case}, EXPR_VALUE
-class, {keyword_class, keyword_class}, EXPR_CLASS
-def, {keyword_def, keyword_def}, EXPR_FNAME
-do, {keyword_do, keyword_do}, EXPR_BEG
-else, {keyword_else, keyword_else}, EXPR_BEG
-elsif, {keyword_elsif, keyword_elsif}, EXPR_VALUE
-end, {keyword_end, keyword_end}, EXPR_END
-ensure, {keyword_ensure, keyword_ensure}, EXPR_BEG
-false, {keyword_false, keyword_false}, EXPR_END
-for, {keyword_for, keyword_for}, EXPR_VALUE
-if, {keyword_if, modifier_if}, EXPR_VALUE
-in, {keyword_in, keyword_in}, EXPR_VALUE
-module, {keyword_module, keyword_module}, EXPR_VALUE
-next, {keyword_next, keyword_next}, EXPR_MID
-nil, {keyword_nil, keyword_nil}, EXPR_END
-not, {keyword_not, keyword_not}, EXPR_ARG
-or, {keyword_or, keyword_or}, EXPR_VALUE
-redo, {keyword_redo, keyword_redo}, EXPR_END
-rescue, {keyword_rescue, modifier_rescue}, EXPR_MID
-retry, {keyword_retry, keyword_retry}, EXPR_END
-return, {keyword_return, keyword_return}, EXPR_MID
-self, {keyword_self, keyword_self}, EXPR_END
-super, {keyword_super, keyword_super}, EXPR_ARG
-then, {keyword_then, keyword_then}, EXPR_BEG
-true, {keyword_true, keyword_true}, EXPR_END
-undef, {keyword_undef, keyword_undef}, EXPR_FNAME
-unless, {keyword_unless, modifier_unless}, EXPR_VALUE
-until, {keyword_until, modifier_until}, EXPR_VALUE
-when, {keyword_when, keyword_when}, EXPR_VALUE
-while, {keyword_while, modifier_while}, EXPR_VALUE
-yield, {keyword_yield, keyword_yield}, EXPR_ARG
+__FILE__, {keyword__FILE__, keyword__FILE__}, EXPR_END
+__LINE__, {keyword__LINE__, keyword__LINE__}, EXPR_END
+BEGIN, {keyword_BEGIN, keyword_BEGIN}, EXPR_END
+END, {keyword_END, keyword_END}, EXPR_END
+alias, {keyword_alias, keyword_alias}, EXPR_FNAME
+and, {keyword_and, keyword_and}, EXPR_VALUE
+begin, {keyword_begin, keyword_begin}, EXPR_BEG
+break, {keyword_break, keyword_break}, EXPR_MID
+case, {keyword_case, keyword_case}, EXPR_VALUE
+class, {keyword_class, keyword_class}, EXPR_CLASS
+def, {keyword_def, keyword_def}, EXPR_FNAME
+do, {keyword_do, keyword_do}, EXPR_BEG
+else, {keyword_else, keyword_else}, EXPR_BEG
+elsif, {keyword_elsif, keyword_elsif}, EXPR_VALUE
+end, {keyword_end, keyword_end}, EXPR_END
+ensure, {keyword_ensure, keyword_ensure}, EXPR_BEG
+false, {keyword_false, keyword_false}, EXPR_END
+for, {keyword_for, keyword_for}, EXPR_VALUE
+if, {keyword_if, modifier_if}, EXPR_VALUE
+in, {keyword_in, keyword_in}, EXPR_VALUE
+module, {keyword_module, keyword_module}, EXPR_VALUE
+next, {keyword_next, keyword_next}, EXPR_MID
+nil, {keyword_nil, keyword_nil}, EXPR_END
+not, {keyword_not, keyword_not}, EXPR_ARG
+or, {keyword_or, keyword_or}, EXPR_VALUE
+redo, {keyword_redo, keyword_redo}, EXPR_END
+rescue, {keyword_rescue, modifier_rescue}, EXPR_MID
+retry, {keyword_retry, keyword_retry}, EXPR_END
+return, {keyword_return, keyword_return}, EXPR_MID
+self, {keyword_self, keyword_self}, EXPR_END
+super, {keyword_super, keyword_super}, EXPR_ARG
+then, {keyword_then, keyword_then}, EXPR_BEG
+true, {keyword_true, keyword_true}, EXPR_END
+undef, {keyword_undef, keyword_undef}, EXPR_FNAME
+unless, {keyword_unless, modifier_unless}, EXPR_VALUE
+until, {keyword_until, modifier_until}, EXPR_VALUE
+when, {keyword_when, keyword_when}, EXPR_VALUE
+while, {keyword_while, modifier_while}, EXPR_VALUE
+yield, {keyword_yield, keyword_yield}, EXPR_ARG
%%
diff --git a/src/lex.def b/src/lex.def
index 5223aac1b..ea456a843 100644
--- a/src/lex.def
+++ b/src/lex.def
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.4 */
+/* ANSI-C code produced by gperf version 3.0.3 */
/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' src/keywords */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -44,10 +44,12 @@ struct kwtable;
#define MAX_HASH_VALUE 50
/* maximum key range = 43, duplicates = 0 */
-#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) || defined(__GNUC_STDC_INLINE__)
-inline
-#elif defined(__GNUC__)
+#ifdef __GNUC__
__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
#endif
static unsigned int
hash (register const char *str, register unsigned int len)
@@ -98,7 +100,7 @@ hash (register const char *str, register unsigned int len)
#ifdef __GNUC__
__inline
-#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
@@ -109,87 +111,87 @@ mrb_reserved_word (register const char *str, register unsigned int len)
{
{""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
#line 18 "src/keywords"
- {"break", {keyword_break, keyword_break}, EXPR_MID},
+ {"break", {keyword_break, keyword_break}, EXPR_MID},
#line 23 "src/keywords"
- {"else", {keyword_else, keyword_else}, EXPR_BEG},
+ {"else", {keyword_else, keyword_else}, EXPR_BEG},
#line 33 "src/keywords"
- {"nil", {keyword_nil, keyword_nil}, EXPR_END},
+ {"nil", {keyword_nil, keyword_nil}, EXPR_END},
#line 26 "src/keywords"
- {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
+ {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
#line 25 "src/keywords"
- {"end", {keyword_end, keyword_end}, EXPR_END},
+ {"end", {keyword_end, keyword_end}, EXPR_END},
#line 42 "src/keywords"
- {"then", {keyword_then, keyword_then}, EXPR_BEG},
+ {"then", {keyword_then, keyword_then}, EXPR_BEG},
#line 34 "src/keywords"
- {"not", {keyword_not, keyword_not}, EXPR_ARG},
+ {"not", {keyword_not, keyword_not}, EXPR_ARG},
#line 27 "src/keywords"
- {"false", {keyword_false, keyword_false}, EXPR_END},
+ {"false", {keyword_false, keyword_false}, EXPR_END},
#line 40 "src/keywords"
- {"self", {keyword_self, keyword_self}, EXPR_END},
+ {"self", {keyword_self, keyword_self}, EXPR_END},
#line 24 "src/keywords"
- {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
+ {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
#line 37 "src/keywords"
- {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
+ {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
#line 43 "src/keywords"
- {"true", {keyword_true, keyword_true}, EXPR_END},
+ {"true", {keyword_true, keyword_true}, EXPR_END},
#line 46 "src/keywords"
- {"until", {keyword_until, modifier_until}, EXPR_VALUE},
+ {"until", {keyword_until, modifier_until}, EXPR_VALUE},
#line 45 "src/keywords"
- {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
+ {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
#line 39 "src/keywords"
- {"return", {keyword_return, keyword_return}, EXPR_MID},
+ {"return", {keyword_return, keyword_return}, EXPR_MID},
#line 21 "src/keywords"
- {"def", {keyword_def, keyword_def}, EXPR_FNAME},
+ {"def", {keyword_def, keyword_def}, EXPR_FNAME},
#line 16 "src/keywords"
- {"and", {keyword_and, keyword_and}, EXPR_VALUE},
+ {"and", {keyword_and, keyword_and}, EXPR_VALUE},
#line 22 "src/keywords"
- {"do", {keyword_do, keyword_do}, EXPR_BEG},
+ {"do", {keyword_do, keyword_do}, EXPR_BEG},
#line 49 "src/keywords"
- {"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
+ {"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
#line 28 "src/keywords"
- {"for", {keyword_for, keyword_for}, EXPR_VALUE},
+ {"for", {keyword_for, keyword_for}, EXPR_VALUE},
#line 44 "src/keywords"
- {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
+ {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
#line 35 "src/keywords"
- {"or", {keyword_or, keyword_or}, EXPR_VALUE},
+ {"or", {keyword_or, keyword_or}, EXPR_VALUE},
#line 30 "src/keywords"
- {"in", {keyword_in, keyword_in}, EXPR_VALUE},
+ {"in", {keyword_in, keyword_in}, EXPR_VALUE},
#line 47 "src/keywords"
- {"when", {keyword_when, keyword_when}, EXPR_VALUE},
+ {"when", {keyword_when, keyword_when}, EXPR_VALUE},
#line 38 "src/keywords"
- {"retry", {keyword_retry, keyword_retry}, EXPR_END},
+ {"retry", {keyword_retry, keyword_retry}, EXPR_END},
#line 29 "src/keywords"
- {"if", {keyword_if, modifier_if}, EXPR_VALUE},
+ {"if", {keyword_if, modifier_if}, EXPR_VALUE},
#line 19 "src/keywords"
- {"case", {keyword_case, keyword_case}, EXPR_VALUE},
+ {"case", {keyword_case, keyword_case}, EXPR_VALUE},
#line 36 "src/keywords"
- {"redo", {keyword_redo, keyword_redo}, EXPR_END},
+ {"redo", {keyword_redo, keyword_redo}, EXPR_END},
#line 32 "src/keywords"
- {"next", {keyword_next, keyword_next}, EXPR_MID},
+ {"next", {keyword_next, keyword_next}, EXPR_MID},
#line 41 "src/keywords"
- {"super", {keyword_super, keyword_super}, EXPR_ARG},
+ {"super", {keyword_super, keyword_super}, EXPR_ARG},
#line 31 "src/keywords"
- {"module", {keyword_module, keyword_module}, EXPR_VALUE},
+ {"module", {keyword_module, keyword_module}, EXPR_VALUE},
#line 17 "src/keywords"
- {"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
-#line 11 "src/keywords"
- {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
+ {"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
#line 12 "src/keywords"
- {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
+ {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
+#line 11 "src/keywords"
+ {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
#line 10 "src/keywords"
{"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
#line 14 "src/keywords"
- {"END", {keyword_END, keyword_END}, EXPR_END},
+ {"END", {keyword_END, keyword_END}, EXPR_END},
#line 15 "src/keywords"
- {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
+ {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
#line 13 "src/keywords"
- {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
+ {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
{""},
#line 20 "src/keywords"
- {"class", {keyword_class, keyword_class}, EXPR_CLASS},
+ {"class", {keyword_class, keyword_class}, EXPR_CLASS},
{""}, {""},
#line 48 "src/keywords"
- {"while", {keyword_while, modifier_while}, EXPR_VALUE}
+ {"while", {keyword_while, modifier_while}, EXPR_VALUE}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/src/load.c b/src/load.c
index 84c21c186..fcffcd9de 100644
--- a/src/load.c
+++ b/src/load.c
@@ -4,6 +4,7 @@
** See Copyright Notice in mruby.h
*/
+#include <stdlib.h>
#include <string.h>
#include "mruby/dump.h"
@@ -683,7 +684,7 @@ static void
irep_error(mrb_state *mrb, int n)
{
static const char msg[] = "irep load error";
- mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
}
#ifdef ENABLE_STDIO
diff --git a/src/node.h b/src/node.h
index e12672bfe..df27c431f 100644
--- a/src/node.h
+++ b/src/node.h
@@ -65,6 +65,8 @@ enum node_type {
NODE_SYM,
NODE_STR,
NODE_DSTR,
+ NODE_XSTR,
+ NODE_DXSTR,
NODE_REGX,
NODE_DREGX,
NODE_DREGX_ONCE,
@@ -106,6 +108,9 @@ enum node_type {
NODE_DSYM,
NODE_ATTRASGN,
NODE_HEREDOC,
+ NODE_LITERAL_DELIM,
+ NODE_WORDS,
+ NODE_SYMBOLS,
NODE_LAST
};
diff --git a/src/numeric.c b/src/numeric.c
index 61b9a2f73..1e089c970 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -9,17 +9,15 @@
#include "mruby/string.h"
#include "mruby/array.h"
+#include <float.h>
#include <math.h>
#include <assert.h>
+#include <stdlib.h>
#if defined(__FreeBSD__) && __FreeBSD__ < 4
#include <floatingpoint.h>
#endif
-#ifdef HAVE_FLOAT_H
-#include <float.h>
-#endif
-
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
@@ -165,6 +163,99 @@ num_abs(mrb_state *mrb, mrb_value num)
* representation.
*/
+mrb_value
+mrb_flo_to_str(mrb_state *mrb, mrb_float n, int max_digit)
+{
+ mrb_value result;
+
+ if (max_digit > 40) {
+ mrb_raise(mrb, E_RANGE_ERROR, "Too large max_digit.");
+ }
+
+ if (isnan(n)) {
+ result = mrb_str_new(mrb, "NaN", 3);
+ }
+ else if (isinf(n)) {
+ if (n < 0) {
+ result = mrb_str_new(mrb, "-inf", 4);
+ }
+ else {
+ result = mrb_str_new(mrb, "inf", 3);
+ }
+ }
+ else {
+ int digit;
+ int m;
+ int exp;
+ int e = 0;
+ char s[48];
+ char *c = &s[0];
+
+ if (n < 0) {
+ n = -n;
+ *(c++) = '-';
+ }
+
+ exp = log10(n);
+
+ if ((exp < 0 ? -exp : exp) > max_digit) {
+ /* exponent representation */
+ e = 1;
+ m = exp;
+ if (m < 0) {
+ m -= 1;
+ }
+ n = n / pow(10.0, m);
+ m = 0;
+ }
+ else {
+ /* un-exponent (normal) representation */
+ m = exp;
+ if (m < 0) {
+ m = 0;
+ }
+ }
+
+ /* puts digits */
+ while (max_digit >= 0) {
+ mrb_float weight = pow(10.0, m);
+ digit = floor(n / weight + FLT_EPSILON);
+ *(c++) = '0' + digit;
+ n -= (digit * weight);
+ max_digit--;
+ if (m-- == 0) {
+ *(c++) = '.';
+ }
+ else if (m < -1 && n < FLT_EPSILON) {
+ break;
+ }
+ }
+
+ if (e) {
+ *(c++) = 'e';
+ if (exp > 0) {
+ *(c++) = '+';
+ } else {
+ *(c++) = '-';
+ exp = -exp;
+ }
+
+ if (exp >= 100) {
+ mrb_raise(mrb, E_RANGE_ERROR, "Too large expornent.");
+ }
+
+ *(c++) = '0' + exp / 10;
+ *(c++) = '0' + exp % 10;
+ }
+
+ *c = '\0';
+
+ result = mrb_str_new(mrb, &s[0], c - &s[0]);
+ }
+
+ return result;
+}
+
/* 15.2.9.3.16(x) */
/*
* call-seq:
@@ -179,27 +270,11 @@ num_abs(mrb_state *mrb, mrb_value num)
static mrb_value
flo_to_s(mrb_state *mrb, mrb_value flt)
{
- char buf[32];
- int n;
-
- mrb_float value = mrb_float(flt);
-
- if (isinf(value)) {
- static const char s[2][5] = { "-inf", "inf" };
- static const int n[] = { 4, 3 };
- int idx;
- idx = (value < 0) ? 0 : 1;
- return mrb_str_new(mrb, s[idx], n[idx]);
- } else if(isnan(value))
- return mrb_str_new(mrb, "NaN", 3);
-
#ifdef MRB_USE_FLOAT
- n = sprintf(buf, "%.7g", value);
+ return mrb_flo_to_str(mrb, mrb_float(flt), 7);
#else
- n = sprintf(buf, "%.14g", value);
+ return mrb_flo_to_str(mrb, mrb_float(flt), 14);
#endif
- assert(n >= 0);
- return mrb_str_new(mrb, buf, n);
}
/* 15.2.9.3.2 */
@@ -305,15 +380,17 @@ static mrb_value
num_eql(mrb_state *mrb, mrb_value x)
{
mrb_value y;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &y);
- if (mrb_type(x) != mrb_type(y)) return mrb_false_value();
- if (mrb_equal(mrb, x, y)) {
- return mrb_true_value();
+ if (mrb_type(x) != mrb_type(y)) {
+ eql_p = 0;
}
else {
- return mrb_false_value();
+ eql_p = mrb_equal(mrb, x, y);
}
+
+ return mrb_bool_value(eql_p);
}
static mrb_value
@@ -355,7 +432,7 @@ flo_eq(mrb_state *mrb, mrb_value x)
return num_equal(mrb, x, y);
}
a = mrb_float(x);
- return (a == b)?mrb_true_value():mrb_false_value();
+ return mrb_bool_value(a == b);
}
/* 15.2.8.3.18 */
@@ -370,7 +447,8 @@ flo_hash(mrb_state *mrb, mrb_value num)
{
mrb_float d;
char *c;
- int i, hash;
+ size_t i;
+ int hash;
d = (mrb_float)mrb_fixnum(num);
/* normalize -0.0 to 0.0 */
@@ -436,10 +514,11 @@ static mrb_value
flo_finite_p(mrb_state *mrb, mrb_value num)
{
mrb_float value = mrb_float(num);
+ mrb_bool finite_p;
- if (isinf(value) || isnan(value))
- return mrb_false_value();
- return mrb_true_value();
+ finite_p = !(isinf(value) || isnan(value));
+
+ return mrb_bool_value(finite_p);
}
/* 15.2.9.3.10 */
@@ -848,19 +927,15 @@ static mrb_value
fix_equal(mrb_state *mrb, mrb_value x)
{
mrb_value y;
+ mrb_bool equal_p;
mrb_get_args(mrb, "o", &y);
- if (mrb_obj_equal(mrb, x, y)) return mrb_true_value();
- switch (mrb_type(y)) {
- case MRB_TT_FLOAT:
- if ((mrb_float)mrb_fixnum(x) == mrb_float(y))
- return mrb_true_value();
- /* fall through */
- case MRB_TT_FIXNUM:
- default:
- return mrb_false_value();
- }
+ equal_p = mrb_obj_equal(mrb, x, y) ||
+ (mrb_type(y) == MRB_TT_FLOAT &&
+ (mrb_float)mrb_fixnum(x) == mrb_float(y));
+
+ return mrb_bool_value(equal_p);
}
/* 15.2.8.3.8 */
diff --git a/src/object.c b/src/object.c
index 0d1cc85b9..5cf165000 100644
--- a/src/object.c
+++ b/src/object.c
@@ -5,7 +5,6 @@
*/
#include "mruby.h"
-#include <string.h>
#include "mruby/string.h"
#include "mruby/class.h"
#include "mruby/numeric.h"
@@ -115,7 +114,8 @@ true_and(mrb_state *mrb, mrb_value obj)
int obj2;
mrb_get_args(mrb, "b", &obj2);
- return obj2 ? mrb_true_value() : mrb_false_value();
+
+ return mrb_bool_value(obj2);
}
/* 15.2.5.3.2 */
@@ -134,7 +134,7 @@ true_xor(mrb_state *mrb, mrb_value obj)
int obj2;
mrb_get_args(mrb, "b", &obj2);
- return obj2 ? mrb_false_value() : mrb_true_value();
+ return mrb_bool_value(!obj2);
}
/* 15.2.5.3.3 */
@@ -227,7 +227,7 @@ false_xor(mrb_state *mrb, mrb_value obj)
int obj2;
mrb_get_args(mrb, "b", &obj2);
- return obj2 ? mrb_true_value() : mrb_false_value();
+ return mrb_bool_value(obj2);
}
/* 15.2.4.3.3 */
@@ -247,7 +247,7 @@ false_or(mrb_state *mrb, mrb_value obj)
int obj2;
mrb_get_args(mrb, "b", &obj2);
- return obj2 ? mrb_true_value() : mrb_false_value();
+ return mrb_bool_value(obj2);
}
/* 15.2.6.3.3 */
@@ -439,8 +439,15 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
mrb_value
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
{
+ mrb_value str = mrb_str_buf_new(mrb, 20);
const char *cname = mrb_obj_classname(mrb, obj);
- return mrb_sprintf(mrb, "#<%s:%p>", cname, mrb_voidp(obj));
+
+ mrb_str_buf_cat(mrb, str, "#<", 2);
+ mrb_str_cat2(mrb, str, cname);
+ mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_voidp(obj)));
+ mrb_str_buf_cat(mrb, str, ">", 1);
+
+ return str;
}
/*
diff --git a/src/opcode.h b/src/opcode.h
index d77e2451f..b4f843116 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -7,12 +7,15 @@
#ifndef OPCODE_H
#define OPCODE_H
-#define MAXARG_Bx ((1<<16)-1)
+#define MAXARG_Bx (0xffff)
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
-/* instructions OP:A:B:C = 7:9:9:7 (32 bits) */
-/* OP:A:Bx = 7:9:16 */
-/* OP:Ax = 7:25 */
+/* instructions: packed 32 bit */
+/* ------------------------------- */
+/* A:B:C:OP = 9: 9: 7: 7 */
+/* A:Bx:OP = 9:16: 7 */
+/* Ax:OP = 25: 7 */
+/* A:Bz:Cz:OP = 9:14: 2: 7 */
#define GET_OPCODE(i) ((int)(((mrb_code)(i)) & 0x7f))
#define GETARG_A(i) ((int)((((mrb_code)(i)) >> 23) & 0x1ff))
@@ -20,19 +23,19 @@
#define GETARG_C(i) ((int)((((mrb_code)(i)) >> 7) & 0x7f))
#define GETARG_Bx(i) ((int)((((mrb_code)(i)) >> 7) & 0xffff))
#define GETARG_sBx(i) ((int)(GETARG_Bx(i)-MAXARG_sBx))
-#define GETARG_Ax(i) ((int)((((mrb_code)(i)) >> 7) & 0x1ffffff))
-#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+n2)) & (((1<<n1)-1))))
-#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<n2)-1))))
+#define GETARG_Ax(i) ((int32_t)((((mrb_code)(i)) >> 7) & 0x1ffffff))
+#define GETARG_UNPACK_b(i,n1,n2) ((int)((((mrb_code)(i)) >> (7+(n2))) & (((1<<(n1))-1))))
+#define GETARG_UNPACK_c(i,n1,n2) ((int)((((mrb_code)(i)) >> 7) & (((1<<(n2))-1))))
#define GETARG_b(i) GETARG_UNPACK_b(i,14,2)
#define GETARG_c(i) GETARG_UNPACK_c(i,14,2)
#define MKOPCODE(op) ((op) & 0x7f)
-#define MKARG_A(c) (((c) & 0x1ff) << 23)
-#define MKARG_B(c) (((c) & 0x1ff) << 14)
+#define MKARG_A(c) ((mrb_code)((c) & 0x1ff) << 23)
+#define MKARG_B(c) ((mrb_code)((c) & 0x1ff) << 14)
#define MKARG_C(c) (((c) & 0x7f) << 7)
-#define MKARG_Bx(v) (((v) & 0xffff) << 7)
+#define MKARG_Bx(v) ((mrb_code)((v) & 0xffff) << 7)
#define MKARG_sBx(v) MKARG_Bx((v)+MAXARG_sBx)
-#define MKARG_Ax(v) (((v) & 0x1ffffff) << 7)
+#define MKARG_Ax(v) ((mrb_code)((v) & 0x1ffffff) << 7)
#define MKARG_PACK(b,n1,c,n2) ((((b) & ((1<<n1)-1)) << (7+n2))|(((c) & ((1<<n2)-1)) << 7))
#define MKARG_bc(b,c) MKARG_PACK(b,14,c,2)
diff --git a/src/parse.y b/src/parse.y
index 62393a0bb..29ea34c59 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -25,6 +25,7 @@
#include <errno.h>
#include <ctype.h>
#include <string.h>
+#include <stdlib.h>
#define YYLEX_PARAM p
@@ -60,13 +61,27 @@ typedef unsigned int stack_type;
#define sym(x) ((mrb_sym)(intptr_t)(x))
#define nsym(x) ((node*)(intptr_t)(x))
-static mrb_sym
+static inline mrb_sym
intern_gen(parser_state *p, const char *s)
{
return mrb_intern(p->mrb, s);
}
#define intern(s) intern_gen(p,(s))
+static inline mrb_sym
+intern_gen2(parser_state *p, const char *s, size_t len)
+{
+ return mrb_intern2(p->mrb, s, len);
+}
+#define intern2(s,len) intern_gen2(p,(s),(len))
+
+static inline mrb_sym
+intern_gen_c(parser_state *p, const char c)
+{
+ return mrb_intern2(p->mrb, &c, 1);
+}
+#define intern_c(c) intern_gen_c(p,(c))
+
static void
cons_free_gen(parser_state *p, node *cons)
{
@@ -701,6 +716,20 @@ new_dstr(parser_state *p, node *a)
return cons((node*)NODE_DSTR, a);
}
+// (:str . (s . len))
+static node*
+new_xstr(parser_state *p, const char *s, int len)
+{
+ return cons((node*)NODE_XSTR, cons((node*)strndup(s, len), (node*)(intptr_t)len));
+}
+
+// (:xstr . a)
+static node*
+new_dxstr(parser_state *p, node *a)
+{
+ return cons((node*)NODE_DXSTR, a);
+}
+
// (:dsym . a)
static node*
new_dsym(parser_state *p, node *a)
@@ -749,6 +778,26 @@ new_bv(parser_state *p, mrb_sym id)
{
}
+static node*
+new_literal_delim(parser_state *p)
+{
+ return cons((node*)NODE_LITERAL_DELIM, 0);
+}
+
+// (:words . a)
+static node*
+new_words(parser_state *p, node *a)
+{
+ return cons((node*)NODE_WORDS, a);
+}
+
+// (:symbols . a)
+static node*
+new_symbols(parser_state *p, node *a)
+{
+ return cons((node*)NODE_SYMBOLS, a);
+}
+
// xxx -----------------------------
// (:call a op)
@@ -843,48 +892,21 @@ var_reference(parser_state *p, node *lhs)
return lhs;
}
+typedef enum mrb_string_type string_type;
static node*
-heredoc_start_sb(parser_state *p, const char* term, size_t term_len, enum heredoc_type type, int allow_indent)
-{
- node *newnode = new_heredoc(p);
- parser_heredoc_info *inf = (parser_heredoc_info*)newnode->cdr;
- inf->term = term;
- inf->term_len = term_len;
- inf->type = type;
- inf->allow_indent = allow_indent;
- inf->line_head = TRUE;
- inf->doc = NULL;
- p->heredocs = push(p->heredocs, newnode);
- if (p->parsing_heredoc == NULL) {
- node *c = p->heredocs;
- while (c->cdr)
- c = c->cdr;
- p->parsing_heredoc = c;
- }
- p->heredoc_starts_nextline = TRUE;
- p->lstate = EXPR_END;
- return newnode;
-}
-
-static node*
-heredoc_start(parser_state *p, node *beg, node *str, enum heredoc_type type)
+new_strterm(parser_state *p, string_type type, int term, int paren)
{
- char *bs = (char*)beg->cdr->car;
- int allow_indent = (bs[2] == '-');
- const char *s = (char*)str->cdr->car;
- size_t len = (intptr_t)str->cdr->cdr;
- return heredoc_start_sb(p, s, len, type, allow_indent);
+ return cons((node*)(intptr_t)type, cons((node*)0, cons((node*)(intptr_t)paren, (node*)(intptr_t)term)));
}
-static node*
-heredoc_start_sym(parser_state *p, node *beg, mrb_sym sym, enum heredoc_type type)
+static void
+end_strterm(parser_state *p)
{
- char *bs = (char*)beg->cdr->car;
- int allow_indent = (bs[2] == '-');
- int len;
- const char *s = mrb_sym2name_len(p->mrb, sym, &len);
- return heredoc_start_sb(p, s, len, type, allow_indent);
+ cons_free(p->lex_strterm->cdr->cdr);
+ cons_free(p->lex_strterm->cdr);
+ cons_free(p->lex_strterm);
+ p->lex_strterm = NULL;
}
parser_heredoc_info *
@@ -904,19 +926,19 @@ heredoc_end(parser_state *p)
if (p->parsing_heredoc == NULL) {
p->lstate = EXPR_BEG;
p->cmd_start = TRUE;
- p->sterm = 0;
+ end_strterm(p);
p->heredoc_end_now = TRUE;
} else {
- p->sterm = ' '; /* next heredoc */
+ /* next heredoc */
+ p->lex_strterm->car = (node*)(intptr_t)parsing_heredoc_inf(p)->type;
}
}
-
+#define is_strterm_type(p,str_func) ((int)(intptr_t)((p)->lex_strterm->car) & (str_func))
// xxx -----------------------------
%}
-%expect 2
%pure_parser
%parse-param {parser_state *p}
%lex-param {parser_state *p}
@@ -980,12 +1002,12 @@ heredoc_end(parser_state *p)
keyword__ENCODING__
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
-%token <nd> tINTEGER tFLOAT tCHAR tREGEXP
-%token <nd> tSTRING tSTRING_PART
+%token <nd> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
+%token <nd> tSTRING tSTRING_PART tSTRING_MID
%token <nd> tNTH_REF tBACK_REF
%token <num> tREGEXP_END
-%type <nd> singleton string string_interp regexp
+%type <nd> singleton string string_rep string_interp xstring regexp
%type <nd> literal numeric cpath symbol
%type <nd> top_compstmt top_stmts top_stmt
%type <nd> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
@@ -1004,7 +1026,7 @@ heredoc_end(parser_state *p)
%type <nd> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
%type <id> fsym sym basic_symbol operation operation2 operation3
%type <id> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg
-%type <nd> heredoc heredoc_rep heredoc_interp
+%type <nd> heredoc words symbols
%token tUPLUS /* unary+ */
%token tUMINUS /* unary- */
@@ -1033,10 +1055,10 @@ heredoc_end(parser_state *p)
%token tSTAR /* * */
%token tAMPER /* & */
%token tLAMBDA /* -> */
-%token tSYMBEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
-%token tSTRING_BEG tSTRING_DVAR tLAMBEG
+%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
+%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
%token <nd> tHEREDOC_BEG /* <<, <<- */
-%token tHEREDOC_END
+%token tHEREDOC_END tLITERAL_DELIM
/*
* precedence table
@@ -1096,7 +1118,7 @@ top_compstmt : top_stmts opt_terms
;
top_stmts : none
- {
+ {
$$ = new_begin(p, 0);
}
| top_stmt
@@ -1159,7 +1181,7 @@ compstmt : stmts opt_terms
;
stmts : none
- {
+ {
$$ = new_begin(p, 0);
}
| stmt
@@ -1220,7 +1242,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym
}
| primary_value '[' opt_call_args rbracket tOP_ASGN command_call
{
- $$ = new_op_asgn(p, new_call(p, $1, intern("[]"), $3), $5, $6);
+ $$ = new_op_asgn(p, new_call(p, $1, intern2("[]",2), $3), $5, $6);
}
| primary_value '.' tIDENTIFIER tOP_ASGN command_call
{
@@ -1459,7 +1481,7 @@ mlhs_node : variable
}
| primary_value '[' opt_call_args rbracket
{
- $$ = new_call(p, $1, intern("[]"), $3);
+ $$ = new_call(p, $1, intern2("[]",2), $3);
}
| primary_value '.' tIDENTIFIER
{
@@ -1498,7 +1520,7 @@ lhs : variable
}
| primary_value '[' opt_call_args rbracket
{
- $$ = new_call(p, $1, intern("[]"), $3);
+ $$ = new_call(p, $1, intern2("[]",2), $3);
}
| primary_value '.' tIDENTIFIER
{
@@ -1581,34 +1603,35 @@ undef_list : fsym
}
;
-op : '|' { $$ = intern("|"); }
- | '^' { $$ = intern("^"); }
- | '&' { $$ = intern("&"); }
- | tCMP { $$ = intern("<=>"); }
- | tEQ { $$ = intern("=="); }
- | tEQQ { $$ = intern("==="); }
- | tMATCH { $$ = intern("=~"); }
- | tNMATCH { $$ = intern("!~"); }
- | '>' { $$ = intern(">"); }
- | tGEQ { $$ = intern(">="); }
- | '<' { $$ = intern("<"); }
- | tLEQ { $$ = intern("<="); }
- | tNEQ { $$ = intern("!="); }
- | tLSHFT { $$ = intern("<<"); }
- | tRSHFT { $$ = intern(">>"); }
- | '+' { $$ = intern("+"); }
- | '-' { $$ = intern("-"); }
- | '*' { $$ = intern("*"); }
- | tSTAR { $$ = intern("*"); }
- | '/' { $$ = intern("/"); }
- | '%' { $$ = intern("%"); }
- | tPOW { $$ = intern("**"); }
- | '!' { $$ = intern("!"); }
- | '~' { $$ = intern("~"); }
- | tUPLUS { $$ = intern("+@"); }
- | tUMINUS { $$ = intern("-@"); }
- | tAREF { $$ = intern("[]"); }
- | tASET { $$ = intern("[]="); }
+op : '|' { $$ = intern_c('|'); }
+ | '^' { $$ = intern_c('^'); }
+ | '&' { $$ = intern_c('&'); }
+ | tCMP { $$ = intern2("<=>",3); }
+ | tEQ { $$ = intern2("==",2); }
+ | tEQQ { $$ = intern2("===",3); }
+ | tMATCH { $$ = intern2("=~",2); }
+ | tNMATCH { $$ = intern2("!~",2); }
+ | '>' { $$ = intern_c('>'); }
+ | tGEQ { $$ = intern2(">=",2); }
+ | '<' { $$ = intern_c('<'); }
+ | tLEQ { $$ = intern2("<=",2); }
+ | tNEQ { $$ = intern2("!=",2); }
+ | tLSHFT { $$ = intern2("<<",2); }
+ | tRSHFT { $$ = intern2(">>",2); }
+ | '+' { $$ = intern_c('+'); }
+ | '-' { $$ = intern_c('-'); }
+ | '*' { $$ = intern_c('*'); }
+ | tSTAR { $$ = intern_c('*'); }
+ | '/' { $$ = intern_c('/'); }
+ | '%' { $$ = intern_c('%'); }
+ | tPOW { $$ = intern2("**",2); }
+ | '!' { $$ = intern_c('!'); }
+ | '~' { $$ = intern_c('~'); }
+ | tUPLUS { $$ = intern2("+@",2); }
+ | tUMINUS { $$ = intern2("-@",2); }
+ | tAREF { $$ = intern2("[]",2); }
+ | tASET { $$ = intern2("[]=",3); }
+ | '`' { $$ = intern_c('`'); }
;
reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
@@ -1643,7 +1666,7 @@ arg : lhs '=' arg
}
| primary_value '[' opt_call_args rbracket tOP_ASGN arg
{
- $$ = new_op_asgn(p, new_call(p, $1, intern("[]"), $3), $5, $6);
+ $$ = new_op_asgn(p, new_call(p, $1, intern2("[]",2), $3), $5, $6);
}
| primary_value '.' tIDENTIFIER tOP_ASGN arg
{
@@ -1942,6 +1965,7 @@ mrhs : args ',' arg_value
primary : literal
| string
+ | xstring
| regexp
| heredoc
| var_ref
@@ -2281,7 +2305,7 @@ block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
{
$$ = new_args(p, $1, $3, 0, $5, $6);
}
- | f_arg ',' f_rest_arg opt_f_block_arg
+ | f_arg ',' f_rest_arg opt_f_block_arg
{
$$ = new_args(p, $1, 0, $3, 0, $4);
}
@@ -2413,7 +2437,7 @@ block_call : command do_block
yyerror(p, "block given to yield");
}
else {
- call_with_block(p, $1, $2);
+ call_with_block(p, $1, $2);
}
$$ = $1;
}
@@ -2451,11 +2475,11 @@ method_call : operation paren_args
}
| primary_value '.' paren_args
{
- $$ = new_call(p, $1, intern("call"), $3);
+ $$ = new_call(p, $1, intern2("call",4), $3);
}
| primary_value tCOLON2 paren_args
{
- $$ = new_call(p, $1, intern("call"), $3);
+ $$ = new_call(p, $1, intern2("call",4), $3);
}
| keyword_super paren_args
{
@@ -2467,7 +2491,7 @@ method_call : operation paren_args
}
| primary_value '[' opt_call_args rbracket
{
- $$ = new_call(p, $1, intern("[]"), $3);
+ $$ = new_call(p, $1, intern2("[]",2), $3);
}
;
@@ -2547,6 +2571,8 @@ opt_ensure : keyword_ensure compstmt
literal : numeric
| symbol
+ | words
+ | symbols
;
string : tCHAR
@@ -2555,65 +2581,62 @@ string : tCHAR
{
$$ = $2;
}
- | tSTRING_BEG string_interp tSTRING
+ | tSTRING_BEG string_rep tSTRING
{
$$ = new_dstr(p, push($2, $3));
}
;
-string_interp : tSTRING_PART
+string_rep : string_interp
+ | string_rep string_interp
{
- $<num>$ = p->sterm;
- p->sterm = 0;
+ $$ = append($1, $2);
}
- compstmt
- '}'
+ ;
+
+string_interp : tSTRING_MID
{
- p->sterm = $<num>2;
- $$ = list2($1, $3);
+ $$ = list1($1);
}
- | string_interp
- tSTRING_PART
+ | tSTRING_PART
{
- $<num>$ = p->sterm;
- p->sterm = 0;
+ $<nd>$ = p->lex_strterm;
+ p->lex_strterm = NULL;
}
compstmt
'}'
{
- p->sterm = $<num>3;
- $$ = push(push($1, $2), $4);
+ p->lex_strterm = $<nd>2;
+ $$ = list2($1, $3);
+ }
+ | tLITERAL_DELIM
+ {
+ $$ = list1(new_literal_delim(p));
}
;
-regexp : tREGEXP_BEG tREGEXP
+xstring : tXSTRING_BEG tXSTRING
{
$$ = $2;
}
- | tREGEXP_BEG string_interp tREGEXP
+ | tXSTRING_BEG string_rep tXSTRING
{
- $$ = new_dregx(p, $2, $3);
+ $$ = new_dxstr(p, push($2, $3));
}
;
-heredoc : tHEREDOC_BEG tSTRING_BEG tSTRING
- {
- $$ = heredoc_start(p, $1, $3, heredoc_type_norm);
- }
- | tHEREDOC_BEG tSTRING
- {
- $$ = heredoc_start(p, $1, $2, heredoc_type_quote);
- }
- | tHEREDOC_BEG tIDENTIFIER
+regexp : tREGEXP_BEG tREGEXP
{
- $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm);
+ $$ = $2;
}
- | tHEREDOC_BEG tCONSTANT
+ | tREGEXP_BEG string_rep tREGEXP
{
- $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm);
+ $$ = new_dregx(p, $2, $3);
}
;
+heredoc : tHEREDOC_BEG
+ ;
opt_heredoc_bodies : none
| heredoc_bodies
@@ -2625,42 +2648,27 @@ heredoc_bodies : heredoc_body
heredoc_body : tHEREDOC_END
{
- /* assert(parsing_heredoc_inf(p) != NULL); */
parsing_heredoc_inf(p)->doc = list1(new_str(p, "", 0));
heredoc_end(p);
}
- | heredoc_rep tHEREDOC_END
+ | string_rep tHEREDOC_END
{
- /* assert(parsing_heredoc_inf(p) != NULL); */
parsing_heredoc_inf(p)->doc = $1;
heredoc_end(p);
}
;
-heredoc_rep : heredoc_interp
- | heredoc_rep heredoc_interp
+words : tWORDS_BEG tSTRING
{
- $$ = append($1, $2);
+ $$ = new_words(p, list1($2));
}
- ;
-
-heredoc_interp : tSTRING
+ | tWORDS_BEG string_rep tSTRING
{
- $$ = list1($1);
- }
- | tSTRING_PART
- {
- $<num>$ = p->sterm;
- p->sterm = 0;
- }
- compstmt
- '}'
- {
- p->sterm = $<num>2;
- $$ = list2($1, $3);
+ $$ = new_words(p, push($2, $3));
}
;
+
symbol : basic_symbol
{
$$ = new_sym(p, $1);
@@ -2693,6 +2701,16 @@ sym : fname
}
;
+symbols : tSYMBOLS_BEG tSTRING
+ {
+ $$ = new_symbols(p, list1($2));
+ }
+ | tSYMBOLS_BEG string_rep tSTRING
+ {
+ $$ = new_symbols(p, push($2, $3));
+ }
+ ;
+
numeric : tINTEGER
| tFLOAT
| tUMINUS_NUM tINTEGER %prec tLOWEST
@@ -3007,6 +3025,8 @@ singleton : var_ref
switch ((enum node_type)(int)(intptr_t)$3->car) {
case NODE_STR:
case NODE_DSTR:
+ case NODE_XSTR:
+ case NODE_DXSTR:
case NODE_DREGX:
case NODE_MATCH:
case NODE_FLOAT:
@@ -3232,7 +3252,6 @@ nextc(parser_state *p)
else {
c = (unsigned char)*p->s++;
}
- /* if (c == '\n') { } */ /* heredoc treated in parser_yylex() */
}
p->column++;
return c;
@@ -3315,7 +3334,7 @@ skips(parser_state *p, const char *s)
int len = strlen(s);
while (len--) {
- nextc(p);
+ nextc(p);
}
return TRUE;
}
@@ -3326,23 +3345,6 @@ skips(parser_state *p, const char *s)
return FALSE;
}
-#define STR_FUNC_ESCAPE 0x01
-#define STR_FUNC_EXPAND 0x02
-#define STR_FUNC_REGEXP 0x04
-#define STR_FUNC_QWORDS 0x08
-#define STR_FUNC_SYMBOL 0x10
-#define STR_FUNC_INDENT 0x20
-
-enum string_type {
- str_squote = (0),
- str_dquote = (STR_FUNC_EXPAND),
- str_xquote = (STR_FUNC_EXPAND),
- str_regexp = (STR_FUNC_REGEXP|STR_FUNC_ESCAPE|STR_FUNC_EXPAND),
- str_sword = (STR_FUNC_QWORDS),
- str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND),
- str_ssym = (STR_FUNC_SYMBOL),
- str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND)
-};
static int
newtok(parser_state *p)
@@ -3354,7 +3356,7 @@ newtok(parser_state *p)
static void
tokadd(parser_state *p, int c)
{
- if (p->bidx < 1024) {
+ if (p->bidx < MRB_PARSER_BUF_SIZE) {
p->buf[p->bidx++] = c;
}
}
@@ -3368,7 +3370,7 @@ toklast(parser_state *p)
static void
tokfix(parser_state *p)
{
- if (p->bidx >= 1024) {
+ if (p->bidx >= MRB_PARSER_BUF_SIZE) {
yyerror(p, "string too long (truncated)");
}
p->buf[p->bidx] = '\0';
@@ -3393,34 +3395,38 @@ toklen(parser_state *p)
#define IS_LABEL_POSSIBLE() ((p->lstate == EXPR_BEG && !cmd_state) || IS_ARG())
#define IS_LABEL_SUFFIX(n) (peek_n(p, ':',(n)) && !peek_n(p, ':', (n)+1))
-static unsigned long
+static int
scan_oct(const int *start, int len, int *retlen)
{
const int *s = start;
- unsigned long retval = 0;
+ int retval = 0;
+ /* assert(len <= 3) */
while (len-- && *s >= '0' && *s <= '7') {
retval <<= 3;
retval |= *s++ - '0';
}
*retlen = s - start;
+
return retval;
}
-static unsigned long
+static int
scan_hex(const int *start, int len, int *retlen)
{
static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
register const int *s = start;
- register unsigned long retval = 0;
+ register int retval = 0;
char *tmp;
- while (len-- && *s && (tmp = (char *)strchr(hexdigit, *s))) {
+ /* assert(len <= 2) */
+ while (len-- && *s && (tmp = strchr(hexdigit, *s))) {
retval <<= 4;
retval |= (tmp - hexdigit) & 15;
s++;
}
*retlen = s - start;
+
return retval;
}
@@ -3457,19 +3463,19 @@ read_escape(parser_state *p)
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
{
- int buf[3];
- int i;
+ int buf[3];
+ int i;
- buf[0] = c;
- for (i=1; i<3; i++) {
+ buf[0] = c;
+ for (i=1; i<3; i++) {
buf[i] = nextc(p);
if (buf[i] == -1) goto eof;
- if (buf[i] < '0' || '7' < buf[i]) {
- pushback(p, buf[i]);
- break;
- }
- }
- c = scan_oct(buf, i, &i);
+ if (buf[i] < '0' || '7' < buf[i]) {
+ pushback(p, buf[i]);
+ break;
+ }
+ }
+ c = scan_oct(buf, i, &i);
}
return c;
@@ -3479,33 +3485,25 @@ read_escape(parser_state *p)
int i;
for (i=0; i<2; i++) {
- buf[i] = nextc(p);
- if (buf[i] == -1) goto eof;
- if (!isxdigit(buf[i])) {
- pushback(p, buf[i]);
- break;
- }
+ buf[i] = nextc(p);
+ if (buf[i] == -1) goto eof;
+ if (!isxdigit(buf[i])) {
+ pushback(p, buf[i]);
+ break;
+ }
}
c = scan_hex(buf, i, &i);
if (i == 0) {
- yyerror(p, "Invalid escape character syntax");
- return 0;
+ yyerror(p, "Invalid escape character syntax");
+ return 0;
}
}
return c;
case 'b': /* backspace */
- if (p->regexp) {
- tokadd(p, '\\');
- return 'b';
- }
return '\010';
case 's': /* space */
- if (p->regexp) {
- tokadd(p, '\\');
- return 's';
- }
return ' ';
case 'M':
@@ -3543,57 +3541,154 @@ read_escape(parser_state *p)
return '\0';
default:
- if (p->regexp) {
- tokadd(p, '\\');
- }
return c;
}
}
+
static int
-parse_string(parser_state *p, int term)
+parse_string(parser_state *p)
{
int c;
+ string_type type = (string_type)(intptr_t)p->lex_strterm->car;
+ int nest_level = (intptr_t)p->lex_strterm->cdr->car;
+ int beg = (intptr_t)p->lex_strterm->cdr->cdr->car;
+ int end = (intptr_t)p->lex_strterm->cdr->cdr->cdr;
+ parser_heredoc_info *hinf = (type & STR_FUNC_HEREDOC) ? parsing_heredoc_inf(p) : NULL;
newtok(p);
- while ((c = nextc(p)) != term) {
- if (c == -1) {
+ while ((c = nextc(p)) != end || nest_level != 0) {
+ if (hinf && (c == '\n' || c == -1)) {
+ int line_head;
+ tokadd(p, '\n');
+ tokfix(p);
+ p->lineno++;
+ p->column = 0;
+ line_head = hinf->line_head;
+ hinf->line_head = TRUE;
+ if (line_head) {
+ /* check whether end of heredoc */
+ const char *s = tok(p);
+ int len = toklen(p);
+ if (hinf->allow_indent) {
+ while (ISSPACE(*s) && len > 0) {
+ ++s;
+ --len;
+ }
+ }
+ if ((len-1 == hinf->term_len) && (strncmp(s, hinf->term, len-1) == 0)) {
+ return tHEREDOC_END;
+ }
+ }
+ if (c == -1) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "can't find string \"%s\" anywhere before EOF", hinf->term);
+ yyerror(p, buf);
+ return 0;
+ }
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ return tSTRING_MID;
+ }
+ if (c == -1) {
yyerror(p, "unterminated string meets end of file");
return 0;
}
+ else if (c == beg) {
+ nest_level++;
+ p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
+ }
+ else if (c == end) {
+ nest_level--;
+ p->lex_strterm->cdr->car = (node*)(intptr_t)nest_level;
+ }
else if (c == '\\') {
c = nextc(p);
- if (c == term) {
- tokadd(p, c);
- }
- else {
- pushback(p, c);
- tokadd(p, read_escape(p));
+ if (type & STR_FUNC_EXPAND) {
+ if (c == end || c == beg) {
+ tokadd(p, c);
+ }
+ else if ((c == '\n') && (type & STR_FUNC_ARRAY)) {
+ p->lineno++;
+ p->column = 0;
+ tokadd(p, '\n');
+ }
+ else {
+ pushback(p, c);
+
+ if(type & STR_FUNC_REGEXP)
+ tokadd(p, '\\');
+
+ tokadd(p, read_escape(p));
+ if (hinf)
+ hinf->line_head = FALSE;
+ }
+ } else {
+ if (c != beg && c != end) {
+ switch (c) {
+ case '\n':
+ p->lineno++;
+ p->column = 0;
+ break;
+
+ case '\\':
+ break;
+
+ default:
+ if (! ISSPACE(c))
+ tokadd(p, '\\');
+ }
+ }
+ tokadd(p, c);
}
continue;
}
- if (c == '#') {
+ else if ((c == '#') && (type & STR_FUNC_EXPAND)) {
c = nextc(p);
if (c == '{') {
- tokfix(p);
- p->lstate = EXPR_BEG;
- p->sterm = term;
- p->cmd_start = TRUE;
- yylval.nd = new_str(p, tok(p), toklen(p));
- return tSTRING_PART;
+ tokfix(p);
+ p->lstate = EXPR_BEG;
+ p->cmd_start = TRUE;
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ if (hinf)
+ hinf->line_head = FALSE;
+ return tSTRING_PART;
}
tokadd(p, '#');
pushback(p, c);
continue;
}
+ if ((type & STR_FUNC_ARRAY) && ISSPACE(c)) {
+ if (toklen(p) == 0) {
+ do {
+ if (c == '\n') {
+ p->lineno++;
+ p->column = 0;
+ }
+ } while (ISSPACE(c = nextc(p)));
+ pushback(p, c);
+ return tLITERAL_DELIM;
+ } else {
+ pushback(p, c);
+ tokfix(p);
+ yylval.nd = new_str(p, tok(p), toklen(p));
+ return tSTRING_MID;
+ }
+ }
+
tokadd(p, c);
- }
+
+ }
tokfix(p);
p->lstate = EXPR_END;
- p->sterm = 0;
+ end_strterm(p);
- if (p->regexp) {
+ if (type & STR_FUNC_XQUOTE) {
+ yylval.nd = new_xstr(p, tok(p), toklen(p));
+ return tXSTRING;
+ }
+
+ if (type & STR_FUNC_REGEXP) {
int f = 0;
int c;
char *s = strndup(tok(p), toklen(p));
@@ -3613,14 +3708,13 @@ parse_string(parser_state *p, int term)
char msg[128];
tokfix(p);
snprintf(msg, sizeof(msg), "unknown regexp option%s - %s",
- toklen(p) > 1 ? "s" : "", tok(p));
+ toklen(p) > 1 ? "s" : "", tok(p));
yyerror(p, msg);
}
if (f & 1) strcat(flag, "i");
if (f & 2) strcat(flag, "x");
if (f & 4) strcat(flag, "m");
yylval.nd = new_regx(p, s, strdup(flag));
- p->regexp = 0;
return tREGEXP;
}
@@ -3628,128 +3722,78 @@ parse_string(parser_state *p, int term)
yylval.nd = new_str(p, tok(p), toklen(p));
return tSTRING;
}
+
-static node*
-qstring_node(parser_state *p, int beg, int end)
+static int
+heredoc_identifier(parser_state *p)
{
int c;
- int nest_level = 0;
-
- newtok(p);
- while ((c = nextc(p)) != end || nest_level != 0) {
- if (c == -1) {
- yyerror(p, "unterminated string meets end of file");
- return 0;
- }
- else if (c == beg) {
- nest_level++;
- }
- else if (c == end) {
- nest_level--;
- }
- else if (c == '\\') {
- c = nextc(p);
- if (c != beg && c != end) {
- switch (c) {
- case '\n':
- p->lineno++;
- p->column = 0;
- continue;
-
- case '\\':
- c = '\\';
- break;
-
- default:
- tokadd(p, '\\');
- }
- }
- }
- tokadd(p, c);
+ int type = str_heredoc;
+ int indent = FALSE;
+ int quote = FALSE;
+ node *newnode;
+ parser_heredoc_info *info;
+
+ c = nextc(p);
+ if (ISSPACE(c) || c == '=') {
+ pushback(p, c);
+ return 0;
}
-
- tokfix(p);
- p->lstate = EXPR_END;
- return new_str(p, tok(p), toklen(p));
-}
-
-static int
-parse_qstring(parser_state *p, int beg, int end)
-{
- node *nd = qstring_node(p, beg, end);
-
- if (nd) {
- yylval.nd = nd;
- return tSTRING;
+ if (c == '-') {
+ indent = TRUE;
+ c = nextc(p);
}
- return 0;
-}
-
-static int
-parse_heredoc_line(parser_state *p)
-{
- parser_heredoc_info *inf = parsing_heredoc_inf(p);
- /* assert(inf != NULL); */
- int c;
- int line_head;
-
- newtok(p);
- while ((c = nextc(p)) != '\n') {
- if (c == -1)
- break;
- if (inf->type != heredoc_type_quote) {
- if (c == '\\') {
- tokadd(p, read_escape(p));
- inf->line_head = FALSE;
- continue;
- }
- if (c == '#') {
- c = nextc(p);
- if (c == '{') {
- tokfix(p);
- p->lstate = EXPR_BEG;
- p->sterm = ' ';
- p->cmd_start = TRUE;
- yylval.nd = new_str(p, tok(p), toklen(p));
- inf->line_head = FALSE;
- return tSTRING_PART;
- }
- tokadd(p, '#');
- pushback(p, c);
- continue;
+ if (c == '\'' || c == '"') {
+ int term = c;
+ if (c == '\'')
+ quote = TRUE;
+ newtok(p);
+ while ((c = nextc(p)) != -1 && c != term) {
+ if (c == '\n') {
+ c = -1;
+ break;
}
+ tokadd(p, c);
}
- tokadd(p, c);
- }
- tokadd(p, '\n');
- tokfix(p);
- p->lineno++;
- p->column = 0;
- line_head = inf->line_head;
- inf->line_head = TRUE;
- if (line_head) {
- /* check whether end of heredoc */
- const char *s = tok(p);
- int len = toklen(p);
- if (inf->allow_indent) {
- while (ISSPACE(*s) && len > 0) {
- ++s;
- --len;
- }
+ if (c == -1) {
+ yyerror(p, "unterminated here document identifier");
+ return 0;
}
- if ((len-1 == inf->term_len) && (strncmp(s, inf->term, len-1) == 0)) {
- return tHEREDOC_END;
+ } else {
+ if (! identchar(c)) {
+ pushback(p, c);
+ if (indent) pushback(p, '-');
+ return 0;
}
+ newtok(p);
+ do {
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1 && identchar(c));
+ pushback(p, c);
}
- if (c == -1) {
- char buf[256];
- snprintf(buf, sizeof(buf), "can't find string \"%s\" anywhere before EOF", inf->term);
- yyerror(p, buf);
- return 0;
+ tokfix(p);
+ newnode = new_heredoc(p);
+ info = (parser_heredoc_info*)newnode->cdr;
+ info->term = strndup(tok(p), toklen(p));
+ info->term_len = toklen(p);
+ if (! quote)
+ type |= STR_FUNC_EXPAND;
+ info->type = type;
+ info->allow_indent = indent;
+ info->line_head = TRUE;
+ info->doc = NULL;
+ p->heredocs = push(p->heredocs, newnode);
+ if (p->parsing_heredoc == NULL) {
+ node *n = p->heredocs;
+ while (n->cdr)
+ n = n->cdr;
+ p->parsing_heredoc = n;
}
+ p->heredoc_starts_nextline = TRUE;
+ p->lstate = EXPR_END;
- yylval.nd = new_str(p, tok(p), toklen(p));
- return tSTRING;
+ yylval.nd = newnode;
+ return tHEREDOC_BEG;
}
static int
@@ -3765,17 +3809,18 @@ static int
parser_yylex(parser_state *p)
{
register int c;
- int c2;
int space_seen = 0;
int cmd_state;
enum mrb_lex_state_enum last_state;
int token_column;
- if ((p->sterm == ' ') && (p->parsing_heredoc != NULL) && (! p->heredoc_starts_nextline)) {
- return parse_heredoc_line(p);
- }
- if (p->sterm) {
- return parse_string(p, p->sterm);
+ if (p->lex_strterm) {
+ if (is_strterm_type(p, STR_FUNC_HEREDOC)) {
+ if ((p->parsing_heredoc != NULL) && (! p->heredoc_starts_nextline))
+ return parse_string(p);
+ }
+ else
+ return parse_string(p);
}
cmd_state = p->cmd_start;
p->cmd_start = FALSE;
@@ -3800,7 +3845,7 @@ parser_yylex(parser_state *p)
case '\n':
p->heredoc_starts_nextline = FALSE;
if (p->parsing_heredoc != NULL) {
- p->sterm = ' ';
+ p->lex_strterm = new_strterm(p, parsing_heredoc_inf(p)->type, 0, 0);
goto normal_newline;
}
switch (p->lstate) {
@@ -3819,19 +3864,19 @@ parser_yylex(parser_state *p)
switch (c) {
case ' ': case '\t': case '\f': case '\r':
case '\13': /* '\v' */
- space_seen = 1;
- break;
+ space_seen = 1;
+ break;
case '.':
- if ((c = nextc(p)) != '.') {
- pushback(p, c);
- pushback(p, '.');
- goto retry;
- }
+ if ((c = nextc(p)) != '.') {
+ pushback(p, c);
+ pushback(p, '.');
+ goto retry;
+ }
case -1: /* EOF */
- goto normal_newline;
+ goto normal_newline;
default:
- pushback(p, c);
- goto normal_newline;
+ pushback(p, c);
+ goto normal_newline;
}
}
normal_newline:
@@ -3842,29 +3887,29 @@ parser_yylex(parser_state *p)
case '*':
if ((c = nextc(p)) == '*') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern("**");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern2("**",2);
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
c = tPOW;
}
else {
if (c == '=') {
- yylval.id = intern("*");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern_c('*');
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
if (IS_SPCARG(c)) {
- yywarning(p, "`*' interpreted as argument prefix");
- c = tSTAR;
+ yywarning(p, "`*' interpreted as argument prefix");
+ c = tSTAR;
}
else if (IS_BEG()) {
- c = tSTAR;
+ c = tSTAR;
}
else {
- c = '*';
+ c = '*';
}
}
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
@@ -3879,7 +3924,7 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return '!';
+ return '!';
}
}
else {
@@ -3897,7 +3942,7 @@ parser_yylex(parser_state *p)
case '=':
if (p->column == 1) {
if (peeks(p, "begin\n")) {
- skips(p, "\n=end\n");
+ skips(p, "\n=end\n");
goto retry;
}
}
@@ -3908,7 +3953,7 @@ parser_yylex(parser_state *p)
}
if ((c = nextc(p)) == '=') {
if ((c = nextc(p)) == '=') {
- return tEQQ;
+ return tEQQ;
}
pushback(p, c);
return tEQ;
@@ -3926,45 +3971,34 @@ parser_yylex(parser_state *p)
last_state = p->lstate;
c = nextc(p);
if (c == '<' &&
- p->lstate != EXPR_DOT &&
- p->lstate != EXPR_CLASS &&
- !IS_END() &&
- (!IS_ARG() || space_seen)) {
- /* heredocument check */
- newtok(p); tokadd(p, '<'); tokadd(p, '<');
- c2 = nextc(p);
- if (c2 == '-') {
- tokadd(p, c2);
- c2 = nextc(p);
- }
- pushback(p, c2);
- if (!ISSPACE(c2)) {
- tokfix(p);
- yylval.nd = new_str(p, tok(p), toklen(p));
- p->lstate = EXPR_DOT;
- return tHEREDOC_BEG;
- }
+ p->lstate != EXPR_DOT &&
+ p->lstate != EXPR_CLASS &&
+ !IS_END() &&
+ (!IS_ARG() || space_seen)) {
+ int token = heredoc_identifier(p);
+ if (token)
+ return token;
}
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
} else {
p->lstate = EXPR_BEG;
if (p->lstate == EXPR_CLASS) {
- p->cmd_start = TRUE;
+ p->cmd_start = TRUE;
}
}
if (c == '=') {
if ((c = nextc(p)) == '>') {
- return tCMP;
+ return tCMP;
}
pushback(p, c);
return tLEQ;
}
if (c == '<') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern("<<");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern2("<<",2);
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tLSHFT;
@@ -3983,9 +4017,9 @@ parser_yylex(parser_state *p)
}
if (c == '>') {
if ((c = nextc(p)) == '=') {
- yylval.id = intern(">>");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern2(">>",2);
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tRSHFT;
@@ -3994,11 +4028,27 @@ parser_yylex(parser_state *p)
return '>';
case '"':
- p->sterm = '"';
+ p->lex_strterm = new_strterm(p, str_dquote, '"', 0);
return tSTRING_BEG;
case '\'':
- return parse_qstring(p, '\'', '\'');
+ p->lex_strterm = new_strterm(p, str_squote, '\'', 0);
+ return parse_string(p);
+
+ case '`':
+ if (p->lstate == EXPR_FNAME) {
+ p->lstate = EXPR_ENDFN;
+ return '`';
+ }
+ if (p->lstate == EXPR_DOT) {
+ if (cmd_state)
+ p->lstate = EXPR_CMDARG;
+ else
+ p->lstate = EXPR_ARG;
+ return '`';
+ }
+ p->lex_strterm = new_strterm(p, str_xquote, '`', 0);
+ return tXSTRING_BEG;
case '?':
if (IS_END()) {
@@ -4012,35 +4062,35 @@ parser_yylex(parser_state *p)
}
if (isspace(c)) {
if (!IS_ARG()) {
- int c2;
- switch (c) {
- case ' ':
- c2 = 's';
- break;
- case '\n':
- c2 = 'n';
- break;
- case '\t':
- c2 = 't';
- break;
- case '\v':
- c2 = 'v';
- break;
- case '\r':
- c2 = 'r';
- break;
- case '\f':
- c2 = 'f';
- break;
- default:
- c2 = 0;
- break;
- }
- if (c2) {
- char buf[256];
- snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
- yyerror(p, buf);
- }
+ int c2;
+ switch (c) {
+ case ' ':
+ c2 = 's';
+ break;
+ case '\n':
+ c2 = 'n';
+ break;
+ case '\t':
+ c2 = 't';
+ break;
+ case '\v':
+ c2 = 'v';
+ break;
+ case '\r':
+ c2 = 'r';
+ break;
+ case '\f':
+ c2 = 'f';
+ break;
+ default:
+ c2 = 0;
+ break;
+ }
+ if (c2) {
+ char buf[256];
+ snprintf(buf, sizeof(buf), "invalid character syntax; use ?\\%c", c2);
+ yyerror(p, buf);
+ }
}
ternary:
pushback(p, c);
@@ -4053,20 +4103,20 @@ parser_yylex(parser_state *p)
int c2 = nextc(p);
pushback(p, c2);
if ((isalnum(c2) || c2 == '_')) {
- goto ternary;
+ goto ternary;
}
}
if (c == '\\') {
c = nextc(p);
if (c == 'u') {
#if 0
- tokadd_utf8(p);
+ tokadd_utf8(p);
#endif
}
else {
- pushback(p, c);
- c = read_escape(p);
- tokadd(p, c);
+ pushback(p, c);
+ c = read_escape(p);
+ tokadd(p, c);
}
}
else {
@@ -4081,15 +4131,15 @@ parser_yylex(parser_state *p)
if ((c = nextc(p)) == '&') {
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '=') {
- yylval.id = intern("&&");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern2("&&",2);
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tANDOP;
}
else if (c == '=') {
- yylval.id = intern("&");
+ yylval.id = intern_c('&');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4115,15 +4165,15 @@ parser_yylex(parser_state *p)
if ((c = nextc(p)) == '|') {
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '=') {
- yylval.id = intern("||");
- p->lstate = EXPR_BEG;
- return tOP_ASGN;
+ yylval.id = intern2("||",2);
+ p->lstate = EXPR_BEG;
+ return tOP_ASGN;
}
pushback(p, c);
return tOROP;
}
if (c == '=') {
- yylval.id = intern("|");
+ yylval.id = intern_c('|');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4141,13 +4191,13 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return tUPLUS;
+ return tUPLUS;
}
pushback(p, c);
return '+';
}
if (c == '=') {
- yylval.id = intern("+");
+ yylval.id = intern_c('+');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4155,8 +4205,8 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- c = '+';
- goto start_num;
+ c = '+';
+ goto start_num;
}
return tUPLUS;
}
@@ -4169,13 +4219,13 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if (c == '@') {
- return tUMINUS;
+ return tUMINUS;
}
pushback(p, c);
return '-';
}
if (c == '=') {
- yylval.id = intern("-");
+ yylval.id = intern_c('-');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4187,7 +4237,7 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
pushback(p, c);
if (c != -1 && ISDIGIT(c)) {
- return tUMINUS_NUM;
+ return tUMINUS_NUM;
}
return tUMINUS;
}
@@ -4199,7 +4249,7 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_BEG;
if ((c = nextc(p)) == '.') {
if ((c = nextc(p)) == '.') {
- return tDOT3;
+ return tDOT3;
}
pushback(p, c);
return tDOT2;
@@ -4221,218 +4271,218 @@ parser_yylex(parser_state *p)
p->lstate = EXPR_END;
token_column = newtok(p);
if (c == '-' || c == '+') {
- tokadd(p, c);
- c = nextc(p);
+ tokadd(p, c);
+ c = nextc(p);
}
if (c == '0') {
#define no_digits() do {yyerror(p,"numeric literal without digits"); return 0;} while (0)
- int start = toklen(p);
- c = nextc(p);
- if (c == 'x' || c == 'X') {
- /* hexadecimal */
- c = nextc(p);
- if (c != -1 && ISXDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISXDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, tolower(c));
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 16);
- return tINTEGER;
- }
- if (c == 'b' || c == 'B') {
- /* binary */
- c = nextc(p);
- if (c == '0' || c == '1') {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c != '0' && c != '1') break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 2);
- return tINTEGER;
- }
- if (c == 'd' || c == 'D') {
- /* decimal */
- c = nextc(p);
- if (c != -1 && ISDIGIT(c)) {
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (!ISDIGIT(c)) break;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
- }
- pushback(p, c);
- tokfix(p);
- if (toklen(p) == start) {
- no_digits();
- }
- else if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 10);
- return tINTEGER;
- }
- if (c == '_') {
- /* 0_0 */
- goto octal_number;
- }
- if (c == 'o' || c == 'O') {
- /* prefixed octal */
- c = nextc(p);
- if (c == -1 || c == '_' || !ISDIGIT(c)) {
- no_digits();
- }
- }
- if (c >= '0' && c <= '7') {
- /* octal */
- octal_number:
- do {
- if (c == '_') {
- if (nondigit) break;
- nondigit = c;
- continue;
- }
- if (c < '0' || c > '9') break;
- if (c > '7') goto invalid_octal;
- nondigit = 0;
- tokadd(p, c);
- } while ((c = nextc(p)) != -1);
-
- if (toklen(p) > start) {
- pushback(p, c);
- tokfix(p);
- if (nondigit) goto trailing_uc;
- yylval.nd = new_int(p, tok(p), 8);
- return tINTEGER;
- }
- if (nondigit) {
- pushback(p, c);
- goto trailing_uc;
- }
- }
- if (c > '7' && c <= '9') {
- invalid_octal:
- yyerror(p, "Invalid octal digit");
- }
- else if (c == '.' || c == 'e' || c == 'E') {
- tokadd(p, '0');
- }
- else {
- pushback(p, c);
- yylval.nd = new_int(p, "0", 10);
- return tINTEGER;
- }
+ int start = toklen(p);
+ c = nextc(p);
+ if (c == 'x' || c == 'X') {
+ /* hexadecimal */
+ c = nextc(p);
+ if (c != -1 && ISXDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISXDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, tolower(c));
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 16);
+ return tINTEGER;
+ }
+ if (c == 'b' || c == 'B') {
+ /* binary */
+ c = nextc(p);
+ if (c == '0' || c == '1') {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c != '0' && c != '1') break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 2);
+ return tINTEGER;
+ }
+ if (c == 'd' || c == 'D') {
+ /* decimal */
+ c = nextc(p);
+ if (c != -1 && ISDIGIT(c)) {
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (!ISDIGIT(c)) break;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+ }
+ pushback(p, c);
+ tokfix(p);
+ if (toklen(p) == start) {
+ no_digits();
+ }
+ else if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 10);
+ return tINTEGER;
+ }
+ if (c == '_') {
+ /* 0_0 */
+ goto octal_number;
+ }
+ if (c == 'o' || c == 'O') {
+ /* prefixed octal */
+ c = nextc(p);
+ if (c == -1 || c == '_' || !ISDIGIT(c)) {
+ no_digits();
+ }
+ }
+ if (c >= '0' && c <= '7') {
+ /* octal */
+ octal_number:
+ do {
+ if (c == '_') {
+ if (nondigit) break;
+ nondigit = c;
+ continue;
+ }
+ if (c < '0' || c > '9') break;
+ if (c > '7') goto invalid_octal;
+ nondigit = 0;
+ tokadd(p, c);
+ } while ((c = nextc(p)) != -1);
+
+ if (toklen(p) > start) {
+ pushback(p, c);
+ tokfix(p);
+ if (nondigit) goto trailing_uc;
+ yylval.nd = new_int(p, tok(p), 8);
+ return tINTEGER;
+ }
+ if (nondigit) {
+ pushback(p, c);
+ goto trailing_uc;
+ }
+ }
+ if (c > '7' && c <= '9') {
+ invalid_octal:
+ yyerror(p, "Invalid octal digit");
+ }
+ else if (c == '.' || c == 'e' || c == 'E') {
+ tokadd(p, '0');
+ }
+ else {
+ pushback(p, c);
+ yylval.nd = new_int(p, "0", 10);
+ return tINTEGER;
+ }
}
for (;;) {
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- nondigit = 0;
- tokadd(p, c);
- break;
-
- case '.':
- if (nondigit) goto trailing_uc;
- if (seen_point || seen_e) {
- goto decode_num;
- }
- else {
- int c0 = nextc(p);
- if (c0 == -1 || !ISDIGIT(c0)) {
- pushback(p, c0);
- goto decode_num;
- }
- c = c0;
- }
- tokadd(p, '.');
- tokadd(p, c);
- is_float++;
- seen_point++;
- nondigit = 0;
- break;
-
- case 'e':
- case 'E':
- if (nondigit) {
- pushback(p, c);
- c = nondigit;
- goto decode_num;
- }
- if (seen_e) {
- goto decode_num;
- }
- tokadd(p, c);
- seen_e++;
- is_float++;
- nondigit = c;
- c = nextc(p);
- if (c != '-' && c != '+') continue;
- tokadd(p, c);
- nondigit = c;
- break;
-
- case '_': /* `_' in number just ignored */
- if (nondigit) goto decode_num;
- nondigit = c;
- break;
-
- default:
- goto decode_num;
- }
- c = nextc(p);
+ switch (c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ nondigit = 0;
+ tokadd(p, c);
+ break;
+
+ case '.':
+ if (nondigit) goto trailing_uc;
+ if (seen_point || seen_e) {
+ goto decode_num;
+ }
+ else {
+ int c0 = nextc(p);
+ if (c0 == -1 || !ISDIGIT(c0)) {
+ pushback(p, c0);
+ goto decode_num;
+ }
+ c = c0;
+ }
+ tokadd(p, '.');
+ tokadd(p, c);
+ is_float++;
+ seen_point++;
+ nondigit = 0;
+ break;
+
+ case 'e':
+ case 'E':
+ if (nondigit) {
+ pushback(p, c);
+ c = nondigit;
+ goto decode_num;
+ }
+ if (seen_e) {
+ goto decode_num;
+ }
+ tokadd(p, c);
+ seen_e++;
+ is_float++;
+ nondigit = c;
+ c = nextc(p);
+ if (c != '-' && c != '+') continue;
+ tokadd(p, c);
+ nondigit = c;
+ break;
+
+ case '_': /* `_' in number just ignored */
+ if (nondigit) goto decode_num;
+ nondigit = c;
+ break;
+
+ default:
+ goto decode_num;
+ }
+ c = nextc(p);
}
decode_num:
pushback(p, c);
if (nondigit) {
trailing_uc:
- yyerror_i(p, "trailing `%c' in number", nondigit);
+ yyerror_i(p, "trailing `%c' in number", nondigit);
}
tokfix(p);
if (is_float) {
- double d;
- char *endp;
-
- errno = 0;
- d = strtod(tok(p), &endp);
- if (d == 0 && endp == tok(p)) {
- yywarning_s(p, "corrupted float value %s", tok(p));
- }
- else if (errno == ERANGE) {
- yywarning_s(p, "float %s out of range", tok(p));
- errno = 0;
- }
- yylval.nd = new_float(p, tok(p));
- return tFLOAT;
+ double d;
+ char *endp;
+
+ errno = 0;
+ d = strtod(tok(p), &endp);
+ if (d == 0 && endp == tok(p)) {
+ yywarning_s(p, "corrupted float value %s", tok(p));
+ }
+ else if (errno == ERANGE) {
+ yywarning_s(p, "float %s out of range", tok(p));
+ errno = 0;
+ }
+ yylval.nd = new_float(p, tok(p));
+ return tFLOAT;
}
yylval.nd = new_int(p, tok(p), 10);
return tINTEGER;
@@ -4454,8 +4504,8 @@ parser_yylex(parser_state *p)
c = nextc(p);
if (c == ':') {
if (IS_BEG() || p->lstate == EXPR_CLASS || IS_SPCARG(-1)) {
- p->lstate = EXPR_BEG;
- return tCOLON3;
+ p->lstate = EXPR_BEG;
+ return tCOLON3;
}
p->lstate = EXPR_DOT;
return tCOLON2;
@@ -4471,25 +4521,17 @@ parser_yylex(parser_state *p)
case '/':
if (IS_BEG()) {
-#if 0
p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
-#endif
- p->regexp = 1;
- p->sterm = '/';
return tREGEXP_BEG;
}
if ((c = nextc(p)) == '=') {
- yylval.id = intern("/");
+ yylval.id = intern_c('/');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
pushback(p, c);
if (IS_SPCARG(c)) {
-#if 0
p->lex_strterm = new_strterm(p, str_regexp, '/', 0);
-#endif
- p->regexp = 1;
- p->sterm = '/';
return tREGEXP_BEG;
}
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
@@ -4501,7 +4543,7 @@ parser_yylex(parser_state *p)
case '^':
if ((c = nextc(p)) == '=') {
- yylval.id = intern("^");
+ yylval.id = intern_c('^');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4524,7 +4566,7 @@ parser_yylex(parser_state *p)
case '~':
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
if ((c = nextc(p)) != '@') {
- pushback(p, c);
+ pushback(p, c);
}
p->lstate = EXPR_ARG;
}
@@ -4551,11 +4593,11 @@ parser_yylex(parser_state *p)
if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) {
p->lstate = EXPR_ARG;
if ((c = nextc(p)) == ']') {
- if ((c = nextc(p)) == '=') {
- return tASET;
- }
- pushback(p, c);
- return tAREF;
+ if ((c = nextc(p)) == '=') {
+ return tASET;
+ }
+ pushback(p, c);
+ return tAREF;
}
pushback(p, c);
return '[';
@@ -4604,92 +4646,77 @@ parser_yylex(parser_state *p)
case '%':
if (IS_BEG()) {
- int beg = 0, term;
-#if 0
+ int term;
int paren;
-#endif
c = nextc(p);
quotation:
if (c == -1 || !ISALNUM(c)) {
- term = c;
- c = 'Q';
+ term = c;
+ c = 'Q';
}
else {
- beg = term = nextc(p);
- if (isalnum(term)) {
- yyerror(p, "unknown type of %string");
- return 0;
- }
+ term = nextc(p);
+ if (isalnum(term)) {
+ yyerror(p, "unknown type of %string");
+ return 0;
+ }
}
if (c == -1 || term == -1) {
- yyerror(p, "unterminated quoted string meets end of file");
- return 0;
+ yyerror(p, "unterminated quoted string meets end of file");
+ return 0;
}
-#if 0
paren = term;
-#endif
if (term == '(') term = ')';
else if (term == '[') term = ']';
else if (term == '{') term = '}';
else if (term == '<') term = '>';
- p->sterm = term;
-#if 0
else paren = 0;
-#endif
switch (c) {
case 'Q':
-#if 0
- p->lex_strterm = new_strterm(p, str_dquote, term, paren);
-#endif
- return tSTRING_BEG;
+ p->lex_strterm = new_strterm(p, str_dquote, term, paren);
+ return tSTRING_BEG;
case 'q':
-#if 0
- p->lex_strterm = new_strterm(p, str_squote, term, paren);
-#endif
- p->sterm = 0;
- return parse_qstring(p, beg, term);
+ p->lex_strterm = new_strterm(p, str_squote, term, paren);
+ return parse_string(p);
case 'W':
-#if 0
- p->lex_strterm = new_strterm(p, str_dword, term, paren);
-#endif
- do {c = nextc(p);} while (isspace(c));
- pushback(p, c);
- return tWORDS_BEG;
+ p->lex_strterm = new_strterm(p, str_dword, term, paren);
+ return tWORDS_BEG;
case 'w':
-#if 0
- p->lex_strterm = new_strterm(p, str_sword, term, paren);
-#endif
- do {c = nextc(p);} while (isspace(c));
- pushback(p, c);
- return tQWORDS_BEG;
+ p->lex_strterm = new_strterm(p, str_sword, term, paren);
+ return tWORDS_BEG;
+
+ case 'x':
+ p->lex_strterm = new_strterm(p, str_xquote, term, paren);
+ return tXSTRING_BEG;
case 'r':
-#if 0
- p->lex_strterm = new_strterm(p, str_regexp, term, paren);
-#endif
- p->regexp = 1;
- p->sterm = term;
- return tREGEXP_BEG;
+ p->lex_strterm = new_strterm(p, str_regexp, term, paren);
+ return tREGEXP_BEG;
case 's':
-#if 0
- p->lex_strterm = new_strterm(p, str_ssym, term, paren);
-#endif
- p->lstate = EXPR_FNAME;
- return tSYMBEG;
+ p->lex_strterm = new_strterm(p, str_ssym, term, paren);
+ return tSYMBEG;
+
+ case 'I':
+ p->lex_strterm = new_strterm(p, str_dsymbols, term, paren);
+ return tSYMBOLS_BEG;
+
+ case 'i':
+ p->lex_strterm = new_strterm(p, str_ssymbols, term, paren);
+ return tSYMBOLS_BEG;
default:
- yyerror(p, "unknown type of %string");
- return 0;
+ yyerror(p, "unknown type of %string");
+ return 0;
}
}
if ((c = nextc(p)) == '=') {
- yylval.id = intern("%");
+ yylval.id = intern_c('%');
p->lstate = EXPR_BEG;
return tOP_ASGN;
}
@@ -4751,9 +4778,9 @@ parser_yylex(parser_state *p)
case '\'': /* $': string after last match */
case '+': /* $+: string matches last pattern */
if (last_state == EXPR_FNAME) {
- tokadd(p, '$');
- tokadd(p, c);
- goto gvar;
+ tokadd(p, '$');
+ tokadd(p, c);
+ goto gvar;
}
yylval.nd = new_back_ref(p, c);
return tBACK_REF;
@@ -4762,8 +4789,8 @@ parser_yylex(parser_state *p)
case '4': case '5': case '6':
case '7': case '8': case '9':
do {
- tokadd(p, c);
- c = nextc(p);
+ tokadd(p, c);
+ c = nextc(p);
} while (c != -1 && isdigit(c));
pushback(p, c);
if (last_state == EXPR_FNAME) goto gvar;
@@ -4773,8 +4800,8 @@ parser_yylex(parser_state *p)
default:
if (!identchar(c)) {
- pushback(p, c);
- return '$';
+ pushback(p, c);
+ return '$';
}
case '0':
tokadd(p, '$');
@@ -4791,10 +4818,10 @@ parser_yylex(parser_state *p)
}
if (c != -1 && isdigit(c)) {
if (p->bidx == 1) {
- yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
+ yyerror_i(p, "`@%c' is not allowed as an instance variable name", c);
}
else {
- yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
+ yyerror_i(p, "`@@%c' is not allowed as a class variable name", c);
}
return 0;
}
@@ -4852,95 +4879,95 @@ parser_yylex(parser_state *p)
case '@':
p->lstate = EXPR_END;
if (tok(p)[1] == '@')
- result = tCVAR;
+ result = tCVAR;
else
- result = tIVAR;
+ result = tIVAR;
break;
default:
if (toklast(p) == '!' || toklast(p) == '?') {
- result = tFID;
+ result = tFID;
}
else {
- if (p->lstate == EXPR_FNAME) {
- if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
- (!peek(p, '=') || (peek_n(p, '>', 1)))) {
- result = tIDENTIFIER;
- tokadd(p, c);
- tokfix(p);
- }
- else {
- pushback(p, c);
- }
- }
- if (result == 0 && isupper((int)tok(p)[0])) {
- result = tCONSTANT;
- }
- else {
- result = tIDENTIFIER;
- }
+ if (p->lstate == EXPR_FNAME) {
+ if ((c = nextc(p)) == '=' && !peek(p, '~') && !peek(p, '>') &&
+ (!peek(p, '=') || (peek_n(p, '>', 1)))) {
+ result = tIDENTIFIER;
+ tokadd(p, c);
+ tokfix(p);
+ }
+ else {
+ pushback(p, c);
+ }
+ }
+ if (result == 0 && isupper((int)tok(p)[0])) {
+ result = tCONSTANT;
+ }
+ else {
+ result = tIDENTIFIER;
+ }
}
if (IS_LABEL_POSSIBLE()) {
- if (IS_LABEL_SUFFIX(0)) {
- p->lstate = EXPR_BEG;
- nextc(p);
- tokfix(p);
- yylval.id = intern(tok(p));
- return tLABEL;
- }
+ if (IS_LABEL_SUFFIX(0)) {
+ p->lstate = EXPR_BEG;
+ nextc(p);
+ tokfix(p);
+ yylval.id = intern(tok(p));
+ return tLABEL;
+ }
}
if (p->lstate != EXPR_DOT) {
- const struct kwtable *kw;
-
- /* See if it is a reserved word. */
- kw = mrb_reserved_word(tok(p), toklen(p));
- if (kw) {
- enum mrb_lex_state_enum state = p->lstate;
- p->lstate = kw->state;
- if (state == EXPR_FNAME) {
- yylval.id = intern(kw->name);
- return kw->id[0];
- }
- if (p->lstate == EXPR_BEG) {
- p->cmd_start = TRUE;
- }
- if (kw->id[0] == keyword_do) {
- if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
- p->lpar_beg = 0;
- p->paren_nest--;
- return keyword_do_LAMBDA;
- }
- if (COND_P()) return keyword_do_cond;
- if (CMDARG_P() && state != EXPR_CMDARG)
- return keyword_do_block;
- if (state == EXPR_ENDARG || state == EXPR_BEG)
- return keyword_do_block;
- return keyword_do;
- }
- if (state == EXPR_BEG || state == EXPR_VALUE)
- return kw->id[0];
- else {
- if (kw->id[0] != kw->id[1])
- p->lstate = EXPR_BEG;
- return kw->id[1];
- }
- }
+ const struct kwtable *kw;
+
+ /* See if it is a reserved word. */
+ kw = mrb_reserved_word(tok(p), toklen(p));
+ if (kw) {
+ enum mrb_lex_state_enum state = p->lstate;
+ p->lstate = kw->state;
+ if (state == EXPR_FNAME) {
+ yylval.id = intern(kw->name);
+ return kw->id[0];
+ }
+ if (p->lstate == EXPR_BEG) {
+ p->cmd_start = TRUE;
+ }
+ if (kw->id[0] == keyword_do) {
+ if (p->lpar_beg && p->lpar_beg == p->paren_nest) {
+ p->lpar_beg = 0;
+ p->paren_nest--;
+ return keyword_do_LAMBDA;
+ }
+ if (COND_P()) return keyword_do_cond;
+ if (CMDARG_P() && state != EXPR_CMDARG)
+ return keyword_do_block;
+ if (state == EXPR_ENDARG || state == EXPR_BEG)
+ return keyword_do_block;
+ return keyword_do;
+ }
+ if (state == EXPR_BEG || state == EXPR_VALUE)
+ return kw->id[0];
+ else {
+ if (kw->id[0] != kw->id[1])
+ p->lstate = EXPR_BEG;
+ return kw->id[1];
+ }
+ }
}
if (IS_BEG() || p->lstate == EXPR_DOT || IS_ARG()) {
- if (cmd_state) {
- p->lstate = EXPR_CMDARG;
- }
- else {
- p->lstate = EXPR_ARG;
- }
+ if (cmd_state) {
+ p->lstate = EXPR_CMDARG;
+ }
+ else {
+ p->lstate = EXPR_ARG;
+ }
}
else if (p->lstate == EXPR_FNAME) {
- p->lstate = EXPR_ENDFN;
+ p->lstate = EXPR_ENDFN;
}
else {
- p->lstate = EXPR_END;
+ p->lstate = EXPR_END;
}
}
{
@@ -4949,7 +4976,7 @@ parser_yylex(parser_state *p)
yylval.id = ident;
#if 0
if (last_state != EXPR_DOT && islower(tok(p)[0]) && lvar_defined(ident)) {
- p->lstate = EXPR_END;
+ p->lstate = EXPR_END;
}
#endif
}
@@ -5021,7 +5048,7 @@ mrb_parser_parse(parser_state *p, mrbc_context *c)
p->cmd_start = TRUE;
p->in_def = p->in_single = FALSE;
p->nerr = p->nwarn = 0;
- p->sterm = 0;
+ p->lex_strterm = NULL;
parser_init_cxt(p, c);
yyparse(p);
@@ -5064,6 +5091,7 @@ mrb_parser_new(mrb_state *mrb)
yydebug = 1;
#endif
+ p->lex_strterm = NULL;
p->heredocs = p->parsing_heredoc = NULL;
return p;
@@ -5153,13 +5181,13 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
n = snprintf(buf, sizeof(buf), "line %d: %s\n",
p->error_buffer[0].lineno, p->error_buffer[0].message);
- mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, buf, n));
mrb_parser_free(p);
return mrb_undef_value();
}
else {
static const char msg[] = "syntax error";
- mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SYNTAX_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SYNTAX_ERROR, msg, sizeof(msg) - 1));
mrb_parser_free(p);
return mrb_undef_value();
}
@@ -5168,7 +5196,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c)
mrb_parser_free(p);
if (n < 0) {
static const char msg[] = "codegen error";
- mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
+ mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, E_SCRIPT_ERROR, msg, sizeof(msg) - 1));
return mrb_nil_value();
}
if (c) {
@@ -5269,23 +5297,23 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
dump_prefix(offset+1);
printf("rescue:\n");
while (n2) {
- node *n3 = n2->car;
- if (n3->car) {
- dump_prefix(offset+2);
- printf("handle classes:\n");
- dump_recur(mrb, n3->car, offset+3);
- }
- if (n3->cdr->car) {
- dump_prefix(offset+2);
- printf("exc_var:\n");
- parser_dump(mrb, n3->cdr->car, offset+3);
- }
- if (n3->cdr->cdr->car) {
- dump_prefix(offset+2);
- printf("rescue body:\n");
- parser_dump(mrb, n3->cdr->cdr->car, offset+3);
- }
- n2 = n2->cdr;
+ node *n3 = n2->car;
+ if (n3->car) {
+ dump_prefix(offset+2);
+ printf("handle classes:\n");
+ dump_recur(mrb, n3->car, offset+3);
+ }
+ if (n3->cdr->car) {
+ dump_prefix(offset+2);
+ printf("exc_var:\n");
+ parser_dump(mrb, n3->cdr->car, offset+3);
+ }
+ if (n3->cdr->cdr->car) {
+ dump_prefix(offset+2);
+ printf("rescue body:\n");
+ parser_dump(mrb, n3->cdr->cdr->car, offset+3);
+ }
+ n2 = n2->cdr;
}
}
tree = tree->cdr;
@@ -5318,40 +5346,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
dump_prefix(offset+1);
@@ -5431,25 +5459,25 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
- printf("pre:\n");
- dump_recur(mrb, n2->car, offset+3);
+ dump_prefix(offset+2);
+ printf("pre:\n");
+ dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("rest:\n");
- parser_dump(mrb, n2->car, offset+3);
- }
- n2 = n2->cdr;
- if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("post:\n");
- dump_recur(mrb, n2->car, offset+3);
- }
- }
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("rest:\n");
+ parser_dump(mrb, n2->car, offset+3);
+ }
+ n2 = n2->cdr;
+ if (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("post:\n");
+ dump_recur(mrb, n2->car, offset+3);
+ }
+ }
}
}
tree = tree->cdr;
@@ -5468,17 +5496,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
- printf("local variables:\n");
- dump_prefix(offset+2);
- while (n2) {
- if (n2->car) {
- if (n2 != tree->car) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
- }
- n2 = n2->cdr;
- }
- printf("\n");
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+ dump_prefix(offset+2);
+ while (n2) {
+ if (n2->car) {
+ if (n2 != tree->car) printf(", ");
+ printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5499,9 +5527,9 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
- printf("block:\n");
- parser_dump(mrb, tree->cdr, offset+2);
+ dump_prefix(offset+1);
+ printf("block:\n");
+ parser_dump(mrb, tree->cdr, offset+2);
}
}
break;
@@ -5572,31 +5600,31 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2->car) {
- dump_prefix(offset+2);
- printf("pre:\n");
- dump_recur(mrb, n2->car, offset+3);
+ dump_prefix(offset+2);
+ printf("pre:\n");
+ dump_recur(mrb, n2->car, offset+3);
}
n2 = n2->cdr;
if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("rest:\n");
- if (n2->car == (node*)-1) {
- dump_prefix(offset+2);
- printf("(empty)\n");
- }
- else {
- parser_dump(mrb, n2->car, offset+3);
- }
- }
- n2 = n2->cdr;
- if (n2) {
- if (n2->car) {
- dump_prefix(offset+2);
- printf("post:\n");
- dump_recur(mrb, n2->car, offset+3);
- }
- }
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("rest:\n");
+ if (n2->car == (node*)-1) {
+ dump_prefix(offset+2);
+ printf("(empty)\n");
+ }
+ else {
+ parser_dump(mrb, n2->car, offset+3);
+ }
+ }
+ n2 = n2->cdr;
+ if (n2) {
+ if (n2->car) {
+ dump_prefix(offset+2);
+ printf("post:\n");
+ dump_recur(mrb, n2->car, offset+3);
+ }
+ }
}
}
dump_prefix(offset+1);
@@ -5623,9 +5651,9 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
printf("args:\n");
dump_recur(mrb, tree->car, offset+2);
if (tree->cdr) {
- dump_prefix(offset+1);
- printf("block:\n");
- parser_dump(mrb, tree->cdr, offset+2);
+ dump_prefix(offset+1);
+ printf("block:\n");
+ parser_dump(mrb, tree->cdr, offset+2);
}
}
break;
@@ -5731,6 +5759,15 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
dump_recur(mrb, tree, offset+1);
break;
+ case NODE_XSTR:
+ printf("NODE_XSTR \"%s\" len %d\n", (char*)tree->car, (int)(intptr_t)tree->cdr);
+ break;
+
+ case NODE_DXSTR:
+ printf("NODE_DXSTR\n");
+ dump_recur(mrb, tree, offset+1);
+ break;
+
case NODE_REGX:
printf("NODE_REGX /%s/%s\n", (char*)tree->car, (char*)tree->cdr);
break;
@@ -5766,8 +5803,8 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
case NODE_ALIAS:
printf("NODE_ALIAS %s %s:\n",
- mrb_sym2name(mrb, sym(tree->car)),
- mrb_sym2name(mrb, sym(tree->cdr)));
+ mrb_sym2name(mrb, sym(tree->car)),
+ mrb_sym2name(mrb, sym(tree->cdr)));
break;
case NODE_UNDEF:
@@ -5775,8 +5812,8 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
{
node *t = tree;
while (t) {
- printf(" %s", mrb_sym2name(mrb, sym(t->car)));
- t = t->cdr;
+ printf(" %s", mrb_sym2name(mrb, sym(t->car)));
+ t = t->cdr;
}
}
printf(":\n");
@@ -5844,17 +5881,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n2 = tree->car;
if (n2 && (n2->car || n2->cdr)) {
- dump_prefix(offset+1);
- printf("local variables:\n");
- dump_prefix(offset+2);
- while (n2) {
- if (n2->car) {
- if (n2 != tree->car) printf(", ");
- printf("%s", mrb_sym2name(mrb, sym(n2->car)));
- }
- n2 = n2->cdr;
- }
- printf("\n");
+ dump_prefix(offset+1);
+ printf("local variables:\n");
+ dump_prefix(offset+2);
+ while (n2) {
+ if (n2->car) {
+ if (n2 != tree->car) printf(", ");
+ printf("%s", mrb_sym2name(mrb, sym(n2->car)));
+ }
+ n2 = n2->cdr;
+ }
+ printf("\n");
}
}
tree = tree->cdr;
@@ -5862,40 +5899,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
parser_dump(mrb, tree->cdr->car, offset+1);
@@ -5912,40 +5949,40 @@ parser_dump(mrb_state *mrb, node *tree, int offset)
node *n = tree->car;
if (n->car) {
- dump_prefix(offset+1);
- printf("mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("optional args:\n");
- {
- node *n2 = n->car;
-
- while (n2) {
- dump_prefix(offset+2);
- printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
- parser_dump(mrb, n2->car->cdr, 0);
- n2 = n2->cdr;
- }
- }
+ dump_prefix(offset+1);
+ printf("optional args:\n");
+ {
+ node *n2 = n->car;
+
+ while (n2) {
+ dump_prefix(offset+2);
+ printf("%s=", mrb_sym2name(mrb, sym(n2->car->car)));
+ parser_dump(mrb, n2->car->cdr, 0);
+ n2 = n2->cdr;
+ }
+ }
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
+ dump_prefix(offset+1);
+ printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car)));
}
n = n->cdr;
if (n->car) {
- dump_prefix(offset+1);
- printf("post mandatory args:\n");
- dump_recur(mrb, n->car, offset+2);
+ dump_prefix(offset+1);
+ printf("post mandatory args:\n");
+ dump_recur(mrb, n->car, offset+2);
}
n = n->cdr;
if (n) {
- dump_prefix(offset+1);
- printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
+ dump_prefix(offset+1);
+ printf("blk=&%s\n", mrb_sym2name(mrb, sym(n)));
}
}
tree = tree->cdr;
diff --git a/src/print.c b/src/print.c
index 9d8a751f7..5367781f5 100644
--- a/src/print.c
+++ b/src/print.c
@@ -34,29 +34,6 @@ mrb_p(mrb_state *mrb, mrb_value obj)
#endif
}
-/* 15.3.1.2.9 */
-/* 15.3.1.3.34 */
-mrb_value
-mrb_printstr(mrb_state *mrb, mrb_value self)
-{
- mrb_value argv;
-
- mrb_get_args(mrb, "o", &argv);
- printstr(mrb, argv);
-
- return argv;
-}
-
-void
-mrb_init_print(mrb_state *mrb)
-{
- struct RClass *krn;
-
- krn = mrb->kernel_module;
-
- mrb_define_method(mrb, krn, "__printstr__", mrb_printstr, ARGS_REQ(1));
-}
-
void
mrb_show_version(mrb_state *mrb)
{
diff --git a/src/range.c b/src/range.c
index 59bf445aa..fb4d975e7 100644
--- a/src/range.c
+++ b/src/range.c
@@ -8,7 +8,6 @@
#include "mruby/class.h"
#include "mruby/range.h"
#include "mruby/string.h"
-#include <string.h>
#define RANGE_CLASS (mrb_class_obj_get(mrb, "Range"))
@@ -92,7 +91,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
{
struct RRange *r = mrb_range_ptr(range);
- return r->excl ? mrb_true_value() : mrb_false_value();
+ return mrb_bool_value(r->excl);
}
static void
@@ -153,25 +152,30 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
struct RRange *rr;
struct RRange *ro;
mrb_value obj;
+ mrb_bool eq_p;
mrb_get_args(mrb, "o", &obj);
- if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
-
- /* same class? */
- if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range)))
- return mrb_false_value();
-
- rr = mrb_range_ptr(range);
- ro = mrb_range_ptr(obj);
- if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg))
- return mrb_false_value();
- if (!mrb_obj_equal(mrb, rr->edges->end, ro->edges->end))
- return mrb_false_value();
- if (rr->excl != ro->excl)
- return mrb_false_value();
+ if (mrb_obj_equal(mrb, range, obj)) {
+ eq_p = 1;
+ }
+ else if (!mrb_obj_is_instance_of(mrb, obj, mrb_obj_class(mrb, range))) { /* same class? */
+ eq_p = 0;
+ }
+ else {
+ rr = mrb_range_ptr(range);
+ ro = mrb_range_ptr(obj);
+ if (!mrb_obj_equal(mrb, rr->edges->beg, ro->edges->beg) ||
+ !mrb_obj_equal(mrb, rr->edges->end, ro->edges->end) ||
+ rr->excl != ro->excl) {
+ eq_p = 0;
+ }
+ else {
+ eq_p = 1;
+ }
+ }
- return mrb_true_value();
+ return mrb_bool_value(eq_p);
}
static int
@@ -228,21 +232,17 @@ mrb_range_include(mrb_state *mrb, mrb_value range)
mrb_value val;
struct RRange *r = mrb_range_ptr(range);
mrb_value beg, end;
+ mrb_bool include_p;
mrb_get_args(mrb, "o", &val);
beg = r->edges->beg;
end = r->edges->end;
- if (r_le(mrb, beg, val)) {
- /* beg <= val */
- if (r->excl) {
- if (r_gt(mrb, end, val)) return mrb_true_value(); /* end > val */
- }
- else {
- if (r_ge(mrb, end, val)) return mrb_true_value(); /* end >= val */
- }
- }
- return mrb_false_value();
+ include_p = r_le(mrb, beg, val) && /* beg <= val */
+ ((r->excl && r_gt(mrb, end, val)) || /* end > val */
+ (r_ge(mrb, end, val))); /* end >= val */
+
+ return mrb_bool_value(include_p);
}
/*
@@ -385,23 +385,34 @@ range_eql(mrb_state *mrb, mrb_value range)
{
mrb_value obj;
struct RRange *r, *o;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &obj);
- if (mrb_obj_equal(mrb, range, obj))
- return mrb_true_value();
- if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS))
- return mrb_false_value();
-
- r = mrb_range_ptr(range);
- if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
- o = mrb_range_ptr(obj);
- if (!mrb_eql(mrb, r->edges->beg, o->edges->beg))
- return mrb_false_value();
- if (!mrb_eql(mrb, r->edges->end, o->edges->end))
- return mrb_false_value();
- if (r->excl != o->excl)
- return mrb_false_value();
- return mrb_true_value();
+ if (mrb_obj_equal(mrb, range, obj)) {
+ eql_p = 1;
+ }
+ else if (!mrb_obj_is_kind_of(mrb, obj, RANGE_CLASS)) {
+ eql_p = 0;
+ }
+ else {
+ r = mrb_range_ptr(range);
+ if (mrb_type(obj) != MRB_TT_RANGE) {
+ eql_p = 0;
+ }
+ else {
+ o = mrb_range_ptr(obj);
+ if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
+ !mrb_eql(mrb, r->edges->end, o->edges->end) ||
+ (r->excl != o->excl)) {
+ eql_p = 0;
+ }
+ else {
+ eql_p = 1;
+ }
+ }
+ }
+
+ return mrb_bool_value(eql_p);
}
/* 15.2.14.4.15(x) */
diff --git a/src/state.c b/src/state.c
index b6805a4a4..7b5bd1002 100644
--- a/src/state.c
+++ b/src/state.c
@@ -7,6 +7,7 @@
#include "mruby.h"
#include "mruby/irep.h"
#include "mruby/variable.h"
+#include <stdlib.h>
#include <string.h>
void mrb_init_heap(mrb_state*);
@@ -53,6 +54,7 @@ mrb_alloca(mrb_state *mrb, size_t size)
struct alloca_header *p;
p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
+ if (p == NULL) return NULL;
p->next = mrb->mems;
mrb->mems = p;
return (void*)p->buf;
@@ -61,9 +63,12 @@ mrb_alloca(mrb_state *mrb, size_t size)
static void
mrb_alloca_free(mrb_state *mrb)
{
- struct alloca_header *p = mrb->mems;
+ struct alloca_header *p;
struct alloca_header *tmp;
+ if (mrb == NULL) return;
+ p = mrb->mems;
+
while (p) {
tmp = p;
p = p->next;
@@ -134,7 +139,7 @@ mrb_add_irep(mrb_state *mrb)
mrb->irep_capa = max;
}
else if (mrb->irep_capa <= mrb->irep_len) {
- int i;
+ size_t i;
size_t old_capa = mrb->irep_capa;
while (mrb->irep_capa <= mrb->irep_len) {
mrb->irep_capa *= 2;
diff --git a/src/string.c b/src/string.c
index cfef5730c..09777ac69 100644
--- a/src/string.c
+++ b/src/string.c
@@ -6,6 +6,8 @@
#include "mruby.h"
+#include <stddef.h>
+#include <stdlib.h>
#include <string.h>
#include "mruby/string.h"
#include "mruby/class.h"
@@ -20,19 +22,13 @@
const char mrb_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
static mrb_value str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2);
-static mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, int beg, int len);
+static mrb_value mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
#define RESIZE_CAPA(s,capacity) do {\
s->ptr = (char *)mrb_realloc(mrb, s->ptr, (capacity)+1);\
s->aux.capa = capacity;\
} while (0)
-static const char*
-_obj_classname(mrb_state *mrb, mrb_value obj)
-{
- return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
-}
-
void
mrb_str_decref(mrb_state *mrb, mrb_shared_string *shared)
{
@@ -56,11 +52,11 @@ str_modify(mrb_state *mrb, struct RString *s)
}
else {
char *ptr, *p;
- long len;
+ mrb_int len;
p = s->ptr;
len = s->len;
- ptr = (char *)mrb_malloc(mrb, len+1);
+ ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
if (p) {
memcpy(ptr, p, len);
}
@@ -104,21 +100,6 @@ str_mod_check(mrb_state *mrb, mrb_value str, char *p, mrb_int len)
#define mrb_obj_alloc_string(mrb) ((struct RString*)mrb_obj_alloc((mrb), MRB_TT_STRING, (mrb)->string_class))
-static struct RString*
-str_alloc(mrb_state *mrb, struct RClass *c)
-{
- struct RString* s;
-
- s = mrb_obj_alloc_string(mrb);
-
- s->c = c;
- s->ptr = 0;
- s->len = 0;
- s->aux.capa = 0;
-
- return s;
-}
-
/* char offset to byte offset */
int
mrb_str_offset(mrb_state *mrb, mrb_value str, int pos)
@@ -129,8 +110,9 @@ mrb_str_offset(mrb_state *mrb, mrb_value str, int pos)
static struct RString*
str_new(mrb_state *mrb, const char *p, int len)
{
- struct RString *s = str_alloc(mrb, mrb->string_class);
+ struct RString *s;
+ s = mrb_obj_alloc_string(mrb);
s->len = len;
s->aux.capa = len;
s->ptr = (char *)mrb_malloc(mrb, len+1);
@@ -156,6 +138,10 @@ mrb_str_new_empty(mrb_state *mrb, mrb_value str)
return mrb_obj_value(s);
}
+#ifndef MRB_STR_BUF_MIN_SIZE
+# define MRB_STR_BUF_MIN_SIZE 128
+#endif
+
mrb_value
mrb_str_buf_new(mrb_state *mrb, int capa)
{
@@ -163,8 +149,8 @@ mrb_str_buf_new(mrb_state *mrb, int capa)
s = mrb_obj_alloc_string(mrb);
- if (capa < STR_BUF_MIN_SIZE) {
- capa = STR_BUF_MIN_SIZE;
+ if (capa < MRB_STR_BUF_MIN_SIZE) {
+ capa = MRB_STR_BUF_MIN_SIZE;
}
s->len = 0;
s->aux.capa = capa;
@@ -175,9 +161,11 @@ mrb_str_buf_new(mrb_state *mrb, int capa)
}
static void
-str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, int len)
+str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, size_t len)
{
- long capa, total, off = -1;
+ mrb_int capa;
+ mrb_int total;
+ ptrdiff_t off = -1;
str_modify(mrb, s);
if (ptr >= s->ptr && ptr <= s->ptr + s->len) {
@@ -185,13 +173,13 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, int len)
}
if (len == 0) return;
capa = s->aux.capa;
- if (s->len >= INT_MAX - len) {
+ if (s->len >= MRB_INT_MAX - len) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string sizes too big");
}
total = s->len+len;
if (capa <= total) {
while (total > capa) {
- if (capa + 1 >= INT_MAX / 2) {
+ if (capa + 1 >= MRB_INT_MAX / 2) {
capa = (total + 4095) / 4096;
break;
}
@@ -208,7 +196,7 @@ str_buf_cat(mrb_state *mrb, struct RString *s, const char *ptr, int len)
}
mrb_value
-mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, int len)
+mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len)
{
if (len == 0) return str;
str_buf_cat(mrb, mrb_str_ptr(str), ptr, len);
@@ -216,7 +204,7 @@ mrb_str_buf_cat(mrb_state *mrb, mrb_value str, const char *ptr, int len)
}
mrb_value
-mrb_str_new(mrb_state *mrb, const char *p, int len)
+mrb_str_new(mrb_state *mrb, const char *p, size_t len)
{
struct RString *s;
@@ -224,17 +212,6 @@ mrb_str_new(mrb_state *mrb, const char *p, int len)
return mrb_obj_value(s);
}
-mrb_value
-mrb_str_new2(mrb_state *mrb, const char *ptr)
-{
- struct RString *s;
- if (!ptr) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "NULL pointer given");
- }
- s = str_new(mrb, ptr, strlen(ptr));
- return mrb_obj_value(s);
-}
-
/*
* call-seq: (Caution! NULL string)
* String.new(str="") => new_str
@@ -246,11 +223,23 @@ mrb_value
mrb_str_new_cstr(mrb_state *mrb, const char *p)
{
struct RString *s;
- int len = strlen(p);
+ size_t len;
+
+ if (p) {
+ len = strlen(p);
+ if ((mrb_int)len < 0) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
+ }
+ }
+ else {
+ len = 0;
+ }
s = mrb_obj_alloc_string(mrb);
s->ptr = (char *)mrb_malloc(mrb, len+1);
- memcpy(s->ptr, p, len);
+ if (p) {
+ memcpy(s->ptr, p, len);
+ }
s->ptr[len] = 0;
s->len = len;
s->aux.capa = len;
@@ -263,6 +252,10 @@ mrb_str_to_cstr(mrb_state *mrb, mrb_value str0)
{
mrb_value str;
+ if (!mrb_string_p(str0)) {
+ mrb_raise(mrb, E_TYPE_ERROR, "expected String");
+ }
+
str = mrb_str_new(mrb, RSTRING_PTR(str0), RSTRING_LEN(str0));
if (strlen(RSTRING_PTR(str)) != RSTRING_LEN(str)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
@@ -302,7 +295,7 @@ mrb_str_literal(mrb_state *mrb, mrb_value str)
struct RString *s, *orig;
mrb_shared_string *shared;
- s = str_alloc(mrb, mrb->string_class);
+ s = mrb_obj_alloc_string(mrb);
orig = mrb_str_ptr(str);
if (!(orig->flags & MRB_STR_SHARED)) {
str_make_shared(mrb, mrb_str_ptr(str));
@@ -311,6 +304,7 @@ mrb_str_literal(mrb_state *mrb, mrb_value str)
shared->refcnt++;
s->ptr = shared->ptr;
s->len = shared->len;
+ s->aux.capa = 0;
s->aux.shared = shared;
s->flags |= MRB_STR_SHARED;
@@ -446,7 +440,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self)
if (times < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
}
- if (times && INT_MAX/times < RSTRING_LEN(self)) {
+ if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
}
@@ -532,10 +526,10 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
mrb_get_args(mrb, "o", &str2);
if (!mrb_string_p(str2)) {
- if (!mrb_respond_to(mrb, str2, mrb_intern(mrb, "to_s"))) {
+ if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "to_s", 4))) {
return mrb_nil_value();
}
- else if (!mrb_respond_to(mrb, str2, mrb_intern(mrb, "<=>"))) {
+ else if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "<=>", 3))) {
return mrb_nil_value();
}
else {
@@ -557,8 +551,9 @@ mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
static int
str_eql(mrb_state *mrb, const mrb_value str1, const mrb_value str2)
{
- const long len = RSTRING_LEN(str1);
+ const size_t len = RSTRING_LEN(str1);
+ /* assert(SIZE_MAX >= MRB_INT_MAX) */
if (len != RSTRING_LEN(str2)) return FALSE;
if (memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len) == 0)
return TRUE;
@@ -571,7 +566,7 @@ mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2)
if (mrb_obj_equal(mrb, str1, str2)) return TRUE;
if (!mrb_string_p(str2)) {
if (mrb_nil_p(str2)) return FALSE;
- if (!mrb_respond_to(mrb, str2, mrb_intern(mrb, "to_str"))) {
+ if (!mrb_respond_to(mrb, str2, mrb_intern2(mrb, "to_str", 6))) {
return FALSE;
}
str2 = mrb_funcall(mrb, str2, "to_str", 0);
@@ -595,11 +590,12 @@ static mrb_value
mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
{
mrb_value str2;
+ mrb_bool equal_p;
mrb_get_args(mrb, "o", &str2);
- if (mrb_str_equal(mrb, str1, str2))
- return mrb_true_value();
- return mrb_false_value();
+ equal_p = mrb_str_equal(mrb, str1, str2);
+
+ return mrb_bool_value(equal_p);
}
/* ---------------------------------- */
mrb_value
@@ -657,8 +653,8 @@ mrb_str_match(mrb_state *mrb, mrb_value self/* x */)
return mrb_nil_value();
}
-static inline long
-mrb_memsearch_qs(const unsigned char *xs, long m, const unsigned char *ys, long n)
+static inline mrb_int
+mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n)
{
const unsigned char *x = xs, *xe = xs + m;
const unsigned char *y = ys;
@@ -677,8 +673,8 @@ mrb_memsearch_qs(const unsigned char *xs, long m, const unsigned char *ys, long
return -1;
}
-static int
-mrb_memsearch(const void *x0, int m, const void *y0, int n)
+static mrb_int
+mrb_memsearch(const void *x0, mrb_int m, const void *y0, mrb_int n)
{
const unsigned char *x = (const unsigned char *)x0, *y = (const unsigned char *)y0;
@@ -705,7 +701,8 @@ mrb_str_index(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int offset)
{
mrb_int pos;
char *s, *sptr;
- int len, slen;
+ mrb_int len, slen;
+
len = RSTRING_LEN(str);
slen = RSTRING_LEN(sub);
if (offset < 0) {
@@ -739,9 +736,9 @@ mrb_str_dup(mrb_state *mrb, mrb_value str)
static mrb_value
mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
{
- long idx;
+ mrb_int idx;
- if (!strcmp(_obj_classname(mrb, indx), REGEXP_CLASS)) {
+ if (!strcmp(mrb_obj_classname(mrb, indx), REGEXP_CLASS)) {
mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp Class not implemented");
}
switch (mrb_type(indx)) {
@@ -920,7 +917,8 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
mrb_value rs;
mrb_int newline;
char *p, *pp;
- long len, rslen;
+ mrb_int rslen;
+ mrb_int len;
struct RString *s = mrb_str_ptr(str);
str_modify(mrb, s);
@@ -1131,9 +1129,7 @@ mrb_str_empty_p(mrb_state *mrb, mrb_value self)
{
struct RString *s = mrb_str_ptr(self);
- if (s->len == 0)
- return mrb_true_value();
- return mrb_false_value();
+ return mrb_bool_value(s->len == 0);
}
/* 15.2.10.5.17 */
@@ -1147,17 +1143,16 @@ static mrb_value
mrb_str_eql(mrb_state *mrb, mrb_value self)
{
mrb_value str2;
+ mrb_bool eql_p;
mrb_get_args(mrb, "o", &str2);
- if (mrb_type(str2) != MRB_TT_STRING)
- return mrb_false_value();
- if (str_eql(mrb, self, str2))
- return mrb_true_value();
- return mrb_false_value();
+ eql_p = (mrb_type(str2) == MRB_TT_STRING) && str_eql(mrb, self, str2);
+
+ return mrb_bool_value(eql_p);
}
static mrb_value
-mrb_str_subseq(mrb_state *mrb, mrb_value str, int beg, int len)
+mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
{
struct RString *orig, *s;
mrb_shared_string *shared;
@@ -1176,7 +1171,7 @@ mrb_str_subseq(mrb_state *mrb, mrb_value str, int beg, int len)
}
mrb_value
-mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, int len)
+mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len)
{
mrb_value str2;
@@ -1267,7 +1262,7 @@ mrb_str_hash(mrb_state *mrb, mrb_value str)
{
/* 1-8-7 */
struct RString *s = mrb_str_ptr(str);
- long len = s->len;
+ mrb_int len = s->len;
char *p = s->ptr;
mrb_int key = 0;
@@ -1311,18 +1306,20 @@ mrb_str_include(mrb_state *mrb, mrb_value self)
{
mrb_int i;
mrb_value str2;
+ mrb_bool include_p;
mrb_get_args(mrb, "o", &str2);
if (mrb_type(str2) == MRB_TT_FIXNUM) {
- if (memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self)))
- return mrb_true_value();
- return mrb_false_value();
+ include_p = memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self));
+ }
+ else {
+ mrb_string_value(mrb, &str2);
+ i = mrb_str_index(mrb, self, str2, 0);
+
+ include_p = (i != -1);
}
- mrb_string_value(mrb, &str2);
- i = mrb_str_index(mrb, self, str2, 0);
- if (i == -1) return mrb_false_value();
- return mrb_true_value();
+ return mrb_bool_value(include_p);
}
/* 15.2.10.5.22 */
@@ -1381,7 +1378,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
switch (mrb_type(sub)) {
case MRB_TT_FIXNUM: {
int c = mrb_fixnum(sub);
- long len = RSTRING_LEN(str);
+ mrb_int len = RSTRING_LEN(str);
unsigned char *p = (unsigned char*)RSTRING_PTR(str);
for (;pos<len;pos++) {
@@ -1396,7 +1393,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
tmp = mrb_check_string_type(mrb, sub);
if (mrb_nil_p(tmp)) {
mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %s given",
- _obj_classname(mrb, sub));
+ mrb_obj_classname(mrb, sub));
}
sub = tmp;
}
@@ -1404,10 +1401,10 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str)
case MRB_TT_STRING:
pos = mrb_str_index(mrb, str, sub, pos);
break;
- }
+ }
- if (pos == -1) return mrb_nil_value();
- return mrb_fixnum_value(pos);
+ if (pos == -1) return mrb_nil_value();
+ return mrb_fixnum_value(pos);
}
#define STR_REPLACE_SHARED_MIN 10
@@ -1532,6 +1529,36 @@ mrb_obj_as_string(mrb_state *mrb, mrb_value obj)
}
mrb_value
+mrb_ptr_to_str(mrb_state *mrb, void *p)
+{
+ struct RString *p_str;
+ char *p1;
+ char *p2;
+ intptr_t n = (intptr_t)p;
+
+ p_str = str_new(mrb, NULL, 2 + sizeof(uintptr_t) * CHAR_BIT / 4);
+ p1 = p_str->ptr;
+ *p1++ = '0';
+ *p1++ = 'x';
+ p2 = p1;
+
+ do {
+ *p2++ = mrb_digitmap[n % 16];
+ n /= 16;
+ } while (n > 0);
+ *p2 = '\0';
+ p_str->len = (mrb_int)(p2 - p_str->ptr);
+
+ while (p1 < p2) {
+ const char c = *p1;
+ *p1++ = *--p2;
+ *p2 = c;
+ }
+
+ return mrb_obj_value(p_str);
+}
+
+mrb_value
mrb_check_string_type(mrb_state *mrb, mrb_value str)
{
return mrb_check_convert_type(mrb, str, MRB_TT_STRING, "String", "to_str");
@@ -1637,7 +1664,7 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
char *s, *sbeg, *t;
struct RString *ps = mrb_str_ptr(str);
struct RString *psub = mrb_str_ptr(sub);
- long len = psub->len;
+ mrb_int len = psub->len;
/* substring longer than string */
if (ps->len < len) return -1;
@@ -1661,15 +1688,6 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str, mrb_value sub, mrb_int pos)
}
}
-#ifdef INCLUDE_ENCODING
-/* byte offset to char offset */
-int
-mrb_str_sublen(mrb_state *mrb, mrb_value str, long pos)
-{
- return pos;
-}
-#endif //INCLUDE_ENCODING
-
/* 15.2.10.5.31 */
/*
* call-seq:
@@ -1728,7 +1746,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
switch (mrb_type(sub)) {
case MRB_TT_FIXNUM: {
int c = mrb_fixnum(sub);
- long len = RSTRING_LEN(str);
+ mrb_int len = RSTRING_LEN(str);
unsigned char *p = (unsigned char*)RSTRING_PTR(str);
for (pos=len;pos>=0;pos--) {
@@ -1865,7 +1883,9 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
int argc;
mrb_value spat = mrb_nil_value();
enum {awk, string, regexp} split_type = string;
- long beg, end, i = 0, lim_p;
+ long i = 0, lim_p;
+ mrb_int beg;
+ mrb_int end;
mrb_int lim = 0;
mrb_value result, tmp;
@@ -1934,7 +1954,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
char *ptr = RSTRING_PTR(str);
char *temp = ptr;
char *eptr = RSTRING_END(str);
- long slen = RSTRING_LEN(spat);
+ mrb_int slen = RSTRING_LEN(spat);
if (slen == 0) {
int ai = mrb_gc_arena_save(mrb);
@@ -1972,7 +1992,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str)
mrb_ary_push(mrb, result, tmp);
}
if (!lim_p && lim == 0) {
- long len;
+ mrb_int len;
while ((len = RARRAY_LEN(result)) > 0 &&
(tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0))
mrb_ary_pop(mrb, result);
@@ -2054,7 +2074,8 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
char *end;
char sign = 1;
int c;
- unsigned long val;
+ unsigned long n;
+ mrb_int val;
#undef ISDIGIT
#define ISDIGIT(c) ('0' <= (c) && (c) <= '9')
@@ -2158,19 +2179,18 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
return mrb_fixnum_value(0);
}
- val = strtoul((char*)str, &end, base);
-
+ n = strtoul((char*)str, &end, base);
+ if (n > MRB_INT_MAX) {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%s) too big for integer", str);
+ }
+ val = n;
if (badcheck) {
if (end == str) goto bad; /* no number */
while (*end && ISSPACE(*end)) end++;
if (*end) goto bad; /* trailing garbage */
}
- if (sign) return mrb_fixnum_value(val);
- else {
- long result = -(long)val;
- return mrb_fixnum_value(result);
- }
+ return mrb_fixnum_value(sign ? val : -val);
bad:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%s)", str);
/* not reached */
@@ -2440,7 +2460,7 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
mrb_value
mrb_str_dump(mrb_state *mrb, mrb_value str)
{
- long len;
+ mrb_int len;
const char *p, *pend;
char *q;
struct RString *result;
@@ -2542,7 +2562,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str)
}
mrb_value
-mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len)
+mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, mrb_int len)
{
if (len < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)");
@@ -2552,7 +2572,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, long len)
}
mrb_value
-mrb_str_cat2(mrb_state *mrb, mrb_value str, const char *ptr)
+mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr)
{
return mrb_str_cat(mrb, str, ptr, strlen(ptr));
}
diff --git a/src/symbol.c b/src/symbol.c
index 72a5bea6b..243cb4b5d 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -10,10 +10,11 @@
#include "mruby/string.h"
#include <ctype.h>
+#include <limits.h>
/* ------------------------------------------------------ */
typedef struct symbol_name {
- int len;
+ size_t len;
const char *name;
} symbol_name;
@@ -35,7 +36,7 @@ KHASH_DECLARE(n2s, symbol_name, mrb_sym, 1)
KHASH_DEFINE (n2s, symbol_name, mrb_sym, 1, sym_hash_func, sym_hash_equal)
/* ------------------------------------------------------ */
mrb_sym
-mrb_intern2(mrb_state *mrb, const char *name, int len)
+mrb_intern2(mrb_state *mrb, const char *name, size_t len)
{
khash_t(n2s) *h = mrb->name2sym;
symbol_name sname;
@@ -61,7 +62,7 @@ mrb_intern2(mrb_state *mrb, const char *name, int len)
}
mrb_sym
-mrb_intern(mrb_state *mrb, const char *name)
+mrb_intern_cstr(mrb_state *mrb, const char *name)
{
return mrb_intern2(mrb, name, strlen(name));
}
@@ -72,8 +73,9 @@ mrb_intern_str(mrb_state *mrb, mrb_value str)
return mrb_intern2(mrb, RSTRING_PTR(str), RSTRING_LEN(str));
}
+/* lenp must be a pointer to a size_t variable */
const char*
-mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, int *lenp)
+mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, size_t *lenp)
{
khash_t(n2s) *h = mrb->name2sym;
khiter_t k;
@@ -156,10 +158,12 @@ static mrb_value
sym_equal(mrb_state *mrb, mrb_value sym1)
{
mrb_value sym2;
+ mrb_bool equal_p;
mrb_get_args(mrb, "o", &sym2);
- if (mrb_obj_equal(mrb, sym1, sym2)) return mrb_true_value();
- return mrb_false_value();
+ equal_p = mrb_obj_equal(mrb, sym1, sym2);
+
+ return mrb_bool_value(equal_p);
}
/* 15.2.11.3.2 */
@@ -178,7 +182,7 @@ mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
{
mrb_sym id = mrb_symbol(sym);
const char *p;
- int len;
+ size_t len;
p = mrb_sym2name_len(mrb, id, &len);
return mrb_str_new(mrb, p, len);
@@ -198,7 +202,7 @@ mrb_sym_to_s(mrb_state *mrb, mrb_value sym)
static mrb_value
sym_to_sym(mrb_state *mrb, mrb_value sym)
{
- return sym;
+ return sym;
}
/* 15.2.11.3.5(x) */
@@ -222,106 +226,107 @@ sym_to_sym(mrb_state *mrb, mrb_value sym)
static int
is_special_global_name(const char* m)
{
- switch (*m) {
- case '~': case '*': case '$': case '?': case '!': case '@':
- case '/': case '\\': case ';': case ',': case '.': case '=':
- case ':': case '<': case '>': case '\"':
- case '&': case '`': case '\'': case '+':
- case '0':
- ++m;
- break;
- case '-':
- ++m;
- if (is_identchar(*m)) m += 1;
- break;
- default:
- if (!ISDIGIT(*m)) return FALSE;
- do ++m; while (ISDIGIT(*m));
- }
- return !*m;
+ switch (*m) {
+ case '~': case '*': case '$': case '?': case '!': case '@':
+ case '/': case '\\': case ';': case ',': case '.': case '=':
+ case ':': case '<': case '>': case '\"':
+ case '&': case '`': case '\'': case '+':
+ case '0':
+ ++m;
+ break;
+ case '-':
+ ++m;
+ if (is_identchar(*m)) m += 1;
+ break;
+ default:
+ if (!ISDIGIT(*m)) return FALSE;
+ do ++m; while (ISDIGIT(*m));
+ break;
+ }
+ return !*m;
}
static int
symname_p(const char *name)
{
- const char *m = name;
- int localid = FALSE;
-
- if (!m) return FALSE;
- switch (*m) {
- case '\0':
- return FALSE;
-
- case '$':
- if (is_special_global_name(++m)) return TRUE;
- goto id;
-
- case '@':
- if (*++m == '@') ++m;
- goto id;
-
- case '<':
- switch (*++m) {
- case '<': ++m; break;
- case '=': if (*++m == '>') ++m; break;
- default: break;
- }
- break;
+ const char *m = name;
+ int localid = FALSE;
+
+ if (!m) return FALSE;
+ switch (*m) {
+ case '\0':
+ return FALSE;
+
+ case '$':
+ if (is_special_global_name(++m)) return TRUE;
+ goto id;
+
+ case '@':
+ if (*++m == '@') ++m;
+ goto id;
+
+ case '<':
+ switch (*++m) {
+ case '<': ++m; break;
+ case '=': if (*++m == '>') ++m; break;
+ default: break;
+ }
+ break;
- case '>':
- switch (*++m) {
- case '>': case '=': ++m; break;
- default: break;
- }
- break;
+ case '>':
+ switch (*++m) {
+ case '>': case '=': ++m; break;
+ default: break;
+ }
+ break;
- case '=':
- switch (*++m) {
- case '~': ++m; break;
- case '=': if (*++m == '=') ++m; break;
- default: return FALSE;
- }
- break;
-
- case '*':
- if (*++m == '*') ++m;
- break;
- case '!':
- if (*++m == '=') ++m;
- break;
- case '+': case '-':
- if (*++m == '@') ++m;
- break;
- case '|':
- if (*++m == '|') ++m;
- break;
- case '&':
- if (*++m == '&') ++m;
- break;
-
- case '^': case '/': case '%': case '~': case '`':
- ++m;
- break;
-
- case '[':
- if (*++m != ']') return FALSE;
- if (*++m == '=') ++m;
- break;
-
- default:
- localid = !ISUPPER(*m);
+ case '=':
+ switch (*++m) {
+ case '~': ++m; break;
+ case '=': if (*++m == '=') ++m; break;
+ default: return FALSE;
+ }
+ break;
+
+ case '*':
+ if (*++m == '*') ++m;
+ break;
+ case '!':
+ if (*++m == '=') ++m;
+ break;
+ case '+': case '-':
+ if (*++m == '@') ++m;
+ break;
+ case '|':
+ if (*++m == '|') ++m;
+ break;
+ case '&':
+ if (*++m == '&') ++m;
+ break;
+
+ case '^': case '/': case '%': case '~': case '`':
+ ++m;
+ break;
+
+ case '[':
+ if (*++m != ']') return FALSE;
+ if (*++m == '=') ++m;
+ break;
+
+ default:
+ localid = !ISUPPER(*m);
id:
- if (*m != '_' && !ISALPHA(*m)) return FALSE;
- while (is_identchar(*m)) m += 1;
- if (localid) {
- switch (*m) {
- case '!': case '?': case '=': ++m;
- default: break;
+ if (*m != '_' && !ISALPHA(*m)) return FALSE;
+ while (is_identchar(*m)) m += 1;
+ if (localid) {
+ switch (*m) {
+ case '!': case '?': case '=': ++m;
+ default: break;
}
}
- break;
- }
- return *m ? FALSE : TRUE;
+ break;
+ }
+ return *m ? FALSE : TRUE;
}
static mrb_value
@@ -329,7 +334,7 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
{
mrb_value str;
const char *name;
- int len;
+ size_t len;
mrb_sym id = mrb_symbol(sym);
name = mrb_sym2name_len(mrb, id, &len);
@@ -346,7 +351,7 @@ sym_inspect(mrb_state *mrb, mrb_value sym)
const char*
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
{
- int len;
+ size_t len;
const char *name = mrb_sym2name_len(mrb, sym, &len);
if (!name) return NULL;
@@ -374,7 +379,8 @@ sym_cmp(mrb_state *mrb, mrb_value s1)
if (sym1 == sym2) return mrb_fixnum_value(0);
else {
const char *p1, *p2;
- int len, len1, len2, retval;
+ int retval;
+ size_t len, len1, len2;
p1 = mrb_sym2name_len(mrb, sym1, &len1);
p2 = mrb_sym2name_len(mrb, sym2, &len2);
diff --git a/src/value_array.h b/src/value_array.h
new file mode 100644
index 000000000..cabd2426d
--- /dev/null
+++ b/src/value_array.h
@@ -0,0 +1,27 @@
+#ifndef MRB_VALUE_ARRAY_H__
+#define MRB_VALUE_ARRAY_H__
+
+#include "mruby.h"
+
+static inline void
+value_move(mrb_value *s1, const mrb_value *s2, size_t n)
+{
+ if (s1 > s2 && s1 < s2 + n)
+ {
+ s1 += n;
+ s2 += n;
+ while (n-- > 0) {
+ *--s1 = *--s2;
+ }
+ }
+ else if (s1 != s2) {
+ while (n-- > 0) {
+ *s1++ = *s2++;
+ }
+ }
+ else {
+ /* nothing to do. */
+ }
+}
+
+#endif /* MRB_VALUE_ARRAY_H__ */
diff --git a/src/variable.c b/src/variable.c
index 8715505c3..c191b2be2 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -28,8 +28,8 @@ typedef struct segment {
typedef struct iv_tbl {
segment *rootseg;
- int size;
- int last_len;
+ size_t size;
+ size_t last_len;
} iv_tbl;
static iv_tbl*
@@ -52,8 +52,8 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
segment *seg = t->rootseg;
segment *prev = NULL;
segment *matched_seg = NULL;
- int matched_idx = 0;
- int i;
+ size_t matched_idx = 0;
+ size_t i;
while (seg) {
for (i=0; i<MRB_SEGMENT_SIZE; i++) {
@@ -102,11 +102,11 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
return;
}
-static int
+static mrb_bool
iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
segment *seg;
- int i;
+ size_t i;
seg = t->rootseg;
while (seg) {
@@ -126,11 +126,11 @@ iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
-static int
+static mrb_bool
iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
segment *seg;
- int i;
+ size_t i;
seg = t->rootseg;
while (seg) {
@@ -152,11 +152,12 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
-static int
+static mrb_bool
iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
{
segment *seg;
- int i, n;
+ size_t i;
+ int n;
seg = t->rootseg;
while (seg) {
@@ -181,11 +182,11 @@ iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
return TRUE;
}
-static int
+static size_t
iv_size(mrb_state *mrb, iv_tbl *t)
{
segment *seg;
- int size = 0;
+ size_t size = 0;
if (!t) return 0;
if (t->size > 0) return t->size;
@@ -208,7 +209,7 @@ iv_copy(mrb_state *mrb, iv_tbl *t)
segment *seg;
iv_tbl *t2;
- int i;
+ size_t i;
seg = t->rootseg;
t2 = iv_new(mrb);
@@ -273,7 +274,7 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val)
kh_value(h, k) = val;
}
-static int
+static mrb_bool
iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
khash_t(iv) *h = &t->h;
@@ -287,7 +288,7 @@ iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
-static int
+static mrb_bool
iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
{
khash_t(iv) *h = &t->h;
@@ -305,7 +306,7 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp)
return FALSE;
}
-static int
+static mrb_bool
iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
{
khash_t(iv) *h = &t->h;
@@ -326,7 +327,7 @@ iv_foreach(mrb_state *mrb, iv_tbl *t, iv_foreach_func *func, void *p)
return TRUE;
}
-static int
+static size_t
iv_size(mrb_state *mrb, iv_tbl *t)
{
khash_t(iv) *h = &t->h;
@@ -408,7 +409,7 @@ mrb_vm_special_set(mrb_state *mrb, mrb_sym i, mrb_value v)
{
}
-static int
+static mrb_bool
obj_iv_p(mrb_value obj)
{
switch (mrb_type(obj)) {
@@ -481,7 +482,7 @@ mrb_iv_set(mrb_state *mrb, mrb_value obj, mrb_sym sym, mrb_value v)
}
}
-int
+mrb_bool
mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
{
iv_tbl *t;
@@ -493,7 +494,7 @@ mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
return FALSE;
}
-int
+mrb_bool
mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym)
{
if (!obj_iv_p(obj)) return FALSE;
@@ -520,15 +521,15 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value str = *(mrb_value*)p;
const char *s;
- int len;
+ size_t len;
/* need not to show internal data */
if (RSTRING_PTR(str)[0] == '-') { /* first element */
RSTRING_PTR(str)[0] = '#';
- mrb_str_cat2(mrb, str, " ");
+ mrb_str_cat(mrb, str, " ", 1);
}
else {
- mrb_str_cat2(mrb, str, ", ");
+ mrb_str_cat(mrb, str, ", ", 2);
}
s = mrb_sym2name_len(mrb, sym, &len);
mrb_str_cat(mrb, str, s, len);
@@ -541,13 +542,19 @@ mrb_value
mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
{
iv_tbl *t = obj->iv;
- int len = iv_size(mrb, t);
+ size_t len = iv_size(mrb, t);
if (len > 0) {
const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj));
- mrb_value str = mrb_sprintf(mrb, "-<%s:%p", cn, (void*)obj);
+ mrb_value str = mrb_str_buf_new(mrb, 30);
+
+ mrb_str_buf_cat(mrb, str, "-<", 2);
+ mrb_str_cat2(mrb, str, cn);
+ mrb_str_cat(mrb, str, ":", 1);
+ mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj));
iv_foreach(mrb, t, inspect_i, &str);
+ mrb_str_cat(mrb, str, ">", 1);
return str;
}
return mrb_any_to_s(mrb, mrb_obj_value(obj));
@@ -586,7 +593,7 @@ iv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value ary;
const char* s;
- int len;
+ size_t len;
ary = *(mrb_value*)p;
s = mrb_sym2name_len(mrb, sym, &len);
@@ -630,7 +637,7 @@ cv_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p)
{
mrb_value ary;
const char* s;
- int len;
+ size_t len;
ary = *(mrb_value*)p;
s = mrb_sym2name_len(mrb, sym, &len);
@@ -727,7 +734,7 @@ mrb_cv_set(mrb_state *mrb, mrb_value mod, mrb_sym sym, mrb_value v)
mrb_mod_cv_set(mrb, mrb_class_ptr(mod), sym, v);
}
-int
+mrb_bool
mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
{
while (c) {
@@ -741,7 +748,7 @@ mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
return FALSE;
}
-int
+mrb_bool
mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
{
return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym);
@@ -783,7 +790,7 @@ mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
iv_put(mrb, c->iv, sym, v);
}
-int
+mrb_bool
mrb_const_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym)
{
struct RClass *m = mrb_class_ptr(mod);
@@ -813,7 +820,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
struct RClass *c = base;
mrb_value v;
iv_tbl *t;
- int retry = 0;
+ mrb_bool retry = 0;
mrb_sym cm;
L_RETRY:
@@ -831,7 +838,7 @@ L_RETRY:
goto L_RETRY;
}
c = base;
- cm = mrb_intern(mrb, "const_missing");
+ cm = mrb_intern2(mrb, "const_missing", 13);
while (c) {
if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
mrb_value name = mrb_symbol_value(sym);
@@ -964,7 +971,7 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self)
{
iv_tbl *t = mrb->globals;
mrb_value ary = mrb_ary_new(mrb);
- int i;
+ size_t i;
char buf[3];
if (t) {
@@ -979,11 +986,11 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self)
return ary;
}
-static int
-mrb_const_defined_0(mrb_state *mrb, struct RClass *klass, mrb_sym id, int exclude, int recurse)
+static mrb_bool
+mrb_const_defined_0(mrb_state *mrb, struct RClass *klass, mrb_sym id, mrb_bool exclude, mrb_bool recurse)
{
struct RClass * tmp;
- int mod_retry = 0;
+ mrb_bool mod_retry = 0;
tmp = klass;
retry:
@@ -1046,7 +1053,7 @@ mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer)
{
mrb_value name;
- name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern(mrb, "__classid__"));
+ name = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern2(mrb, "__classid__", 11));
if (mrb_nil_p(name)) {
if (!outer) return 0;
diff --git a/src/vm.c b/src/vm.c
index dd8edf4bc..aa7be1968 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -16,6 +16,7 @@
#include "mruby/class.h"
#include "mruby/numeric.h"
#include "error.h"
+#include "value_array.h"
#include <string.h>
#include <setjmp.h>
@@ -45,7 +46,7 @@
/* Maximum stack depth. Should be set lower on memory constrained systems.
The value below allows about 60000 recursive calls in the simplest case. */
#ifndef MRB_STACK_MAX
-#define MRB_STACK_MAX ((1<<18) - MRB_STACK_GROWTH)
+#define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH)
#endif
#ifdef VM_DEBUG
@@ -55,12 +56,20 @@ The value below allows about 60000 recursive calls in the simplest case. */
#endif
static inline void
-stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
+stack_clear(mrb_value *from, size_t count)
{
- size_t i;
+ const mrb_value mrb_value_zero = { { 0 } };
+
+ while(count-- > 0) {
+ *from++ = mrb_value_zero;
+ }
+}
- for (i = 0; i < size; i++) {
- dst[i] = src[i];
+static inline void
+stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
+{
+ while (size-- > 0) {
+ *dst++ = *src++;
}
}
@@ -79,7 +88,7 @@ stack_init(mrb_state *mrb)
mrb->ci->target_class = mrb->object_class;
}
-static void
+static inline void
envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
{
mrb_callinfo *ci = mrb->cibase;
@@ -87,7 +96,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
while (ci <= mrb->ci) {
struct REnv *e = ci->env;
if (e && e->cioff >= 0) {
- int off = e->stack - oldbase;
+ ptrdiff_t off = e->stack - oldbase;
e->stack = newbase + off;
}
@@ -100,8 +109,9 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
static void
stack_extend(mrb_state *mrb, int room, int keep)
{
- int size, off;
if (mrb->stack + room >= mrb->stend) {
+ int size, off;
+
mrb_value *oldbase = mrb->stbase;
size = mrb->stend - mrb->stbase;
@@ -130,26 +140,18 @@ stack_extend(mrb_state *mrb, int room, int keep)
}
if (room > keep) {
- int i;
- for (i=keep; i<room; i++) {
#ifndef MRB_NAN_BOXING
- static const mrb_value mrb_value_zero = { { 0 } };
- mrb->stack[i] = mrb_value_zero;
+ stack_clear(&(mrb->stack[keep]), room - keep);
#else
+ int i;
+ for (i=keep; i<room; i++) {
SET_NIL_VALUE(mrb->stack[i]);
-#endif
}
+#endif
}
}
-int
-mrb_checkstack(mrb_state *mrb, int size)
-{
- stack_extend(mrb, size+1, 1);
- return 0;
-}
-
-struct REnv*
+static inline struct REnv*
uvenv(mrb_state *mrb, int up)
{
struct REnv *e = mrb->ci->proc->env;
@@ -161,25 +163,6 @@ uvenv(mrb_state *mrb, int up)
return e;
}
-static mrb_value
-uvget(mrb_state *mrb, int up, int idx)
-{
- struct REnv *e = uvenv(mrb, up);
-
- if (!e) return mrb_nil_value();
- return e->stack[idx];
-}
-
-static void
-uvset(mrb_state *mrb, int up, int idx, mrb_value v)
-{
- struct REnv *e = uvenv(mrb, up);
-
- if (!e) return;
- e->stack[idx] = v;
- mrb_write_barrier(mrb, (struct RBasic*)e);
-}
-
static inline int
is_strict(mrb_state *mrb, struct REnv *e)
{
@@ -192,7 +175,7 @@ is_strict(mrb_state *mrb, struct REnv *e)
return 0;
}
-struct REnv*
+inline struct REnv*
top_env(mrb_state *mrb, struct RProc *proc)
{
struct REnv *e = proc->env;
@@ -231,7 +214,7 @@ cipop(mrb_state *mrb)
{
if (mrb->ci->env) {
struct REnv *e = mrb->ci->env;
- int len = (int)e->flags;
+ size_t len = (size_t)e->flags;
mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
e->cioff = -1;
@@ -273,14 +256,13 @@ mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
mrb_sym mid = mrb_intern(mrb, name);
- va_list ap;
- int i;
if (argc == 0) {
return mrb_funcall_argv(mrb, self, mid, 0, 0);
}
else if (argc == 1) {
mrb_value v;
+ va_list ap;
va_start(ap, argc);
v = va_arg(ap, mrb_value);
@@ -289,6 +271,8 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
}
else {
mrb_value argv[MRB_FUNCALL_ARGC_MAX];
+ va_list ap;
+ int i;
if (argc > MRB_FUNCALL_ARGC_MAX) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX);
@@ -306,11 +290,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
mrb_value
mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk)
{
- struct RProc *p;
- struct RClass *c;
- mrb_sym undef = 0;
- mrb_callinfo *ci;
- int n;
mrb_value val;
if (!mrb->jmp) {
@@ -323,66 +302,74 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr
cipop(mrb);
}
mrb->jmp = 0;
- return mrb_nil_value();
+ val = mrb_nil_value();
+ }
+ else {
+ mrb->jmp = &c_jmp;
+ /* recursive call */
+ val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
+ mrb->jmp = 0;
}
- mrb->jmp = &c_jmp;
- /* recursive call */
- val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
- mrb->jmp = 0;
- return val;
- }
-
- if (!mrb->stack) {
- stack_init(mrb);
- }
- n = mrb->ci->nregs;
- if (argc < 0) {
- mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
- }
- c = mrb_class(mrb, self);
- p = mrb_method_search_vm(mrb, &c, mid);
- if (!p) {
- undef = mid;
- mid = mrb_intern(mrb, "method_missing");
- p = mrb_method_search_vm(mrb, &c, mid);
- n++; argc++;
- }
- ci = cipush(mrb);
- ci->mid = mid;
- ci->proc = p;
- ci->stackidx = mrb->stack - mrb->stbase;
- ci->argc = argc;
- ci->target_class = p->target_class;
- if (MRB_PROC_CFUNC_P(p)) {
- ci->nregs = argc + 2;
}
else {
- ci->nregs = p->body.irep->nregs + 2;
- }
- ci->acc = -1;
- mrb->stack = mrb->stack + n;
+ struct RProc *p;
+ struct RClass *c;
+ mrb_sym undef = 0;
+ mrb_callinfo *ci;
+ int n;
- stack_extend(mrb, ci->nregs, 0);
- mrb->stack[0] = self;
- if (undef) {
- mrb->stack[1] = mrb_symbol_value(undef);
- stack_copy(mrb->stack+2, argv, argc-1);
- }
- else if (argc > 0) {
- stack_copy(mrb->stack+1, argv, argc);
- }
- mrb->stack[argc+1] = blk;
-
- if (MRB_PROC_CFUNC_P(p)) {
- int ai = mrb_gc_arena_save(mrb);
- val = p->body.func(mrb, self);
- mrb_gc_arena_restore(mrb, ai);
- mrb_gc_protect(mrb, val);
- mrb->stack = mrb->stbase + mrb->ci->stackidx;
- cipop(mrb);
- }
- else {
- val = mrb_run(mrb, p, self);
+ if (!mrb->stack) {
+ stack_init(mrb);
+ }
+ n = mrb->ci->nregs;
+ if (argc < 0) {
+ mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
+ }
+ c = mrb_class(mrb, self);
+ p = mrb_method_search_vm(mrb, &c, mid);
+ if (!p) {
+ undef = mid;
+ mid = mrb_intern2(mrb, "method_missing", 14);
+ p = mrb_method_search_vm(mrb, &c, mid);
+ n++; argc++;
+ }
+ ci = cipush(mrb);
+ ci->mid = mid;
+ ci->proc = p;
+ ci->stackidx = mrb->stack - mrb->stbase;
+ ci->argc = argc;
+ ci->target_class = p->target_class;
+ if (MRB_PROC_CFUNC_P(p)) {
+ ci->nregs = argc + 2;
+ }
+ else {
+ ci->nregs = p->body.irep->nregs + 2;
+ }
+ ci->acc = -1;
+ mrb->stack = mrb->stack + n;
+
+ stack_extend(mrb, ci->nregs, 0);
+ mrb->stack[0] = self;
+ if (undef) {
+ mrb->stack[1] = mrb_symbol_value(undef);
+ stack_copy(mrb->stack+2, argv, argc-1);
+ }
+ else if (argc > 0) {
+ stack_copy(mrb->stack+1, argv, argc);
+ }
+ mrb->stack[argc+1] = blk;
+
+ if (MRB_PROC_CFUNC_P(p)) {
+ int ai = mrb_gc_arena_save(mrb);
+ val = p->body.func(mrb, self);
+ mrb_gc_arena_restore(mrb, ai);
+ mrb_gc_protect(mrb, val);
+ mrb->stack = mrb->stbase + mrb->ci->stackidx;
+ cipop(mrb);
+ }
+ else {
+ val = mrb_run(mrb, p, self);
+ }
}
return val;
}
@@ -471,14 +458,14 @@ localjump_error(mrb_state *mrb, localjump_error_kind kind)
mrb_str_buf_cat(mrb, msg, lead, sizeof(lead) - 1);
mrb_str_buf_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
exc = mrb_exc_new3(mrb, E_LOCALJUMP_ERROR, msg);
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
}
static void
argnum_error(mrb_state *mrb, int num)
{
char buf[256];
- int len;
+ size_t len;
mrb_value exc;
if (mrb->ci->mid) {
@@ -491,7 +478,7 @@ argnum_error(mrb_state *mrb, int num)
mrb->ci->argc, num);
}
exc = mrb_exc_new(mrb, E_ARGUMENT_ERROR, buf, len);
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
}
#ifdef ENABLE_DEBUG
@@ -709,14 +696,34 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_GETUPVAR) {
/* A B C R(A) := uvget(B,C) */
+ mrb_value *regs_a = regs + GETARG_A(i);
+ int up = GETARG_C(i);
+
+ struct REnv *e = uvenv(mrb, up);
- regs[GETARG_A(i)] = uvget(mrb, GETARG_C(i), GETARG_B(i));
+ if (!e) {
+ *regs_a = mrb_nil_value();
+ }
+ else {
+ int idx = GETARG_B(i);
+ *regs_a = e->stack[idx];
+ }
NEXT;
}
CASE(OP_SETUPVAR) {
/* A B C uvset(B,C,R(A)) */
- uvset(mrb, GETARG_C(i), GETARG_B(i), regs[GETARG_A(i)]);
+ /* A B C R(A) := uvget(B,C) */
+ int up = GETARG_C(i);
+
+ struct REnv *e = uvenv(mrb, up);
+
+ if (e) {
+ mrb_value *regs_a = regs + GETARG_A(i);
+ int idx = GETARG_B(i);
+ e->stack[idx] = *regs_a;
+ mrb_write_barrier(mrb, (struct RBasic*)e);
+ }
NEXT;
}
@@ -773,7 +780,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_RAISE) {
/* A raise(R(A)) */
- mrb->exc = (struct RObject*)mrb_object(regs[GETARG_A(i)]);
+ mrb->exc = mrb_obj_ptr(regs[GETARG_A(i)]);
goto L_RAISE;
}
@@ -842,15 +849,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (!m) {
mrb_value sym = mrb_symbol_value(mid);
- mid = mrb_intern(mrb, "method_missing");
+ mid = mrb_intern2(mrb, "method_missing", 14);
m = mrb_method_search_vm(mrb, &c, mid);
if (n == CALL_MAXARGS) {
mrb_ary_unshift(mrb, regs[a+1], sym);
}
else {
- memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1));
+ value_move(regs+a+2, regs+a+1, ++n);
regs[a+1] = sym;
- n++;
}
}
@@ -859,8 +865,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->mid = mid;
ci->proc = m;
ci->stackidx = mrb->stack - mrb->stbase;
- ci->argc = n;
- if (ci->argc == CALL_MAXARGS) ci->argc = -1;
+ if (n == CALL_MAXARGS) {
+ ci->argc = -1;
+ }
+ else {
+ ci->argc = n;
+ }
ci->target_class = c;
ci->pc = pc + 1;
ci->acc = a;
@@ -981,15 +991,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
c = mrb->ci->target_class->super;
m = mrb_method_search_vm(mrb, &c, mid);
if (!m) {
- mid = mrb_intern(mrb, "method_missing");
+ mid = mrb_intern2(mrb, "method_missing", 14);
m = mrb_method_search_vm(mrb, &c, mid);
if (n == CALL_MAXARGS) {
mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
}
else {
- memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1));
+ value_move(regs+a+2, regs+a+1, ++n);
SET_SYM_VALUE(regs[a+1], ci->mid);
- n++;
}
}
@@ -998,8 +1007,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci->mid = mid;
ci->proc = m;
ci->stackidx = mrb->stack - mrb->stbase;
- ci->argc = n;
- if (ci->argc == CALL_MAXARGS) ci->argc = -1;
+ if (n == CALL_MAXARGS) {
+ ci->argc = -1;
+ }
+ else {
+ ci->argc = n;
+ }
ci->target_class = m->target_class;
ci->pc = pc + 1;
@@ -1026,7 +1039,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
pool = irep->pool;
syms = irep->syms;
ci->nregs = irep->nregs;
- if (ci->argc < 0) {
+ if (n == CALL_MAXARGS) {
stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
}
else {
@@ -1055,7 +1068,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_value exc;
static const char m[] = "super called outside of method";
exc = mrb_exc_new(mrb, E_NOMETHOD_ERROR, m, sizeof(m) - 1);
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
stack = e->stack + 1;
@@ -1093,7 +1106,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_ENTER) {
/* Ax arg setup according to flags (24=5:5:1:5:5:1:1) */
/* number of optional arguments times OP_JMP should follow */
- int ax = GETARG_Ax(i);
+ int32_t ax = GETARG_Ax(i);
int m1 = (ax>>18)&0x1f;
int o = (ax>>13)&0x1f;
int r = (ax>>12)&0x1;
@@ -1131,10 +1144,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (argc < len) {
regs[len+1] = *blk; /* move block */
if (argv0 != argv) {
- memmove(&regs[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */
+ value_move(&regs[1], argv, argc-m2); /* m1 + o */
}
if (m2) {
- memmove(&regs[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */
+ value_move(&regs[len-m2+1], &argv[argc-m2], m2); /* m2 */
}
if (r) { /* r */
regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
@@ -1146,13 +1159,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
else {
if (argv0 != argv) {
regs[len+1] = *blk; /* move block */
- memmove(&regs[1], argv, sizeof(mrb_value)*(m1+o)); /* m1 + o */
+ value_move(&regs[1], argv, m1+o); /* m1 + o */
}
if (r) { /* r */
regs[m1+o+1] = mrb_ary_new_from_values(mrb, argc-m1-o-m2, argv+m1+o);
}
if (m2) {
- memmove(&regs[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2);
+ value_move(&regs[m1+o+r+1], &argv[argc-m2], m2);
}
if (argv0 == argv) {
regs[len+1] = *blk; /* move block */
@@ -1183,8 +1196,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
L_RAISE:
ci = mrb->ci;
- mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern(mrb, "lastpc"), mrb_voidp_value(pc));
- mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->cibase));
+ mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "lastpc", 6), mrb_voidp_value(pc));
+ mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern2(mrb, "ciidx", 5), mrb_fixnum_value(ci - mrb->cibase));
eidx = ci->eidx;
if (ci == mrb->cibase) {
if (ci->ridx == 0) goto L_STOP;
@@ -1300,15 +1313,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (!m) {
mrb_value sym = mrb_symbol_value(mid);
- mid = mrb_intern(mrb, "method_missing");
+ mid = mrb_intern2(mrb, "method_missing", 14);
m = mrb_method_search_vm(mrb, &c, mid);
if (n == CALL_MAXARGS) {
mrb_ary_unshift(mrb, regs[a+1], sym);
}
else {
- memmove(regs+a+2, regs+a+1, sizeof(mrb_value)*(n+1));
+ value_move(regs+a+2, regs+a+1, ++n);
regs[a+1] = sym;
- n++;
}
}
@@ -1317,11 +1329,15 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
ci = mrb->ci;
ci->mid = mid;
ci->target_class = m->target_class;
- ci->argc = n;
- if (ci->argc == CALL_MAXARGS) ci->argc = -1;
+ if (n == CALL_MAXARGS) {
+ ci->argc = -1;
+ }
+ else {
+ ci->argc = n;
+ }
/* move stack */
- memmove(mrb->stack, &regs[a], (ci->argc+1)*sizeof(mrb_value));
+ value_move(mrb->stack, &regs[a], ci->argc+1);
if (MRB_PROC_CFUNC_P(m)) {
mrb->stack[0] = m->body.func(mrb, recv);
@@ -1375,7 +1391,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
#define attr_f value.f
#endif
-#define TYPES2(a,b) (((((int)(a))<<8)|((int)(b)))&0xffff)
+#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
#define OP_MATH_BODY(op,v1,v2) do {\
regs[a].v1 = regs[a].v1 op regs[a+1].v2;\
} while(0)
@@ -1389,16 +1405,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
{
mrb_int x, y, z;
+ mrb_value *regs_a = regs + a;
- x = mrb_fixnum(regs[a]);
- y = mrb_fixnum(regs[a+1]);
+ x = mrb_fixnum(regs_a[0]);
+ y = mrb_fixnum(regs_a[1]);
z = x + y;
- if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) {
+ if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) {
/* integer overflow */
- SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y);
- break;
+ SET_FLT_VALUE(regs_a[0], (mrb_float)x + (mrb_float)y);
+ }
+ else {
+ regs_a[0].attr_i = z;
}
- SET_INT_VALUE(regs[a], z);
}
break;
case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
@@ -1570,28 +1588,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
CASE(OP_SUBI) {
/* A B C R(A) := R(A)-C (Syms[B]=:+)*/
int a = GETARG_A(i);
+ mrb_value *regs_a = regs + a;
/* need to check if + is overridden */
- switch (mrb_type(regs[a])) {
+ switch (mrb_type(regs_a[0])) {
case MRB_TT_FIXNUM:
{
- mrb_int x = regs[a].attr_i;
+ mrb_int x = regs_a[0].attr_i;
mrb_int y = GETARG_C(i);
mrb_int z = x - y;
- if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) {
+ if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) {
/* integer overflow */
- SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y);
- break;
+ SET_FLT_VALUE(regs_a[0], (mrb_float)x - (mrb_float)y);
+ }
+ else {
+ regs_a[0].attr_i = z;
}
- regs[a].attr_i = z;
}
break;
case MRB_TT_FLOAT:
- regs[a].attr_f -= GETARG_C(i);
+ regs_a[0].attr_f -= GETARG_C(i);
break;
default:
- SET_INT_VALUE(regs[a+1], GETARG_C(i));
+ SET_INT_VALUE(regs_a[1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND;
}
@@ -1904,7 +1924,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
if (!mrb->ci->target_class) {
static const char msg[] = "no target class or module";
mrb_value exc = mrb_exc_new(mrb, E_TYPE_ERROR, msg, sizeof(msg) - 1);
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
regs[GETARG_A(i)] = mrb_obj_value(mrb->ci->target_class);
@@ -1957,7 +1977,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
else {
exc = mrb_exc_new3(mrb, E_LOCALJUMP_ERROR, msg);
}
- mrb->exc = (struct RObject*)mrb_object(exc);
+ mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
}