From: nobu.nakada@... Date: 2002-10-22T18:56:43+09:00 Subject: [ruby-dev:18557] Re: symbol literal with non-alphanumeric なかだです。 At Tue, 22 Oct 2002 00:00:48 +0900, Yukihiro Matsumoto wrote: > |> * :".."形式で式展開を許すか(許したほうが一貫性がある?) > | > |やっぱり使えたほうがいいでしょうか。NODEを追加したほうがいいの > |かも知れませんが、とりあえず[ruby-dev:18537]への追加です。 > > 使えた方が良いでしょう。NODE_CALLを使うよりは専用のNODEを用 > 意したほうが良いのかなあ。 あと、Symbol#inspectも忘れてました。 いささか手抜きっぽいですが、こんなとこでしょうか。 Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.342 diff -u -2 -p -r1.342 eval.c --- eval.c 17 Oct 2002 16:13:44 -0000 1.342 +++ eval.c 22 Oct 2002 08:49:13 -0000 @@ -3090,4 +3090,5 @@ rb_eval(self, n) case NODE_DREGX: case NODE_DREGX_ONCE: + case NODE_DSYM: { VALUE str, str2; @@ -3124,4 +3125,7 @@ rb_eval(self, n) result = rb_funcall(self, '`', 1, str); break; + case NODE_DSYM: + result = rb_str_intern(str); + break; default: result = str; Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.97 diff -u -2 -p -r1.97 intern.h --- intern.h 23 Sep 2002 15:48:42 -0000 1.97 +++ intern.h 22 Oct 2002 09:52:57 -0000 @@ -298,4 +298,5 @@ int rb_is_instance_id _((ID)); int rb_is_class_id _((ID)); int rb_is_local_id _((ID)); +int rb_is_junk_id _((ID)); VALUE rb_backref_get _((void)); void rb_backref_set _((VALUE)); @@ -381,8 +382,10 @@ VALUE rb_str_upto _((VALUE, VALUE, int)) void rb_str_update _((VALUE, long, long, VALUE)); VALUE rb_str_inspect _((VALUE)); +VALUE rb_str_dump _((VALUE)); VALUE rb_str_split _((VALUE, const char*)); void rb_str_associate _((VALUE, VALUE)); VALUE rb_str_associated _((VALUE)); void rb_str_setter _((VALUE, ID, VALUE*)); +VALUE rb_str_intern _((VALUE)); /* struct.c */ VALUE rb_struct_new __((VALUE, ...)); Index: node.h =================================================================== RCS file: /cvs/ruby/src/ruby/node.h,v retrieving revision 1.33 diff -u -2 -p -r1.33 node.h --- node.h 27 Aug 2002 08:27:11 -0000 1.33 +++ node.h 22 Oct 2002 08:50:51 -0000 @@ -123,4 +123,5 @@ enum node_type { NODE_MEMO, NODE_IFUNC, + NODE_DSYM, NODE_LAST }; @@ -295,4 +296,5 @@ typedef struct RNode { #define NEW_XSTR(s) rb_node_newnode(NODE_XSTR,s,0,0) #define NEW_DXSTR(s) rb_node_newnode(NODE_DXSTR,s,0,0) +#define NEW_DSYM(s) rb_node_newnode(NODE_DSYM,s,0,0) #define NEW_EVSTR(n) rb_node_newnode(NODE_EVSTR,0,(n),0) #define NEW_CALL(r,m,a) rb_node_newnode(NODE_CALL,r,m,a) Index: object.c =================================================================== RCS file: /cvs/ruby/src/ruby/object.c,v retrieving revision 1.90 diff -u -2 -p -r1.90 object.c --- object.c 17 Oct 2002 07:26:59 -0000 1.90 +++ object.c 22 Oct 2002 09:53:13 -0000 @@ -520,9 +520,14 @@ sym_inspect(sym) VALUE str; char *name; + ID id = SYM2ID(sym); - name = rb_id2name(SYM2ID(sym)); + name = rb_id2name(id); str = rb_str_new(0, strlen(name)+1); RSTRING(str)->ptr[0] = ':'; strcpy(RSTRING(str)->ptr+1, name); + if (rb_is_junk_id(id)) { + str = rb_str_dump(str); + strncpy(RSTRING(str)->ptr, ":\"", 2); + } return str; } Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.223 diff -u -2 -p -r1.223 parse.y --- parse.y 18 Oct 2002 14:13:41 -0000 1.223 +++ parse.y 22 Oct 2002 09:40:55 -0000 @@ -49,4 +49,5 @@ #define is_const_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CONST) #define is_class_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_CLASS) +#define is_junk_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_JUNK) #define is_asgn_or_id(id) ((is_notop_id(id)) && \ @@ -239,5 +240,5 @@ static void top_local_setup(); %type string_contents xstring_contents string_content %type words qwords word_list qword_list word -%type literal numeric +%type literal numeric dsym %type bodystmt compstmt stmts stmt expr arg primary command command_call method_call %type expr_value arg_value primary_value @@ -1741,4 +1742,5 @@ literal : numeric $$ = NEW_LIT(ID2SYM($1)); } + | dsym ; @@ -1958,4 +1960,29 @@ sym : fname ; +dsym : tSYMBEG xstring_contents tSTRING_END + { + lex_state = EXPR_END; + if (!$2) { + yyerror("empty symbol literal"); + } + else { + $$ = $2; + switch (nd_type($$)) { + case NODE_STR: + $$->nd_lit = ID2SYM(rb_intern(RSTRING($$->nd_lit)->ptr)); + nd_set_type($$, NODE_LIT); + break; + case NODE_DSTR: + nd_set_type($$, NODE_DSYM); + break; + default: + $$ = rb_node_newnode(NODE_DSYM, rb_str_new(0, 0), + 1, NEW_LIST($$)); + break; + } + } + } + ; + numeric : tINTEGER | tFLOAT @@ -2771,4 +2798,5 @@ regx_options() #define STR_FUNC_REGEXP 0x04 #define STR_FUNC_QWORDS 0x08 +#define STR_FUNC_SYMBOL 0x10 #define STR_FUNC_INDENT 0x20 @@ -2780,4 +2808,6 @@ enum string_type { str_sword = (STR_FUNC_QWORDS), str_dword = (STR_FUNC_QWORDS|STR_FUNC_EXPAND), + str_ssym = (STR_FUNC_SYMBOL), + str_dsym = (STR_FUNC_SYMBOL|STR_FUNC_EXPAND), }; @@ -2852,4 +2882,9 @@ tokadd_string(func, term, paren) break; } + if (!c && (func & STR_FUNC_SYMBOL)) { + func &= ~STR_FUNC_SYMBOL; + rb_compile_error("symbol cannot contain '\\0'"); + continue; + } tokadd(c); } @@ -3763,9 +3798,20 @@ yylex() return tCOLON2; } - pushback(c); if (lex_state == EXPR_END || lex_state == EXPR_ENDARG || ISSPACE(c)) { + pushback(c); lex_state = EXPR_BEG; return ':'; } + switch (c) { + case '\'': + lex_strterm = NEW_STRTERM(str_ssym, c, 0); + break; + case '"': + lex_strterm = NEW_STRTERM(str_dsym, c, 0); + break; + default: + pushback(c); + break; + } lex_state = EXPR_FNAME; return tSYMBEG; @@ -3969,4 +4015,9 @@ yylex() return tREGEXP_BEG; + case 's': + lex_strterm = NEW_STRTERM(str_ssym, term, paren); + lex_state = EXPR_FNAME; + return tSYMBEG; + default: yyerror("unknown type of %string"); @@ -5603,4 +5654,12 @@ rb_is_local_id(id) { if (is_local_id(id)) return Qtrue; + return Qfalse; +} + +int +rb_is_junk_id(id) + ID id; +{ + if (is_junk_id(id)) return Qtrue; return Qfalse; } Index: string.c =================================================================== RCS file: /cvs/ruby/src/ruby/string.c,v retrieving revision 1.121 diff -u -2 -p -r1.121 string.c --- string.c 25 Sep 2002 07:03:01 -0000 1.121 +++ string.c 22 Oct 2002 09:52:50 -0000 @@ -1874,5 +1874,5 @@ rb_str_inspect(str) } -static VALUE +VALUE rb_str_dump(str) VALUE str; @@ -3004,5 +3004,5 @@ rb_str_crypt(str, salt) } -static VALUE +VALUE rb_str_intern(str) VALUE str; -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦