kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

J-Bobを作ってみよう(8) 簡易プロファイラ

関数の呼び出し回数が見えるようにしてみようかと
envに覚えるようにしておいて、japplyかなにかのタイミングで更新すればよさそう
リストのままだと更新しづらい(気がする)から、structにしてみようか
こういうの「純粋」なやりかたではどうやるのかな

まず動きはそのまま内部表現だけ変えます

+(struct fentry (name vars body) #:transparent)

-  (set! env (cons (list name args body) env)))
+  (set! env (cons (fentry name args body) env)))
 
   (jeval
    (let* ((f (findfunc name))
-          (vars (cadr f)))
-     (subst (caddr f) vars args))))
+          (vars (fentry-vars f)))
+     (subst (fentry-body f) vars args))))

#transparentがないと、画面に表示させても中身がわかりません

> (fentry 'tcons '(x y) '(cons x y))
#<fentry>

#transparentにすれば

> (fentry 'tcons '(x y) '(cons x y))
(fentry 'tcons '(x y) '(cons x y))

と表示されます

>> (show-env)
'()
#<void>
>> (defun double (x) (+ x x))
#<void>
>> (show-env)
(list (fentry 'double '(x) '(+ x x) 0))
#<void>
>> (double '2)
4
>> (show-env)
(list (fentry 'double '(x) '(+ x x) 1))
#<void>
>> (double '3)
6
>> (show-env)
(list (fentry 'double '(x) '(+ x x) 2))
#<void>

できてますね
数が数えられたらあとは少し見やすくしてやるくらいでいいかな
こんな感じ

(define (reset-env) (set! env '()))
(define (show-env) (pretty-print env))

(define (reset-profile)
  (for ((e env))
       (set-fentry-count! e 0)))
(define (profile)
  (map (λ (e) (list (fentry-name e) (fentry-count e))) env))
(define (show-profile)
  (pretty-print (sort (profile) > #:key cadr)))

(define op0s '(reset-env env show-env reset-profile profile show-profile))

(define (op0 op)
  (cond ((eq? op 'reset-env) (reset-env))
        ((eq? op 'env) env)
        ((eq? op 'show-env) (show-env))
        ((eq? op 'reset-profile) (reset-profile))
        ((eq? op 'profile) (profile))
        ((eq? op 'show-profile) (show-profile))))

(define (jeval e)
  (cond
    ((string? e) e)
    (else
     (let ((op (car e)))
       (cond ((member op op0s) (op0 op))
              :

pretty-printっていうステキな関数があることを知りました
さて動かしてみますと

> (repl)
>> (reset-env)
#<void>
>> (defun len (x) (if (atom x) '0 (+ '1 (len (cdr x)))))
#<void>
>> (len '(a b c))
3
>> (show-profile)
'((len 4))
#<void>

大丈夫