Index: parse.y =================================================================== --- parse.y (revision 22458) +++ parse.y (working copy) @@ -91,6 +91,7 @@ static enum lex_state { EXPR_FNAME, /* ignore newline, no reserved words. */ EXPR_DOT, /* right after `.' or `::', no reserved words. */ EXPR_CLASS, /* immediate after `class', no here document. */ + EXPR_VALUE /* alike EXPR_BEG but label is disallowed. */ } lex_state; static NODE *lex_strterm; @@ -267,7 +268,7 @@ static void fixup_nodes(); k__LINE__ k__FILE__ -%token tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR +%token tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL %token tINTEGER tFLOAT tSTRING_CONTENT %token tNTH_REF tBACK_REF %token tREGEXP_END @@ -2504,6 +2505,10 @@ assoc : arg_value tASSOC arg_value { $$ = list_append(NEW_LIST($1), $3); } + | tLABEL arg_value + { + $$ = list_append(NEW_LIST(NEW_LIT(ID2SYM($1))), $2); + } ; operation : tIDENTIFIER @@ -3434,7 +3439,8 @@ arg_ambiguous() } #define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG) -#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || lex_state == EXPR_CLASS) +#define IS_BEG() (lex_state == EXPR_BEG || lex_state == EXPR_MID || \ + lex_state == EXPR_VALUE || lex_state == EXPR_CLASS) static int yylex() @@ -3491,6 +3497,7 @@ yylex() case EXPR_FNAME: case EXPR_DOT: case EXPR_CLASS: + case EXPR_VALUE: goto retry; default: break; @@ -3673,7 +3680,7 @@ yylex() case '?': if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) { - lex_state = EXPR_BEG; + lex_state = EXPR_VALUE; return '?'; } c = nextc(); @@ -3710,7 +3717,7 @@ yylex() } ternary: pushback(c); - lex_state = EXPR_BEG; + lex_state = EXPR_VALUE; return '?'; } else if (ismbchar(c)) { @@ -4526,6 +4533,17 @@ yylex() } } + if ((lex_state == EXPR_BEG && !cmd_state) || + lex_state == EXPR_ARG || + lex_state == EXPR_CMDARG) { + if (peek(':') && !(lex_p + 1 < lex_pend && lex_p[1] == ':')) { + lex_state = EXPR_BEG; + nextc(); + yylval.id = rb_intern(tok()); + return tLABEL; + } + } + if (lex_state != EXPR_DOT) { const struct kwtable *kw; @@ -4547,7 +4565,7 @@ yylex() return kDO_BLOCK; return kDO; } - if (state == EXPR_BEG) + if (state == EXPR_BEG || state == EXPR_VALUE) return kw->id[0]; else { if (kw->id[0] != kw->id[1]) @@ -4557,12 +4575,9 @@ yylex() } } - if (lex_state == EXPR_BEG || - lex_state == EXPR_MID || + if (IS_BEG() || lex_state == EXPR_DOT || - lex_state == EXPR_ARG || - lex_state == EXPR_CLASS || - lex_state == EXPR_CMDARG) { + IS_ARG()) { if (cmd_state) { lex_state = EXPR_CMDARG; } Index: NEWS =================================================================== --- NEWS (revision 22458) +++ NEWS (working copy) @@ -18,6 +18,21 @@ with all sufficient information, see the specific directories such as library directories, ri directories and gem directories. +=== Language core changes + +* new syntax + + * New literal syntax for hash is introduced, which is also + applicable to hash style arguments. + + colormap = { apple: 'red', banana: 'yellow', melon: 'green' } + FileUtils.mkdir 'tmp', mode: 0700 + + The lines above are equivalent to the lines below: + + colormap = { :apple => 'red', :banana => 'yellow', :melon => 'green' } + FileUtils.mkdir 'tmp', :mode => 0700 + === Library updates (outstanding ones only) * builtin classes Index: ChangeLog =================================================================== --- ChangeLog (revision 22458) +++ ChangeLog (working copy) @@ -1,3 +1,9 @@ +Thu Feb 19 17:32:59 2009 Akinori MUSHA + + * parse.y: Backport the new literal syntax for hash and hash style + arguments; based on the patch by Brent Roman + in [ruby-core:21984]. + Thu Feb 19 14:22:02 2009 Nobuyoshi Nakada * lib/mkmf.rb (create_makefile): added phony targets.