何がうれしいの
- わざわざ"function"という長いキーワードを入力しなくて済む
- 記号だけで関数が記述できる
- ソースコードからアルファベットや数字を除外できる
- アルファベットや数字を読めない子供にやさしい
->って元々はRight Assignmentですよね
Right Assignmentはなかったことになった.
パッチ
パッチは以下の通り.このパッチでRのソースファイルsrc/main/gram.yを修正してRをコンパイルすると,->(){}で関数が書けるようになる.R 2.12.1で動作確認済.
*** R-2.12.1.org/src/main/gram.y 2010-09-17 07:02:24.000000000 +0900 --- R-2.12.1/src/main/gram.y 2011-01-19 17:39:26.000000000 +0900 *************** *** 215,221 **** %token END_OF_INPUT ERROR %token STR_CONST NUM_CONST NULL_CONST SYMBOL FUNCTION ! %token LEFT_ASSIGN EQ_ASSIGN RIGHT_ASSIGN LBB %token FOR IN IF ELSE WHILE NEXT BREAK REPEAT %token GT GE LT LE EQ NE AND OR AND2 OR2 %token NS_GET NS_GET_INT --- 215,221 ---- %token END_OF_INPUT ERROR %token STR_CONST NUM_CONST NULL_CONST SYMBOL FUNCTION ! %token LEFT_ASSIGN EQ_ASSIGN /*RIGHT_ASSIGN*/ LBB %token FOR IN IF ELSE WHILE NEXT BREAK REPEAT %token GT GE LT LE EQ NE AND OR AND2 OR2 %token NS_GET NS_GET_INT *************** *** 227,233 **** %left ELSE %right LEFT_ASSIGN %right EQ_ASSIGN ! %left RIGHT_ASSIGN %left '~' TILDE %left OR OR2 %left AND AND2 --- 227,233 ---- %left ELSE %right LEFT_ASSIGN %right EQ_ASSIGN ! /*%left RIGHT_ASSIGN*/ %left '~' TILDE %left OR OR2 %left AND AND2 *************** *** 295,301 **** | expr OR2 expr { $$ = xxbinary($2,$1,$3); } | expr LEFT_ASSIGN expr { $$ = xxbinary($2,$1,$3); } ! | expr RIGHT_ASSIGN expr { $$ = xxbinary($2,$3,$1); } | FUNCTION '(' formlist ')' cr expr_or_assign %prec LOW { $$ = xxdefun($1,$3,$6); } | expr '(' sublist ')' { $$ = xxfuncall($1,$3); } --- 295,301 ---- | expr OR2 expr { $$ = xxbinary($2,$1,$3); } | expr LEFT_ASSIGN expr { $$ = xxbinary($2,$1,$3); } ! /*| expr RIGHT_ASSIGN expr { $$ = xxbinary($2,$3,$1); }*/ | FUNCTION '(' formlist ')' cr expr_or_assign %prec LOW { $$ = xxdefun($1,$3,$6); } | expr '(' sublist ')' { $$ = xxfuncall($1,$3); } *************** *** 1533,1538 **** --- 1533,1539 ---- { "NA_character_", NUM_CONST }, { "NA_complex_", NUM_CONST }, { "function", FUNCTION }, + { "->", FUNCTION }, { "while", WHILE }, { "repeat", REPEAT }, { "for", FOR }, *************** *** 1687,1693 **** "NULL_CONST", "'NULL'", "FUNCTION", "'function'", "EQ_ASSIGN", "'='", ! "RIGHT_ASSIGN", "'->'", "LBB", "'[['", "FOR", "'for'", "IN", "'in'", --- 1688,1694 ---- "NULL_CONST", "'NULL'", "FUNCTION", "'function'", "EQ_ASSIGN", "'='", ! /*"RIGHT_ASSIGN", "'->'",*/ "LBB", "'[['", "FOR", "'for'", "IN", "'in'", *************** *** 2520,2533 **** return LT; case '-': if (nextchar('>')) { ! if (nextchar('>')) { ! yylval = install("<<-"); ! return RIGHT_ASSIGN; ! } ! else { ! yylval = install("<-"); ! return RIGHT_ASSIGN; } } yylval = install("-"); return '-'; --- 2521,2540 ---- return LT; case '-': if (nextchar('>')) { ! /* -> : function */ ! if (FunctionLevel >= MAXNEST) ! error(_("functions nested too deeply in source code at line %d"), ParseState.xxlineno); ! if ( FunctionLevel++ == 0 && GenerateCode) { ! strcpy((char *)FunctionSource, "function"); ! SourcePtr = FunctionSource + 8; } + FunctionStart[FunctionLevel] = SourcePtr - 8; + #if 0 + printf("%d,%d\n", SourcePtr - FunctionSource, FunctionLevel); + #endif + + yylval = install("function"); + return FUNCTION; } yylval = install("-"); return '-'; *************** *** 2764,2770 **** case '$': case '@': case LEFT_ASSIGN: ! case RIGHT_ASSIGN: case EQ_ASSIGN: EatLines = 1; break; --- 2771,2777 ---- case '$': case '@': case LEFT_ASSIGN: ! /*case RIGHT_ASSIGN:*/ case EQ_ASSIGN: EatLines = 1; break;
これをgram.y.patchなどのファイル名で保存して,以下のようにR 2.12.1のsrc/main/gram.yに適用する.また,コンパイルの前にsrc/main/gram.cを手動で削除しておく.
$ tar zxvf R-2.12.1.tar.gz $ cd R-2.12.1 $ patch -p1 < /path/to/gram.y.patch $ rm src/main/gram.c
あとはconfigureとmakeを実行すればOK.
注意点
パッチ適用後にmake checkするとfailします.
以上
Happy Symbolic Programming!!!