Grass インタプリタを書いた

いつものように JavaScript で書きました.

github.com

npm があればnpm install -g @susisu/grass-js でインストールできて, grass /path/to/progfile とかで遊べます.

Grass とは

Grass the grass-planting programming language の通り, 草を生やす言語です.

例えば練習として書いてみた echo がこんな感じ.

wv
wwv
wWWWwwv
wwWWWWWWwWWWwwwv
wWWWWWWWWWwwwWwWWWWwwwWWwWwwwwwwwwwWwwwww

どう動作するのかなどの詳細は上記サイトか プログラミング言語/Grass - プログラミングスレまとめ in VIP などを読むと良いと思う.

実装に関して

ほとんど本家サイトにある操作的意味論を書き下しただけ.

ただ一つ, そのままでは末尾呼び出しでもスタックが増え続けてしまうので,

(App(m, n) :: ε, E, (C0, E0) :: D) → (Cm, (Cn, En) :: Em, (C0, E0) :: D)

みたいなのを入れました. たぶん正しく動作すると思うのですが, いまいち自身がないので, 不正な動作をするケースがあれば教えていただけると幸いです.

Original:
(App(m, n) :: nil, E, (C0, E0) :: D)
    ->  (Cm, (Cn, En) :: Em, (nil, E) :: (C0, E0) :: D)
    ->* (nil, f :: E', (nil, E) :: (C0, E0) :: D)
    ->  (nil, f :: E, (C0, E0) :: D) -- nothing to do with E
    ->  (C0, f :: E0, D)

Optimized:
(App(m, n) :: nil, E, (C0, E0) :: D)
    ->  (Cm, (Cn, En) :: Em, (C0, E0) :: D)
    ->* (nil, f :: E', (C0, E0) :: D)
    ->  (C0, f :: E0, D)