Haskellの実装イベントに備えなるはずなのに、何故かlibgaucheをいじっていた
libgaucheを使ったS式リーダできたよー(~ρ~)
% ./srepl 3322 3322 (1 2 3 4) (1 2 3 4) (1 3 (hoge fuga) gggg) (1 3 (hoge fuga) gggg) % cat >sexps (3 2 2 4 8) (hoge "hoge\nfuga" (fuga (fuga (fuga)))) 3322 % ./srepl sexps (3 2 2 4 8) (hoge "hoge\nfuga" (fuga (fuga (fuga)))) 3322
読んで吐きだしてるだっけ。
#include <gauche.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #define GetSymbol(x) \ SCM_SYMBOL(SCM_INTERN(x)) #define GetSymbolValue(x) \ Scm_SymbolValue(Scm_CurrentModule(), SCM_SYMBOL(SCM_INTERN(x))) struct _gosh{ ScmVM *vm; ScmObj env; ScmObj read, write, print; ScmObj add, sub, mul, div; }; typedef struct _gosh gosh; gosh default_gosh_buffer; #define Gosh default_gosh_buffer void Gosh_Init() { Scm_Init(GAUCHE_SIGNATURE); Gosh.vm = Scm_VM(); Gosh.env = Scm_MakeModule(GetSymbol("gosh"), FALSE); Gosh.add = GetSymbolValue("+"); Gosh.sub = GetSymbolValue("-"); Gosh.mul = GetSymbolValue("*"); Gosh.div = GetSymbolValue("/"); } int main(int argc, char **argv) { ScmObj input, output; ScmObj sexp; Gosh_Init(); output = SCM_OBJ(SCM_CUROUT); if(argc == 1) { input = SCM_OBJ(SCM_CURIN); } else { input = Scm_OpenFilePort(argv[1], O_RDONLY, SCM_PORT_BUFFER_FULL, 0); if(SCM_FALSEP(input)) { printf("cannot open %s\n", argv[1]); exit(1); } } while(!SCM_EOFP(sexp = Scm_Read(input))) { Scm_Write(sexp, output, SCM_WRITE_DISPLAY|SCM_WRITE_SHARED); } SCM_FLUSH(output); return 0; }
なんとなく適当にいじってて、やり方が少しわかってきた。SCM_HOGEみたいなのは横着用のラッパーマクロ。Scm_Hogeみたいなのはlibgauche側で定義してある生の関数。扱うデータはだいたいScmObj。実態はScmPortとかScmVMみたいにあつかわれるようなデータだったりする。まあC言語に型は無え、みたいな話ですね。
gaucheん中でもプリミティブなデータとかはマクロが用意されてます。上のコードで言うとSCM_NIL, SCM_FALSEP, SCM_EOFP, SCM_CURINみたいなの。その辺はgauche.hとか、gauche/*.hを探ると色々定義されてて便利。evalみたいなことは最小限で済ませることができる。
適当に「libgauche」でぐぐって出てきた記事をとっかかりに、gaucheのgauche.hと、gaucheのマニュアルと、gaucheのソースコードを参考にしつつ読んで使った。なんかネット上の記事がやたらすくない(さわり程度以上書いてるのあろはくんがshikiつくったときの記録しか無い気するだったりする)けど、普通にライブラリとして使いやすいと思う。
あと俺は今眠くてtypoがやたらおおくなっている。やばい。いま何故かid:suztomoの家でダラダラコード書いてる。主不在。そろそろ帰る。
終えて
何故俺はgauche使ってschemeでやるんじゃなくてlibgaucheをCから使うといった手法を選んだんだっけ…… あと上の方のこととかをやってたせいで寝てなかったので、死んだ。サイボウズラボ到着時に既に死にかけてた。たしかに徹夜だけどなんでそんなに疲れてんだろうと不思議だったけど、よく考えりゃ前の日とかもたぶんそんなに寝てなかった。結果としてはlisp処理系のなりそこないみたいなもんしかできんかった。上に書いたS式リーダ程度の。gaucheの理解がちょっとだけ進んだ。Parsecをすこしだけ触った。「俺はまだまだだな」というのを徹底的に感じることができた。メタプログラミング力が足りない気がした。
腕がおもい。ねむい。ラボから退出したとき、机の上に置いてたノートPCだふつけるだのを丸ごと忘れて一回取りにもどったり阿呆なことしてた。