自作Lua処理系に型注釈をつけた(嘘)
こんにちは、びしょ〜じょです。梅祭りということでT山に行ったら本場のガマ口上が聞けたんですが、老人が景気の良い話しててムカついた。
1. はじめに
ネタがないのでまたこれの話です。
動機は特に無く、時間を大きく潰す必要がありながらも徹夜で頭がうまく働かないというシナリオの上で何をするのが良いかというと既存の拙作いじるのが無難かなと。
だらだらツイタッーをみていたら構文木の最適化の話がちょっとでて、パーサーをいじろうという気持ちがフッとわいてきた。 ところでRustのチュートリアルを読み進めていて、Rustにはコメントによる型注釈というものが将来できるらしい1。 じゃ、型注釈実装しよっか。
2. 実装
TACore: with types = {"number", "string", "table", "function", "coroutine", "userdata", "nil"} return spaces(P'T@', CV'Name', P'::', C foldmap types, ((x) => P(x) + @), #(-P'.')) / (n, t) -> (parse"assert((type(#{n}) == "#{t}"), [[`#{n}' is not "#{t}"]])")[1]
-- ......
parse = (msg) -> tree = {llix\match msg}
if h = tree[1] #tree > 1 and tree or h else nil, "Failed to parse"
parse
型注釈とはいったものの、つまるところ--T@ foo :: T
がassert(type(foo) == "T")
の糖衣構文という見方でいいです、というか実際そうです。
ですのでfoo
の定義以降ならどこに書いてもいいことになります。しかし定義と注釈のあいだに何かあると、型検査(ただのassert
)がされずに進んでいきます。だめじゃん(完)。
@ foo :: T
でもよかったと思うけど、「luadocとかぶってはマズい」という全く必要のない心配をしたのでT@
という目印にしました。
assert(A == B)
の構文木を手で書くのはアレだし今後書き換わる可能性も考えてパーサー内でパーサーを使うことにした。これが一番ミソですね。嘘です。
3. 後に出す先行研究
(Lua+Rustとか風の型注釈)→コンパイル→Lua
という物体です。こちらは今回の型注釈と違いコメント外にダイレクトに書くのでLuaとしてのポータビリティ(?)にやや欠ける、
しかしTypedLuaコンパイラtld
にオプションを渡せば、プレーンなLuaもコンパイル時にWarningやError出してくれるのでGod100%。完敗ですおわり。
さらにはHOGE.tldというファイルに型情報を記述するだけでそれもしっかりチェキしてくれるのでもう言うことなしです最高。
今日お客さんがたにお伝えしたかったのはこのTypedLuaです!!! 以上!!!!
4. おわりに
今月中にはRust Tutorialを抜けたい、あと倉敷に行くぞ、六識美砂さんの働いていた場所で『受胎告知』を観るぞ。 あと@ranha さんが大量に捨てていった本を大量に拾ったので、どんどん読んで行かないとね…。
とりあえず『集合とはなにか』、『理科系のための英文作法』を読んだ。両方とも共通しているのは"読み進めさせる文章力"ですね。 内容をより面白く思わせる文というのは名著たらしめるファクターだと思う。どちらも面白かった、内容も然り。 特に後者は英作文に関する本ですが、まず日本語として正しい文を英語に翻訳していくという進みなので、日本語文の勉強にもなった(が、この文は死んだ脳で書いてるので本の内容があまり適用されていない)。
本を読んで百合を楽しんで積んでるゲームと本を消化してプログラム書いて百合を楽しんで寝る時間が欲しいミャオ…
-
https://doc.rust-lang.org/nightly/book/variable-bindings.html#type-annotations ↩