Scm_Repl 手続き

定義は以下。repl.c の L192。

void Scm_Repl(ScmObj reader, ScmObj evaluator, ScmObj printer,
              ScmObj prompter)
{
    Scm_ApplyRec(SCM_OBJ(&repl_STUB),
                 SCM_LIST4(reader, evaluator, printer, prompter));
}

なんか今までの見方が微妙だなぁ、と思いつつ色々掘じくりカエしてたんですが、repl.c の先頭に以下なコメントを発見。

/*
 * Conceptually, repl can be described by the following Scheme code.
 *
 *  (define (repl reader evaluator printer prompter)
 *    (let loop1 ()
 *      (and
 *        (with-error-handler
 *          (lambda (e) (report-error e) #t)
 *          (lambda ()
 *            (prompter)
 *            (let loop2 ((exp (reader)))
 *              (if (eof-object? exp)
 *                  #f
 *                  (begin
 *                    (call-with-values
 *                      (lambda () (evaluator exp (current-module)))
 *                      printer)
 *                    (loop2 (reader)))))))
 *        (loop1))))
 *
 * It is implemented using trampoline so that it can run without crossing
 * C -> Scheme boundary.
 *
 *  VMRepl -> VMWithErrorHandler -> repl_main -> prompter
 *    -> repl_prompt_cc -> reader -> repl_read_cc -> evaluator
 *    -> repl_eval_cc -> printer -> repl_print_cc -> repl_main
 */

これはなんとなくイメージできてるな。

話を元に戻す

Scm_ApplyRec と repl_STUB の理解が微妙。
とりあえず repl_STUB は以下なマクロで定義。

static SCM_DEFINE_SUBR(repl_STUB, 0, 1, SCM_OBJ(&repl_NAME), repl_proc, NULL, NULL);

SCM_DEFINE_SUBR マクロは gauche.h で定義。

#define SCM__DEFINE_SUBR_INT(cvar, req, opt, inf, flags, func, inliner, data) \
    ScmSubr cvar = {                                                        \
        SCM__PROCEDURE_INITIALIZER(SCM_CLASS_STATIC_TAG(Scm_ProcedureClass),\
                                   req, opt, SCM_PROC_SUBR, inf, inliner),  \
        flags, (func), (data)                                               \
    }

#define SCM_DEFINE_SUBR(cvar, req, opt, inf, func, inliner, data) \
    SCM__DEFINE_SUBR_INT(cvar, req, opt, inf, 0, func, inliner, data)

ScmSubr 型の repl_STUB というソレを定義している形になるのか。この C な特殊形式を Scm_ApplyRec がどう評価するのか、がイメージできれば良いんですが。
てーか、Scm_ApplyRec 手続きの先が具体的によく分からのですが、別途以下なコメントの意味を確認予定。

/* NB: The ApplyRec family can be called in an inner loop (e.g. the display
   callback from GLUT.)  So we don't want to allocate at all.  We put
   a temporary code vector on C stack.  It is OK, since once
   user_eval_inner returns it would never be reused.   However, tools
   that want to keep a pointer to a code vector would need to be aware
   of this case. */

うーん。