2014/06/22

データスタックに対するパターンマッチ

Erlang ではほとんど関数引数のパターマッチでプログラムが書ける。それを連鎖性言語でやろうとするとデータスタックに対するパターンマッチになる。

Factor だと http://docs.factorcode.org/content/article-locals-examples.html な感じでいろいろできるようではあるが、とりあえず dup 等をそんな感じで実装してみた。

: drop (( _ )) ;
: dup (( X )) X X ;
: swap (( X Y )) Y X ;
: over (( X Y )) X Y X ;
: rot (( X Y Z )) Y Z X ;
: -rot (( X Y Z )) Z X Y ;
: nip (( _ X )) X ;
: tuck (( X Y )) Y X Y ;

わかりやすい。

reverse と map はこんな感じ

: reverse [] swap reverse' ;
: reverse'
(( [] ))
(( Acc [ H T .] )) [ H Acc .] T reverse'


: map [ -rot map' ; # list function -- [ list function
: map'
(( [] _ )) ]
(( [ H T .] F ))
H F call T F map'

そういえば case の書き方をかえたので、いま fib を書くとこうなる。

: fib
= N
N 2 =<
case
true
( 1 )
_
( N 1- fib N 2 - fib + )
;case
;

( ) でブロックというかクオートというかそんなものができる。 Factor の [ ] と同じようなもの。

( 1+ ) 100 swap call .
# => 101
1 10 ( + ) cons call .
# => 11

2014/06/15

また Forth ライクな言語を作っている

最近まったくブログ書いてなかった。できればまた書くようにしたい。

ちかごろまた Forth ライクな言語を作っている。名前は ren(仮)。chon を付けてもいいかもしれない。 Forth ライクな言語を作るのはこれで4つか5つめ。なんか Forth には思い入れがあるみたい。とても簡単に作れる、というのもある。

今回のは Erlang で書いている。ワードを Erlang の関数にコンパイルする。思えば Erlang もコンパイル関数があるいい言語だ。ワードを Erlang の関数にコンパイルし、呼び出しは普通の Erlang 関数と同じなのでリターンスタックがない。そこは残念なところ。パターンマッチングをきれいに取り込みたいけど、なかなかいい書き方を思い付かない。

いまの fib はこんな感じ。

: fib
= N
N 2 =<
case
true
1
;;
_
N 1- fib N 2 - fib +
;case
;

言語を実装するのは不毛な感じがするものの楽しいね。