まずはこの動画を見てほしい。
いや、最先端だね。音声認識エレベーターとは。
でもスコティッシュアクセントには対応していなかったようだ。
これを同僚に見せられたときは思わず大爆笑してしまった。
うちの会社のCEOとマネージャーの一人はスコットランド人だけどね!!
Syntax highlighter
2011-01-30
2011-01-15
LinuxをUSBからインストール
をするための準備の話。
ちょっと古めのデスクトップが転がってて、OSが入ってない。Windowsはもちろんない。ということで、Linuxを入れようと思ったのだが、現在使ってるノートPCにはCDROMがない。
っでちょっと調べてみたらUSBからインストールできるらしい。ということでブータブルUSBを作成する。
手順。
他にも、UNetbootinってツールも試したけど、こいつにはひどい目に合わされた。バージョンが悪いのか(最新版だけど)、そもそもCDイメージをUSBにコピーするだけのツールなのか知らないけど、ブータブルなUSBならない。
これで上手くいったらSSDを買って自分のノートにLinuxを入れよう。
(その前に死んだバッテリーを換えないと。ACアダプタ抜いたら即死ぬノートPCってノートの魅力0なんですけど)
ちょっと古めのデスクトップが転がってて、OSが入ってない。Windowsはもちろんない。ということで、Linuxを入れようと思ったのだが、現在使ってるノートPCにはCDROMがない。
っでちょっと調べてみたらUSBからインストールできるらしい。ということでブータブルUSBを作成する。
手順。
- syslinuxを落としてくる。
- DAEMON Tool Liteを落としてインストール。
- Linuxのisoイメージを落とす。
- 3.を2.のツールでマウントして、中身をUSBドライブにコピー。
- USBドライブにisolinuxってフォルダがあるので、それをsyslinuxに変更。
- 5.のフォルダの中にisolinux.cfgというファイルがあるので、syslinux.cfgに変更
- syslinux.exeを叩く。(syslinux.zipで落としたなら、中のwin32フォルダにある)
C:\> syslinux.exe -maf F:
(F: はUSBドライブ名。これをC:とか自分のHDDにすると多分えらいことになる)
本当は-maでいいんだと思うけど、僕のUSBはリムーバブルと認識されてなくて、強制書き換えの-fが必要だった。
他にも、UNetbootinってツールも試したけど、こいつにはひどい目に合わされた。バージョンが悪いのか(最新版だけど)、そもそもCDイメージをUSBにコピーするだけのツールなのか知らないけど、ブータブルなUSBならない。
これで上手くいったらSSDを買って自分のノートにLinuxを入れよう。
(その前に死んだバッテリーを換えないと。ACアダプタ抜いたら即死ぬノートPCってノートの魅力0なんですけど)
2011-01-12
ワイド文字列
いろいろやってて壁にぶち当たった・・・
C言語で文字列を扱うことがこんなに面倒だとは、知ってたけど改めて痛感。
char = 1 byteはいいとして、
wchat_t != 4 byte ってか処理系依存って結構厳しい。
UCS4を内部エンコードに使いたかった(すでに過去形)のだが、WindowsのVCとCygwin GCCだとwchat_tは2byte。(Linuxだと4byteらしいけど、試してない)
マクロで
そもそも
あと、C内部で文字列を扱う際に、C文字列からUCS4変換する必要が出てくるので、文字列のコピーがどうしても必要になり、アロケーションが走る。使い捨ての文字列とかにアロケーションは走ってほしくない。
Ypsilon方式にするか。ファイルのエンコーディング -> UCS4(中間表現) -> UTF8(内部文字列)とするとCで使ってる文字列はそのまま流用できそう。
改修がすごく広範囲にわたるが今のうちにやったほうがいいだろうなぁ。
C言語で文字列を扱うことがこんなに面倒だとは、知ってたけど改めて痛感。
char = 1 byteはいいとして、
wchat_t != 4 byte ってか処理系依存って結構厳しい。
UCS4を内部エンコードに使いたかった(すでに過去形)のだが、WindowsのVCとCygwin GCCだとwchat_tは2byte。(Linuxだと4byteらしいけど、試してない)
マクロで
typedef wchar_t ucs4char; #define UC(str) L##strなんてことしたかったんだけど、無理になった・・・orz
そもそも
typedef int32_t ucs4char; /* 符号付 4byte(EOFは大抵-1だし) */ static const ucs4char msg[4] = {0x3042, 0x3044, 0x3046 0x0}; /* あいう */ static const char* cmsg = "abcde";ってのがアセンブラ上だとなんかあんまり美味しくないようになってる。こんな感じで。
L0 .long 0x3042 .long 0x3044 : _msg .long L0 .def __somewhere L1 .ascii "abcde\0" .text _cmsg .long L1なんか、静的に配列確保してて(そういう宣言だから当たり前だが)、あんまり静的な文字列な感じがしない。
あと、C内部で文字列を扱う際に、C文字列からUCS4変換する必要が出てくるので、文字列のコピーがどうしても必要になり、アロケーションが走る。使い捨ての文字列とかにアロケーションは走ってほしくない。
Ypsilon方式にするか。ファイルのエンコーディング -> UCS4(中間表現) -> UTF8(内部文字列)とするとCで使ってる文字列はそのまま流用できそう。
改修がすごく広範囲にわたるが今のうちにやったほうがいいだろうなぁ。
2011-01-08
Boehm GCを読む
正直涙が出そうになっているが、現在の所分かった(つもりでいる)部分のメモ。
あ、でも
可変構造体にしないのは、最大限にヒープを使うためなのか、可搬性のためなのかどっちなんだろう?
- 基本的な部分
- ヒープとして渡されるポインタはヘッダー情報を保持していない(ある意味当たり前)
- ファイナライザはオブジェクト(ここではポインタ)に持たせず別に管理している(finalizable_objectを格納するハッシュテーブル)
- ヒープ内部はOSのページブロック(基本4KB)ごとに分けられている(ちと不安)
- 曖昧な理解の部分
- GCのヒープはGC_arraysという構造体で一括管理してるっぽい。
- top_indexとかbottom_indexとか2KBくらいの配列を確保してるけど、この中に実際のヒープのヘッダーが入ってるっぽい。
あ、でも
struct hblkhdr { struct hblk *hb_next; struct hblk *hb_prev; struct hblk *hb_block; /* 以下略 */ }; struct hblk { char hb_body[HBLKSIZE]; }; /* HBLKSIZEは基本4KB */なんてなってるから、ヘッダーにメタ情報を持たせて(使える領域とか、どんなオブジェクト用かとか、残りブロックサイズとか)、ページブロック以下のサイズのオブジェクトに対してはhb_blockからみ使用部分を割り当てるなんて方法なのかも。
可変構造体にしないのは、最大限にヒープを使うためなのか、可搬性のためなのかどっちなんだろう?
2011-01-04
これってOK?
C言語でこんなのって合法?
そのまま見ると1個しかない配列に対して5個入れてるから違法臭いけど、ポインタ自体を書き換えるのであれば合法っぽくもある。
実際、
(いや、仕様書を確認したわけじゃないけど、よく見るテクニックだからそう思ってる。実際char[1]をchar*にするとセグるし、当たり前だが)
ただ、この場合だとポインタを書き換えるのではなく、連続したメモリという扱いになるのかな?
最初のケースだと純粋に書き換えてるから、うっかり鼻から悪魔が出てきても文句が言えなさそうな気はするが。
う~ん。
static int s_value[5] = {1, 2, 3, 4, 5}; struct rec_t { int v[1]; }; static struct s_rec_t { rec_t v[1]; } myth = { { s_value } };用は構造体の初期化だと思うんだけど、rec_tがint*なら合法なのはいいとして、この場合だとどうなるんだろう?
そのまま見ると1個しかない配列に対して5個入れてるから違法臭いけど、ポインタ自体を書き換えるのであれば合法っぽくもある。
実際、
struct string_t { int size; char value[1]; }; --- string_t *s = (string_t*)malloc(sizeof(string_t) + sizeof(char)*10); strcpy(s->value, "abcdefghi"); s->value[10] = '\0';なんてのは合法なんだよね。
(いや、仕様書を確認したわけじゃないけど、よく見るテクニックだからそう思ってる。実際char[1]をchar*にするとセグるし、当たり前だが)
ただ、この場合だとポインタを書き換えるのではなく、連続したメモリという扱いになるのかな?
最初のケースだと純粋に書き換えてるから、うっかり鼻から悪魔が出てきても文句が言えなさそうな気はするが。
う~ん。
2011-01-01
謹賀新年
あけましておめでとうございます。
旧年はお世話になりました。本年もよろしくお願いいたします。
去年(一昨年からか?)やってる個人プロジェクト、まだあんまり形になってないけど、今年中にはなんらかの形にしたいなぁ。
個人的にもう少しな感じがしてる。(気が変わって作り直しをしなければ。何度やったか・・・)
今年はいい年になりそうな気がする。
旧年はお世話になりました。本年もよろしくお願いいたします。
去年(一昨年からか?)やってる個人プロジェクト、まだあんまり形になってないけど、今年中にはなんらかの形にしたいなぁ。
個人的にもう少しな感じがしてる。(気が変わって作り直しをしなければ。何度やったか・・・)
今年はいい年になりそうな気がする。
2010-12-29
続 C言語でオブジェクト指向
バスに揺られた帰り道に思いついた。
忘れないうちにメモしておこう。
unionを使えばいいのかもしれない。
よくよく考えてみれば、設計の段階で回避できる問題なのだからこんな感じにしたらいけそうな気がする。
(対象はSchemeのポート周り)
(どうせ、そうは行ってもそれぞれのcloseを呼ぶことになりそうな気はするので、もう少し練る必要がありそうだ)
メタクラスも考えたが、一朝一夕ではいい案が出ないのと、Scheme内で使うところまで考えないとオーバースペック(苦労に見合わないとも言う)になりそうなのでとりあえず却下。
(Glib、Gaucheのソースを見たけど結構大変そうだったので。いろいろ魅力的ではあるが、自分の手に余りそうだし、recordを使えば一応クラスっぽいのも定義できるのでという理由)
明日この方向で実装を再開しよう。
ポート周りが終わらないと始まらない辛さ・・・
忘れないうちにメモしておこう。
unionを使えばいいのかもしれない。
よくよく考えてみれば、設計の段階で回避できる問題なのだからこんな感じにしたらいけそうな気がする。
(対象はSchemeのポート周り)
struct Port { int type; int direction; int (*close)(Port*); union { struct BinaryPort *bport; struct TextualPort *tport; struct CustomPort *cport; } impl; };typeでバイナリ、テキスト、またはカスタムポートか判別。directionでIN/OUTの判別。実際のポートの実装はimplで行って、closeとかすべてに共通しそうなのは上位に入れる。
(どうせ、そうは行ってもそれぞれのcloseを呼ぶことになりそうな気はするので、もう少し練る必要がありそうだ)
メタクラスも考えたが、一朝一夕ではいい案が出ないのと、Scheme内で使うところまで考えないとオーバースペック(苦労に見合わないとも言う)になりそうなのでとりあえず却下。
(Glib、Gaucheのソースを見たけど結構大変そうだったので。いろいろ魅力的ではあるが、自分の手に余りそうだし、recordを使えば一応クラスっぽいのも定義できるのでという理由)
明日この方向で実装を再開しよう。
ポート周りが終わらないと始まらない辛さ・・・
C言語でオブジェクト指向
ただいま絶賛挫折中・・・orz
その昔(といっても2ヶ月くらい前か?)途中で開発方針変えたため放棄したC++のソースをCに移植してる最中でぶつかった壁。
まだぶつかってるので躓いてる壁か?
単一クラス、振る舞いは変わるが継承、多態はないのなら、こんなのでいける。
たとえばこんなの。
この辺まではいいんだよ。昔から使ってたから。問題は継承が絡んでくると意味が分からん。
vtable使うか、メタクラスを別に作って気合でアクセスするか。
(多分、メタクラスを使った方が後々いい気がする。GObjectとかを参考にするか)
くそ、C++でかければこんなことで悩まないのに・・・
みんなDLLが悪いんだ!
その昔(といっても2ヶ月くらい前か?)途中で開発方針変えたため放棄したC++のソースをCに移植してる最中でぶつかった壁。
まだぶつかってるので躓いてる壁か?
単一クラス、振る舞いは変わるが継承、多態はないのなら、こんなのでいける。
typedef struct ObjectRec Object; struct ObjectRec { int x; int y; int (*squre)(Object*); };こんなことして、適当に関数ポインタに関数を突っ込んでやればいい。
たとえばこんなの。
static int realSqure(Object* o) { return o->x * o->y; } static int fakeSqure(Object* o) { return o->x * o->x * o->y * o->y; } Object* makeObject(int x, int y) { Object* o = (Object*)malloc(sizeof(Object)); o->squre = realSqure; o->x = x; o->y = y; return o; } Object* makeFakeObject(int x, int y) { Object* o = (Object*)malloc(sizeof(Object)); o->squre = fakeSqure; o->x = x; o->y = y; return o; }これで、同じo->squreなのに違う関数にアクセスできる。
この辺まではいいんだよ。昔から使ってたから。問題は継承が絡んでくると意味が分からん。
vtable使うか、メタクラスを別に作って気合でアクセスするか。
(多分、メタクラスを使った方が後々いい気がする。GObjectとかを参考にするか)
くそ、C++でかければこんなことで悩まないのに・・・
みんなDLLが悪いんだ!
2010-12-25
クロワロタwwwww
性の6時間を正すために6時間正拳突きをしようと思う。某巨大掲示板に立ったスレをまとめたもの。
クソ笑った。あほすぎる。でも、これ日本にいてリアルタイムで発見したら大阪までスネークに行ってたかもw
いや、どちらかといえばリア充寄りだと思うけどね、僕。
これだけ行動力があるのなら、もう少し建設的なことに使えばいいのに、とも思ったが。
(別に彼女を作るとかじゃなくて、勉強でもいいと思うし、昨今の政治家に対してのデモとか)
でも、個人的には愛するべきあほだと思う。
そうそう、Merry Christmas!
クソ笑った。あほすぎる。でも、これ日本にいてリアルタイムで発見したら大阪までスネークに行ってたかもw
いや、どちらかといえばリア充寄りだと思うけどね、僕。
これだけ行動力があるのなら、もう少し建設的なことに使えばいいのに、とも思ったが。
(別に彼女を作るとかじゃなくて、勉強でもいいと思うし、昨今の政治家に対してのデモとか)
でも、個人的には愛するべきあほだと思う。
そうそう、Merry Christmas!
2010-12-22
C++/Cで書き始めたい
だいぶ自前Schemeがまとまってきたので、そろそろC++かCで書き始めようと思う。
コンパイラ(+その周りのライブラリ)はコンパイルされたコードをC(多分CよりなC++)にコンバートすればいいとして、
(それでも、ライブラリのインポートとか識別子どうしようとか問題はあるけど)
どこまでをCで書いて、どこからをC++で書こうか迷い中。
迷う理由としてはこんな感じ。
(同じコンパイラ使えばいいんだけどね、実際)
2.は要らないといえば要らないが、あるとすっきりかける気がする。慣れの問題だとは思うが。
おそらく問題になりそうな部分としては、オブジェクトの扱いかなと。
結局こいつらをC++で書くと先に書いた、DLLでモジュール作成に支障が出る気がする。
Gaucheは完全にCだが、Ypsilonは一部Cで主にC++で書いてる。
見ればオブジェクトは単なるポインタで、それぞれのオブジェクト、Pairを除く、にヘッダ(単なるunsigned int)を持たせてる。
Moshは全部C++で、オブジェクトはクラスなんだけど、タグと値を保持するだけ。
(まぁ、その他便利関数が入ってるけど)
MoshとYpsilonを混ぜるのが答えになる気がする。
こんな感じで
そもそも、C++のABIがもっとポータルならいいのに。問題の一つは名前マングルにあると思うんだ、うん。
(try-catchの実装とかもそうか・・・)
コンパイラ(+その周りのライブラリ)はコンパイルされたコードをC(多分CよりなC++)にコンバートすればいいとして、
(それでも、ライブラリのインポートとか識別子どうしようとか問題はあるけど)
どこまでをCで書いて、どこからをC++で書こうか迷い中。
迷う理由としてはこんな感じ。
- C++だとバイナリ互換がない、つまりアプリケーション組み込みに向かない
- C++にはtemplate、class、関数オーバーロードなどCにはない機能がある
(同じコンパイラ使えばいいんだけどね、実際)
2.は要らないといえば要らないが、あるとすっきりかける気がする。慣れの問題だとは思うが。
おそらく問題になりそうな部分としては、オブジェクトの扱いかなと。
結局こいつらをC++で書くと先に書いた、DLLでモジュール作成に支障が出る気がする。
Gaucheは完全にCだが、Ypsilonは一部Cで主にC++で書いてる。
見ればオブジェクトは単なるポインタで、それぞれのオブジェクト、Pairを除く、にヘッダ(単なるunsigned int)を持たせてる。
Moshは全部C++で、オブジェクトはクラスなんだけど、タグと値を保持するだけ。
(まぁ、その他便利関数が入ってるけど)
MoshとYpsilonを混ぜるのが答えになる気がする。
こんな感じで
typedef struct ObjectRec { uint32_t tag; void* value; //多分こいつはintptr_tとかにしないとまずい } Object;っで、シリアライズ可能なオブジェクトはCで書いて、PortとかシリアライズできそうにないのはC++で書けばいいかな。
そもそも、C++のABIがもっとポータルならいいのに。問題の一つは名前マングルにあると思うんだ、うん。
(try-catchの実装とかもそうか・・・)
2010-12-16
続 R6RSのライブラリ その4
理由が全然違うことが発覚した・・・orz
原因はletrec-syntaxでsyntax-rulesにキーワードを入れたら正しく動作しないのが原因だった。
マクロ展開難しすぎる・・・
(ほぼ、Gaucheのを流用してるのになぜ?)
原因はletrec-syntaxでsyntax-rulesにキーワードを入れたら正しく動作しないのが原因だった。
マクロ展開難しすぎる・・・
(ほぼ、Gaucheのを流用してるのになぜ?)
R6RSのライブラリ その4
ライブラリというよりはコンパイラ自身の問題か。
現在自前コンパイラを一つのライブラリにしてコンパイルしようとしている。
コンパイラはGauche上で実装されているので、Gaucheが実行できるコンパイラとそれをR6RSのライブラリにしたコンパイラと2種類ある。
(別に管理するのは面倒なので、cond-expand等を用いてできる限り最小限の重複にしてる、つもり)
っで、ライブラリのコンパイラは一つのライブラリなのにサイズが100KBを超える。多分この辺で問題が発生してる(と思う)。
libraryのコンパイルの順序として、
参照名の解決(不完全実装)、import句の解決、export句の解決、bodyのコンパイルという順番で行っているのだが、
bodyをコンパイルするさ際に、イメージとしてbodyをbeginで包んでからコンパイルしている。
こうすることで1つコンパイル、実行、というのを繰り返さず、全体をコンパイルして実行という感じにできる。
っで、(多分)上記のサイズが問題になってくる。
メモリが足りてないような症状が出てる気がする。というのも中間表現をライブラリ毎にダンプした際に、コンパイラのダンプだけ途中で途切れているからだ。
(本当に途中。ダンプせずに実行するとベクターじゃなく#fだって起こられるのに、ダンプするとぷっつりと死ぬ)
これがWindows版Gaucheだからなのか、そもそもベクターであんまり巨大(といっても目視で16MBしか使ってないけど)なデータを使えない仕様なのかわからない。
解決案は多分いくつかあって、簡単なのでライブラリの分割かな。
ただ、ライブラリを分割するということは、内部にとどめておきたい機能を外部公開する必要がでてくるので、すごく嫌だ。
一つのファイルに複数ライブラリを記述して、参照解決の際の検索方針とかでJava風なライブラリ解決にすれば、実質使えないかもしれないが、ものすごく抵抗がある。
(将来的に直すということにして現状の解決ためということにすればいいのかもしないけど・・・)
さて、どうしたものか。
現在自前コンパイラを一つのライブラリにしてコンパイルしようとしている。
コンパイラはGauche上で実装されているので、Gaucheが実行できるコンパイラとそれをR6RSのライブラリにしたコンパイラと2種類ある。
(別に管理するのは面倒なので、cond-expand等を用いてできる限り最小限の重複にしてる、つもり)
っで、ライブラリのコンパイラは一つのライブラリなのにサイズが100KBを超える。多分この辺で問題が発生してる(と思う)。
libraryのコンパイルの順序として、
参照名の解決(不完全実装)、import句の解決、export句の解決、bodyのコンパイルという順番で行っているのだが、
bodyをコンパイルするさ際に、イメージとしてbodyをbeginで包んでからコンパイルしている。
こうすることで1つコンパイル、実行、というのを繰り返さず、全体をコンパイルして実行という感じにできる。
っで、(多分)上記のサイズが問題になってくる。
メモリが足りてないような症状が出てる気がする。というのも中間表現をライブラリ毎にダンプした際に、コンパイラのダンプだけ途中で途切れているからだ。
(本当に途中。ダンプせずに実行するとベクターじゃなく#fだって起こられるのに、ダンプするとぷっつりと死ぬ)
これがWindows版Gaucheだからなのか、そもそもベクターであんまり巨大(といっても目視で16MBしか使ってないけど)なデータを使えない仕様なのかわからない。
解決案は多分いくつかあって、簡単なのでライブラリの分割かな。
ただ、ライブラリを分割するということは、内部にとどめておきたい機能を外部公開する必要がでてくるので、すごく嫌だ。
一つのファイルに複数ライブラリを記述して、参照解決の際の検索方針とかでJava風なライブラリ解決にすれば、実質使えないかもしれないが、ものすごく抵抗がある。
(将来的に直すということにして現状の解決ためということにすればいいのかもしないけど・・・)
さて、どうしたものか。
2010-12-15
R6RSのライブラリ その3
この話題ばかりだ・・・
展開のフェーズの話。(というよりは依存関係か)
たとえばこのコード
一見何もないように見えるという段階でR6RSのライブラリについて理解してないのだが・・・orz
問題は、subの中で使われているbigger?がフェーズ0でしか参照されないこと。
subが展開されるのはひとつ前のフェーズ1なので、単純にunbound variableな例外を投げてくる。
これを解決するには、bigger?を別ライブラリにして、expandで読み込む必要がある。
まさにこれにはまっていて、
自前実装のコンパイラにライブラリを実装して、R6RSのライブラリにコンバートしてコンパイルなんてことをやっているのだが、
依存関係の解決が面倒くさすぎる。
たとえば、こんなコード
というか、すでに死んでいる・・・
(逆に考えれば、意外と適当に実装したのに、その辺もうまいこと動いているということだが・・・)
これはライブラリの仕組みが悪いのか、Schemeにマクロがあるのが悪いのか(そもそも良い悪いの問題ではないと思うが)
わからないけど、あまり相性が良くない気がする。
プログラマがいろいろなことを気をつければいいのだけど、R5RSで書いてて、R6RSにコンバートするって時に(まさに今)非常に不便・・・
展開のフェーズの話。(というよりは依存関係か)
たとえばこのコード
(library (my-lib) (export sub) (import (rnrs)) (define (bigger? x) (or (> x test))) (define-syntax sub (lambda (x) (syntax-case x () ((_ a b) (or (bigger? (syntax->datum #'a)) (syntax (let ((x b)) (- x 10)))))))) (let () (sub 10 x)))このコード、一見何もないように見えるけど、走らせると死ぬ。
一見何もないように見えるという段階でR6RSのライブラリについて理解してないのだが・・・orz
問題は、subの中で使われているbigger?がフェーズ0でしか参照されないこと。
subが展開されるのはひとつ前のフェーズ1なので、単純にunbound variableな例外を投げてくる。
これを解決するには、bigger?を別ライブラリにして、expandで読み込む必要がある。
まさにこれにはまっていて、
自前実装のコンパイラにライブラリを実装して、R6RSのライブラリにコンバートしてコンパイルなんてことをやっているのだが、
依存関係の解決が面倒くさすぎる。
たとえば、こんなコード
(define something 10) (define-macro (generate) `(make-vector ,(- something 5))) (define generated (generate))こんな感じのをライブラリにするとなると、somethingは外出しにしないと上記の理由で死ぬ。
というか、すでに死んでいる・・・
(逆に考えれば、意外と適当に実装したのに、その辺もうまいこと動いているということだが・・・)
これはライブラリの仕組みが悪いのか、Schemeにマクロがあるのが悪いのか(そもそも良い悪いの問題ではないと思うが)
わからないけど、あまり相性が良くない気がする。
プログラマがいろいろなことを気をつければいいのだけど、R5RSで書いてて、R6RSにコンバートするって時に(まさに今)非常に不便・・・
2010-12-14
続 R6RSのライブラリ その2
よく考えたら(define id expr)の形式で定義されるidは自前VMだとライブラリをプロパティとして持つので、
そこを参照すればいいことに気づいた。
(もともとそのためのものなので早く気づけよ)
とりあえず、importのforキーワードについてはガン無視することにした。
あまりに理解して無さすぎなのと、明確にマクロ展開時((meta 2)以降はそれ以前になるの?)とコンパイル時と分かれているわけではないので、
実装しても煩雑になる上にあまりメリットが享受できそうになかったから。(単なる言い訳)
いい加減ながらライブラリの実装がほぼ完了。あとはバージョンを残すのみ。
でも、バージョンなんてどう管理すんだ?ということで少し整理。
現在のライブラリの構造。
1は現状の構造をいじる必要があるので、少し大掛かりになりそう(そうでもないが)
あぁ、そもそも、キーを(name version)みたいにして、やればいいのか。
(rnrs (6))みたいな例だと(rnrs (6))ってそのままになるな。
(com hoge fuga)ってのだと、適当にバージョン振る必要があるから、まぁ1だろう、こうなる?(com hoge fuga (1))
ということは、バージョンが無いものに関してはバージョンを振って、あるものはそのままキーにすればいいのか。
っで、参照する際に名前とバージョンを解決すればOKと。
とりあえず、この方法で行ってみよう。
どうでもいい話題で、export-allなんてのを作れないかなとか考えていたのだが、
結構大変そうだなぁということに気づいた・・・
importしたシンボルはまぁいいとして、中で定義されてるのを引っ張り出すのが大変そう・・・
でも、rnrsとかの巨大ライブラリを書くときに、export句に全部書き出すのって大変じゃね?っていうだけの話。
そこを参照すればいいことに気づいた。
(もともとそのためのものなので早く気づけよ)
とりあえず、importのforキーワードについてはガン無視することにした。
あまりに理解して無さすぎなのと、明確にマクロ展開時((meta 2)以降はそれ以前になるの?)とコンパイル時と分かれているわけではないので、
実装しても煩雑になる上にあまりメリットが享受できそうになかったから。(単なる言い訳)
いい加減ながらライブラリの実装がほぼ完了。あとはバージョンを残すのみ。
でも、バージョンなんてどう管理すんだ?ということで少し整理。
現在のライブラリの構造。
top-libraries - 単なるハッシュテーブル library - name, imported, exported, tableを持つクラス(もしくは構造体)になる予定 (現在は単なるベクター) 構造として top-libraries = (lib1 => (lib1 instance) lib2 => (lib2 instance)) こうなってるので、このどこかにバージョンをねじ込む必要がある。 案1: もう一枚かませる。こんな感じ。 top-libraries = (lib1 => (version1 => (lib1 v1 instance) version2 => (lib1 v2 instance)) lib2 => (version1 => ... )) 案2: キーにしてる名前にバージョンをくっつける。 top-libraries = (lib1version1 => (lib1 v1 instance) lib1version2 => (lib1 v2 instance)) lib2version1 => ... ) 案3: そんなことよりカラオケ行こうぜ!3は無いとして(当然)、2だと微妙にメモリ消費が少なくなる気がするけど、バージョンマッチで死ぬ気がする。
1は現状の構造をいじる必要があるので、少し大掛かりになりそう(そうでもないが)
あぁ、そもそも、キーを(name version)みたいにして、やればいいのか。
(rnrs (6))みたいな例だと(rnrs (6))ってそのままになるな。
(com hoge fuga)ってのだと、適当にバージョン振る必要があるから、まぁ1だろう、こうなる?(com hoge fuga (1))
ということは、バージョンが無いものに関してはバージョンを振って、あるものはそのままキーにすればいいのか。
っで、参照する際に名前とバージョンを解決すればOKと。
とりあえず、この方法で行ってみよう。
どうでもいい話題で、export-allなんてのを作れないかなとか考えていたのだが、
結構大変そうだなぁということに気づいた・・・
importしたシンボルはまぁいいとして、中で定義されてるのを引っ張り出すのが大変そう・・・
でも、rnrsとかの巨大ライブラリを書くときに、export句に全部書き出すのって大変じゃね?っていうだけの話。
R6RSのライブラリ その2
前回の投稿にコメントをいただいて、ちょっと舞い上がっていたり。
(と同時に、Googleか何かの検索エンジンで調べた結果、役立たずなブログにぶつかったぞ、この野郎!と思われてないか不安にもなったり・・・)
自前実装で、簡単なimportとexportを実装したら不思議な現象(いや、原因はわかっているが)に出くわした。
R6RSのライブラリのフェーズの部分というかimport句の部分なの(か?)
前回syntax-caseで書いた部分、
っで、これが実際に呼ばれる部分はmy-lib3内なので、問題が起きる。
(er-macro-transformerをsyntax-caseの代わりに使ってるからかもしれんが・・・)
書いてる途中で、単に名前解決の仕方がおかしいだけということに気づいた。
考えをまとめるのに、何かに書くというのは有効であるw
my-lib3読み込み → マクロ展開※1 → ライブラリコンパイル
という流れで、※1の展開時にmy-lib2内でexportされてないけど必須になるbigger?の解決を行えばいいのだろう。
一時的にmy-lib3内に取り込んで、展開終了時に開放すればいいか?
まじめにフェーズを実装すればいいんだろうけど、大変そうだしなぁ・・・(よく理解してないし。。。)
(と同時に、Googleか何かの検索エンジンで調べた結果、役立たずなブログにぶつかったぞ、この野郎!と思われてないか不安にもなったり・・・)
自前実装で、簡単なimportとexportを実装したら不思議な現象(いや、原因はわかっているが)に出くわした。
R6RSのライブラリのフェーズの部分というかimport句の部分なの(か?)
前回syntax-caseで書いた部分、
(library (my-lib2) (export sub) (import (for (my-lib1) expand) (rnrs)) (define-syntax sub (er-macro-transformer (lambda (form rename compare) (or (bigger? (cadr form)) `(let ((x ,(caddr form))) (- x 10))))))) (library (my-lib3) (export result) (import (my-lib2) (rnrs)) (define (result x) (sub 10 x))) (import (my-lib3) (rnrs)) (display (result 10))my-lib2は展開するためにbigger?をimportしてる。
っで、これが実際に呼ばれる部分はmy-lib3内なので、問題が起きる。
(er-macro-transformerをsyntax-caseの代わりに使ってるからかもしれんが・・・)
書いてる途中で、単に名前解決の仕方がおかしいだけということに気づいた。
考えをまとめるのに、何かに書くというのは有効であるw
my-lib3読み込み → マクロ展開※1 → ライブラリコンパイル
という流れで、※1の展開時にmy-lib2内でexportされてないけど必須になるbigger?の解決を行えばいいのだろう。
一時的にmy-lib3内に取り込んで、展開終了時に開放すればいいか?
まじめにフェーズを実装すればいいんだろうけど、大変そうだしなぁ・・・(よく理解してないし。。。)
2010-12-13
R6RSのライブラリ
とりあえず、ここを読んでからR6RSを読んでみた。
まぁ、理解できたが、じゃあ既存の実装はどうなってるの?と思い調べてみた。
調査対象:Petite Chez Scheme、Ypsilon、mosh(nmosh)
調査プログラム
で、結果。
run:
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
expand:
petite: 0
Ypsilon: 0
nmosh: 0
(meta 0):
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
(meta 1):
petite: 0
Ypsilon: 0
nmosh: 0
(meta 2):
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
見た感じとして、Petite、Ypsilonはフェーズ関係をガン無視してるくさい。Shibuya.lisp #2か#3だかの資料によると、バグくさいのも実装したと言っているので、意図的?なものかもしれない。Petiteはよく知らん。
逆にnmoshはこの辺の宣言がきちんとされていないとまずいみたい。これはAndre Van Tonderのexpanderがそういう実装なのだろう。
この辺は仕様書に明確に書いてあるので、nmoshが正解なのだろうが、そんなもの考えてプログラム書きたくないなぁと思うとYpsilon実装にした方がいいのか?
まぁ、理解できたが、じゃあ既存の実装はどうなってるの?と思い調べてみた。
調査対象:Petite Chez Scheme、Ypsilon、mosh(nmosh)
調査プログラム
(library (my-lib1 (1)) (export bigger?) (import (rnrs)) (define (bigger? x) (or (> x 10)))) (library (my-lib2) (export sub) (import (for (my-lib1) (meta 1)) ; run expand (meta 0) (meta 1) (meta 2)に適宜変更 (rnrs)) (define-syntax sub (lambda (x) (syntax-case x () ((_ a b) (or (bigger? (syntax->datum #'a)) (syntax (let ((x b)) (- 10 b))))))))) (library (my-lib3) (export result) (import (my-lib2) (rnrs)) (define (result x) (sub 10 x))) (import (my-lib3) (rnrs)) (display (result 10))こんなの。特に何の意味もないプログラムだが、フェーズを調べるには必要十分なのでOK。
で、結果。
run:
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
expand:
petite: 0
Ypsilon: 0
nmosh: 0
(meta 0):
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
(meta 1):
petite: 0
Ypsilon: 0
nmosh: 0
(meta 2):
petite: 0
Ypsilon: 0
nmosh: error bigger?がない
見た感じとして、Petite、Ypsilonはフェーズ関係をガン無視してるくさい。Shibuya.lisp #2か#3だかの資料によると、バグくさいのも実装したと言っているので、意図的?なものかもしれない。Petiteはよく知らん。
逆にnmoshはこの辺の宣言がきちんとされていないとまずいみたい。これはAndre Van Tonderのexpanderがそういう実装なのだろう。
この辺は仕様書に明確に書いてあるので、nmoshが正解なのだろうが、そんなもの考えてプログラム書きたくないなぁと思うとYpsilon実装にした方がいいのか?
2010-12-05
昨日の風景
今日は3度と暖かいので、雪が融けてきてる。いいことだ。
ライデン中央系の様子。
どこが道だか分からんw
近所の川(というか溝というか運河というか)の様子。
どこが水だった場所でしょう?
正解は中央部分。木の柵に見えるのは橋なのでその周りの雪は水だった場所です。
今は融けてるはず。(今日は確認して無いので不明)
今週からは暖かいはずなので、ちょっと一息といったところか。
ライデン中央系の様子。
どこが道だか分からんw
近所の川(というか溝というか運河というか)の様子。
どこが水だった場所でしょう?
正解は中央部分。木の柵に見えるのは橋なのでその周りの雪は水だった場所です。
今は融けてるはず。(今日は確認して無いので不明)
今週からは暖かいはずなので、ちょっと一息といったところか。
2010-12-01
寒い!!
今週くらいから急に、しかもとてつもなく寒くなった。
現在午前7時、気温-6度!!
天気予報によると、風が強いので体感は-20度(!?)くらいらしい。
ようこそミニ氷河期へ。
地球温暖化とはいったいなんだったのか・・・
現在午前7時、気温-6度!!
天気予報によると、風が強いので体感は-20度(!?)くらいらしい。
ようこそミニ氷河期へ。
地球温暖化とはいったいなんだったのか・・・
2010-11-15
メジャーデビュー決まりました
Mixiで変なバトンを踏んだので・・・
これ、マイミクの部分どうすればいいんだよ・・・
しかも、足跡残らねえよ・・・
内容は以下。
☆☆☆☆☆☆☆☆☆☆☆☆
バンドバトン♪♪
見てしまった人は必ずやること♪
足跡に残るので逃げられませんよ♪
タイトルは『メジャーデビュー決まりました』にすること♪
見た以上は必ずコメントすること♪
♪本名は?
⇒外部ブログなのでさすがに伏せさせてくださいm(_ _)m
♪ステージネームは?
⇒ねえよ
♪担当パートは?
⇒Topテナー
♪そのパートを選んだ理由は?
⇒低音が出ないから、High Cとかその辺の音が出る人があんまりいないから
♪メインで使ってる楽器はどんなの?
⇒ファルセットと実声の中間
♪それを選んだ理由は?
⇒高音をきれいに出すにはと試行錯誤した結果、あんまり力まずそこそこ張れるから
♪その楽器のPRポイントは?
⇒High G(ソプラノのG)くらいまでがんばれば出せます(使い物にはならんが・・・)
♪歴はどれくらい?
⇒そろそろ10年か(でも、ここ2年はやってないからもっと少ないか)
♪初めて完コピーした曲は?
⇒ゴスペラーズの星屑の街かな
♪その曲を選んだ理由は?
⇒アカペラの曲で有名なのは少ないのよ
♪憧れのミュージシャンは?
⇒昔はパバロッティ、今は誰だろ?
♪好きなミュージシャンは?
⇒たくさん
♪好きな曲を1曲挙げるとすると?
⇒一曲なんて無理です・・・
♪好きなジャンルは?
⇒最近はHipHopとかも聞くようになったし、おそらく演歌以外すべてかと
でも、あんまり意味不明なジャンルは聞かない
♪今バンド組んでる?
⇒組んでない。
オランダ在住で、アカペラやりたい人やりませんか?w
♪バンド組んでる人はバンド名を教えて下さい
⇒組んでない
♪プロは目指してる?
⇒プロってなに?
♪ライブの失敗談はありますか?
⇒結婚式で歌ったときに、オルガンの演奏がまったく聞こえず、意味不明になった
♪担当パートの楽器にいくらぐらい遣った?
⇒無料、タダ、Free、Gratis
♪生まれ変わってもバンドをやるならパートは何がいい?
⇒楽器を使うパートかな・・・でもアカペラも楽しいんだよね・・・
♪付き合う前の好きな異性をライブに呼んだことはある?
⇒ない
♪その異性とはいい感じになった?
⇒ない
♪その異性と今は?
⇒何の質問だこれ?
♪このバトンを見た人は必ずやらなければなりませんが、中でも特にやってほしいマイミクを5人挙げて下さい
⇒マイミク少ないのに・・・
Rogさん
Zestさん
まっけんじーさん
ラフマさん
うまmiさん
バンド組んでない人は、架空のバンドを想定してくださいm(_ _)m
上三人はB.G.M.でOKだと思います。
♪最後になりますが、音楽は世界を救うと思いますか?
⇒戦闘なんてくだらねぜ、俺の歌を聞け~!!!
こうですか?
以上
☆☆☆☆☆☆☆☆☆☆☆☆
これ、マイミクの部分どうすればいいんだよ・・・
しかも、足跡残らねえよ・・・
内容は以下。
☆☆☆☆☆☆☆☆☆☆☆☆
バンドバトン♪♪
見てしまった人は必ずやること♪
足跡に残るので逃げられませんよ♪
タイトルは『メジャーデビュー決まりました』にすること♪
見た以上は必ずコメントすること♪
♪本名は?
⇒外部ブログなのでさすがに伏せさせてくださいm(_ _)m
♪ステージネームは?
⇒ねえよ
♪担当パートは?
⇒Topテナー
♪そのパートを選んだ理由は?
⇒低音が出ないから、High Cとかその辺の音が出る人があんまりいないから
♪メインで使ってる楽器はどんなの?
⇒ファルセットと実声の中間
♪それを選んだ理由は?
⇒高音をきれいに出すにはと試行錯誤した結果、あんまり力まずそこそこ張れるから
♪その楽器のPRポイントは?
⇒High G(ソプラノのG)くらいまでがんばれば出せます(使い物にはならんが・・・)
♪歴はどれくらい?
⇒そろそろ10年か(でも、ここ2年はやってないからもっと少ないか)
♪初めて完コピーした曲は?
⇒ゴスペラーズの星屑の街かな
♪その曲を選んだ理由は?
⇒アカペラの曲で有名なのは少ないのよ
♪憧れのミュージシャンは?
⇒昔はパバロッティ、今は誰だろ?
♪好きなミュージシャンは?
⇒たくさん
♪好きな曲を1曲挙げるとすると?
⇒一曲なんて無理です・・・
♪好きなジャンルは?
⇒最近はHipHopとかも聞くようになったし、おそらく演歌以外すべてかと
でも、あんまり意味不明なジャンルは聞かない
♪今バンド組んでる?
⇒組んでない。
オランダ在住で、アカペラやりたい人やりませんか?w
♪バンド組んでる人はバンド名を教えて下さい
⇒組んでない
♪プロは目指してる?
⇒プロってなに?
♪ライブの失敗談はありますか?
⇒結婚式で歌ったときに、オルガンの演奏がまったく聞こえず、意味不明になった
♪担当パートの楽器にいくらぐらい遣った?
⇒無料、タダ、Free、Gratis
♪生まれ変わってもバンドをやるならパートは何がいい?
⇒楽器を使うパートかな・・・でもアカペラも楽しいんだよね・・・
♪付き合う前の好きな異性をライブに呼んだことはある?
⇒ない
♪その異性とはいい感じになった?
⇒ない
♪その異性と今は?
⇒何の質問だこれ?
♪このバトンを見た人は必ずやらなければなりませんが、中でも特にやってほしいマイミクを5人挙げて下さい
⇒マイミク少ないのに・・・
Rogさん
Zestさん
まっけんじーさん
ラフマさん
うまmiさん
バンド組んでない人は、架空のバンドを想定してくださいm(_ _)m
上三人はB.G.M.でOKだと思います。
♪最後になりますが、音楽は世界を救うと思いますか?
⇒戦闘なんてくだらねぜ、俺の歌を聞け~!!!
こうですか?
以上
☆☆☆☆☆☆☆☆☆☆☆☆
2010-11-12
syntax-case続き
とりあえず、こういう方針でいこうという考えをまとめておく。
syntax-case自体はコンパイラとは関係ない(ないことはないが)、ライブラリとする。
define-syntaxで定義された構文は変換器を返し、変換器が変換する。
(Gaucheはそうしてると思う。ソース見る限り・・・今のところsyntax-rules限定っぽいけど)
define-syntaxで定義された構文にS式が与えられた場合、構文オブジェクトとしてすべての引数を与える。
こんな感じ?
(print 1 2) -> (transformer syntax-rules '(syntax-object (print 1 2)))
: with-syntaxは略
-> (transformer syntax-case '(syntax-object ...#;多分この辺にsyntax-rulesで作られたtempleteが入る (print 1 2)))
正しいのかよくわからん。その上、どう実装していいのかもよくわからん・・・
syntax-case自体はコンパイラとは関係ない(ないことはないが)、ライブラリとする。
define-syntaxで定義された構文は変換器を返し、変換器が変換する。
(Gaucheはそうしてると思う。ソース見る限り・・・今のところsyntax-rules限定っぽいけど)
define-syntaxで定義された構文にS式が与えられた場合、構文オブジェクトとしてすべての引数を与える。
こんな感じ?
(define-syntax sample (lambda (x) (syntax-case x () ....))) (sample 1 2 3) ;; <- この1 2 3っていうのがsyntax-caseによって処理されるために構文オブジェクトになるということは、マクロを展開する際に、S式をいったん構文オブジェクトにする必要がありそう。 これで、syntax-caseを定義するとすると
(define-syntax syntax-case (lambda (x) ... ;; いろいろ定義がいりそう? ;; x は構文オブジェクト。matchはAndrew Wrightみたいなの(構文オブジェクトにも対応) (match x ((_ e ((? literal? literals) ...) clauses ...) ...)))) ;; きっといろいろするっで、こいつ自体が変換器なので、syntax-rulesはこう書いて
(define-syntax with-syntax (lambda (x) (syntax-case x () ((_ () e1 e2 ...) (syntax (begin e1 e2 ...))) ((_ ((out in)) e1 e2 ...) (syntax (syntax-case in () (out (begin e1 e2 ...))))) ((_ ((out in) ...) e1 e2 ...) (syntax (syntax-case (list in ...) () ((out ...) (begin e1 e2 ...)))))))) (define-syntax syntax-rules (lambda (x) (define clause (lambda (y) (syntax-case y () (((keyword . pattern) template) (syntax ((dummy . pattern) (syntax template)))) (_ (syntax-violation 'syntax-rules "Invalid expression" x))))) (syntax-case x () ((_ (k ...) cl ...) (for-all identifier? (syntax (k ...))) (with-syntax (((cl ...) (map clause (syntax (cl ...))))) (syntax (lambda (x) (syntax-case x (k ...) cl ...))))))))syntax-rulesで定義された構文は 構文 -> syntax-rules変換器 -> syntax-case変換器 -> ごにょごにょ という感じになるはず。 こんなのは
(define-syntax print (syntax-rules () ((_ o) (begin (display o) (newline))) ((_ o1 o2 ...) (begin (display o1)(newline) (print o2 ...))))) (print 1 2)こうなる?
(print 1 2) -> (transformer syntax-rules '(syntax-object (print 1 2)))
: with-syntaxは略
-> (transformer syntax-case '(syntax-object ...#;多分この辺にsyntax-rulesで作られたtempleteが入る (print 1 2)))
正しいのかよくわからん。その上、どう実装していいのかもよくわからん・・・
Subscribe to:
Posts (Atom)