いつものように JavaScript で書きました.
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)