Gauche で書いてみる

処理系に、C++で書かれた手続きを登録するコードを生成するスクリプトGauche で書いてみる。
On Lisp に影響されつつあるので何回も書き直す。


最終的にこんな感じに。

(define file-for-each-line (lambda (file func)
                             (with-input-from-file file
                               (lambda ()
                                 (let loop ((line (read-line)))
                                   (if (eof-object? line)
                                       '()
                                       (begin (func line) (loop (read-line)))))))))

(define p (lambda (s) (display s) (newline)))

(define register-code (lambda (class name)
                        (format #f "env->defineVariable(new Variable(~a), new ~a());" name class)))


(define register-from-file (cut file-for-each-line <> (lambda (line)
                                                        (let ((match (#/^PROCEDURE\(([^,]+),\s*([^\)]+)\)/ line)))
                                                          (if match
                                                              (p (register-code (match 1) (match 2))))))))

(define main (lambda (args)
               (for-each register-from-file (cdr args))))

;; nobita% gosh ./hige.scm scheme/procedures/MiscProcedures.cpp
;; env->defineVariable(new Variable("dynamic-wind"), new DynamicWindProc());
;; env->defineVariable(new Variable("call-with-values"), new CallWithValues());
;; env->defineVariable(new Variable("call-with-current-continuation"), new CallWithCurrentContinuation());
;; env->defineVariable(new Variable("not-supported"), new NotSupported());
;; env->defineVariable(new Variable("procedure?"), new ProcedureP());
;; env->defineVariable(new Variable("boolean?"), new BooleanP());
;; env->defineVariable(new Variable("exit"), new Exit());
;; env->defineVariable(new Variable("apply"), new Apply());
;; env->defineVariable(new Variable("eval"), new Eval());
;; env->defineVariable(new Variable("null-environment"), new NullEnvironment());
;; env->defineVariable(new Variable("scheme-report-environment"), new SchemeReportEnvironment());
;; env->defineVariable(new Variable("interaction-environment"), new InteractionEnvironment());


やっぱりいろいろ迷いがあるなあ
file-for-each-line というのを定義してみたが、この抽出で良いのか?
file->list みたいなのを定義したほうが良い?
いや file->list はメモリがもったいないかも。

file-for-each-line は1層上にもっと抽象度がたかい便利関数があってそれで実現できそうだとか。
このあたりは経験を積まないとな。