目指せギリギリ最少Scheme on Scheme
まぁ実際にはCPU命令程度の機能性は使うけれど。。
Schemeの学習法として良くある、SchemeでSchemeを実装するという課題をギリギリのプリミティブだけで出来ないか企画。とりあえず、浮動小数点 / bignum / read / writeの無いR7RS base実装を実現するまで努力してみる。
リポジトリには、統計用のスクリプトとR7RSに含まれるletや他の構文の実装を予め入れてある。なので、なにもしていない状況での実装状況はこんな感じになる。
Section Implemented Total =================================================================== 4.1.2. Literal expressions 1 1 4.1.4. Procedures 1 1 4.1.5. Conditionals 1 1 4.1.6. Assignments 1 1 4.1.7. Inclusion 0 2 4.2.1. Conditionals 8 9 4.2.2. Binding constructs 6 6 4.2.3. Sequencing 1 1 4.2.4. Iteration 1 1 4.2.5. Delayed evaluation 5 5 4.2.6. Dynamic bindings 2 2 4.2.7. Exception handling 1 1 4.2.8. Quasiquotation 0 3 4.2.9. Case-lambda 1 1 4.3.1. Binding constructs for syntactic keywords 0 2 4.3.2. Pattern language 3 3 4.3.3. Signaling errors in macro transformers 0 1 5.3. Variable definitions 0 1 5.3.3. Multiple-value definitions 1 1 5.4. Syntax definitions 1 1 5.5. Record-type definitions 0 1 6.1. Equivalence predicates 0 3 6.2.6. Numerical operations 0 66 6.2.7. Numerical input and output 0 2 6.3. Booleans 0 3 6.4. Pairs and lists 0 51 6.5. Symbols 0 4 6.6. Characters 0 22 6.7. Strings 0 26 6.8. Vectors 0 14 6.9. Bytevectors 0 11 6.10. Control features 0 13 6.11. Exceptions 0 9 6.12. Environments and evaluation 0 5 6.13.1. Ports 0 28 6.13.2. Input 0 13 6.13.3. Output 0 10 6.14. System interface 0 12 (scheme base) 28 238 (scheme case-lambda) 1 1 (scheme char) 0 22 (scheme complex) 0 6 (scheme cxr) 0 24 (scheme eval) 0 2 (scheme file) 0 10 (scheme inexact) 0 12 (scheme lazy) 5 5 (scheme load) 0 1 (scheme process-context) 0 5 (scheme read) 0 1 (scheme time) 0 3 (scheme write) 0 4
baseは238シンボルもあるのか。。ただ、驚くべきことに何もしなくても10%以上終わっている。構文の実現は考えないので、syntax-rulesなどが予め終わっているのが最大の要因だが。。。
nmoshにはpointer型があるので、すべての値をpointerでwrapすると規定すれば、ホストSchemeとの界面はpointer型の操作手続きとdefineやletのようなbinding constructだけにできる。実際には、pointerのvectorを使ってヒープを実現したり、エラーの出力等の多少の追加は必要。
nmoshのpointerオブジェクトを使う最大の利点は、これがGCフレンドリなオブジェクトなことで、wrap後の値もちゃんとGCのトラバース対象に含まれる。また、普通のScheme on Schemeと違って、今回はホストSchemeのオブジェクトシステムを使わない。このため、pointerがR6RS/R7RSの語彙で認識されないというポイントが、ホストSchemeのオブジェクトとターゲットのSchemeオブジェクトが混ざる危険性を減らすのに効果的と言える。
とにかく必要最低限ということで、これだけの手続きを選んだ。これをwrapしたpointerオブジェクトで実装していくのが当面の目標になる。これらが揃えば、後はR7RSライブラリを実装していくだけの作業になる。
原理的には、この方法で実装したSchemeは単純な変換でC言語に変換し、そのままScheme実装として使える と予想している。この予想が当たった暁には、GCその他も実装して独立した処理系にしたい。