From 7a78ecb14ce2d28f3f99c19eacbbdff5b385e3a8 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 17:04:23 +0900 Subject: Optimize OP_ADD instruction. --- src/vm.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/vm.c b/src/vm.c index 8ae0c1612..ff5d7b829 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1403,7 +1403,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) #define attr_f value.f #endif -#define TYPES2(a,b) (((((int)(a))<<8)|((int)(b)))&0xffff) +#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) #define OP_MATH_BODY(op,v1,v2) do {\ regs[a].v1 = regs[a].v1 op regs[a+1].v2;\ } while(0) @@ -1417,16 +1417,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): { mrb_int x, y, z; + mrb_value *regs_a = regs + a; - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); + x = mrb_fixnum(regs_a[0]); + y = mrb_fixnum(regs_a[1]); z = x + y; - if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { + if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) { /* integer overflow */ - SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y); - break; + SET_FLT_VALUE(regs_a[0], (mrb_float)x + (mrb_float)y); + } + else { + regs_a[0].attr_i = z; } - SET_INT_VALUE(regs[a], z); } break; case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): -- cgit v1.2.3 From b8982c442f4af853583868aea8343b7831e68fbb Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 17:29:43 +0900 Subject: Optimize OP_SUBI. --- src/vm.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/vm.c b/src/vm.c index ff5d7b829..611d9c224 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1600,28 +1600,30 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_SUBI) { /* A B C R(A) := R(A)-C (Syms[B]=:+)*/ int a = GETARG_A(i); + mrb_value *regs_a = regs + a; /* need to check if + is overridden */ - switch (mrb_type(regs[a])) { + switch (mrb_type(regs_a[0])) { case MRB_TT_FIXNUM: { - mrb_int x = regs[a].attr_i; + mrb_int x = regs_a[0].attr_i; mrb_int y = GETARG_C(i); mrb_int z = x - y; - if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) { + if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) { /* integer overflow */ - SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); - break; + SET_FLT_VALUE(regs_a[0], (mrb_float)x - (mrb_float)y); + } + else { + regs_a[0].attr_i = z; } - regs[a].attr_i = z; } break; case MRB_TT_FLOAT: - regs[a].attr_f -= GETARG_C(i); + regs_a[0].attr_f -= GETARG_C(i); break; default: - SET_INT_VALUE(regs[a+1], GETARG_C(i)); + SET_INT_VALUE(regs_a[1], GETARG_C(i)); i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1); goto L_SEND; } -- cgit v1.2.3 From 37263e50e5ad833d6d8faf4abf4c2616788446a1 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 22:03:00 +0900 Subject: Remove mrb_checkstack() as unused. --- include/mruby.h | 1 - src/vm.c | 7 ------- 2 files changed, 8 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index 4e4751c38..84aeff0d7 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -209,7 +209,6 @@ mrb_state* mrb_open(void); mrb_state* mrb_open_allocf(mrb_allocf, void *ud); void mrb_irep_free(mrb_state*, struct mrb_irep*); void mrb_close(mrb_state*); -int mrb_checkstack(mrb_state*,int); mrb_value mrb_top_self(mrb_state *); mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value); diff --git a/src/vm.c b/src/vm.c index 611d9c224..2c579a01d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -170,13 +170,6 @@ stack_extend(mrb_state *mrb, int room, int keep) } } -int -mrb_checkstack(mrb_state *mrb, int size) -{ - stack_extend(mrb, size+1, 1); - return 0; -} - struct REnv* uvenv(mrb_state *mrb, int up) { -- cgit v1.2.3 From 4a17b3d908543fe97365904a3549be7478d7cf2f Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 22:04:17 +0900 Subject: Make some tiny functions inlined. This is for supeed tuning. --- src/vm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vm.c b/src/vm.c index 2c579a01d..640228371 100644 --- a/src/vm.c +++ b/src/vm.c @@ -108,7 +108,7 @@ stack_init(mrb_state *mrb) mrb->ci->target_class = mrb->object_class; } -static void +static inline void envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) { mrb_callinfo *ci = mrb->cibase; @@ -170,7 +170,7 @@ stack_extend(mrb_state *mrb, int room, int keep) } } -struct REnv* +static inline struct REnv* uvenv(mrb_state *mrb, int up) { struct REnv *e = mrb->ci->proc->env; -- cgit v1.2.3 From 1272d5fe0c803d06ff2eb62a65bab817b1fb2f6d Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 22:11:43 +0900 Subject: Extract uvget/uvset to OP_GETUPVAR/OP_SETUPVAR. This is for speed tuning. --- src/vm.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/vm.c b/src/vm.c index 640228371..42fdedf80 100644 --- a/src/vm.c +++ b/src/vm.c @@ -182,25 +182,6 @@ uvenv(mrb_state *mrb, int up) return e; } -static mrb_value -uvget(mrb_state *mrb, int up, int idx) -{ - struct REnv *e = uvenv(mrb, up); - - if (!e) return mrb_nil_value(); - return e->stack[idx]; -} - -static void -uvset(mrb_state *mrb, int up, int idx, mrb_value v) -{ - struct REnv *e = uvenv(mrb, up); - - if (!e) return; - e->stack[idx] = v; - mrb_write_barrier(mrb, (struct RBasic*)e); -} - static inline int is_strict(mrb_state *mrb, struct REnv *e) { @@ -730,14 +711,34 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_GETUPVAR) { /* A B C R(A) := uvget(B,C) */ + mrb_value *regs_a = regs + GETARG_A(i); + int up = GETARG_C(i); - regs[GETARG_A(i)] = uvget(mrb, GETARG_C(i), GETARG_B(i)); + struct REnv *e = uvenv(mrb, up); + + if (!e) { + *regs_a = mrb_nil_value(); + } + else { + int idx = GETARG_B(i); + *regs_a = e->stack[idx]; + } NEXT; } CASE(OP_SETUPVAR) { /* A B C uvset(B,C,R(A)) */ - uvset(mrb, GETARG_C(i), GETARG_B(i), regs[GETARG_A(i)]); + /* A B C R(A) := uvget(B,C) */ + int up = GETARG_C(i); + + struct REnv *e = uvenv(mrb, up); + + if (e) { + mrb_value *regs_a = regs + GETARG_A(i); + int idx = GETARG_B(i); + e->stack[idx] = *regs_a; + mrb_write_barrier(mrb, (struct RBasic*)e); + } NEXT; } -- cgit v1.2.3 From d7c6ebfc918771e9fc14fd292e76eb0fb5833212 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 22:52:57 +0900 Subject: Make topenv() inlined. --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index 42fdedf80..e10988cff 100644 --- a/src/vm.c +++ b/src/vm.c @@ -194,7 +194,7 @@ is_strict(mrb_state *mrb, struct REnv *e) return 0; } -struct REnv* +inline struct REnv* top_env(mrb_state *mrb, struct RProc *proc) { struct REnv *e = proc->env; -- cgit v1.2.3 From f3db33781426415412645d60e178cfa4f40e5ea9 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 22:56:45 +0900 Subject: Clean some redundant code up. --- src/vm.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/vm.c b/src/vm.c index e10988cff..ccfaff175 100644 --- a/src/vm.c +++ b/src/vm.c @@ -870,9 +870,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], sym); } else { - value_move(regs+a+2, regs+a+1, n+1); + value_move(regs+a+2, regs+a+1, ++n); regs[a+1] = sym; - n++; } } @@ -1009,9 +1008,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); } else { - value_move(regs+a+2, regs+a+1, n+1); + value_move(regs+a+2, regs+a+1, ++n); SET_SYM_VALUE(regs[a+1], ci->mid); - n++; } } @@ -1328,9 +1326,8 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) mrb_ary_unshift(mrb, regs[a+1], sym); } else { - value_move(regs+a+2, regs+a+1, n+1); + value_move(regs+a+2, regs+a+1, ++n); regs[a+1] = sym; - n++; } } -- cgit v1.2.3 From 632875a61847a16beff5159bbf67e1bbee5bc91f Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 23:04:31 +0900 Subject: Lazy variable declarations. They are for speed tune. --- src/vm.c | 133 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/src/vm.c b/src/vm.c index ccfaff175..1179c6113 100644 --- a/src/vm.c +++ b/src/vm.c @@ -129,8 +129,9 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) static void stack_extend(mrb_state *mrb, int room, int keep) { - int size, off; if (mrb->stack + room >= mrb->stend) { + int size, off; + mrb_value *oldbase = mrb->stbase; size = mrb->stend - mrb->stbase; @@ -275,14 +276,13 @@ mrb_value mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) { mrb_sym mid = mrb_intern(mrb, name); - va_list ap; - int i; if (argc == 0) { return mrb_funcall_argv(mrb, self, mid, 0, 0); } else if (argc == 1) { mrb_value v; + va_list ap; va_start(ap, argc); v = va_arg(ap, mrb_value); @@ -291,6 +291,8 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) } else { mrb_value argv[MRB_FUNCALL_ARGC_MAX]; + va_list ap; + int i; if (argc > MRB_FUNCALL_ARGC_MAX) { mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX); @@ -308,11 +310,6 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk) { - struct RProc *p; - struct RClass *c; - mrb_sym undef = 0; - mrb_callinfo *ci; - int n; mrb_value val; if (!mrb->jmp) { @@ -325,66 +322,74 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr cipop(mrb); } mrb->jmp = 0; - return mrb_nil_value(); + val = mrb_nil_value(); + } + else { + mrb->jmp = &c_jmp; + /* recursive call */ + val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); + mrb->jmp = 0; } - mrb->jmp = &c_jmp; - /* recursive call */ - val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk); - mrb->jmp = 0; - return val; - } - - if (!mrb->stack) { - stack_init(mrb); - } - n = mrb->ci->nregs; - if (argc < 0) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc); - } - c = mrb_class(mrb, self); - p = mrb_method_search_vm(mrb, &c, mid); - if (!p) { - undef = mid; - mid = mrb_intern(mrb, "method_missing"); - p = mrb_method_search_vm(mrb, &c, mid); - n++; argc++; - } - ci = cipush(mrb); - ci->mid = mid; - ci->proc = p; - ci->stackidx = mrb->stack - mrb->stbase; - ci->argc = argc; - ci->target_class = p->target_class; - if (MRB_PROC_CFUNC_P(p)) { - ci->nregs = argc + 2; } else { - ci->nregs = p->body.irep->nregs + 2; - } - ci->acc = -1; - mrb->stack = mrb->stack + n; - - stack_extend(mrb, ci->nregs, 0); - mrb->stack[0] = self; - if (undef) { - mrb->stack[1] = mrb_symbol_value(undef); - stack_copy(mrb->stack+2, argv, argc-1); - } - else if (argc > 0) { - stack_copy(mrb->stack+1, argv, argc); - } - mrb->stack[argc+1] = blk; + struct RProc *p; + struct RClass *c; + mrb_sym undef = 0; + mrb_callinfo *ci; + int n; - if (MRB_PROC_CFUNC_P(p)) { - int ai = mrb_gc_arena_save(mrb); - val = p->body.func(mrb, self); - mrb_gc_arena_restore(mrb, ai); - mrb_gc_protect(mrb, val); - mrb->stack = mrb->stbase + mrb->ci->stackidx; - cipop(mrb); - } - else { - val = mrb_run(mrb, p, self); + if (!mrb->stack) { + stack_init(mrb); + } + n = mrb->ci->nregs; + if (argc < 0) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc); + } + c = mrb_class(mrb, self); + p = mrb_method_search_vm(mrb, &c, mid); + if (!p) { + undef = mid; + mid = mrb_intern(mrb, "method_missing"); + p = mrb_method_search_vm(mrb, &c, mid); + n++; argc++; + } + ci = cipush(mrb); + ci->mid = mid; + ci->proc = p; + ci->stackidx = mrb->stack - mrb->stbase; + ci->argc = argc; + ci->target_class = p->target_class; + if (MRB_PROC_CFUNC_P(p)) { + ci->nregs = argc + 2; + } + else { + ci->nregs = p->body.irep->nregs + 2; + } + ci->acc = -1; + mrb->stack = mrb->stack + n; + + stack_extend(mrb, ci->nregs, 0); + mrb->stack[0] = self; + if (undef) { + mrb->stack[1] = mrb_symbol_value(undef); + stack_copy(mrb->stack+2, argv, argc-1); + } + else if (argc > 0) { + stack_copy(mrb->stack+1, argv, argc); + } + mrb->stack[argc+1] = blk; + + if (MRB_PROC_CFUNC_P(p)) { + int ai = mrb_gc_arena_save(mrb); + val = p->body.func(mrb, self); + mrb_gc_arena_restore(mrb, ai); + mrb_gc_protect(mrb, val); + mrb->stack = mrb->stbase + mrb->ci->stackidx; + cipop(mrb); + } + else { + val = mrb_run(mrb, p, self); + } } return val; } -- cgit v1.2.3 From 3f3568a2c8e809578bd028a1f4cdbea847b7f08a Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Mon, 18 Mar 2013 23:07:17 +0900 Subject: Simplify conditional expressions. This is for speed tuning. --- src/vm.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/vm.c b/src/vm.c index 1179c6113..881acf4fc 100644 --- a/src/vm.c +++ b/src/vm.c @@ -885,8 +885,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci->mid = mid; ci->proc = m; ci->stackidx = mrb->stack - mrb->stbase; - ci->argc = n; - if (ci->argc == CALL_MAXARGS) ci->argc = -1; + if (n == CALL_MAXARGS) { + ci->argc = -1; + } + else { + ci->argc = n; + } ci->target_class = c; ci->pc = pc + 1; ci->acc = a; @@ -1023,8 +1027,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci->mid = mid; ci->proc = m; ci->stackidx = mrb->stack - mrb->stbase; - ci->argc = n; - if (ci->argc == CALL_MAXARGS) ci->argc = -1; + if (n == CALL_MAXARGS) { + ci->argc = -1; + } + else { + ci->argc = n; + } ci->target_class = m->target_class; ci->pc = pc + 1; @@ -1051,7 +1059,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) pool = irep->pool; syms = irep->syms; ci->nregs = irep->nregs; - if (ci->argc < 0) { + if (n == CALL_MAXARGS) { stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3); } else { @@ -1341,8 +1349,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci = mrb->ci; ci->mid = mid; ci->target_class = m->target_class; - ci->argc = n; - if (ci->argc == CALL_MAXARGS) ci->argc = -1; + if (n == CALL_MAXARGS) { + ci->argc = -1; + } + else { + ci->argc = n; + } /* move stack */ value_move(mrb->stack, ®s[a], ci->argc+1); -- cgit v1.2.3 From cdf8114e27288612139b544a6dea34e33217c88c Mon Sep 17 00:00:00 2001 From: FUKUZAWA-Tadashi Date: Thu, 14 Mar 2013 23:05:05 +0900 Subject: %I %i literal --- include/mruby/compile.h | 16 +++++++++------- src/codegen.c | 4 ++++ src/node.h | 1 + src/parse.y | 30 ++++++++++++++++++++++++++++-- test/t/literals.rb | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 89 insertions(+), 10 deletions(-) diff --git a/include/mruby/compile.h b/include/mruby/compile.h index 4b12cb10c..8b0743fa3 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -68,13 +68,15 @@ struct mrb_parser_message { enum mrb_string_type { str_not_parsing = (0), - str_squote = (STR_FUNC_PARSING), - str_dquote = (STR_FUNC_PARSING|STR_FUNC_EXPAND), - str_regexp = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND), - str_sword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY), - str_dword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND), - str_ssym = (STR_FUNC_PARSING|STR_FUNC_SYMBOL), - str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC), + str_squote = (STR_FUNC_PARSING), + str_dquote = (STR_FUNC_PARSING|STR_FUNC_EXPAND), + str_regexp = (STR_FUNC_PARSING|STR_FUNC_REGEXP|STR_FUNC_EXPAND), + str_sword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY), + str_dword = (STR_FUNC_PARSING|STR_FUNC_WORD|STR_FUNC_ARRAY|STR_FUNC_EXPAND), + str_ssym = (STR_FUNC_PARSING|STR_FUNC_SYMBOL), + str_ssymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY), + str_dsymbols = (STR_FUNC_PARSING|STR_FUNC_SYMBOL|STR_FUNC_ARRAY|STR_FUNC_EXPAND), + str_heredoc = (STR_FUNC_PARSING|STR_FUNC_HEREDOC), }; /* heredoc structure */ diff --git a/src/codegen.c b/src/codegen.c index 992275052..7a91d597d 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2027,6 +2027,10 @@ codegen(codegen_scope *s, node *tree, int val) gen_literal_array(s, tree, FALSE, val); break; + case NODE_SYMBOLS: + gen_literal_array(s, tree, TRUE, val); + break; + case NODE_REGX: if (val) { char *p1 = (char*)tree->car; diff --git a/src/node.h b/src/node.h index bcf02e8ff..4f9db8265 100644 --- a/src/node.h +++ b/src/node.h @@ -108,6 +108,7 @@ enum node_type { NODE_HEREDOC, NODE_LITERAL_DELIM, NODE_WORDS, + NODE_SYMBOLS, NODE_LAST }; diff --git a/src/parse.y b/src/parse.y index 33688e45a..ee95cfb73 100644 --- a/src/parse.y +++ b/src/parse.y @@ -763,6 +763,13 @@ new_words(parser_state *p, node *a) return cons((node*)NODE_WORDS, a); } +// (:symbols . a) +static node* +new_symbols(parser_state *p, node *a) +{ + return cons((node*)NODE_SYMBOLS, a); +} + // xxx ----------------------------- // (:call a op) @@ -991,7 +998,7 @@ heredoc_end(parser_state *p) %type mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner %type fsym sym basic_symbol operation operation2 operation3 %type cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg -%type heredoc words +%type heredoc words symbols %token tUPLUS /* unary+ */ %token tUMINUS /* unary- */ @@ -1020,7 +1027,7 @@ heredoc_end(parser_state *p) %token tSTAR /* * */ %token tAMPER /* & */ %token tLAMBDA /* -> */ -%token tSYMBEG tREGEXP_BEG tWORDS_BEG +%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG %token tSTRING_BEG tSTRING_DVAR tLAMBEG %token tHEREDOC_BEG /* <<, <<- */ %token tHEREDOC_END tLITERAL_DELIM @@ -2535,6 +2542,7 @@ opt_ensure : keyword_ensure compstmt literal : numeric | symbol | words + | symbols ; string : tCHAR @@ -2653,6 +2661,16 @@ sym : fname } ; +symbols : tSYMBOLS_BEG tSTRING + { + $$ = new_symbols(p, list1($2)); + } + | tSYMBOLS_BEG string_rep tSTRING + { + $$ = new_symbols(p, push($2, $3)); + } + ; + numeric : tINTEGER | tFLOAT | tUMINUS_NUM tINTEGER %prec tLOWEST @@ -4625,6 +4643,14 @@ parser_yylex(parser_state *p) p->lex_strterm = new_strterm(p, str_ssym, term, paren); return tSYMBEG; + case 'I': + p->lex_strterm = new_strterm(p, str_dsymbols, term, paren); + return tSYMBOLS_BEG; + + case 'i': + p->lex_strterm = new_strterm(p, str_ssymbols, term, paren); + return tSYMBOLS_BEG; + default: yyerror(p, "unknown type of %string"); return 0; diff --git a/test/t/literals.rb b/test/t/literals.rb index 5a29cff0c..f40852ff9 100644 --- a/test/t/literals.rb +++ b/test/t/literals.rb @@ -186,8 +186,54 @@ d test1 and test2 end +assert('Literals Array of symbols') do + a = %I{abc#{1+2}def \}g} + b = %I(abc #{2+3} def \(g) + c = %I[#{3+4}] + d = %I< #{4+5} > + e = %I// + f = %I[[ab cd][ef]] + g = %I{ + ab + #{-1}1 + 2#{2} + } + + test1 = (a == [:'abc3def', :'}g'] and + b == [:'abc', :'5', :'def', :'(g'] and + c == [:'7'] and + d == [:'9'] and + e == [] and + f == [:'[ab', :'cd][ef]'] and + g == [:'ab', :'-11', :'22'] + ) + + a = %i{abc#{1+2}def \}g} + b = %i(abc #{2+3} def \(g) + c = %i[#{3+4}] + d = %i< #{4+5} > + e = %i// + f = %i[[ab cd][ef]] + g = %i{ + ab + #{-1}1 + 2#{2} + } + + test2 = (a == [:'abc#{1+2}def', :'}g'] and + b == [:'abc', :'#{2+3}', :'def', :'(g'] and + c == [:'#{3+4}'] and + d == [:'#{4+5}'] and + e == [] and + f == [:'[ab', :'cd][ef]'] and + g == [:'ab', :'#{-1}1', :'2#{2}'] + ) + + test1 and test2 +end + assert('Literals Symbol', '8.7.6.6') do - /* do not compile error */ + # do not compile error :$asd :@asd :@@asd -- cgit v1.2.3