加算ができた
やった。加算ができたっ。
$ cat example/add.scm (print (+ 1 2)) $ ./main.byte -o add example/add.scm $ avmplus add 3
トークンを作るときに、"+1"(整数の1)と"+ 1"(+というシンボルと1という整数)を区別するのが大変だった。整数のパースを先にやると+が消費されてしまうので"+"がうまくパースできないし、シンボルのパースを先にやると+1が+と1で別々にパースされてしまう。
Parsecで言うところのtryみたいなのがあればうれしいけれども、Streamモジュールにはない。
しょうがないので、悪魔のObjモジュールを使って、状態を操作するようにした。
let try_ f stream = (* Use black-magic to save stream state from stream.ml: type 'a t = { count : int; data : 'a data } *) let t = Obj.repr stream in let count = Obj.field t 0 in let data = Obj.field t 1 in try f stream with Stream.Failure -> Obj.set_field t 0 count; Obj.set_field t 1 data; fail ()