diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 90 | ||||
| -rw-r--r-- | src/class.c | 12 | ||||
| -rw-r--r-- | src/codegen.c | 55 | ||||
| -rw-r--r-- | src/error.c | 26 | ||||
| -rw-r--r-- | src/gc.c | 4 | ||||
| -rw-r--r-- | src/hash.c | 8 | ||||
| -rw-r--r-- | src/kernel.c | 13 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/node.h | 1 | ||||
| -rw-r--r-- | src/numeric.c | 8 | ||||
| -rw-r--r-- | src/parse.y | 1549 | ||||
| -rw-r--r-- | src/range.c | 8 | ||||
| -rw-r--r-- | src/sprintf.c | 1095 | ||||
| -rw-r--r-- | src/state.c | 8 | ||||
| -rw-r--r-- | src/string.c | 13 | ||||
| -rw-r--r-- | src/variable.c | 2 |
16 files changed, 1019 insertions, 1875 deletions
diff --git a/src/array.c b/src/array.c index c767283aa..b55a47f66 100644 --- a/src/array.c +++ b/src/array.c @@ -10,14 +10,18 @@ #include "mruby/string.h" #include "mruby/class.h" +/* SIZE_MAX is not supported by VC++. */ +#ifndef SIZE_MAX +# define SIZE_MAX ((size_t)-1) +#endif + #define ARY_DEFAULT_LEN 4 #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ -#ifdef INT_MAX -# define ARY_MAX_SIZE (INT_MAX / sizeof(mrb_value)) -#endif +#define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) +#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX) static inline mrb_value -ary_elt(mrb_value ary, int offset) +ary_elt(mrb_value ary, mrb_int offset) { if (RARRAY_LEN(ary) == 0) return mrb_nil_value(); if (offset < 0 || RARRAY_LEN(ary) <= offset) { @@ -27,16 +31,14 @@ ary_elt(mrb_value ary, int offset) } static struct RArray* -ary_new_capa(mrb_state *mrb, int capa) +ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a; - int blen; + mrb_int blen; -#ifdef INT_MAX if (capa > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); } -#endif blen = capa * sizeof(mrb_value) ; if (blen < capa) { mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); @@ -51,7 +53,7 @@ ary_new_capa(mrb_state *mrb, int capa) } mrb_value -mrb_ary_new_capa(mrb_state *mrb, int capa) +mrb_ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a = ary_new_capa(mrb, capa); return mrb_obj_value(a); @@ -89,7 +91,7 @@ array_copy(mrb_value *dst, const mrb_value *src, size_t size) mrb_value -mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals) +mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, mrb_value *vals) { mrb_value ary; struct RArray *a; @@ -112,7 +114,7 @@ mrb_assoc_new(mrb_state *mrb, mrb_value car, mrb_value cdr) } static void -ary_fill_with_nil(mrb_value *ptr, int size) +ary_fill_with_nil(mrb_value *ptr, mrb_int size) { mrb_value nil = mrb_nil_value(); @@ -134,13 +136,13 @@ ary_modify(mrb_state *mrb, struct RArray *a) } else { mrb_value *ptr, *p; - int len; + mrb_int len; p = a->ptr; len = a->len * sizeof(mrb_value); ptr = (mrb_value *)mrb_malloc(mrb, len); if (p) { - array_copy(ptr, p, a->len); + array_copy(ptr, p, a->len); } a->ptr = ptr; a->aux.capa = a->len; @@ -170,15 +172,13 @@ ary_make_shared(mrb_state *mrb, struct RArray *a) } static void -ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) +ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { - int capa = a->aux.capa; + mrb_int capa = a->aux.capa; -#ifdef INT_MAX if (len > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } -#endif while(capa < len) { if (capa == 0) { @@ -189,9 +189,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) } } -#ifdef INT_MAX if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ -#endif if (capa > a->aux.capa) { a->aux.capa = capa; @@ -202,7 +200,7 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) static void ary_shrink_capa(mrb_state *mrb, struct RArray *a) { - int capa = a->aux.capa; + mrb_int capa = a->aux.capa; if (capa < ARY_DEFAULT_LEN * 2) return; if (capa <= a->len * ARY_SHRINK_RATIO) return; @@ -228,13 +226,13 @@ mrb_ary_s_create(mrb_state *mrb, mrb_value self) int len; mrb_get_args(mrb, "*", &vals, &len); - return mrb_ary_new_from_values(mrb, (int)len, vals); + return mrb_ary_new_from_values(mrb, len, vals); } static void -ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, int blen) +ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) { - int len = a->len + blen; + mrb_int len = a->len + blen; ary_modify(mrb, a); if (a->aux.capa < len) ary_expand_capa(mrb, a, len); @@ -255,7 +253,7 @@ mrb_value mrb_ary_concat_m(mrb_state *mrb, mrb_value self) { mrb_value *ptr; - int blen; + mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); ary_concat(mrb, mrb_ary_ptr(self), ptr, blen); @@ -269,7 +267,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) struct RArray *a2; mrb_value ary; mrb_value *ptr; - int blen; + mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); ary = mrb_ary_new_capa(mrb, a1->len + blen); @@ -305,7 +303,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) mrb_value ary2; struct RArray *a1, *a2; mrb_value r = mrb_nil_value(); - int i, len; + mrb_int i, len; mrb_get_args(mrb, "o", &ary2); if (!mrb_array_p(ary2)) return mrb_nil_value(); @@ -329,7 +327,7 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) } static void -ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, int len) +ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, mrb_int len) { ary_modify(mrb, a); if (a->aux.capa < len) @@ -429,7 +427,7 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self) } mrb_value -mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts) +mrb_ary_new4(mrb_state *mrb, mrb_int n, const mrb_value *elts) { mrb_value ary; @@ -443,7 +441,7 @@ mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts) } mrb_value -mrb_ary_new_elts(mrb_state *mrb, int n, const mrb_value *elts) +mrb_ary_new_elts(mrb_state *mrb, mrb_int n, const mrb_value *elts) { return mrb_ary_new4(mrb, n, elts); } @@ -505,7 +503,7 @@ mrb_ary_shift(mrb_state *mrb, mrb_value self) } else { mrb_value *ptr = a->ptr; - int size = a->len; + mrb_int size = a->len; val = *ptr; while((int)(--size)) { @@ -612,9 +610,9 @@ mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl) { struct RArray *a = mrb_ary_ptr(ary); - int tail, size; + mrb_int tail, size; mrb_value *argv; - int i, argc; + mrb_int i, argc; ary_modify(mrb, a); /* range check */ @@ -660,7 +658,7 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val return ary; } -int +mrb_int mrb_ary_len(mrb_state *mrb, mrb_value ary) { return RARRAY_LEN(ary); @@ -677,7 +675,7 @@ mrb_ary_decref(mrb_state *mrb, mrb_shared_array *shared) } static mrb_value -ary_subseq(mrb_state *mrb, struct RArray *a, int beg, int len) +ary_subseq(mrb_state *mrb, struct RArray *a, mrb_int beg, mrb_int len) { struct RArray *b; @@ -714,7 +712,7 @@ mrb_ary_aget(mrb_state *mrb, mrb_value self) len = mrb_fixnum(argv[0]); if (len < 0) return mrb_nil_value(); if (a->len == (int)index) return mrb_ary_new(mrb); - if ((int)len > a->len - index) len = a->len - index; + if (len > a->len - index) len = a->len - index; return ary_subseq(mrb, a, index, len); default: @@ -757,7 +755,7 @@ mrb_ary_delete_at(mrb_state *mrb, mrb_value self) mrb_int index; mrb_value val; mrb_value *ptr; - int len; + mrb_int len; mrb_get_args(mrb, "i", &index); if (index < 0) index += a->len; @@ -803,7 +801,7 @@ mrb_value mrb_ary_last(mrb_state *mrb, mrb_value self) { struct RArray *a = mrb_ary_ptr(self); - int size; + mrb_int size; mrb_value *vals; int len; @@ -830,7 +828,7 @@ mrb_value mrb_ary_index_m(mrb_state *mrb, mrb_value self) { mrb_value obj; - int i; + mrb_int i; mrb_get_args(mrb, "o", &obj); for (i = 0; i < RARRAY_LEN(self); i++) { @@ -845,7 +843,7 @@ mrb_value mrb_ary_rindex_m(mrb_state *mrb, mrb_value self) { mrb_value obj; - int i; + mrb_int i; mrb_get_args(mrb, "o", &obj); for (i = RARRAY_LEN(self) - 1; i >= 0; i--) { @@ -904,7 +902,7 @@ mrb_check_array_type(mrb_state *mrb, mrb_value ary) } mrb_value -mrb_ary_entry(mrb_value ary, int offset) +mrb_ary_entry(mrb_value ary, mrb_int offset) { if (offset < 0) { offset += RARRAY_LEN(ary); @@ -915,7 +913,7 @@ mrb_ary_entry(mrb_value ary, int offset) static mrb_value inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) { - int i; + mrb_int i; mrb_value s, arystr; char head[] = { '[' }; char sep[] = { ',', ' ' }; @@ -934,7 +932,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++) { - int ai = mrb_gc_arena_save(mrb); + mrb_int ai = mrb_gc_arena_save(mrb); if (i > 0) { mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep)); @@ -977,7 +975,7 @@ mrb_ary_inspect(mrb_state *mrb, mrb_value ary) static mrb_value join_ary(mrb_state *mrb, mrb_value ary, mrb_value sep, mrb_value list) { - int i; + mrb_int i; mrb_value result, val, tmp; /* check recursive */ @@ -1092,7 +1090,7 @@ mrb_ary_equal(mrb_state *mrb, mrb_value ary1) } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); else { - int i; + mrb_int i; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) @@ -1121,11 +1119,11 @@ mrb_ary_eql(mrb_state *mrb, mrb_value ary1) if (!mrb_array_p(ary2)) return mrb_false_value(); if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); else { - int i; + mrb_int i; for (i=0; i<RARRAY_LEN(ary1); i++) { if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) - return mrb_false_value(); + return mrb_false_value(); } return mrb_true_value(); } diff --git a/src/class.c b/src/class.c index c0e71dad7..8ea323945 100644 --- a/src/class.c +++ b/src/class.c @@ -29,7 +29,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) if (kh_exist(h, k)){ struct RProc *m = kh_value(h, k); if (m) { - mrb_gc_mark(mrb, (struct RBasic*)m); + mrb_gc_mark(mrb, (struct RBasic*)m); } } } @@ -356,7 +356,7 @@ to_hash(mrb_state *mrb, mrb_value val) retrieve arguments from mrb_state. mrb_get_args(mrb, format, ...) - + returns number of arguments parsed. fortmat specifiers: @@ -367,7 +367,7 @@ to_hash(mrb_state *mrb, mrb_value val) H: Hash [mrb_value] s: String [char*,int] z: String [char*] - a: Array [mrb_value*,int] + a: Array [mrb_value*,mrb_int] f: Float [mrb_float] i: Integer [mrb_int] b: Binary [int] @@ -489,10 +489,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value aa; struct RArray *a; mrb_value **pb; - int *pl; + mrb_int *pl; pb = va_arg(ap, mrb_value**); - pl = va_arg(ap, int*); + pl = va_arg(ap, mrb_int*); if (i < argc) { aa = to_ary(mrb, *sp++); a = mrb_ary_ptr(aa); @@ -774,7 +774,7 @@ mrb_mod_include_p(mrb_state *mrb, mrb_value mod) } return mrb_false_value(); } - + static mrb_value mrb_mod_ancestors(mrb_state *mrb, mrb_value self) { diff --git a/src/codegen.c b/src/codegen.c index ff7e87c28..6f564586c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -330,7 +330,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (c1 == OP_SUB) c = -c; if (c > 127 || c < -127) break; - if (0 <= c) + if (0 <= c) s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); else s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); @@ -410,9 +410,27 @@ new_lit(codegen_scope *s, mrb_value val) { int i; - for (i=0; i<s->irep->plen; i++) { - if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i; + + switch (mrb_type(val)) { + case MRB_TT_STRING: + for (i=0; i<s->irep->plen; i++) { + mrb_value pv = s->irep->pool[i]; + mrb_int len; + + if (mrb_type(pv) != MRB_TT_STRING) continue; + if ((len = RSTRING_LEN(pv)) != RSTRING_LEN(val)) continue; + if (memcmp(RSTRING_PTR(pv), RSTRING_PTR(val), len) == 0) + return i; + } + break; + case MRB_TT_FLOAT: + default: + for (i=0; i<s->irep->plen; i++) { + if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i; + } + break; } + if (s->irep->plen == s->pcapa) { s->pcapa *= 2; s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa); @@ -1161,7 +1179,7 @@ codegen(codegen_scope *s, node *tree, int val) if (e) { if (val) pop(); pos2 = new_label(s); - genop(s, MKOP_sBx(OP_JMP, 0)); + genop(s, MKOP_sBx(OP_JMP, 0)); dispatch(s, pos1); codegen(s, e, val); dispatch(s, pos2); @@ -1902,6 +1920,11 @@ 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) { node *n = tree; @@ -1951,7 +1974,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); sym = new_sym(s, mrb_intern(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); - mrb_gc_arena_restore(s->mrb, ai); + mrb_gc_arena_restore(s->mrb, ai); push(); } break; @@ -1979,16 +2002,16 @@ codegen(codegen_scope *s, node *tree, int val) } n = tree->cdr->cdr; if (n->car) { - p = (char*)n->car; - off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p))); - codegen(s, tree->car, VAL); - genop(s, MKOP_ABx(OP_STRING, cursp(), off)); - pop(); - genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1)); + p = (char*)n->car; + off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p))); + codegen(s, tree->car, VAL); + genop(s, MKOP_ABx(OP_STRING, cursp(), off)); + pop(); + genop(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1)); } if (n->cdr) { - char *p2 = (char*)n->cdr; - int off; + char *p2 = (char*)n->cdr; + int off; push(); off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2))); @@ -1999,7 +2022,7 @@ codegen(codegen_scope *s, node *tree, int val) pop(); sym = new_sym(s, mrb_intern(s->mrb, "compile")); genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc)); - mrb_gc_arena_restore(s->mrb, ai); + mrb_gc_arena_restore(s->mrb, ai); push(); } else { @@ -2370,13 +2393,14 @@ codedump(mrb_state *mrb, int n) { #ifdef ENABLE_STDIO mrb_irep *irep = mrb->irep[n]; - int i; + int i, ai; mrb_code c; if (!irep) return; printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n, irep->nregs, irep->nlocals, irep->plen, irep->slen); for (i=0; i<irep->ilen; i++) { + ai = mrb_gc_arena_save(mrb); printf("%03d ", i); c = irep->iseq[i]; switch (GET_OPCODE(c)) { @@ -2677,6 +2701,7 @@ codedump(mrb_state *mrb, int n) GETARG_A(c), GETARG_B(c), GETARG_C(c)); break; } + mrb_gc_arena_restore(mrb, ai); } printf("\n"); #endif diff --git a/src/error.c b/src/error.c index 70a84455f..7599bd0a9 100644 --- a/src/error.c +++ b/src/error.c @@ -125,7 +125,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc) 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")); - + if (!mrb_nil_p(file) && !mrb_nil_p(line)) { str = file; mrb_str_cat2(mrb, str, ":"); @@ -190,12 +190,12 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) ci--; while (ci >= mrb->cibase) { if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) { - mrb_irep *irep = ci->proc->body.irep; + 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])); - return; + 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])); + return; } } pc = ci->pc; @@ -366,14 +366,14 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr) n = 1; exception_call: { - mrb_sym exc = mrb_intern(mrb, "exception"); - if (mrb_respond_to(mrb, argv[0], exc)) { - mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); - } - else { - /* undef */ - mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); - } + mrb_sym exc = mrb_intern(mrb, "exception"); + if (mrb_respond_to(mrb, argv[0], exc)) { + mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1); + } + else { + /* undef */ + mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected"); + } } break; @@ -301,7 +301,7 @@ mrb_free_heap(mrb_state *mrb) page = page->next; for (p = tmp->objects, e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) { if (p->as.free.tt != MRB_TT_FREE) - obj_free(mrb, &p->as.basic); + obj_free(mrb, &p->as.basic); } mrb_free(mrb, tmp); } @@ -586,7 +586,7 @@ root_scan_phase(mrb_state *mrb) mrb_irep *irep = mrb->irep[i]; if (!irep) continue; for (j=0; j<irep->plen; j++) { - mrb_gc_mark_value(mrb, irep->pool[j]); + mrb_gc_mark_value(mrb, irep->pool[j]); } } } diff --git a/src/hash.c b/src/hash.c index 2439a235d..728fc0f2f 100644 --- a/src/hash.c +++ b/src/hash.c @@ -559,7 +559,7 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash) delVal = mrb_hash_delete_key(mrb, hash, delKey); mrb_gc_protect(mrb, delVal); - return mrb_assoc_new(mrb, delKey, delVal); + return mrb_assoc_new(mrb, delKey, delVal); } } } @@ -1119,9 +1119,9 @@ hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql) key = kh_key(h1,k1); k2 = kh_get(ht, h2, key); if (k2 != kh_end(h2)) { - if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) { - continue; /* next key */ - } + if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) { + continue; /* next key */ + } } return mrb_false_value(); } diff --git a/src/kernel.c b/src/kernel.c index e45953fd3..7187a125d 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -191,7 +191,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) mrb_sym name; mrb_value block, *argv; int argc; - + mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block); return mrb_funcall_with_block(mrb,self, name, argc, argv, block); } @@ -305,7 +305,7 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) case MRB_TT_SCLASS: case MRB_TT_HASH: case MRB_TT_DATA: - mrb_iv_copy(mrb, dest, obj); + mrb_iv_copy(mrb, dest, obj); break; default: @@ -483,7 +483,7 @@ mrb_value mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *a * call-seq: * obj.instance_eval {| | block } -> obj * - * Evaluates the given block,within the context of the receiver (_obj_). + * Evaluates the given block,within the context of the receiver (_obj_). * In order to set the context, the variable +self+ is set to _obj_ while * the code is executing, giving the code access to _obj_'s * instance variables. In the version of <code>instance_eval</code> @@ -913,7 +913,7 @@ mrb_f_raise(mrb_state *mrb, mrb_value self) { mrb_value a[2], exc; int argc; - + argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); switch (argc) { @@ -1108,11 +1108,6 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, ARGS_ANY()); /* 15.3.1.3.45 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, ARGS_NONE()); /* 15.3.1.3.46 */ -#ifdef ENABLE_SPRINTF - mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */ - mrb_define_method(mrb, krn, "format", mrb_f_sprintf, ARGS_ANY()); /* in sprintf.c */ -#endif - mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); mrb_alias_method(mrb, mrb->module_class, mrb_intern(mrb, "dup"), mrb_intern(mrb, "clone")); } diff --git a/src/load.c b/src/load.c index 850fa6e8d..84c21c186 100644 --- a/src/load.c +++ b/src/load.c @@ -536,7 +536,7 @@ mrb_read_irep(mrb_state *mrb, const char *bin) nirep = read_rite_header(mrb, src, &bin_header); if (nirep < 0) return nirep; - + src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc //Read Binary Data Section diff --git a/src/node.h b/src/node.h index 284105023..86933c224 100644 --- a/src/node.h +++ b/src/node.h @@ -102,5 +102,6 @@ enum node_type { NODE_IFUNC, NODE_DSYM, NODE_ATTRASGN, + NODE_HEREDOC, NODE_LAST }; diff --git a/src/numeric.c b/src/numeric.c index b5bff652d..5aa577828 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -306,7 +306,7 @@ static mrb_value num_eql(mrb_state *mrb, mrb_value x) { mrb_value y; - + mrb_get_args(mrb, "o", &y); if (mrb_type(x) != mrb_type(y)) return mrb_false_value(); if (mrb_equal(mrb, x, y)) { @@ -699,7 +699,7 @@ mrb_value mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; - + a = mrb_fixnum(x); if (a == 0) return x; if (mrb_fixnum_p(y)) { @@ -1126,7 +1126,7 @@ mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; - + a = mrb_fixnum(x); if (a == 0) return y; if (mrb_fixnum_p(y)) { @@ -1165,7 +1165,7 @@ mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y) { mrb_int a; - + a = mrb_fixnum(x); if (mrb_fixnum_p(y)) { mrb_int b, c; diff --git a/src/parse.y b/src/parse.y index 7bca4a4d6..2b09c3e56 100644 --- a/src/parse.y +++ b/src/parse.y @@ -31,6 +31,7 @@ typedef mrb_ast_node node; typedef struct mrb_parser_state parser_state; +typedef struct mrb_parser_heredoc_info parser_heredoc_info; static int yylex(void *lval, parser_state *p); static void yyerror(parser_state *p, const char *s); @@ -736,6 +737,14 @@ new_nth_ref(parser_state *p, int n) return cons((node*)NODE_NTH_REF, (node*)(intptr_t)n); } +// (:heredoc . a) +static node* +new_heredoc(parser_state *p) +{ + parser_heredoc_info *inf = parser_palloc(p, sizeof(parser_heredoc_info)); + return cons((node*)NODE_HEREDOC, (node*)inf); +} + static void new_bv(parser_state *p, mrb_sym id) { @@ -757,15 +766,6 @@ call_bin_op(parser_state *p, node *recv, char *m, node *arg1) return new_call(p, recv, intern(m), list1(list1(arg1))); } -/* -// (:match (a . b)) -static node* -match_op(parser_state *p, node *a, node *b) -{ - return cons((node*)NODE_MATCH, cons((node*)a, (node*)b)); -} -*/ - static void args_with_block(parser_state *p, node *a, node *b) { @@ -844,10 +844,80 @@ var_reference(parser_state *p, node *lhs) return lhs; } + +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) +{ + 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); +} + +static node* +heredoc_start_sym(parser_state *p, node *beg, mrb_sym sym, enum heredoc_type type) +{ + 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); +} + +parser_heredoc_info * +parsing_heredoc_inf(parser_state *p) +{ + node *nd = p->parsing_heredoc; + if (nd == NULL) + return NULL; + /* assert(nd->car->car == NODE_HEREDOC); */ + return (parser_heredoc_info*)nd->car->cdr; +} + +static void +heredoc_end(parser_state *p) +{ + p->parsing_heredoc = p->parsing_heredoc->cdr; + if (p->parsing_heredoc == NULL) { + p->lstate = EXPR_BEG; + p->cmd_start = TRUE; + p->sterm = 0; + p->heredoc_end_now = TRUE; + } else { + p->sterm = ' '; /* next heredoc */ + } +} + + // xxx ----------------------------- %} +%expect 2 %pure_parser %parse-param {parser_state *p} %lex-param {parser_state *p} @@ -910,11 +980,11 @@ var_reference(parser_state *p, node *lhs) keyword__FILE__ keyword__ENCODING__ -%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL -%token <nd> tINTEGER tFLOAT tCHAR tREGEXP -%token <nd> tSTRING tSTRING_PART -%token <nd> tNTH_REF tBACK_REF -%token <num> tREGEXP_END +%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL +%token <nd> tINTEGER tFLOAT tCHAR tREGEXP +%token <nd> tSTRING tSTRING_PART +%token <nd> tNTH_REF tBACK_REF +%token <num> tREGEXP_END %type <nd> singleton string string_interp regexp %type <nd> literal numeric cpath symbol @@ -935,36 +1005,39 @@ var_reference(parser_state *p, node *lhs) %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 - -%token tUPLUS /* unary+ */ -%token tUMINUS /* unary- */ -%token tPOW /* ** */ -%token tCMP /* <=> */ -%token tEQ /* == */ -%token tEQQ /* === */ -%token tNEQ /* != */ -%token tGEQ /* >= */ -%token tLEQ /* <= */ -%token tANDOP tOROP /* && and || */ -%token tMATCH tNMATCH /* =~ and !~ */ -%token tDOT2 tDOT3 /* .. and ... */ -%token tAREF tASET /* [] and []= */ -%token tLSHFT tRSHFT /* << and >> */ -%token tCOLON2 /* :: */ -%token tCOLON3 /* :: at EXPR_BEG */ -%token <id> tOP_ASGN /* +=, -= etc. */ -%token tASSOC /* => */ -%token tLPAREN /* ( */ -%token tLPAREN_ARG /* ( */ -%token tRPAREN /* ) */ -%token tLBRACK /* [ */ -%token tLBRACE /* { */ -%token tLBRACE_ARG /* { */ -%token tSTAR /* * */ -%token tAMPER /* & */ -%token tLAMBDA /* -> */ +%type <nd> heredoc heredoc_rep heredoc_interp + +%token tUPLUS /* unary+ */ +%token tUMINUS /* unary- */ +%token tPOW /* ** */ +%token tCMP /* <=> */ +%token tEQ /* == */ +%token tEQQ /* === */ +%token tNEQ /* != */ +%token tGEQ /* >= */ +%token tLEQ /* <= */ +%token tANDOP tOROP /* && and || */ +%token tMATCH tNMATCH /* =~ and !~ */ +%token tDOT2 tDOT3 /* .. and ... */ +%token tAREF tASET /* [] and []= */ +%token tLSHFT tRSHFT /* << and >> */ +%token tCOLON2 /* :: */ +%token tCOLON3 /* :: at EXPR_BEG */ +%token <id> tOP_ASGN /* +=, -= etc. */ +%token tASSOC /* => */ +%token tLPAREN /* ( */ +%token tLPAREN_ARG /* ( */ +%token tRPAREN /* ) */ +%token tLBRACK /* [ */ +%token tLBRACE /* { */ +%token tLBRACE_ARG /* { */ +%token tSTAR /* * */ +%token tAMPER /* & */ +%token tLAMBDA /* -> */ %token tSYMBEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG %token tSTRING_BEG tSTRING_DVAR tLAMBEG +%token <nd> tHEREDOC_BEG /* <<, <<- */ +%token tHEREDOC_END /* * precedence table @@ -1871,6 +1944,7 @@ mrhs : args ',' arg_value primary : literal | string | regexp + | heredoc | var_ref | backref | tFID @@ -2523,6 +2597,71 @@ regexp : tREGEXP_BEG tREGEXP } ; +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 + { + $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm); + } + | tHEREDOC_BEG tCONSTANT + { + $$ = heredoc_start_sym(p, $1, $2, heredoc_type_norm); + } + ; + + +opt_heredoc_bodies : none + | heredoc_bodies + ; + +heredoc_bodies : heredoc_body + | 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 + { + /* assert(parsing_heredoc_inf(p) != NULL); */ + parsing_heredoc_inf(p)->doc = $1; + heredoc_end(p); + } + ; + +heredoc_rep : heredoc_interp + | heredoc_rep heredoc_interp + { + $$ = append($1, $2); + } + ; + +heredoc_interp : tSTRING + { + $$ = list1($1); + } + | tSTRING_PART + { + $<num>$ = p->sterm; + p->sterm = 0; + } + compstmt + '}' + { + p->sterm = $<num>2; + $$ = list2($1, $3); + } + ; + symbol : basic_symbol { $$ = new_sym(p, $1); @@ -2873,6 +3012,7 @@ singleton : var_ref case NODE_MATCH: case NODE_FLOAT: case NODE_ARRAY: + case NODE_HEREDOC: yyerror(p, "can't define singleton method for literals"); default: break; @@ -2957,6 +3097,7 @@ nl : '\n' p->lineno++; p->column = 0; } + opt_heredoc_bodies terms : term | terms ';' {yyerrok;} @@ -3092,9 +3233,7 @@ nextc(parser_state *p) else { c = (unsigned char)*p->s++; } - if (c == '\n') { - // must understand heredoc - } + /* if (c == '\n') { } */ /* heredoc treated in parser_yylex() */ } p->column++; return c; @@ -3324,12 +3463,12 @@ read_escape(parser_state *p) 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; - } + 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); } @@ -3341,17 +3480,17 @@ 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; @@ -3426,23 +3565,23 @@ parse_string(parser_state *p, int term) else if (c == '\\') { c = nextc(p); if (c == term) { - tokadd(p, c); + tokadd(p, c); } else { - pushback(p, c); - tokadd(p, read_escape(p)); + pushback(p, c); + tokadd(p, read_escape(p)); } continue; } if (c == '#') { 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->sterm = term; + p->cmd_start = TRUE; + yylval.nd = new_str(p, tok(p), toklen(p)); + return tSTRING_PART; } tokadd(p, '#'); pushback(p, c); @@ -3548,6 +3687,73 @@ parse_qstring(parser_state *p, int beg, int end) } 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; + } + } + 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 ((len-1 == inf->term_len) && (strncmp(s, inf->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", inf->term); + yyerror(p, buf); + return 0; + } + + yylval.nd = new_str(p, tok(p), toklen(p)); + return tSTRING; +} + +static int arg_ambiguous(parser_state *p) { yywarning(p, "ambiguous first argument; put parentheses or even spaces"); @@ -3560,11 +3766,15 @@ 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); } @@ -3573,22 +3783,27 @@ parser_yylex(parser_state *p) retry: last_state = p->lstate; switch (c = nextc(p)) { - case '\0': /* NUL */ - case '\004': /* ^D */ - case '\032': /* ^Z */ - case -1: /* end of script. */ + case '\0': /* NUL */ + case '\004': /* ^D */ + case '\032': /* ^Z */ + case -1: /* end of script. */ return 0; - /* white spaces */ + /* white spaces */ case ' ': case '\t': case '\f': case '\r': - case '\13': /* '\v' */ + case '\13': /* '\v' */ space_seen = 1; goto retry; - case '#': /* it's a comment */ + case '#': /* it's a comment */ skip(p, '\n'); - /* fall through */ + /* fall through */ case '\n': + p->heredoc_starts_nextline = FALSE; + if (p->parsing_heredoc != NULL) { + p->sterm = ' '; + goto normal_newline; + } switch (p->lstate) { case EXPR_BEG: case EXPR_FNAME: @@ -3605,19 +3820,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: @@ -3628,29 +3843,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 = intern("**"); + 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("*"); + 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) { @@ -3665,7 +3880,7 @@ parser_yylex(parser_state *p) if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { p->lstate = EXPR_ARG; if (c == '@') { - return '!'; + return '!'; } } else { @@ -3683,8 +3898,8 @@ parser_yylex(parser_state *p) case '=': if (p->column == 1) { if (peeks(p, "begin\n")) { - skips(p, "\n=end\n"); - goto retry; + skips(p, "\n=end\n"); + goto retry; } } if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { @@ -3694,7 +3909,7 @@ parser_yylex(parser_state *p) } if ((c = nextc(p)) == '=') { if ((c = nextc(p)) == '=') { - return tEQQ; + return tEQQ; } pushback(p, c); return tEQ; @@ -3711,17 +3926,26 @@ parser_yylex(parser_state *p) case '<': last_state = p->lstate; c = nextc(p); -#if 0 - // no heredoc supported yet if (c == '<' && - p->lstate != EXPR_DOT && - p->lstate != EXPR_CLASS && - !IS_END() && - (!IS_ARG() || space_seen)) { - int token = heredoc_identifier(); - if (token) return token; + 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; + } } -#endif if (p->lstate == EXPR_FNAME || p->lstate == EXPR_DOT) { p->lstate = EXPR_ARG; } else { @@ -3732,16 +3956,16 @@ parser_yylex(parser_state *p) } 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 = intern("<<"); + p->lstate = EXPR_BEG; + return tOP_ASGN; } pushback(p, c); return tLSHFT; @@ -3760,9 +3984,9 @@ parser_yylex(parser_state *p) } if (c == '>') { if ((c = nextc(p)) == '=') { - yylval.id = intern(">>"); - p->lstate = EXPR_BEG; - return tOP_ASGN; + yylval.id = intern(">>"); + p->lstate = EXPR_BEG; + return tOP_ASGN; } pushback(p, c); return tRSHFT; @@ -3789,35 +4013,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); @@ -3830,20 +4054,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 { @@ -3858,9 +4082,9 @@ 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 = intern("&&"); + p->lstate = EXPR_BEG; + return tOP_ASGN; } pushback(p, c); return tANDOP; @@ -3892,9 +4116,9 @@ 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 = intern("||"); + p->lstate = EXPR_BEG; + return tOP_ASGN; } pushback(p, c); return tOROP; @@ -3918,7 +4142,7 @@ 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 '+'; @@ -3932,8 +4156,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; } @@ -3946,7 +4170,7 @@ 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 '-'; @@ -3964,7 +4188,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; } @@ -3976,7 +4200,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; @@ -3993,223 +4217,223 @@ parser_yylex(parser_state *p) case '5': case '6': case '7': case '8': case '9': { int is_float, seen_point, seen_e, nondigit; - + is_float = seen_point = seen_e = nondigit = 0; 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; @@ -4231,8 +4455,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; @@ -4294,7 +4518,7 @@ parser_yylex(parser_state *p) case ';': p->lstate = EXPR_BEG; return ';'; - + case ',': p->lstate = EXPR_BEG; return ','; @@ -4302,7 +4526,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; } @@ -4329,11 +4553,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 '['; @@ -4390,19 +4614,19 @@ parser_yylex(parser_state *p) 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; - } + beg = 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; @@ -4419,51 +4643,51 @@ parser_yylex(parser_state *p) switch (c) { case 'Q': #if 0 - p->lex_strterm = new_strterm(p, str_dquote, term, paren); + p->lex_strterm = new_strterm(p, str_dquote, term, paren); #endif - return tSTRING_BEG; + return tSTRING_BEG; case 'q': #if 0 - p->lex_strterm = new_strterm(p, str_squote, term, paren); + p->lex_strterm = new_strterm(p, str_squote, term, paren); #endif - p->sterm = 0; - return parse_qstring(p, beg, term); + p->sterm = 0; + return parse_qstring(p, beg, term); case 'W': #if 0 - p->lex_strterm = new_strterm(p, str_dword, term, paren); + p->lex_strterm = new_strterm(p, str_dword, term, paren); #endif - do {c = nextc(p);} while (isspace(c)); - pushback(p, c); - return tWORDS_BEG; + do {c = nextc(p);} while (isspace(c)); + pushback(p, c); + return tWORDS_BEG; case 'w': #if 0 - p->lex_strterm = new_strterm(p, str_sword, term, paren); + p->lex_strterm = new_strterm(p, str_sword, term, paren); #endif - do {c = nextc(p);} while (isspace(c)); - pushback(p, c); - return tQWORDS_BEG; + do {c = nextc(p);} while (isspace(c)); + pushback(p, c); + return tQWORDS_BEG; case 'r': #if 0 - p->lex_strterm = new_strterm(p, str_regexp, term, paren); + p->lex_strterm = new_strterm(p, str_regexp, term, paren); #endif - p->regexp = 1; - p->sterm = term; - return tREGEXP_BEG; + p->regexp = 1; + p->sterm = term; + return tREGEXP_BEG; case 's': #if 0 - p->lex_strterm = new_strterm(p, str_ssym, term, paren); + p->lex_strterm = new_strterm(p, str_ssym, term, paren); #endif - p->lstate = EXPR_FNAME; - return tSYMBEG; + p->lstate = EXPR_FNAME; + return tSYMBEG; default: - yyerror(p, "unknown type of %string"); - return 0; + yyerror(p, "unknown type of %string"); + return 0; } } if ((c = nextc(p)) == '=') { @@ -4487,27 +4711,27 @@ parser_yylex(parser_state *p) token_column = newtok(p); c = nextc(p); switch (c) { - case '_': /* $_: last read line string */ + case '_': /* $_: last read line string */ c = nextc(p); pushback(p, c); c = '_'; /* fall through */ - case '~': /* $~: match-data */ - case '*': /* $*: argv */ - case '$': /* $$: pid */ - case '?': /* $?: last status */ - case '!': /* $!: error string */ - case '@': /* $@: error position */ - case '/': /* $/: input record separator */ - case '\\': /* $\: output record separator */ - case ';': /* $;: field separator */ - case ',': /* $,: output field separator */ - case '.': /* $.: last read line number */ - case '=': /* $=: ignorecase */ - case ':': /* $:: load path */ - case '<': /* $<: reading filename */ - case '>': /* $>: default output handle */ - case '\"': /* $": already loaded files */ + case '~': /* $~: match-data */ + case '*': /* $*: argv */ + case '$': /* $$: pid */ + case '?': /* $?: last status */ + case '!': /* $!: error string */ + case '@': /* $@: error position */ + case '/': /* $/: input record separator */ + case '\\': /* $\: output record separator */ + case ';': /* $;: field separator */ + case ',': /* $,: output field separator */ + case '.': /* $.: last read line number */ + case '=': /* $=: ignorecase */ + case ':': /* $:: load path */ + case '<': /* $<: reading filename */ + case '>': /* $>: default output handle */ + case '\"': /* $": already loaded files */ tokadd(p, '$'); tokadd(p, c); tokfix(p); @@ -4524,14 +4748,14 @@ parser_yylex(parser_state *p) yylval.id = intern(tok(p)); return tGVAR; - case '&': /* $&: last match */ - case '`': /* $`: string before last match */ - case '\'': /* $': string after last match */ - case '+': /* $+: string matches last paren. */ + case '&': /* $&: last match */ + case '`': /* $`: string before last match */ + 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; @@ -4540,8 +4764,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; @@ -4551,8 +4775,8 @@ parser_yylex(parser_state *p) default: if (!identchar(c)) { - pushback(p, c); - return '$'; + pushback(p, c); + return '$'; } case '0': tokadd(p, '$'); @@ -4569,10 +4793,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; } @@ -4630,97 +4854,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 (IS_BEG() || p->lstate == EXPR_DOT || IS_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; } } { @@ -4729,7 +4951,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 } @@ -4740,12 +4962,12 @@ parser_yylex(parser_state *p) static int yylex(void *lval, parser_state *p) { - int t; + int t; - p->ylval = lval; - t = parser_yylex(p); + p->ylval = lval; + t = parser_yylex(p); - return t; + return t; } static void @@ -4844,6 +5066,8 @@ mrb_parser_new(mrb_state *mrb) yydebug = 1; #endif + p->heredocs = p->parsing_heredoc = NULL; + return p; } @@ -4930,7 +5154,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) char buf[256]; n = snprintf(buf, sizeof(buf), "line %d: %s\n", - p->error_buffer[0].lineno, p->error_buffer[0].message); + 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_parser_free(p); return mrb_undef_value(); @@ -5047,23 +5271,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; @@ -5096,40 +5320,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); @@ -5209,25 +5433,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; @@ -5246,17 +5470,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; @@ -5269,17 +5493,17 @@ parser_dump(mrb_state *mrb, node *tree, int offset) parser_dump(mrb, tree->car, offset+1); dump_prefix(offset+1); printf("method='%s' (%d)\n", - mrb_sym2name(mrb, sym(tree->cdr->car)), - (int)(intptr_t)tree->cdr->car); + mrb_sym2name(mrb, sym(tree->cdr->car)), + (int)(intptr_t)tree->cdr->car); tree = tree->cdr->cdr->car; if (tree) { dump_prefix(offset+1); 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; @@ -5350,31 +5574,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) { + dump_prefix(offset+2); + printf("rest:\n"); if (n2->car == (node*)-1) { - dump_prefix(offset+2); - printf("(empty)\n"); - } + 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); - } - } + 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); @@ -5401,9 +5625,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; @@ -5544,8 +5768,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: @@ -5622,17 +5846,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; @@ -5640,40 +5864,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); @@ -5690,40 +5914,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; @@ -5735,6 +5959,11 @@ parser_dump(mrb_state *mrb, node *tree, int offset) parser_dump(mrb, tree, offset+1); break; + case NODE_HEREDOC: + printf("NODE_HEREDOC:\n"); + parser_dump(mrb, ((parser_heredoc_info*)tree)->doc, offset+1); + break; + default: printf("node type: %d (0x%x)\n", (int)n, (int)n); break; diff --git a/src/range.c b/src/range.c index aac1d830a..59bf445aa 100644 --- a/src/range.c +++ b/src/range.c @@ -16,8 +16,8 @@ static void range_check(mrb_state *mrb, mrb_value a, mrb_value b) { mrb_value ans; - int ta; - int tb; + enum mrb_vtype ta; + enum mrb_vtype tb; ta = mrb_type(a); tb = mrb_type(b); @@ -181,7 +181,7 @@ r_le(mrb_state *mrb, mrb_value a, mrb_value b) /* output :a < b => -1, a = b => 0, a > b => +1 */ if (mrb_type(r) == MRB_TT_FIXNUM) { - int c = mrb_fixnum(r); + mrb_int c = mrb_fixnum(r); if (c == 0 || c == -1) return TRUE; } @@ -208,7 +208,7 @@ r_ge(mrb_state *mrb, mrb_value a, mrb_value b) /* output :a < b => -1, a = b => 0, a > b => +1 */ if (mrb_type(r) == MRB_TT_FIXNUM) { - int c = mrb_fixnum(r); + mrb_int c = mrb_fixnum(r); if (c == 0 || c == 1) return TRUE; } diff --git a/src/sprintf.c b/src/sprintf.c deleted file mode 100644 index 905182147..000000000 --- a/src/sprintf.c +++ /dev/null @@ -1,1095 +0,0 @@ -/* -** sprintf.c - Kernel.#sprintf -** -** See Copyright Notice in mruby.h -*/ - -#include "mruby.h" - -#ifdef ENABLE_SPRINTF - -#include <stdio.h> -#include <string.h> -#include "mruby/string.h" -#include "mruby/hash.h" -#include "mruby/numeric.h" -#include <math.h> -#include <ctype.h> - -#ifdef _MSC_VER -#include <float.h> -#endif - -#ifdef HAVE_IEEEFP_H -#include <ieeefp.h> -#endif - -#define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ -#define BITSPERDIG (sizeof(mrb_int)*CHAR_BIT) -#define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n))) - -static void fmt_setup(char*,size_t,int,int,int,int); - -static char* -remove_sign_bits(char *str, int base) -{ - char *t; - - t = str; - if (base == 16) { - while (*t == 'f') { - t++; - } - } - else if (base == 8) { - *t |= EXTENDSIGN(3, strlen(t)); - while (*t == '7') { - t++; - } - } - else if (base == 2) { - while (*t == '1') { - t++; - } - } - - return t; -} - -static char -sign_bits(int base, const char *p) -{ - char c; - - switch (base) { - case 16: - if (*p == 'X') c = 'F'; - else c = 'f'; - break; - case 8: - c = '7'; break; - case 2: - c = '1'; break; - default: - c = '.'; break; - } - return c; -} - -static mrb_value -mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) -{ - char buf[64], *b = buf + sizeof buf; - unsigned long val = mrb_fixnum(x); - char d; - - if (base != 2) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); - } - - if (val >= (1 << 10)) - val &= 0x3ff; - - if (val == 0) { - return mrb_str_new(mrb, "0", 1); - } - *--b = '\0'; - do { - *--b = mrb_digitmap[(int)(val % base)]; - } while (val /= base); - - if (mrb_fixnum(x) < 0) { - b = remove_sign_bits(b, base); - switch (base) { - case 16: d = 'f'; break; - case 8: d = '7'; break; - case 2: d = '1'; break; - default: d = 0; break; - } - - if (d && *b != d) { - *--b = d; - } - } - - return mrb_str_new2(mrb, b); -} - -#define FNONE 0 -#define FSHARP 1 -#define FMINUS 2 -#define FPLUS 4 -#define FZERO 8 -#define FSPACE 16 -#define FWIDTH 32 -#define FPREC 64 -#define FPREC0 128 - -#define CHECK(l) do {\ -/* int cr = ENC_CODERANGE(result);*/\ - while (blen + (l) >= bsiz) {\ - bsiz*=2;\ - }\ - mrb_str_resize(mrb, result, bsiz);\ -/* ENC_CODERANGE_SET(result, cr);*/\ - buf = RSTRING_PTR(result);\ -} while (0) - -#define PUSH(s, l) do { \ - CHECK(l);\ - memcpy(&buf[blen], s, l);\ - blen += (l);\ -} while (0) - -#define FILL(c, l) do { \ - CHECK(l);\ - memset(&buf[blen], c, l);\ - blen += (l);\ -} while (0) - -#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \ - posarg == -1 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg), mrb_undef_value()) : \ - posarg == -2 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg), mrb_undef_value()) : \ - (posarg = nextarg++, GETNTHARG(posarg))) - -#define GETPOSARG(n) (posarg > 0 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%d) after unnumbered(%d)", n, posarg), mrb_undef_value()) : \ - posarg == -2 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%d) after named", n), mrb_undef_value()) : \ - ((n < 1) ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %d$", n), mrb_undef_value()) : \ - (posarg = -1, GETNTHARG(n)))) - -#define GETNTHARG(nth) \ - ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth]) - -#define GETNAMEARG(id, name, len) ( \ - posarg > 0 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%.*s after unnumbered(%d)", (len), (name), posarg), mrb_undef_value()) : \ - posarg == -1 ? \ - (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%.*s after numbered", (len), (name)), mrb_undef_value()) : \ - (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value()))) - -#define GETNUM(n, val) \ - for (; p < end && ISDIGIT(*p); p++) {\ - int next_n = 10 * n + (*p - '0'); \ - if (next_n / 10 != n) {\ - mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \ - } \ - n = next_n; \ - } \ - if (p >= end) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %*[0-9]"); \ - } - -#define GETASTER(num) do { \ - t = p++; \ - n = 0; \ - GETNUM(n, val); \ - if (*p == '$') { \ - tmp = GETPOSARG(n); \ - } \ - else { \ - tmp = GETARG(); \ - p = t; \ - } \ - num = mrb_fixnum(tmp); \ -} while (0) - -static mrb_value -get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) -{ - mrb_value tmp; - - if (!mrb_undef_p(*hash)) return *hash; - if (argc != 2) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); - } - tmp = mrb_check_convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash"); - if (mrb_nil_p(tmp)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); - } - return (*hash = tmp); -} - -/* - * call-seq: - * format(format_string [, arguments...] ) -> string - * sprintf(format_string [, arguments...] ) -> string - * - * Returns the string resulting from applying <i>format_string</i> to - * any additional arguments. Within the format string, any characters - * other than format sequences are copied to the result. - * - * The syntax of a format sequence is follows. - * - * %[flags][width][.precision]type - * - * A format - * sequence consists of a percent sign, followed by optional flags, - * width, and precision indicators, then terminated with a field type - * character. The field type controls how the corresponding - * <code>sprintf</code> argument is to be interpreted, while the flags - * modify that interpretation. - * - * The field type characters are: - * - * Field | Integer Format - * ------+-------------------------------------------------------------- - * b | Convert argument as a binary number. - * | Negative numbers will be displayed as a two's complement - * | prefixed with `..1'. - * B | Equivalent to `b', but uses an uppercase 0B for prefix - * | in the alternative format by #. - * d | Convert argument as a decimal number. - * i | Identical to `d'. - * o | Convert argument as an octal number. - * | Negative numbers will be displayed as a two's complement - * | prefixed with `..7'. - * u | Identical to `d'. - * x | Convert argument as a hexadecimal number. - * | Negative numbers will be displayed as a two's complement - * | prefixed with `..f' (representing an infinite string of - * | leading 'ff's). - * X | Equivalent to `x', but uses uppercase letters. - * - * Field | Float Format - * ------+-------------------------------------------------------------- - * e | Convert floating point argument into exponential notation - * | with one digit before the decimal point as [-]d.dddddde[+-]dd. - * | The precision specifies the number of digits after the decimal - * | point (defaulting to six). - * E | Equivalent to `e', but uses an uppercase E to indicate - * | the exponent. - * f | Convert floating point argument as [-]ddd.dddddd, - * | where the precision specifies the number of digits after - * | the decimal point. - * g | Convert a floating point number using exponential form - * | if the exponent is less than -4 or greater than or - * | equal to the precision, or in dd.dddd form otherwise. - * | The precision specifies the number of significant digits. - * G | Equivalent to `g', but use an uppercase `E' in exponent form. - * a | Convert floating point argument as [-]0xh.hhhhp[+-]dd, - * | which is consisted from optional sign, "0x", fraction part - * | as hexadecimal, "p", and exponential part as decimal. - * A | Equivalent to `a', but use uppercase `X' and `P'. - * - * Field | Other Format - * ------+-------------------------------------------------------------- - * c | Argument is the numeric code for a single character or - * | a single character string itself. - * p | The valuing of argument.inspect. - * s | Argument is a string to be substituted. If the format - * | sequence contains a precision, at most that many characters - * | will be copied. - * % | A percent sign itself will be displayed. No argument taken. - * - * The flags modifies the behavior of the formats. - * The flag characters are: - * - * Flag | Applies to | Meaning - * ---------+---------------+----------------------------------------- - * space | bBdiouxX | Leave a space at the start of - * | aAeEfgG | non-negative numbers. - * | (numeric fmt) | For `o', `x', `X', `b' and `B', use - * | | a minus sign with absolute value for - * | | negative values. - * ---------+---------------+----------------------------------------- - * (digit)$ | all | Specifies the absolute argument number - * | | for this field. Absolute and relative - * | | argument numbers cannot be mixed in a - * | | sprintf string. - * ---------+---------------+----------------------------------------- - * # | bBoxX | Use an alternative format. - * | aAeEfgG | For the conversions `o', increase the precision - * | | until the first digit will be `0' if - * | | it is not formatted as complements. - * | | For the conversions `x', `X', `b' and `B' - * | | on non-zero, prefix the result with ``0x'', - * | | ``0X'', ``0b'' and ``0B'', respectively. - * | | For `a', `A', `e', `E', `f', `g', and 'G', - * | | force a decimal point to be added, - * | | even if no digits follow. - * | | For `g' and 'G', do not remove trailing zeros. - * ---------+---------------+----------------------------------------- - * + | bBdiouxX | Add a leading plus sign to non-negative - * | aAeEfgG | numbers. - * | (numeric fmt) | For `o', `x', `X', `b' and `B', use - * | | a minus sign with absolute value for - * | | negative values. - * ---------+---------------+----------------------------------------- - * - | all | Left-justify the result of this conversion. - * ---------+---------------+----------------------------------------- - * 0 (zero) | bBdiouxX | Pad with zeros, not spaces. - * | aAeEfgG | For `o', `x', `X', `b' and `B', radix-1 - * | (numeric fmt) | is used for negative numbers formatted as - * | | complements. - * ---------+---------------+----------------------------------------- - * * | all | Use the next argument as the field width. - * | | If negative, left-justify the result. If the - * | | asterisk is followed by a number and a dollar - * | | sign, use the indicated argument as the width. - * - * Examples of flags: - * - * # `+' and space flag specifies the sign of non-negative numbers. - * sprintf("%d", 123) #=> "123" - * sprintf("%+d", 123) #=> "+123" - * sprintf("% d", 123) #=> " 123" - * - * # `#' flag for `o' increases number of digits to show `0'. - * # `+' and space flag changes format of negative numbers. - * sprintf("%o", 123) #=> "173" - * sprintf("%#o", 123) #=> "0173" - * sprintf("%+o", -123) #=> "-173" - * sprintf("%o", -123) #=> "..7605" - * sprintf("%#o", -123) #=> "..7605" - * - * # `#' flag for `x' add a prefix `0x' for non-zero numbers. - * # `+' and space flag disables complements for negative numbers. - * sprintf("%x", 123) #=> "7b" - * sprintf("%#x", 123) #=> "0x7b" - * sprintf("%+x", -123) #=> "-7b" - * sprintf("%x", -123) #=> "..f85" - * sprintf("%#x", -123) #=> "0x..f85" - * sprintf("%#x", 0) #=> "0" - * - * # `#' for `X' uses the prefix `0X'. - * sprintf("%X", 123) #=> "7B" - * sprintf("%#X", 123) #=> "0X7B" - * - * # `#' flag for `b' add a prefix `0b' for non-zero numbers. - * # `+' and space flag disables complements for negative numbers. - * sprintf("%b", 123) #=> "1111011" - * sprintf("%#b", 123) #=> "0b1111011" - * sprintf("%+b", -123) #=> "-1111011" - * sprintf("%b", -123) #=> "..10000101" - * sprintf("%#b", -123) #=> "0b..10000101" - * sprintf("%#b", 0) #=> "0" - * - * # `#' for `B' uses the prefix `0B'. - * sprintf("%B", 123) #=> "1111011" - * sprintf("%#B", 123) #=> "0B1111011" - * - * # `#' for `e' forces to show the decimal point. - * sprintf("%.0e", 1) #=> "1e+00" - * sprintf("%#.0e", 1) #=> "1.e+00" - * - * # `#' for `f' forces to show the decimal point. - * sprintf("%.0f", 1234) #=> "1234" - * sprintf("%#.0f", 1234) #=> "1234." - * - * # `#' for `g' forces to show the decimal point. - * # It also disables stripping lowest zeros. - * sprintf("%g", 123.4) #=> "123.4" - * sprintf("%#g", 123.4) #=> "123.400" - * sprintf("%g", 123456) #=> "123456" - * sprintf("%#g", 123456) #=> "123456." - * - * The field width is an optional integer, followed optionally by a - * period and a precision. The width specifies the minimum number of - * characters that will be written to the result for this field. - * - * Examples of width: - * - * # padding is done by spaces, width=20 - * # 0 or radix-1. <------------------> - * sprintf("%20d", 123) #=> " 123" - * sprintf("%+20d", 123) #=> " +123" - * sprintf("%020d", 123) #=> "00000000000000000123" - * sprintf("%+020d", 123) #=> "+0000000000000000123" - * sprintf("% 020d", 123) #=> " 0000000000000000123" - * sprintf("%-20d", 123) #=> "123 " - * sprintf("%-+20d", 123) #=> "+123 " - * sprintf("%- 20d", 123) #=> " 123 " - * sprintf("%020x", -123) #=> "..ffffffffffffffff85" - * - * For - * numeric fields, the precision controls the number of decimal places - * displayed. For string fields, the precision determines the maximum - * number of characters to be copied from the string. (Thus, the format - * sequence <code>%10.10s</code> will always contribute exactly ten - * characters to the result.) - * - * Examples of precisions: - * - * # precision for `d', 'o', 'x' and 'b' is - * # minimum number of digits <------> - * sprintf("%20.8d", 123) #=> " 00000123" - * sprintf("%20.8o", 123) #=> " 00000173" - * sprintf("%20.8x", 123) #=> " 0000007b" - * sprintf("%20.8b", 123) #=> " 01111011" - * sprintf("%20.8d", -123) #=> " -00000123" - * sprintf("%20.8o", -123) #=> " ..777605" - * sprintf("%20.8x", -123) #=> " ..ffff85" - * sprintf("%20.8b", -11) #=> " ..110101" - * - * # "0x" and "0b" for `#x' and `#b' is not counted for - * # precision but "0" for `#o' is counted. <------> - * sprintf("%#20.8d", 123) #=> " 00000123" - * sprintf("%#20.8o", 123) #=> " 00000173" - * sprintf("%#20.8x", 123) #=> " 0x0000007b" - * sprintf("%#20.8b", 123) #=> " 0b01111011" - * sprintf("%#20.8d", -123) #=> " -00000123" - * sprintf("%#20.8o", -123) #=> " ..777605" - * sprintf("%#20.8x", -123) #=> " 0x..ffff85" - * sprintf("%#20.8b", -11) #=> " 0b..110101" - * - * # precision for `e' is number of - * # digits after the decimal point <------> - * sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03" - * - * # precision for `f' is number of - * # digits after the decimal point <------> - * sprintf("%20.8f", 1234.56789) #=> " 1234.56789000" - * - * # precision for `g' is number of - * # significant digits <-------> - * sprintf("%20.8g", 1234.56789) #=> " 1234.5679" - * - * # <-------> - * sprintf("%20.8g", 123456789) #=> " 1.2345679e+08" - * - * # precision for `s' is - * # maximum number of characters <------> - * sprintf("%20.8s", "string test") #=> " string t" - * - * Examples: - * - * sprintf("%d %04x", 123, 123) #=> "123 007b" - * sprintf("%08b '%4s'", 123, 123) #=> "01111011 ' 123'" - * sprintf("%1$*2$s %2$d %1$s", "hello", 8) #=> " hello 8 hello" - * sprintf("%1$*2$s %2$d", "hello", -8) #=> "hello -8" - * sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23) #=> "+1.23: 1.23:1.23" - * sprintf("%u", -123) #=> "-123" - * - * For more complex formatting, Ruby supports a reference by name. - * %<name>s style uses format style, but %{name} style doesn't. - * - * Exapmles: - * sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 }) - * #=> 1 : 2.000000 - * sprintf("%{foo}f", { :foo => 1 }) - * # => "1f" - */ - -mrb_value -mrb_f_sprintf(mrb_state *mrb, mrb_value obj) -{ - int argc; - mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); - - if (argc <= 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"); - return mrb_nil_value(); - } - else { - return mrb_str_format(mrb, argc - 1, argv + 1, argv[0]); - } -} - -mrb_value -mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt) -{ - const char *p, *end; - char *buf; - long blen, bsiz; - mrb_value result; - int n; - int width, prec, flags = FNONE; - int nextarg = 1; - int posarg = 0; - mrb_value nextvalue; - mrb_value tmp; - mrb_value str; - mrb_value hash = mrb_undef_value(); - -#define CHECK_FOR_WIDTH(f) \ - if ((f) & FWIDTH) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "width given twice"); \ - } \ - if ((f) & FPREC0) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "width after precision"); \ - } -#define CHECK_FOR_FLAGS(f) \ - if ((f) & FWIDTH) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after width"); \ - } \ - if ((f) & FPREC0) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "flag after precision"); \ - } - - ++argc; - --argv; - mrb_string_value(mrb, &fmt); - p = RSTRING_PTR(fmt); - end = p + RSTRING_LEN(fmt); - blen = 0; - bsiz = 120; - result = mrb_str_buf_new(mrb, bsiz); - buf = RSTRING_PTR(result); - memset(buf, 0, bsiz); - - for (; p < end; p++) { - const char *t; - mrb_sym id = 0; - - for (t = p; t < end && *t != '%'; t++) ; - PUSH(p, t - p); - if (t >= end) - goto sprint_exit; /* end of fmt string */ - - p = t + 1; /* skip `%' */ - - width = prec = -1; - nextvalue = mrb_undef_value(); - -retry: - switch (*p) { - default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); - break; - - case ' ': - CHECK_FOR_FLAGS(flags); - flags |= FSPACE; - p++; - goto retry; - - case '#': - CHECK_FOR_FLAGS(flags); - flags |= FSHARP; - p++; - goto retry; - - case '+': - CHECK_FOR_FLAGS(flags); - flags |= FPLUS; - p++; - goto retry; - - case '-': - CHECK_FOR_FLAGS(flags); - flags |= FMINUS; - p++; - goto retry; - - case '0': - CHECK_FOR_FLAGS(flags); - flags |= FZERO; - p++; - goto retry; - - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - GETNUM(n, width); - if (*p == '$') { - if (!mrb_undef_p(nextvalue)) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %d$", n); - } - nextvalue = GETPOSARG(n); - p++; - goto retry; - } - CHECK_FOR_WIDTH(flags); - width = n; - flags |= FWIDTH; - goto retry; - - case '<': - case '{': { - const char *start = p; - char term = (*p == '<') ? '>' : '}'; - mrb_value symname; - - for (; p < end && *p != term; ) - p++; - if (id) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%.*s after <%s>", - (int)(p - start + 1), start, mrb_sym2name(mrb, id)); - } - symname = mrb_str_new(mrb, start + 1, p - start - 1); - id = mrb_intern_str(mrb, symname); - nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1)); - if (mrb_undef_p(nextvalue)) { - mrb_raisef(mrb, E_KEY_ERROR, "key%.*s not found", (int)(p - start + 1), start); - } - if (term == '}') goto format_s; - p++; - goto retry; - } - - case '*': - CHECK_FOR_WIDTH(flags); - flags |= FWIDTH; - GETASTER(width); - if (width < 0) { - flags |= FMINUS; - width = -width; - } - p++; - goto retry; - - case '.': - if (flags & FPREC0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "precision given twice"); - } - flags |= FPREC|FPREC0; - - prec = 0; - p++; - if (*p == '*') { - GETASTER(prec); - if (prec < 0) { /* ignore negative precision */ - flags &= ~FPREC; - } - p++; - goto retry; - } - - GETNUM(prec, precision); - goto retry; - - case '\n': - case '\0': - p--; - - case '%': - if (flags != FNONE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %"); - } - PUSH("%", 1); - break; - - case 'c': { - mrb_value val = GETARG(); - mrb_value tmp; - unsigned int c; - - tmp = mrb_check_string_type(mrb, val); - if (!mrb_nil_p(tmp)) { - if (RSTRING_LEN(tmp) != 1 ) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character"); - } - c = RSTRING_PTR(tmp)[0]; - n = 1; - } - else { - c = mrb_fixnum(val); - n = 1; - } - if (n <= 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); - } - if (!(flags & FWIDTH)) { - CHECK(n); - buf[blen] = c; - blen += n; - } - else if ((flags & FMINUS)) { - CHECK(n); - buf[blen] = c; - blen += n; - FILL(' ', width-1); - } - else { - FILL(' ', width-1); - CHECK(n); - buf[blen] = c; - blen += n; - } - } - break; - - case 's': - case 'p': - format_s: - { - mrb_value arg = GETARG(); - long len, slen; - - if (*p == 'p') arg = mrb_inspect(mrb, arg); - str = mrb_obj_as_string(mrb, arg); - len = RSTRING_LEN(str); - RSTRING_LEN(result) = blen; - if (flags&(FPREC|FWIDTH)) { - slen = RSTRING_LEN(str); - if (slen < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid mbstring sequence"); - } - if ((flags&FPREC) && (prec < slen)) { - char *p = RSTRING_PTR(str) + prec; - slen = prec; - len = p - RSTRING_PTR(str); - } - /* need to adjust multi-byte string pos */ - if ((flags&FWIDTH) && (width > slen)) { - width -= (int)slen; - if (!(flags&FMINUS)) { - CHECK(width); - while (width--) { - buf[blen++] = ' '; - } - } - CHECK(len); - memcpy(&buf[blen], RSTRING_PTR(str), len); - blen += len; - if (flags&FMINUS) { - CHECK(width); - while (width--) { - buf[blen++] = ' '; - } - } - break; - } - } - PUSH(RSTRING_PTR(str), len); - } - break; - - case 'd': - case 'i': - case 'o': - case 'x': - case 'X': - case 'b': - case 'B': - case 'u': { - mrb_value val = GETARG(); - char fbuf[32], nbuf[64], *s; - const char *prefix = 0; - int sign = 0, dots = 0; - char sc = 0; - long v = 0, org_v = 0; - int base; - int len; - - switch (*p) { - case 'd': - case 'i': - case 'u': - sign = 1; break; - case 'o': - case 'x': - case 'X': - case 'b': - case 'B': - if (flags&(FPLUS|FSPACE)) sign = 1; - break; - default: - break; - } - if (flags & FSHARP) { - switch (*p) { - case 'o': prefix = "0"; break; - case 'x': prefix = "0x"; break; - case 'X': prefix = "0X"; break; - case 'b': prefix = "0b"; break; - case 'B': prefix = "0B"; break; - default: break; - } - } - - bin_retry: - switch (mrb_type(val)) { - case MRB_TT_FLOAT: - if (FIXABLE(mrb_float(val))) { - val = mrb_fixnum_value((mrb_int)mrb_float(val)); - goto bin_retry; - } - val = mrb_flt2big(mrb, mrb_float(val)); - if (mrb_fixnum_p(val)) goto bin_retry; - break; - case MRB_TT_STRING: - val = mrb_str_to_inum(mrb, val, 0, TRUE); - goto bin_retry; - case MRB_TT_FIXNUM: - v = (long)mrb_fixnum(val); - break; - default: - val = mrb_Integer(mrb, val); - goto bin_retry; - } - - switch (*p) { - case 'o': - base = 8; break; - case 'x': - case 'X': - base = 16; break; - case 'b': - case 'B': - base = 2; break; - case 'u': - case 'd': - case 'i': - default: - base = 10; break; - } - - if (base == 2) { - org_v = v; - if ( v < 0 && !sign ) { - val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); - dots = 1; - } - else { - val = mrb_fix2str(mrb, mrb_fixnum_value(v), base); - } - v = mrb_fixnum(mrb_str_to_inum(mrb, val, 10, 0/*Qfalse*/)); - } - if (sign) { - char c = *p; - if (c == 'i') c = 'd'; /* %d and %i are identical */ - if (base == 2) c = 'd'; - if (v < 0) { - v = -v; - sc = '-'; - width--; - } - else if (flags & FPLUS) { - sc = '+'; - width--; - } - else if (flags & FSPACE) { - sc = ' '; - width--; - } - snprintf(fbuf, sizeof(fbuf), "%%l%c", c); - snprintf(nbuf, sizeof(nbuf), fbuf, v); - s = nbuf; - } - else { - char c = *p; - if (c == 'X') c = 'x'; - if (base == 2) c = 'd'; - s = nbuf; - if (v < 0) { - dots = 1; - } - snprintf(fbuf, sizeof(fbuf), "%%l%c", c); - snprintf(++s, sizeof(nbuf) - 1, fbuf, v); - if (v < 0) { - char d; - - s = remove_sign_bits(s, base); - switch (base) { - case 16: d = 'f'; break; - case 8: d = '7'; break; - case 2: d = '1'; break; - default: d = 0; break; - } - - if (d && *s != d) { - *--s = d; - } - } - } - len = (int)strlen(s); - - if (dots) { - prec -= 2; - width -= 2; - } - - if (*p == 'X') { - char *pp = s; - int c; - while ((c = (int)(unsigned char)*pp) != 0) { - *pp = toupper(c); - pp++; - } - } - - if (prefix && !prefix[1]) { /* octal */ - if (dots) { - prefix = 0; - } - else if (len == 1 && *s == '0') { - len = 0; - if (flags & FPREC) prec--; - } - else if ((flags & FPREC) && (prec > len)) { - prefix = 0; - } - } - else if (len == 1 && *s == '0') { - prefix = 0; - } - - if (prefix) { - width -= (int)strlen(prefix); - } - - if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) { - prec = width; - width = 0; - } - else { - if (prec < len) { - if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0; - prec = len; - } - width -= prec; - } - - if (!(flags&FMINUS)) { - CHECK(width); - while (width-- > 0) { - buf[blen++] = ' '; - } - } - - if (sc) PUSH(&sc, 1); - - if (prefix) { - int plen = (int)strlen(prefix); - PUSH(prefix, plen); - } - CHECK(prec - len); - if (dots) PUSH("..", 2); - - if (v < 0 || (base == 2 && org_v < 0)) { - char c = sign_bits(base, p); - while (len < prec--) { - buf[blen++] = c; - } - } - else if ((flags & (FMINUS|FPREC)) != FMINUS) { - char c = '0'; - while (len < prec--) { - buf[blen++] = c; - } - } - - PUSH(s, len); - CHECK(width); - while (width-- > 0) { - buf[blen++] = ' '; - } - } - break; - - case 'f': - case 'g': - case 'G': - case 'e': - case 'E': - case 'a': - case 'A': { - mrb_value val = GETARG(); - double fval; - int i, need = 6; - char fbuf[32]; - - fval = mrb_float(mrb_Float(mrb, val)); - if (isnan(fval) || isinf(fval)) { - const char *expr; - const int elen = 3; - - if (isnan(fval)) { - expr = "NaN"; - } - else { - expr = "Inf"; - } - need = elen; - if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS)) - need++; - if ((flags & FWIDTH) && need < width) - need = width; - - CHECK(need + 1); - n = snprintf(&buf[blen], need + 1, "%*s", need, ""); - if (flags & FMINUS) { - if (!isnan(fval) && fval < 0.0) - buf[blen++] = '-'; - else if (flags & FPLUS) - buf[blen++] = '+'; - else if (flags & FSPACE) - blen++; - memcpy(&buf[blen], expr, elen); - } - else { - if (!isnan(fval) && fval < 0.0) - buf[blen + need - elen - 1] = '-'; - else if (flags & FPLUS) - buf[blen + need - elen - 1] = '+'; - else if ((flags & FSPACE) && need > width) - blen++; - memcpy(&buf[blen + need - elen], expr, elen); - } - blen += strlen(&buf[blen]); - break; - } - - fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); - need = 0; - if (*p != 'e' && *p != 'E') { - i = INT_MIN; - frexp(fval, &i); - if (i > 0) - need = BIT_DIGITS(i); - } - need += (flags&FPREC) ? prec : 6; - if ((flags&FWIDTH) && need < width) - need = width; - need += 20; - - CHECK(need); - n = snprintf(&buf[blen], need, fbuf, fval); - blen += n; - } - break; - } - flags = FNONE; - } - - sprint_exit: -#if 0 - /* XXX - We cannot validate the number of arguments if (digit)$ style used. - */ - if (posarg >= 0 && nextarg < argc) { - const char *mesg = "too many arguments for format string"; - if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); - if (mrb_test(ruby_verbose)) mrb_warn("%s", mesg); - } -#endif - mrb_str_resize(mrb, result, blen); - - return result; -} - -static void -fmt_setup(char *buf, size_t size, int c, int flags, int width, int prec) -{ - char *end = buf + size; - int n; - - *buf++ = '%'; - if (flags & FSHARP) *buf++ = '#'; - if (flags & FPLUS) *buf++ = '+'; - if (flags & FMINUS) *buf++ = '-'; - if (flags & FZERO) *buf++ = '0'; - if (flags & FSPACE) *buf++ = ' '; - - if (flags & FWIDTH) { - n = snprintf(buf, end - buf, "%d", width); - buf += n; - } - - if (flags & FPREC) { - n = snprintf(buf, end - buf, ".%d", prec); - buf += n; - } - - *buf++ = c; - *buf = '\0'; -} - -#endif /* ENABLE_SPRINTF */ diff --git a/src/state.c b/src/state.c index 53773ac89..1936b8aab 100644 --- a/src/state.c +++ b/src/state.c @@ -72,7 +72,7 @@ mrb_alloca_free(mrb_state *mrb) } mrb_state* -mrb_open() +mrb_open(void) { mrb_state *mrb = mrb_open_allocf(allocf, NULL); @@ -110,6 +110,10 @@ mrb_close(mrb_state *mrb) mrb_free(mrb, mrb); } +#ifndef MRB_IREP_ARRAY_INIT_SIZE +# define MRB_IREP_ARRAY_INIT_SIZE (256u) +#endif + mrb_irep* mrb_add_irep(mrb_state *mrb) { @@ -117,7 +121,7 @@ mrb_add_irep(mrb_state *mrb) mrb_irep *irep; if (!mrb->irep) { - int max = 256; + size_t max = MRB_IREP_ARRAY_INIT_SIZE; if (mrb->irep_len > max) max = mrb->irep_len+1; mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*)); diff --git a/src/string.c b/src/string.c index 28cf0ab9a..23da3baa6 100644 --- a/src/string.c +++ b/src/string.c @@ -2056,7 +2056,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) char *end; char sign = 1; int c; - long len; unsigned long val; #undef ISDIGIT @@ -2113,30 +2112,25 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) } switch (base) { case 2: - len = 1; if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) { str += 2; } break; case 3: - len = 2; break; case 8: if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) { str += 2; } case 4: case 5: case 6: case 7: - len = 3; break; case 10: if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) { str += 2; } case 9: case 11: case 12: case 13: case 14: case 15: - len = 4; break; case 16: - len = 4; if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) { str += 2; } @@ -2145,12 +2139,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) if (base < 2 || 36 < base) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base); } - if (base <= 32) { - len = 5; - } - else { - len = 6; - } break; } /* end of switch (base) { */ if (*str == '0') { /* squeeze preceeding 0s */ @@ -2171,7 +2159,6 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) if (badcheck) goto bad; return mrb_fixnum_value(0); } - len *= strlen(str); val = strtoul((char*)str, &end, base); diff --git a/src/variable.c b/src/variable.c index 5f657e3d7..d5331f844 100644 --- a/src/variable.c +++ b/src/variable.c @@ -753,7 +753,7 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) struct RClass *c = mrb->ci->proc->target_class; if (!c) c = mrb->ci->target_class; - + return mrb_mod_cv_get(mrb, c, sym); } |
