More Related Content
More from Nobukuni Kino (6)
Rのハラワタ
- 2. 自己紹介 誰:26歳で起業=人生の半分より前 過:K-Prolog Compiler を作りました。 過:S をBell Labs.と契約して、日本に持ってきました。(アイザック) 日本語化やGUI化をして売りました。(社員が) SやRから離れて、ん10年 故:大規模計算、大規模データ、Rが注目される時代になった 興:えさを与えて育てること Ex.天然酵母パン、味噌、ビール風飲料、ベンチャー企業 趣:ギャンブル=麻雀と人生 言語処理系がもともと専門、統計については知識なし
- 7. Rのトップレベル main.c: /* Read-Eval-Print Loop */ for(;;) { R_PPStackTop = savestack; R_CurrentExpr = R_Parse1File(fp, 1, &status, &ParseState); switch (status) { case PARSE_OK: ... PROTECT(R_CurrentExpr); R_CurrentExpr = eval(R_CurrentExpr, rho); SET_SYMVALUE(R_LastvalueSymbol, R_CurrentExpr); UNPROTECT(1); if (R_Visible) PrintValueEnv(R_CurrentExpr, rho); }
- 8. eval() 評価する式 eval.c SEXP eval(SEXP e, SEXP rho) switch (TYPEOF(e)) { case NILSXP: case LISTSXP: .... case LANGSXP: if (TYPEOF(CAR(e)) == SYMSXP) if (TYPEOF(op) == SPECIALSXP) { } 環境(どこで呼び出されたか、変数はどうなっているか) 教えて:rhoは何の略? 構文要素による場合分け
- 10. 関数の呼び出し 普通の関数の場合 PROTECT(op = findFun(CAR(e), rho)); PROTECT(tmp = promiseArgs(CDR(e), rho)); /* arglist */ SEXP applyClosure(SEXP call, SEXP op, SEXP arglist, SEXP rho, SEXP suppliedenv) SETJMP(cntxt.cjmpbuf) PROTECT(tmp = eval(body, newrho)) ・applyClosureは、引数を処理して関数本体をeval() ・return がlongjmpなので、setjmpを準備 return do_return(SEXP call, SEXP op, SEXP args, SEXP rho) findcontext(int mask, SEXP env, SEXP val) LONGJMP(cptr->cjmpbuf, mask);
- 12. 環境を作る SEXP NewEnvironment(SEXP namelist, SEXP valuelist, SEXP rho){ newrho->sxpinfo = UnmarkedNodeTemplate.sxpinfo; TYPEOF(newrho) = ENVSXP; FRAME(newrho) = valuelist; ENCLOS(newrho) = rho; HASHTAB(newrho) = R_NilValue; ATTRIB(newrho) = R_NilValue; v = valuelist; n = namelist; while (v != R_NilValue && n != R_NilValue) { SET_TAG(v, TAG(n)); v = CDR(v); n = CDR(n); } return (newrho); } actual formal
- 13. repeat,while repeatstatement do_repeat(SEXP call, SEXP op, SEXP args, SEXP rho) body = CAR(args); for (;;) { eval(body, rho); } while (statement1) statement2 do_while(SEXP call, SEXP op, SEXP args, SEXP rho) while (asLogicalNoNA(eval(CAR(args), rho), call)) { eval(body, rho); } ・繰り返し構文は、C言語レベルでも繰り返しで処理
- 14. for for (name in vector) statement1 do_for(SEXP call, SEXP op, SEXP args, SEXP rho) val = CADR(args); body = CADDR(args) if (isList(val) || isNull(val)) { n = length(val); PROTECT_WITH_INDEX(v = R_NilValue, &vpi); } else { n = LENGTH(val); PROTECT_WITH_INDEX(v = allocVector(TYPEOF(val), 1), &vpi); } for (i = 0; i < n; i++) { switch (TYPEOF(val)) { case LGLSXP: ... } REPROTECT(ans = eval(body, rho), api); } ・for文を処理してnを求め、本体をn回繰り返す
- 15. lapplyなど apply.c /* .Internal(lapply(X, FUN)) */ do_lapply(SEXP call, SEXP op, SEXP args, SEXP rho) PROTECT(XX = eval(CAR(args), rho)); FUN = CADR(args); /* must be unevaluated for use in e.g. bquote */ n = length(XX); .. PROTECT(R_fcall = LCONS(FUN, LCONS(tmp, LCONS(R_DotsSymbol, R_NilValue)))); for(i = 0; i < n; i++) { INTEGER(ind)[0] = i + 1; SET_VECTOR_ELT(ans, i, eval(R_fcall, rho)); } 要素を引数として繰り返し