Open11

RibbitでSchemeテストを通したい会

okuokuokuoku

とりあえず面倒なところをScheme上で済ませてしまおうの会 ...CやJavaで実装するVMや標準ライブラリはたぶん1000行とかに収まるので。

okuokuokuoku

(integer? 1.0) は真である

わりと忘れがちだけど、不正確数と正確数の両方をサポートしたScheme処理系では (integer? 1.0) において小数点以下がゼロの数は真値を返却する。

$ gosh
gosh> (integer? 1.0)
#t

シリアライズ時に真の整数として処理したいのは正確数だけなので、一旦 exact? を挟んでチェックする。そうでないと vector-ref 等にindexとして不正確数を渡してしまうことになる。

https://github.com/okuoku/yuni/commit/da65a188e48b816f5a2ff5517f4e3c62ea20a1e3

okuokuokuoku

可変長引数の実行がおかしい

(import (rvm-primitives))

(define (check a . b)
  (if (eqv? '() b)
      (error "OK" a)
      (error "ERR" a)))

(check 12345)

これがVM内でクラッシュする。 (check 12345 1234) のように、 b が nil にならないようにすると正常に実行できる。

... 普通に実装漏れだった。

https://github.com/okuoku/yuniribbit-proto/commit/cdd4fff14ecdc9c95cae7289a4aeacbc21b9e540

argnc は "余り" 引数の数だが、可変長引数の手続きで argnc がゼロになるケースは特別扱いしないといけないのを忘れてた。

okuokuokuoku

unless が正常に動かない

(define step1 'notyet)
(define step2 'notyet)

(define-syntax unless
  (syntax-rules ()
    ((unless test result1 result2 ...)
     (if (not test)
       (begin result1 result2 ...)))))

(define (check x)
  (unless x
    (set! step1 'ok) ;; ★ ← これがスキップされる
    (set! step2 'ok)))

これは if の中に書かれた begin が top-level の begin だと判断されて消えるのが原因だった。そもそもtop-levelフラグを寝かす必要がある。

https://github.com/okuoku/yuni/commit/f4059ded7f8a0acfbafd5099ec05cd18efd0f453

okuokuokuoku

テストを仕分け

通る:

https://github.com/okuoku/yuniribbit-proto/blob/7659e02d438566b7de615d30abe27b6f46a09189/CMakeLists.txt#L11-L26

通らない:

https://github.com/okuoku/yuniribbit-proto/blob/7659e02d438566b7de615d30abe27b6f46a09189/CMakeLists.txt#L28-L61

inexact1 (シリアライズで失敗する) みたいな奴は修正しないと不味いな。。逆に、syntax-rulesのテストみたいに現状のフロントエンドでは成功しないテストもある。

okuokuokuoku

NaN はハッシュテーブルに入れられない

NaN と何かの比較は常に偽になるので、ハッシュテーブルに NaN と紐付いたオブジェクトを入れても取り出す方法がない。特に NaN != NaN なのに注意する。

https://github.com/okuoku/yuni/commit/04aecad197bfe229e528b612971293601c6327b0

NaNの替わりに別のオブジェクトを代表として使うことで回避した。。これで inexact1 が治った。

okuokuokuoku

hashtablesを実装

https://github.com/okuoku/yuniribbit-proto/commit/b5da300de794913530e95f69895984f46a174fe0

hashtable-fold とかは無くても良いかなぁ。。その替わり make-bytevector-hashtable とかあっても良いんではないか説がある。 make-string-hashtable は有るんだし。。

hashtable-update! が何で必要なのかと思ったら、この形式のAPIがあるとキーのハッシュ値を1度だけ計算すれば良いからか。