repl.c あたり

面白いんですが整理が大変。とりあえず確認したのは Scm_ApplyRec 手続きからなんですが、ここでは引数で渡されたリストの要素を取り出しながら vm->vals 配列に格納して apply_rec 手続きを呼び出してます。
apply_rec 手続きの定義が以下。

static ScmObj apply_rec(ScmVM *vm, ScmObj proc, int nargs)
{
    ScmObj program;
    ScmWord code[2];
    code[0] = SCM_WORD(SCM_VM_INSN1(SCM_VM_VALUES_APPLY, nargs));
    code[1] = SCM_WORD(SCM_VM_INSN(SCM_VM_RET));

    vm->val0 = proc;
    program = vm->base? SCM_OBJ(vm->base) : SCM_OBJ(&internal_apply_compiled_code);
    return user_eval_inner(program, code);
}

いっちゃん下で呼ばれる user_eval_inner で上記の code な配列は PC にセットされて run_loop 手続きが呼び出されてます。vm->val0 に repl_STUB な C 手続きがセットされてるので、これが apply されるはず。
ここが bootstrap なナニですな。
あとなんとなくな理解としては、上記の user_eval_inner 手続きからは戻らないのではないかな。ちょっと確証ないですが。

apply される手続き

repl.c の repl_proc 手続き以降がナニ。この手続きからの戻りは末端で呼び出されてる Scm_VMRepl 手続きの戻り値。Scm_VMRepl 手続きの定義は以下で

ScmObj Scm_VMRepl(ScmObj reader, ScmObj evaluator,
                  ScmObj printer, ScmObj prompter)
{
    ScmObj ehandler, reploop;
    ScmObj *packet = SCM_NEW_ARRAY(ScmObj, 4);
    packet[0] = reader;
    packet[1] = evaluator;
    packet[2] = printer;
    packet[3] = prompter;
    ehandler = Scm_MakeSubr(repl_error_handle, packet, 1, 0, SCM_FALSE);
    reploop = Scm_MakeSubr(repl_main, packet, 0, 0, SCM_FALSE);
    Scm_VMPushCC(repl_loop_cc, (void**)packet, 4);
    return Scm_VMWithErrorHandler(ehandler, reploop);
}

継続を repl_loop_cc 手続きにして Scm_VMWithErrorHandler 手続きの戻りを戻す形。これは reploop (repl_main 手続き) の戻り値を戻すはず。

repl_main 手続きの戻り

は何か、というと順に

  • repl_main
    • repl_prompt_cc
      • repl_read_cc

という順で呼び出されて repl_read_cc 手続きにて

  • repl_eval_cc 手続きが Scm_VMPushCC されて
  • Scm_VMEval 手続きが呼び出される

という形。戻りは Scm_VMEVal 手続きの戻り。継続な read_eval_cc 手続きでは結果が出力されて repl_main 手続きが起動されてます。
む、でも継続な repl_eval_cc では Scm_VMEval 手続きの戻りは完全スルーに見えますな。このあたり、もう少しきちんと掘ってみた方が良さげ。