2010-12-29

続 C言語でオブジェクト指向

バスに揺られた帰り道に思いついた。
忘れないうちにメモしておこう。

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に移植してる最中でぶつかった壁。
まだぶつかってるので躓いてる壁か?

単一クラス、振る舞いは変わるが継承、多態はないのなら、こんなのでいける。
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!

2010-12-22

C++/Cで書き始めたい

だいぶ自前Schemeがまとまってきたので、そろそろC++かCで書き始めようと思う。
コンパイラ(+その周りのライブラリ)はコンパイルされたコードをC(多分CよりなC++)にコンバートすればいいとして、
(それでも、ライブラリのインポートとか識別子どうしようとか問題はあるけど)
どこまでをCで書いて、どこからをC++で書こうか迷い中。

迷う理由としてはこんな感じ。
  1. C++だとバイナリ互換がない、つまりアプリケーション組み込みに向かない
  2. C++にはtemplate、class、関数オーバーロードなどCにはない機能がある
1.はアプリケーション組み込みをするのかという話にもなる。でも、たとえばDLLでモジュール(ライブラリか?)を作成したいと思ったときに、Cまたは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のを流用してるのになぜ?)

R6RSのライブラリ その4

ライブラリというよりはコンパイラ自身の問題か。

現在自前コンパイラを一つのライブラリにしてコンパイルしようとしている。
コンパイラは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

この話題ばかりだ・・・

展開のフェーズの話。(というよりは依存関係か)
たとえばこのコード
(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)以降はそれ以前になるの?)とコンパイル時と分かれているわけではないので、
実装しても煩雑になる上にあまりメリットが享受できそうになかったから。(単なる言い訳)

いい加減ながらライブラリの実装がほぼ完了。あとはバージョンを残すのみ。
でも、バージョンなんてどう管理すんだ?ということで少し整理。
現在のライブラリの構造。
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で書いた部分、
(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)
調査プログラム
(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

近所の川(というか溝というか運河というか)の様子。
どこが水だった場所でしょう?
正解は中央部分。木の柵に見えるのは橋なのでその周りの雪は水だった場所です。
今は融けてるはず。(今日は確認して無いので不明)

今週からは暖かいはずなので、ちょっと一息といったところか。

2010-12-01

寒い!!

今週くらいから急に、しかもとてつもなく寒くなった。
現在午前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だと思います。

♪最後になりますが、音楽は世界を救うと思いますか?

⇒戦闘なんてくだらねぜ、俺の歌を聞け~!!!
こうですか?

以上

☆☆☆☆☆☆☆☆☆☆☆☆

2010-11-12

syntax-case続き

とりあえず、こういう方針でいこうという考えをまとめておく。

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)))

正しいのかよくわからん。その上、どう実装していいのかもよくわからん・・・

syntax-caseの実装

Schemeの話。

マクロの展開を実装しようとした際に、syntax-caseがどうしてもキーワードになる。
これはなんだ?
いや、何かはわかっているんだけど、R6RSの仕様書を見ると、こいつはライブラリだと書かれている。

っで、いろいろなR6RS準拠の処理系で試したところ、
どうもこいつはキーワードっぽい動きをする。(defineとかlambdaとか見たいな)

ということは、組み込みか、(define-syntax ...)で定義されたものかという気がする。
っで、仕様書にはライブラリと書かれている・・・
syntax-rulesとかはsytax-caseで定義できるみたいだが、
syntax-caseはどうやって定義するのだろう?
こんな感じ?
(define-syntax syntax-case
   (lambda (form literal rules)
     ...))
っで、適当にパースすればOK?

ちなみに、psyntaxはよく知らないけど、
YpsilonとかAndre van Tonderのexpanderとかだと割りと組み込みみたいな書き方してる。
(コンパイラが持ってるわけじゃないからライブラリ?)
細かいこと考えなくてもいい?
う~ん。

2010-11-05

【尖閣ビデオ】見た!!!!

昨日の夜(といっても日本時間なら午前5時か6時くらい)にYoutubeにアップされていたビデオを見た。
中国は真っ黒です!!

これみて、コツンと当たったとか、日本側が悪いとか言ってるアホ議員がいるということが正直信じられない。
個人的な意見だけど、これ逆の立場だったら中国は最大級の外交カードとして使うだろう。
そもそも、領海侵犯してる漁船が体当たり+逃亡なんてロシアとかアメリカに対してやったら船がこの世から消えてるレベル。

この動画の2分くらいのところから:

明らかにぶつけにきて、かつ逃亡。

こっちの方は海保の船「みずき」が黒煙を上げてる:


これで
こんな穴が船体右側に空くわけがない!!!
ってか、仮に先端部が当たってあいたとして、真四角の穴が開くわけないだろ!!

これで船員を釈放した無能議員とか死んでいいんじゃね?

2010-11-02

Infoseekが終了した

まぁ、2ヶ月くらい前から知っていたことではあるが、自分の過去のHPも一緒に消えた。
(メンテナンスしてなかった上に、FTPのパスワード忘れちゃったのでどうにでもなれ状態ではあったが・・・)

困るなぁと思うのは、自分のとは違って有益な情報を載せてるサイトが結構多かったので、移転せずに消えてしまったらいやだなぁということ。
有料のサービスは残るとのことなので、有益サイトがそっちだったらいいなぁ・・・

2010-10-28

Movie: It Could Happen to You(邦題:あなたに降る夢)

1994年なんだこれ・・・
実話をヒントに作られた映画。ジャンルはラブコメでいいのかな?
あらすじと実話は適当にググってください。

感想。ニコラス・ケイジ演じるチャーリーの駄目男っぷりと、その妻の強欲っぷりが素敵な映画。
ブリジット・フォンダ演じるイヴォインヌの薄幸ぶりもかな?
いや、まだ観てるんだけど実は、今のところの感想として、宝くじは結婚してから買っては駄目だね。当たったらいろいろ火種にしかならない気がする。
ってか、ニューヨーカーとマスコミは主人公2人に振り回されすぎ。宝くじが当たったからといってそこまで追跡されんと思うぞ。
(書いてる途中で終わった)

なんというか、女が腐ったような男(イヴォインヌの元夫)とか嫌いなタイプの人間が出てくる映画ってあまり好きじゃなかったり・・・
借金背負わせて逃げたくせに、2億入ったから戻ってくるって、どの面下げて(ryって感じ。

個人的に最後のお約束は要らないんじゃないかなぁとは思った。別に強欲妻は勝ち逃げでもよくね?金手に入れるために裁判して、60過ぎのおじいちゃんと結婚までしたんだから?
ま、お約束がないといかんのだろうけど、ハリウッド映画って。

見る価値は、野郎だけでなら0かな。

2010-10-20

寒い!!!

先週くらいから急激に寒くなった。
最低気温が3度とかある・・・

んで、今日は雹が降ってきた!!!
どうやら上空には寒気団があるくさい。

まだ10月なのに冬の到来を感じる。
12月とかになったら氷点下確定コースかなぁ?
-10度とか去年だけのことだと思いたい・・・

2010-10-15

契約更改の話

僕自身の契約更改は順調に終わり、無事に正社員になったわけだが、
そうでは無い人もいたという話。

実際知ったのは今日(昨日?)なのだが、僕より二週間早く入社した人が8月の段階で契約延長(もしくは正社員になる契約)をしないということだった。
そういえば今週の頭から姿を見てないなぁ、と思っていたらその通知のメールと、PC撤去が同時できた。
(ちなみに、席は僕の目の前)
理由は知らない。あまり一緒に仕事したことはないが(一時期同じプロジェクトにいたくらい)、可もなく不可もなくという感じの仕事ぶりだった気がする。
(個人的には汚いコードを書くなぁとは思っていたが・・・)

まぁ、理由は以下のどれかなのは自明で、
・解雇
・自主退職
ってか大別するとこの2つしかないわけで。

8月の時点ですでに話し合っていたということは、おそらく後者かな?
僕が契約更改の話を受け取ったのは9月に入ってからだし。最近まで何かのプロジェクトに参加してたみたいだし。
もし、解雇だとしたら、当然それは僕だったかもしれなくて、なんて考えるとちょっと複雑な気分であった。

2010-10-01

ハッシュテーブルの検索

超有名なデータ格納の方法の一つ。
諸事情により、自前でハッシュマップとハッシュセットを作る必要があったので、作ってみた。
理論上計算回数がΟ(1)でいけるはずなんだけど、どうもそんな感じがしない。

っで、STLのsetと自作ハッシュセットで比較してみた。
結論だけ言うと、
ハッシュセットは早いけど遅い。
なんのことだ?と思うかもしれないけどそんな感じ。
実装の都合上、衝突が起きた際に得られたハッシュ関数で得られたハッシュ値を増やして空きを探したり、
要素が存在しているか検索しているのだが、これがまずい。
無限の箱があってハッシュ値も衝突がおき得ないのならΟ(1)なんだろうけど、箱は有限。っで箱が50000とか超えた時に、存在しない値の検索をすると、ループが50000回走る。つまりΟ(n)になる。
う~ん、存在する値だとものすごく早くてそれこそΟ(1)に近い値が出るんだけど、う~ん。
衝突時にリストにしてもいいけど、メモリ管理が面倒な気がする・・・う~ん・・・

どうでもいいけど、
「Ο」これ「O(アルファベット)」じゃなくて「Ο(オミクロン)」だったのね。初めて知った^^;

契約更改

今の職場についてほぼ1年が過ぎようとしている。
契約は最初は1年契約なので、今日契約の更新の面接があった。

結果、無事正社員に昇格!
昇給もしたし、う~ん、いいことだ。

オランダだと一年で正社員になるというのは珍しいらしく、普通はなんだかんだ契約の延長だけというのが間々あるらしい。
マネージャー(日本語に直すとなんだ?部長とかそれ以上?)との面接で、
働きぶりに満足してるし、ここで働いてほしいというようなことも言ってもらえたのだが、
しかし、正直ほとんど何もしてないに近いくらい楽な仕事なのだが、
いいのだろうかと不安になる。
(もちろんやることはやっているのだが、いかんせん楽すぎる)

ま、プログラマは天職なんだということにしておこう。

iPhone

いろいろな経緯からiPhoneが今手元にある。
3Gなので一つ前のだ。

PDAかつiPodに電話がついてる感じで、正直もてあましてる感が大きいが今のところ気にいっている。

誰か、お勧めアプリを教えてくれ!

2010-09-26

Cygwinのメモリ

Cygwinだけなのか、Mingwもなのか、そもそもC++の企画なのか分からんけど、メモリの確保ではまった話。

Cygwin上のGCCで(正確にはG++)1M以上のメモリを確保して、そのメモリに生でアクセスしようとしたらセグメンテーションフォールトが起きた。
なんでだろうと思ったが、プログラム全体で見ると動いていたのでとりあえず放置していたのが、やっぱりおかしいよなぁと思って検証してみた。

検証プログラム
#include "test-a.h"
#include 
int main()
{
  void* p = (void*)new char[1024* 1024];
  printf("%p\n", p);

  test t;
  t.print();

  test *t2 = new test();
  t2->print();
  delete t2;
  return 0;
}
test-a.hはtestクラスを持ち、そのコンストラクタ内で1Mのメモリをoperator newで確保し、printメソッドでメモリアドレスをプリントする。それだけ。
実際はtestクラスの詳細はスタティックライブラリにしてある。スタティックライブラリの制限かなとも思ったので。

結果。
そもそも最初のnewで死んでた。
帰ってきたアドレスが、0x7fea0008。完全に死亡アドレスです。
理由は分からんが、アウトなんだろう。

しょうがないのでとりあえずWin32APIのVirtualAllocを使って回避。こっちならOKっぽい。
この制限があると、多き目のメモリープールとか不可能になる気がするが、どうなんだろう?
ってか、一気にメガ単位で確保しちゃ駄目ってこと?
誰か理由教えて(´;ω;`)

2011/10/25 追記
ひょっとしたらこの辺と関係あるかも=>Cygwinのヒープ

2010-09-13

英語の発音について

英語の発音で日ごろ理不尽に感じてることをちょっと書いてみる。
(なんで今更こんなことをとか自分で突っ込み)

同スペル、異発音
Houston:
/ˈhjuːstən/ ≒ ひゅーすとん と発音すればテキサス州の都市(が有名、ほかにもある)
/ˈhaʊstən/ ≒ はうすとん と発音すればニューヨーク市の通りの名前(が有名、ほかにもある)

読みにくい系
simultaneously:
/ˌsī-məl-ˈtā-nē-əs-ly/ ≒ さいみゅるてにあうすりぃ。
ちなみにsimulateは/ˈsim-yə-ˌlāt/ ≒ しみゅれいと だったりする。(個人的に前者は米語だと思ってる)。

cupboard:
/ˈkʌbərd/ ≒ かばーど。知らなきゃ読めない。
ちなみに、boardは/bord/ ≒ ぼーど なので、後半だけ見ると同スペル、異発音かも。

nature:
/ˈnā-chər/ ≒ ねいちゃー。でもこれ、naturalになると/ˈna-chə-rəl/ ≒ なちゅらる になる。

英語と米語で発音が違う系
tomato:
「これが、"とめいと"だと!」と中学に入ってまず間違いなくショックを受けた言葉の一つだと思う。でも、英語(イギリス系)だと"とまーと"と発音したりする。ちなみに、tamagoは「ためいご」ではないのであしからず。

あんまりぱっと思いつかなかった。
この手のねたは需要があるかテストもかねて投稿してみたり。

2010-09-03

Java: Preferenceクラス

Javaのことを書くなんて本当はしたくないがあまりにネタがないので。
(Schemeの方は遅々として進まん・・・orz)

仕事は当然Javaを使うのだが、APIではまった話。
Preferenceというクラスがあるのだが、こいつは設定とか値をプラットフォーム固有の方法で永続化して使いまわせる便利なもの(のはず)
っで、今のプロジェクトでこいつを使っているのだが、なんか値がおかしい。
Windowsなので、レジストリに登録されるのだが、どうも1個しか値が存在してない。
っで調べてみた。

JavaDocによると、こいつはノードを取得する際にクラスを要求するくせに、値の保存はパッケージごとに行われるということ。クラスを要求するのは、パッケージ名を取得するためだけみたい。
つまり、
foo.bar.Hogeと、foo.bar.FugaっていうクラスでPreferenceを使うと値が共有されるらしい。
この方がありがたい人もいれば、そうじゃない人もいるだろう。僕は後者なわけだが・・・

foo.bar.configなんてパッケージを作ってその下にいくつかの設定値クラスなんかを作った場合問題になる、というか僕の問題はまさにこれ。
パッケージごとに一個の永続値って需要があるのだろうか?
ドキュメントをしっかり読めば早期発見できた問題ではあるが・・・

2010-08-15

前回から1ヶ月くらい離れてるなぁ・・・

日本にいたときは便利だったなぁという話。

スーパーとかなら切り身で売ってるけど、
マーケットで魚を買うとあまり魚はきれいになっていない。
頭、内臓、鱗のことだけど。
鮮度とか安さとかならきっと上なんだと思うけど、よくて内臓くらいまでか、さばいてくれるの?
しょうがないので、包丁で鱗を落とすし、三枚にもおろす。
(身が骨の方にたくさんつくときもあるが)

この辺のサービスは絶対的に日本の方がいい気がする。
しても、追加料金取るとかざらだし。
こっちの人たちあんまり客を大切にしないイメージ。

日本が過剰サービス過ぎなのか?

2010-07-16

どれが正しいんだ?

Schemeでdefine-syntaxの実装をしないといけないことに気づき、ちょっと調査。
単にマクロ展開のタイミングの話なのかな?

(import (rnrs))
(define (print x)
  (display x)
  (newline))

(define x 1)
(define (incf x . i)
  (if (pair? i)
      (begin (set! x (+ x (car i)))
      (print "procedure")
      x)
      (begin (set! x (+ x 1))
      (print "procedure")
      x)))
(print (incf x 2))

(define (test x i)
  (print (incf x i)))
(test x 1)

(print "define incf as define-syntax!")

(set! x 1)
(define-syntax incf
  (syntax-rules ()
    ((_ x) (begin (set! x (+ x 1)) x))
    ((_ x i) (begin (set! x (+ x i)) x))))
(print (incf x 2))
(test x 1)
こんなコードを、Chez(7.9.4)、Ypsilon(0.9.6-update3)、Mosh(0.2.5)に食わせてみる。

結果。
Chezは正常終了。最後の(test x 1)で展開されると思われてincfマクロは展開されず。
Ypisilonは最後の(test x 1)でincfの定義がない(多分、マクロで上書きされたから?)と怒る。
Moshはincfが複数定義されたといって例外。

それぞれの結果はこれ。
Chez
------------
procedure
3
procedure
2
define incf as define-syntax!
3
procedure
4
------------

Ypsilon
------------
procedure
3
procedure
2
define incf as define-syntax!
3

error: unbound variable incf

backtrace:
0 (incf x i)
..."D:/home/t.kato/test.scm" line 18
1 (test x 1)
..."D:/home/t.kato/test.scm" line 29
------------

mosh
------------
Condition components:
1. &who who: incf
2. &message message: "multiple definitions of identifier"
3. &syntax form: incf
subform: #f

Exception:
error in raise: returned from non-continuable exception

Stack trace:
1. throw:
2. (raise c): baselib.scm:943
3. apply:
------------

これだけバラバラだとどれが正しいのかわからない・・・

2010-07-09

英語で仕事をするということ

最近、楽天の社長が社内公用語を英語にするという記事を読んだのと、
それに反応してソニーかどこかの人がTwitterで、そんなことするくらいなら公用語をC言語にする、などといったのを読んだので無駄に反応してみた。

個人的な意見。
まったく無駄だと思います。
日本に本社があって、社長も日本人で、働いてる人の95%以上が日本人の環境で、英語にする意味がない。こっちで働いていて、使用言語はオランダ語ではなく英語なわけだが、オランダ人同士が会議している場所だと当然オランダ語。
そもそも、怪しい英語で会議しても意味なくね?英語が喋れることが最重要事項な会社って、翻訳会社か何かだと思う。楽天はそっち系に変わるのかね?

できることなら日本語環境がいいなぁと思う人の独り言・・・

2010-07-02

街が揺れた日

その日は暑い夏の日だった。仕事帰りの私はいつもと同じ道を歩いていた。
突如凄まじい轟音とともに街が一瞬揺れた!

えぇ、その瞬間がオランダがブラジルを下したことが決定した瞬間です。
正直、1点とったのかなと思ったんだけど、勝ってました。
ブラジルにですよ。信じられん。

ブラジルに勝てたということはそのまま優勝ということもありえるなぁ。

2010-06-30

C++で書き始めた

Scheme処理系をC++で書き始めた。
(実際は片付いてない問題が多々あるのだが・・・)

とりあえず、コードがVectorで構成されているのでVectorを。あと物が動くとやはりうれしいので、Fixnumなクラスを作成。
xyzzyの参考に(パチッてとも言う)、クラスのタグ付けとか、即値の判定とか作成。
っで、適当にごにょごにょして動かす。

(+ 1 2 3)をコンパイルした結果をC++のオブジェクトに置き換えたものが動いた。
説明が長い・・・

気になる点としては、現状だとコードはベクターの中にベクターが入れ子になるように作ってあるのだが、これだとメモリー効率が激しく悪い気がする。
Schemeで書いてるときは気にしなかったのだが、C++で書いてみると一つのコードを書くのにベクターの割り当てが激しく出てくる感じ。
コンパイラを書き換えて全部フラットにするべきだろうか・・・するべきなんだろうなぁ・・・

2010-06-24

ワールドカップ

日本が3-1でデンマークに勝った!!
何が起きてるんだろう?天変地異の前触れか?

どうでもいいが、ここオランダではサッカーがあるとえらいことになる。
僕の住んでるライデンにはちょっとした広場が街の中央にあるのだが、そこにパブリックビューがあって結構な人が集まっていた。
酒が飲めればいいのか、騒げればいいのか、純粋にサッカーが好きなのかどれなのかは分からないが、街中がやかましい。
噂によると、サッカーの観戦をするために仕事を病欠する人がいるそうだ。
そんな国。

2010-06-22

letのフレーム

A正規化の話だったりする。
たとえばこんなコード(変な数字が入ってるのはα変換後だから)
(define
 tarai
 (lambda
  (x.1 y.2 z.3)
  (if
   (not (< y.2 x.1))
   y.2
   (tarai
    (tarai (- x.1 1) y.2 z.3)
    (tarai (- y.2 1) z.3 x.1)
    (tarai (- z.3 1) x.1 y.2))))
こいつをA正規形にするとこうなる
(define
 tarai
 (lambda
  (x.1 y.2 z.3)
  (let
   ((#:G267 (< y.2 x.1)))
   (let
    ((#:G268 (not #:G267)))
    (if
     #:G268
     y.2
     (let
      ((#:G269 (- x.1 1)))
      (let
       ((#:G270 (tarai #:G269 y.2 z.3)))
       (let
        ((#:G271 (- y.2 1)))
        (let
         ((#:G272 (tarai #:G271 z.3 x.1)))
         (let
          ((#:G273 (- z.3 1)))
          (let
           ((#:G274 (tarai #:G273 x.1 y.2)))
           (tarai #:G270 #:G272 #:G274)))))))))))
見てのとおりコードが増大。それだけならまだいいのだが(よくないが)、問題はコードの増大に伴ってletが出現していること。
前回、継続周りで不具合が起きることを踏まえて、letが現れたらフレームを作るようにコンパイラとVMを修正したのだが、その影響で単なるたらいまわし関数がスタックオーバーフローを起こすようになった。
原因は、この大量のlet。これだけコードが増大すれば当然VMのインストラクションも増大する。どれだけ影響があるかスタックを1000から10000にして上記の関数でベンチマークをとってみた。
4秒が14秒に・・・orz

後の最適化がしやすいようにと思ってのA正規化だが、ちょっとないなぁ・・・
今のところこいつの恩恵って、変数の寿命がわかりやすいことだけだし・・・
どうしよう。

2010-06-18

スタックポインタ、フレームポインタ

Schemeのコンパイラの話。
3impという論文のコンパイラを参考に作っているわけだが、スタックポインタとフレームポインタではまった。
(ってか、今でも解決してない)

ここにあるスタックとフレームの関係を参考にして、letのコンパイルをしたのだが、上手くいかない。
原因は分かっている。本来はletごとにフレームを作成して自由変数とかの解決をしないといけないのに、フレームを作るコストを嫌って、letが続く限り一つのローカルフレームのようにしたから。
そもそも、letではフレームを作ってないので、フレーム情報があることを前提にしているVMインストラクションでおかしなことが起きる。

どうしよう。
とりあえず、Gaucheがletをどう処理してるのかdisasmしてみた。
...
let毎にフレーム作ってる・・・
やっぱりそうするべきかなぁ?でもA正規化後ってあほかと思うほどletが増えるんだよなぁ・・・
その辺も踏まえてどうしよう。

2010-06-15

コンパイル

いろいろ弄って、letをコンパイルできるようにした。
意外と上手くいくもんだ。四苦八苦したけど・・・

っで、たらいまわし関数を動かしてみたら、10,5,0の引数で36秒かかる・・・
まぁ、schemeをscheme上で動かしてるのでオーバーヘッドとかもあるだろう。っがあまりに遅いのでできそうな高速化を施すことに。
現状リストでVMのインストラクションを書いていたが、全部ベクターに変更。でも、面倒くさがりなので、
ベクターの中にベクターを入れるといういんちき(?)をして、データ構造は特に変更しない。
勢いあまってVMにプログラムカウンタをつけてみたけど、要らん気がする。まぁいいや。

これで、一時的に5倍くらい早くなった。
次にインストラクションを今後のために数値に変更。これは逆に遅くなった。
考えられそうな理由は現状プリミティブの実装がかなり適当で、シンボルと数値の比較が一つのcond文に混在している。なので、シンボルの比較を先にしないと、Gaucheに怒られた。っで先に回したら鈍足に・・・
比較の分だけ遅くなるわね。
逆に言えば、よく使われるインストラクションは前の方に持ってくると幸せになれるか?

っで、とりあえずプリミティブをいんちきせずにコンパイルするようにしている最中。
物が動いてくるとやはり楽しい。

2010-06-14

カメルーンに勝った

ワールドカップの話。
職場が半日だれも仕事しないくらいオランダはサッカーが熱い(個人的にはどうでもいいが)
職場で点が入るたびに雄たけびが聞こえてくるくらい。

っで、それのあおりで日本VSカメルーンを少し見た。
あれ?勝ってる?
1-0で日本が勝った・・・

とりあえず、前評判を的確に表していたであろうコピペ。
A                              B 
南アフリカ「ガチ抽選をした結果がこれだよ!」   アルゼンチン「なんだ楽勝じゃん」
メキシコ「南アフリカ乙」                 ナイジェリア「2位ならなんとか」
ウルグアイ「南アフリカ乙」               韓国「\( ^o^)/」
フランス「実質シードワロスww」             ギリシャ「2位ならなんとか」

C                              D 
イングランド「アジアとやらせろよ」           ドイツ「そこそこの組み合わせかな」
アメリカ「微妙・・・」                    オーストラリア「2位いけるな」
アルジェリア「無理くさい」                セルビア「2位いけるな」
スロベニア「微妙・・・」                  ガーナ 「2位いけるな」

E                              F
オランダ「まぁ、おk」                   イタリア「楽勝www」
デンマーク「日本には勝つとして・・・」         パラグアイ「ニュージーには勝つ」
日本「なかなかいい組み合わせだな(キリッ」      ニュージーランド「なにこの無理ゲー?」
カメルーン「日本には勝つとして・・・」         スロバキア 「ニュージーには勝つ」

G                              H
ブラジル「1位通過するよ」               スペイン「楽勝すぐるww」
北朝鮮「どうしてこうなった!」             スイス「ホンジュラスには勝つ」
コートジボワール「1位通過するよ」          ホンジュラス「まぁ、がんばる」
ポルトガル「1位通過するよ」              チリ 「ホンジュラスには勝つ」 

う~ん、何が起きたんだろう?

ミーはおフランス帰りざんす

ということで、パリに行ってきました。
パッケージツアーというのは今までの人生でほとんど経験がないので(修学旅行等除く)それなりにいい経験になったかなと。
言葉の壁さえ考えなければ、交通費、朝食、夕食、セーヌ川のボートツアー、その他いろいろ混みで150ユーロは安いのではないかな。

パリの街は思っていた以上になじむなぁとちょっと感じた。
そこらじゅうで言われていた、犬の糞の問題は特になく、きれいだったし。

っが、街はきれいでも人は・・・
パリで運転する必要がある人はかなりの胆力が必要になるだろうなぁと。

時間がないので適当。

2010-06-09

やっつけA正規形拡張

とりあえず、オリジナルのA正規形で問題かなと思ったのが以下の点。
  1. letが引数一つ
  2. cond、letrec等の必要そうな構文がない(condはif文で書きかえれるけど・・・)
  3. quoteしたものも正規化する
ということでちょいちょい変更。

1. letが変数一つって扱い難いので複数取るように変更。(let (<binds>) <body>)というが普通のletなのでこれを取るようにし、<binds>の(変数 値)という式を一つずつ正規化後letを再構築。

2. condは
(cond (<pred1> <then1>)
      (<pred2> <then2>)
      (else <then>)
という式なので、pred1 ... pred2をこんな感じに
(let ((p1 (normalize <pred1>)))
   ; 以下predの数だけ
っでthenを正規化してcondを再構築。
letrecとletrec*はバインド変数だけ正規化してそのまま放置。とりあえずこれでいいか?

3. オリジナルは(display 'a)というのが(let ((r 'a)) (display r))ってなってたので、さすがにあほらしいかと思い、quoteは正規化しないことにした。

っで、とりあえず3impのコンパイラでコンパイルしてみた。
おぉ、コンパイルできた。
っが、コンパイラにletをコンパイルする記述はない・・・さて、考えるか・・・

2010-06-08

A正規形に切り替える

CPS変換がどうにも上手くいかない。
なんとかなるんだろうけど、涙が出そうになってきたので断念。
一応、それ以外の理由として、
  1. コードの肥大化がすさまじい
  2. 変換することによって、関数のシグネチャが変わる(継続を渡すように変更するため)
  3. ベンチマークで脅威の低速を叩き出してる
この辺がそれ以外の理由。まぁ、3番目はVMの最適化次第だと思うけど・・・
(Gauche上で動かしてるのでしょうがない)

ということで、A正規形に切り替えることにする。
A正規形はCPS変換後逆CPS変換した形に極めて近い気がする。すべての継続の結果を変数として確保するので、スタックの肥大化が問題かな?
ここが詳しい。別に論文も読むといいと思う。
論文の最後にアルゴリズムをschemeで実装した例がある。
問題はこいつはCore SchemeというSchemeのサブセットを対象としているので、いろんな部分で限定的。(letrecとかないし・・・condとかどうするんだろう?)
その辺りを自前で拡張することができればよさそうだ。できるかな?

2010-06-07

コメントの仕方

コメントの仕方が分からないという指摘が累計2件ほどたまったので(少ない)
蛇足ではあると思うけど書いてみる。

コメントしたいと思う投稿の一番下にある、数字 + コメントという(このブログだと緑)のリンクをクリックする。
するとなんとも味気ないコメント投稿画面が現れるので、大き目のテキストエリアにコメントを書き込む。
スパム防止機能があるので、コメントのテキストエリアの下にあるフィールドに画像の英数字を入力。
投稿者のIDを選択。OpenIDはよく分かっていないが、Googleアカウントがあればそれでもいいし、そんなもの無いなら名前/URLを選択し名前を入力。もちろん匿名でも構わない。
最後に投稿ボタンを押せば完了。
bloggerのコメントはきっと共通だと思うので、これで他のbloggerにもコメントができる!

さぁ、早速この投稿にコメントして練習だ!

2010-06-03

ぬか喜びだった件・・・

前述のベンチマークだが、手動CPS変換が間違っていた。
正しくはこう
(define (<=/cps x y k) (k (<= x y)))
(define (-/cps x y k) (k (- x y)))
(define tarai-cps  
  (lambda (x y z k)
    (<=/cps x y
     (lambda (b)
       (if b
    ;ここが違う
    (k y)
    (-/cps x 1 
    (lambda (x2)
      (tarai-cps x2 y z
          (lambda (t1)
     (-/cps y 1 
     (lambda (y2)
       (tarai-cps y2 z x
           (lambda (t2)
             (-/cps z 1
             (lambda (z2)
        (tarai-cps z2 x y
            (lambda (t3)
              ;ここも
              (tarai-cps t1 t2 t3 k))))))))))))))))))
(time (tarai-cps 10 5 0 (lambda (x) x)))
っで、ベンチマークの結果。
Petite Chez Scheme 7.9.4
(time (tarai-org 10 ...))
    no collections
    16 ms elapsed cpu time
    0 ms elapsed real time
    0 bytes allocated
(time (tarai-cps 10 ...))
    10 collections
    125 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    44600752 bytes allocated, including 42111448 bytes reclaimed
(time (tarai-anf 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29499488 bytes reclaimed
(time (tarai-lambda 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29490760 bytes reclaimed

Gauche 0.9
;(time (tarai-org 10 5 0))
; real   0.016
; user   0.015
; sys    0.000
;(time (tarai-cps 10 5 0 (lambda (x) x)))
; real   0.453
; user   0.407
; sys    0.047
;(time (tarai-anf 10 5 0))
; real   0.031
; user   0.031
; sys    0.000
;(time (tarai-lambda 10 5 0))
; real   0.422
; user   0.375
; sys    0.047
圧倒的じゃないか。。。orz
どう考えてもなしの方向っぽいです、本当に(ry

ベンチマーク

CPS変換の勉強中にANF(A-normal form)との共通点を見つけて、
ひょっとしてCPS変換しなくてもA正規化すればいいのでは?
という誘惑にかられたことから、ちょっとベンチマークとってみた。
(どっちが速度が出るか比較したかった。速い方がいいじゃん!)

使用したコードは以下
(define tarai-org
  (lambda (x y z)
    (if (<= x y)
 y
 (tarai-org (tarai-org (- x 1) y z)
     (tarai-org (- y 1) z x)
     (tarai-org (- z 1) x y)))))
(time (tarai-org 10 5 0))

(define (<=/cps x y k) (k (<= x y)))
(define (-/cps x y k) (k (- x y)))
(define tarai-cps  
  (lambda (x y z k)
    (<=/cps 
     x y
     (lambda (b)
       (if b
    y
    (-/cps
     x 1 
     (lambda (x2)
       (tarai-cps 
        x2 y z
        (lambda (t1)
   (-/cps
    y 1 
    (lambda (y2)
      (tarai-cps
       y2 z x
       (lambda (t2)
         (-/cps
   z 1
   (lambda (z2)
     (tarai-cps
      z2 x y
      (lambda (t3)
        (k (tarai-cps t1 t2 t3)))))))))))))))))))
(time (tarai-cps 10 5 0 (lambda (x) x)))

(define tarai-anf
  (lambda (x y z)
    (let ((G139 (<= x y)))
      (if G139
   y
       (let ((G140 (- x 1)))
  (let ((G141 (tarai-anf G140 y z)))
    (let ((G142 (- y 1)))
      (let ((G143 (tarai-anf G142 z x)))
        (let ((G144 (- z 1)))
   (let ((G145 (tarai-anf G144 x y)))
     (tarai-anf G141 G143 G145)))))))))))
(time (tarai-anf 10 5 0))

(define tarai-lambda
 (lambda (x y z)
  ((lambda (G143)
     (if G143
  y
  ((lambda (G144)
     ((lambda (G145)
        ((lambda (G146)
    ((lambda (G147)
       ((lambda (G148)
   ((lambda (G149)
      (tarai-lambda G145 G147 G149))
    (tarai-lambda G148 x y)))
        (- z 1)))
     (tarai-lambda G146 z x)))
  (- y 1)))
      (tarai-lambda G144 y z)))
   (- x 1))))
   (<= x y))))
(time (tarai-lambda 10 5 0))
tarai-orgが元のたらいまわし関数。以下、-cps、-anf、-lambdaと続くが、順に元の関数のお手製CPS変換、A正規化、A正規化後letをlambdaに変換したものとなっている。 っで、以下がベンチマーク結果
Petite Chez Scheme 7.9.4
(time (tarai-org 10 ...))
    no collections
    16 ms elapsed cpu time
    0 ms elapsed real time
    0 bytes allocated
(time (tarai-cps 10 ...))
    no collections
    0 ms elapsed cpu time
    0 ms elapsed real time
    840 bytes allocated
(time (tarai-anf 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505472 bytes allocated, including 29469704 bytes reclaimed
(time (tarai-lambda 10 ...))
    7 collections
    78 ms elapsed cpu time, including 0 ms collecting
    0 ms elapsed real time, including 0 ms collecting
    29505120 bytes allocated, including 29489216 bytes reclaimed

Gauche 0.9
;(time (tarai-org 10 5 0))
; real   0.016
; user   0.016
; sys    0.000
;(time (tarai-cps 10 5 0 (lambda (x) x)))
; real   0.000
; user   0.000
; sys    0.000
;(time (tarai-anf 10 5 0))
; real   0.031
; user   0.031
; sys    0.000
;(time (tarai-lambda 10 5 0))
; real   0.437
; user   0.359
; sys    0.078
個人的には超意外にもCPSが一番早かった!!
Gaucheのdisasm関数でコンパイル結果を見てみたが、末尾最適化が効いてるのかな?
Chez Schemeの結果からアロケーションが結構発生するみたいだけど、それを踏まえてもありと思わせる結果である。

でも、これってこれらのVMがCPS変換されたコードを速く走らせるのであって、CPS変換されたコードが無条件で速くなるわけではないんだよなぁ・・・
う~ん・・・

2010-06-01

CPS変換

とりあえず基本的なことを勉強してみた。
とにかく、すべてのλ抽象は次に計算される継続を持てばいいみたいで、こんな感じに変換される。
(この辺は知っていた・・・つもり)
; 変換前
(define (pyth x y)
  (sqrt (+ (* x x) (* y y))))
; 変換後
(define (pyth x y k)
  (* x x (lambda (x2)
    (* y y (lambda (y2)
      (+ x2 y2 (lambda (x2py2)
          (sqrt x2py2 k))))))))
CPS変換するとこうなる。プログラムは継続渡しスタイルなので、「*」、「+」といったプリミティブでさえ、引数に継続を取る。
ということは、継続を取る引数を定義しないといけない・・・
こんな感じ。
(define (cps/* x y k) (k (* x y)))
(define (cps/+ x y k) (k (+ x y)))
(define (cps/sqrt x k) (k (sqrt x)))
上記のプログラムの*、+及びsqrtをCPSなプリミティブに置き換えれば動く。面倒・・・

っで、これ見ると分かるのだが、継続渡しのプログラムは戻り値を次の継続に渡すので必然的に渡される継続の引数は1つに固定される。
引数を一つに固定して、あだこだするというと、カリー化が思い浮かぶが、やらにゃならんのだろうか・・・

とりあえず、用事ができたのでここまで。続きは帰ってきてから。

-----------------
帰ってきた。

引数を一つに固定したくないという思いをいただいたので(誰からだよ!)
継続の戻り値が多値なら問題ないかと。とりあえず、実験。
(define (cps/+ k . arg)(k (apply + arg)))
(call-with-values (lambda () (values (lambda (k) k) 1 2 3)) cps/+)
call-with-valuesが内部で何してるのか実はよく分かっていないが、動きから第二引数に第一引数の戻り値をapplyしてるのではないかと・・・
まぁ、どうでもいいや。
こう書けば一応複数の引数を何とかできそうだが、いいのか?
とりあえず、最初のプログラムを手動CPS変換してみる。

と思ったが、CPS変換で生じたλ抽象って、この場合だと(* x y)の戻り値を引数にするのだから、1つ固定でも問題ない気がする。もちろん、 (values 1 2)見たいな多値を返すんだとしたら問題かもしれないが、Schemeは多値をそのままでは扱えないので、やっぱり問題ない気がする。

例みたいな、defineをCPS変換する際には関係ないのだろう、きっと・・・

2010-05-30

ラムダ計算 入門

SchemeでSchemeのコンパイラを作っているのだが、いろいろやるに当たって必要になったので勉強中。
(泥縄とかそういう突っ込みはいらない)

ラムダ計算入門のPDFが分かりやすかったのでこれを元に入門編を勉強。

とりあえずラムダ計算の定義。
e(λ式) ::= x     (変数)
          | λx.e (λ抽象)
          | e1e2  (関数適用)
この辺は余裕。
Schemeで変数を定義するときにlet式を使うが、let式もlambdaに変換できる。
(SICPで出たが復習)
(let ((x 1)) <body>) -> ((lambda (x) <body>) 1)
λ式に対して関数適用をするといった感じ?

β簡約
いくつかやり方があるらしい。とりあえず資料にあったのは、R-Beta、R-App1、R-App2とR-Absの4つ。
R-Beta:
--------------------------
  (λx.e1)e2 -> [e2/x]e1
例: 
(λx.x)y -> y
(λx.λy.x)z -> λy.z
[e2/x]e1はe1の変数xにe2を代入したという意味。
R-App1:
     e1 -> e1'
-----------------
  e1e2 -> e1'e2
例:
(λa.b)cd -> bd
λ式は左結合なので、(λa.b)cdは実際は((λa.b)c)dとなる。R-Betaで(λa.b)cが[c/a]bになって、このbに対してdを適用するということ。
じゃあ、正確には[c/a]bdじゃないのだろうかと、ちと疑問。
R-App2:
    e2 -> e2'
-----------------
  e1e2 -> e1e2'
例:
a((λx.x)b) -> ab
R-App2はR-App1のe2版。つまり引数に対してβ簡約をするということ。
例は資料になかったので自分で考えた。間違い指摘大歓迎!!
R-Abs:
      e -> e'
-------------------
  λx.e -> λx.e'
例:
λx.(λy.y)x -> λx.x
λ抽象に対しての簡約。実行時に関数を評価するMLでは必要ないらしい。でも、簡約=最適化だとすればコンパイル時に評価しなくてもいいので、簡約はしておきたいなぁ。ということでこれも必要としておこう。

α変換
変数名を一意に変換すること。こんな感じ(まんま資料から)。
(λx.λy.xy)y -α変換-> (λx.λy'.xy')y -β簡約-> λy'.yy'
最初の式のyと適用されるyは異なる変数だが同名がつけられている。このまま簡約すると式の意味が変わるので変数名を変えようというだけの話。
仰々しい名前が着いてるけど、変数名の衝突を防ぐだけ・・・

とりあえず、入門の入門としてはこれくらいにする。
1時間の勉強内容としてはこんなもんだろう・・・

最終的にはSabry&WadlerのCPS変換の実装をSchemeでできるまでには習得したい・・・

2010-05-23

New York最終日

書いてる時間がおかしいが、まぁ無事に帰ってきた後ということで^^;

特に何もない、実は(じゃあ書くなよ)
飛行場の近くにあるモールでランチ取っただけという話。

飛行場はNewarkという飛行場。なんとも紛らわしい名前だ。
んでもって、あほかというほど混んでた。
飛行場でいつも気になるのは、清掃のおばちゃんじゃないけど、係員みたいな人は大抵アメリカ人じゃない発音の英語を話すこと。
大抵インド系かスペイン系。
そういえばタクシーの運ちゃんとかバスの運ちゃんもスペイン系が多かったなぁ。
この辺りは移民が着く仕事なんだろうか?

帰りの飛行機は特に問題なく7時間弱で到着。
特に時差ぼけも無く、普通のフライトだった。

どうでもいいが、今回の旅行で分かったことがある。
僕は英語が話せない・・・(T_T)

2010-05-21

New York四日目

四日目もニューヨーク。
今日はツアーバスには乗らずいろいろぶらぶら。
といっても、あんまりどこにも行ってないなぁ。

お茶して、
自由の女神をフェリーから見て、
セントラルパークで(大分遅い)昼食をとって(17時)、
チャイナタウンで買い物して、
終了。

セントラルパークはかなりいい感じの公園だった。
都会の雑踏を完全に忘れることができるというか、まぁそんな感じ。
しかも、やたらでかい!
もう来ることはないと思うが、もし機会があればレンタル自転車で一周してみたいなぁ。

2010-05-20

New York三日目

今日もNew York。
New YorkというかManhattanは基本的に3つの地域(?)から成り立つっぽい。
Uptown、MidtownそれにDowntownの3つ。DowntownにはWall Streetとか経済の中心っぽいところがあり、UptownはHarlemとか居住地っぽい感じ。
個人的にHarlemって聞くとスラム街ってイメージがあったのだが、それは今や昔の話で今は(バスのガイドさんの話によると)完全に安全らしい。
どうでもいいのだがUptownにはコロンビア大学があり、コロンビア大学というとシヴァ、アレクサンドライトなどの漫画が思い浮かぶ。
(浮かぶ人の方が少ないだろう上に、20年近く前の漫画だったりする)
個人的に、あの漫画のManhattan描写はなんだかいろいろ違うような気が今更ながらにしたが、20年くらい前なので当時はそうだったのかもしれない。どうでもいい話。
ちなみに、コロンビア大学はもっとも学費が高い私立大学の一つらしい。っで、同じくManhattanにあるニューヨーク大学は年間5万ドル(500万円くらい?)ほどするらしい。漫画の中の話とは言え、彼らはものすごく金持ちだったのだろう・・・

そんなことを考えながら観光バスのUptownツアーを終了し、タイムズスクエアに戻る。っで、何故か吉野家で昼食。
味はまぁまぁだったのだが、なぜ吉野家に寿司があるんだろう?

その後Downtownツアーのバスに乗り、ナイトツアーでManhattan → Brooklyn → Manhattanと移動。無いとツアーのガイドのおっさんがやたら面白い人だった。

ちょっとだけこの街に慣れてきた気がするが、やはり肌に合わない・・・

2010-05-19

New York二日目

今日は普通の時間に起きたのでそれなりに元気。
ホテルで朝食を取ってシャトルバスでManhattanへ。
あいにくの雨なので適当にぶらぶら。
(セントラルパークとか行ってみたいところはあるのだが、雨だしやめた。明日)

タイムススクエアとかそれっぽいとこを見た感じ。
48時間乗り降り自由の観光バスのチケットを買い、それに乗って時間をつぶす。
雨なので説明を聞いてもそれそのものは見えない・・・
無駄金払った気分orz
明日があるさ!

そんな感じでとりあえず二日目終了。

2010-05-18

New York一日目

無事に飛行機に乗れ、無事にNew Yorkに到着。
実際にはNew Jerseyだったりするが、まぁ主に活動するところはNew Yorkになるので細かいことは気にしない。

とりあえず、今日も4時おきだったりするので、ホテルに到着し次第爆睡・・・
う~ん。

飛行場からホテルまでまぁ距離があって、電車に乗る必要があったのだが、その車窓から覗いた世界がなんだかセピア色だった。
う~ん、とりあえずすでに自分になじまないなぁという雰囲気が漂っている・・・

2010-05-17

Orlandおまけ

Orlandoを出発する予定だったのだが、いろいろあって飛行機に乗れなかった・・・
ということで、おまけの一日。
朝4時起きという超睡眠不足に加えて連日の疲れから何もできなかったけど・・・
とりあえず、シーワールドに行っておしまい。

明日は本当にNew Yorkのはず・・・

2010-05-16

Orland最終日

諸事情により、6日目と7日目はスキップ。

最終日。今日はユニバーサルスタジオに行ってきた。新しいジェットコースターがあったのだが、60分待ちとかだったので断念。
適当に他のを堪能して一日終了。
かなり歩いたので足が痛い。
今日がOrlando最終日。次はニューヨーク。

どうでもいいが、昨日と一昨日で韓国人が嫌いから大嫌いになった。やつらは本当におかしい。

2010-05-13

Orlando五日目

今日はアクアティカで泳いだ。
前回いけなかったウォータースライダーを制覇したので、ちょっと満足。
やはりシーズンより少し早いせいか、人がまばら。いいことだが、ちと(気温的に)寒かった・・・

っで、疲れたので早めに切り上げて、適当に休憩してからIron Man 2を観ることに。
きっとまだ日本では上映されて無いだろうのでネタはばらさない方向で。
(ってか前作は上映されたのか?)
感想。近作はコメディー色が結構だされている感じで、笑いどころが結構あった。
内容的にはまずまず。突っ込みどころも多々あったが、個人的には観て損はないと思えた。
Iron Manの役者とシャーロックホームズの役者が一緒なのだが(名前を失念・・・)、この人いい演技をするなぁと思う。この手の自信過剰で子供っぽさのある役がはまり役なのか、この人自身がすばらしい役者なのか(もしくは両方か)分からんけど。

そういえば、映画館からの帰りにパトカーがIHop(レストラン)に10台くらい停まってるを見た。きっと強盗が入ったのだろう・・・
怖い・・・

2010-05-12

Orlando四日目

今日はブッシュガーデンに行ってきた。
特筆するようなことは実はないのだが、とりあえず人は少なめだった。

どうでもいいのだが、この時期のフロリダは天気が微妙。昼間はあほかと思うほど暑いのに、夜になると冷える。ってか、寒い。
レストランとかバスとかガンガンに冷房が効いてるので、長袖を着ないと寒くてしょうがない。っが外は暑い(昼限定)。

更にどうでもいいのだが、枕が替わったせいか眠りが浅く疲れが取れない。毎日寝不足で太陽の下はきつい・・・

2010-05-11

Orlando三日目

今日はシーワールドに行ってきた。
入園する前に、一悶着あったのでその話と+α
シーワールド、アクアティカ、ブッシュガーデン、その他といくつかのテーマパークは経営者が同じっぽいのでいくつか周るなちょっとお得なチケットがある。
っでそのチケットを買った際に、何を間違ったのか名前のつづりが違った。っで、正しいのにしてくれといったら、
「問題ない」
との一言。どう考えてもおかしい。
チケットに必要に応じてID(大概パスポート)を見せてもらうことがあるなんて注意書きがあって、チケットの名前とIDの名前が食い違ってたら問題にしかならないはずだ。
っが、チケット売り場のおばさんは問題ないの一点張り。しょうがないのでカスタマーサービスへ。
っが、さらにここでも問題ないと言われる。
しょうがないので、ID要求されたらどうなるんだってわざわざ説明したら、その人の判断では決定できないので上司に指示を仰ぐといって中に入ってった。
結論を言えばチケットは無事交換されたのだが、どう考えても手際というかいろいろおかしすぎ。
訴訟大国のくせに、訴えられたらどうするんだって突込みどころが山ほどある気がする。

まだローシーズンなのか、どこもかしももガラガラ。世界的な不景気で旅行者が少ないのかもしれないが、これでは路頭に迷う人がでるんじゃねぇの?ってくらいガラガラ。
実際、去年あったホテルとか、レストランとか結構消えているので路頭に迷っているのだろうが・・・
まぁ、待ち時間が少ないというのはこちらにとってはうれしいことなのでどうでもいいが。

どうでもいい話。
アメリカという国柄なのか、フロリダだからなのかは分からないが、こっちにきて英語を話すことにすごく抵抗を感じる。抵抗というか、(元々そんなに正しくはないが)発音がどうも違うらしい。っで、少しでも発音が違うと理解されない・・・
でも、観光地なんだし旅行者が全員正しい(何をもって正しいというか知らんが)英語が喋れるわけないので、理解しようとする姿勢が必要だと思うのだが、それも見受けられない・・・orz
なので、なんか居心地が悪いというか、そんな感じ。
ちなみに今日通じなかった英語はなんと「hot」!
今まで通じなかったことは無いのだが、こっちで「ホット」という通じない。どちらかと言えば(厳密には違う)「ハット」に近い発音がアメリカ訛り(南部だけかも)っぽい。
waterと同じ感じだわね。
個人的には、「聞き返さないと分からないほどの差はない気がする」のだがどうだろう?
特に「hot tea」って言ったら、少なくとも「tea」の部分は分かるだろうと言いたい。メニューにアイスティーはないんだし。そこも違うかも?それは・・・

2010-05-10

Orlando二日目

ひたすらショッピングな1日であった。ぐったり・・・
ショッピングモールを3つくらいはしごするという地獄のような一日・・・

主にアウトレットなのだが、こっちのアウトレットは結構豪快に(普通なのかもしれないが)値引きをする。今日は母の日ということで50%引きだった。
しかし、それって裏を返せば50%引いても利益がでるってことだよね?
通常価格がどれだけぼられてるのかよく分かる。ブランド名ってつけたもん勝ちだなぁ。

2010-05-09

Orlando一日目

昨日(時差の関係でいつだかもはや分かってないが・・・)飛行機に乗ってアメリカに出発した。
行きの飛行機の中でアイスランドの噴火が見えたのは貴重な体験だったと言えるだろう。
(写真も撮ったけど、いろいろ無いから載せれない。気が向いたら)

まずはNew Yorkでアメリカに入国。なんだか今回の入国審査はえらく人種差別を感じたが、まぁアメリカだしこんなもんだろうと勝手に納得しておく。
(でも、白人は一言交わして他は根掘り葉掘り聞くってさすがにどうよ!)

っで、トランスファーでオーランドへ。
特に何かすることもなく、ウォールマートへ行って飲み物当の買い物。
その後夕食で現在に至る。
一日目だしこんなもんだろう。

時差ぼけはないと思うのだが、旅の疲れでやたら眠い・・・

2010-05-07

出発前夜

なぜか標題の後ろに「の夜」という馬から落馬するみたいな表現にしたくなった。
何故だ?

明日の朝にアメリカに向かって出発。
休暇です。2週間ほど行ってきます。
こっちにきて本当にありがたいなぁと思っているのはこの有給二週間とか普通に取れること!
日本にいたときは1週間でさえ不可能だったのに・・・
(まぁ、その分いろいろサービスは悪いが、24時間のコンビニなんてここではありえん)

アメリカといえば、普天間の問題が深刻化しているようです。
ひっくり返したかと思えば、やっぱり元に戻したいと言ってみたり、そうじゃないとその日のうちに撤回したり。
鳩山由紀夫氏(あえて総理とは呼ばない)は本当に妄言癖がおありのようです。
(正直、今のところ自分とは関係ないので)情報をしっかり選別せず、マスコミの言うなりに民主党に投票した人たち、つまり国民に原因の一端があるので、しっかり苦しんで次回に活かしてもらいたいなぁと。

マスコミは事実を流せばいいんだよ。変な情報操作すんな!
(言いたかっただけ)

口蹄病のこととかもぜんぜん報道されてないみたいだし・・・
どうなってるのかね、日本・・・

2010-04-30

OS: GRUBの続きの続き

前回GRUBでカーネルイメージが読み込めたと思って喜んでいたのだが、VRAM周りのコードが上手く動いていなかった。
GRUBが最初に読み込む部分はアセンブラで書いているのだが、カーネルのコード(になる予定)から戻ってきたときには文字列が表示されるのに、コード内部で表示しようとしたら意図しない文字が表示されていた。
それでもって、自分で作ったVRAM用のクラスを使うとGRUBが再起動しまくりで、大変なことになっていた。

何が原因か分からなかったので、とりあえずデバッグすることに。
qemuのデバッグってどうやるのかとググって見たら、こんなページに遭遇。
-sと-Sオプションをつけるのね。意味は調べてないけど・・・
っで、gdbをカーネルイメージを引数にして起動。
(gdb) target remote localhost:1234
このコマンドでqemuに接続してすれば、普通にブレークポイントとか設定可能。

っで、動かしてみたところ、GRUBはELF形式にしか対応してないことが判明。
Cygwinで作ってるので、PE形式なイメージなわけで、どうしろと?
クロスコンパイラを作るのか?(GCCのターゲット指定でコンパイルだと思う)
と思っていたが、objcopyでバイナリ形式にしたら動いた。
まぁ、とりあえずこれでいいか。GRUB周りで苦しむのは本意ではないし・・・

どうでもいいが、調べている過程でmultiboot.hを覗いたのだが、カーネルに渡す構造体のなかにVBEの情報が入ってた。
まぁ、そのうち対応する予定なので、自前でなんだかやらなくても済んだかもと期待しておこう。
(でも、先にメモリとか割り込みテーブルとかやることは満載・・・)

2010-04-29

歯のクリーニング

今までの人生ではじめての経験であった。
今までそんなものとは無縁で生きてきたのだが、折角保険に入ってるし使わないともったいないとそそのかされて行って来た。

・・・


・・・・・・


・・・・・・・・・


涙が出るほど痛かった。
おかしいだろ!
歯を削るのと同じ機械だと思われるものでがりがり何かを削られて(多分歯石)、そのあとポリッシャーで表面を磨くという工程だったと思うのだが、
30分が永遠に続くんじゃないかと思えたくらい地獄の時間であった。

歯科衛生士さん(でいいのかな?)話によると、少なくとも6ヶ月に1回は行った方いいそうだ。
年に2回もあの地獄を味わうのかと思うと・・・

歯磨きの重要性を思い知った瞬間だった。

2010-04-16

暗いニュースが多いなぁ・・・

日本の政治関連のニュースを読んでいると暗いニュースしかみない。
まぁ、税金は払ってないし個人的にはあまり関係ないのだがやはり読んでいると辛い。

ポーランド大統領の国葬に出席しない総理大臣とか、
オバマ大統領にLoopyと呼ばれる総理大臣とか、
ジミンガーと叫んで自分の責任を放り出す総理大臣とか、
普天間基地の話はマスコミが報道し過ぎたせいで国民が知りすぎたなんて言っちゃう総理大臣とか、
そのくせ桜を見る会は開く総理大臣とか、
会話全文を読んでも質疑応答になってない回答をする総理大臣とか、
そもそも、国会に出ることが嫌いで仕事するのも嫌いそうに見える総理大臣とか

そんな感じの洒落で済むものから洒落にならないレベルのものまでたくさん。
(どれをとっても洒落にはならんが・・・)

ま、それを報道しない(らしい)マスコミも大問題だろうし、傀儡政権の裏でとんでも法案を無理やり通そうとしている民主党幹事長がいるらしいけど・・・

大丈夫なんだろうか、日本・・・

個人的に一番問題だなと思うのは、こんな状態になってもデモ一つ起こさない国民だろうと思ったり・・・
もはや政治家は役に立たないどころか、敵でしかない状態なのだから何か行動を起こす人がいてもよくないか?
(といって自分が起こすわけでもないので、やはり僕も問題な国民の一人・・・)

2010-04-10

OS: GRUBの続き

昨日のエントリーで、いまいち動かないと書いたが、少し前進した。

マルチブートに関してヘッダー等がいるので、GRUBのサイトからmultiboot-0.6.96をダウンロード。その中にboot.Sというファイルとkernel.cというファイルがあるのでコピー。
(とりあえず、動作確認できればいいので・・・)
っで、普通にビルド。
_edataが定義されてないと怒られる。

なんだこれ?

Google先生に聞いてみる。

・・・

・・・・・・

・・・・・・・・・

.dataセクションの終わりを示すポインタらしい。
うわさによるとリンカーが自動で作るものらしいが、CygwinのGCCではなのかGCC 3.4.4ではなのかは知らないが作ってくれないらしい。
とうことで、リンカスクリプトを書く。
というか、ここから拝借。
cygwinではelf-i386はサポートされてない(というかpe-i386しかサポートされてない)ので、OUTPUT_FORMATの行を削除。OUTPUT_ARCHも、まぁいらんかなと思い、削除。
っで、make。
なんか表示された。

激しく文字化けというか、意味不明の文字ばかり見えるが、とりあえず何か表示されているのでよしとしよう。
あとはカーネルっぽくいろいろ作るだか(というかそれが一番大変だと思うが・・・)

2010-04-09

OS: GRUBをCygwinで無理やり使う

ここ3日くらい調べてようやくなんとかなった。

ひょっとして同じところで躓いてる人がいるかもしれないので、メモ。
用意するもの:
Cygwin(当然か)
VFD(ここから)

あらかじめ、fstabに以下を記述。
a: /cygdrive/a vfat binary,posix=0 0 0
っで、ddでFDサイズのファイルを作って、VFDで開いてフォーマットしたら、
grub-installでFDイメージにインストール。このとき、デバイスは/dev/fd0を指定する。

面倒なので、スクリプト書いた。
#!/bin/sh -x
# generate floppy image with grub2.

grub=/lib/grub/i386-pc
file=fd.img
vfd=/cygdrive/d/bin/vfd/vfd
fd0=/cygdrive/a

# create floppy image.
dd if=/dev/zero of=$file bs=1k count=1440
$vfd open $file
# format
$vfd format
# いらないかも・・・
mkdir -p $fd0/boot/grub
# 適当にモジュールを指定しているので、必要なもの不必要なものは調べる。
grub-install --modules="_chain ls pc multiboot gpt fat boot reboot configfile cat help " --root-directory=$fd0 /dev/fd0
# grub.cfgは作ってくれないので、別途コピー
cp grub.cfg $fd0/boot/grub

$vfd save
$vfd close
こんな感じ。
きっと必要に応じて、イメージのdevice.mapとかを編集すればいいはず。とりあえず、GRUBが起動するところまでは確認。

あとは、自前のカーネルを読み込むだけなのだが、grub.cfgの書き方がいまいち分かっていない・・・
それとも、カーネルの方がまずいのかな?
「error: attempt to seek outside of file」
ってエラーだからカーネルかな・・・
調べないと・・・

2010-04-03

小ネタ

あまりに書いてないので小ネタを小出しに・・・
(半分くらい下ネタかも・・・)

日本にいたときのこと。
(こないだの帰省の時です)
栄スカイルのABCマートに靴を買いにいった。ものすごい勢いで地域が特定されているが気にしない・・・
大抵そういう店はBGMが流れているが、そのとき流れていた曲の一部に「ピーナッツ」って言っていると思われる部分があった。
でも、どう聞いても聞こえ方がNGな聞こえ方・・・
「ッツ」が「ス」に聞こえる・・・

どう考えてもアウトだろうと思った瞬間だった。

気合で探してみた。
くるりの愉快なピーナッツという曲みたい。

3:58秒くらいが個人的にはアウト・・・
いい曲だとは思うのだが、そこが印象に残りすぎる・・・

2010-03-19

最終日

明日の朝に日本を発つ。
8時40分の飛行機なので、チェックインは6時半くらいか?
ここ読んでて暇でこのクソ朝早くにこれそうな人は見送りに来てくれるとすごくうれしい、と明に言ってみよう。

最初にオランダに渡ったときは新天地に移動みたいな感じだったので、そうでもなかったが、今回は少し寂しい気がする。
やはりここにはいろいろ残してきたんだなぁと実感した。

涙で前が見えないということはないが、そんな気分。

2010-03-14

定演

行ってきた。

久しぶりに会えた先輩とかもいらっしゃってちょっとした同窓会の気分。
演奏自体は、合同はよかった。
後は、Topが抜きすぎで・・・少人数で大人数の歌い方をしていても映えんだろうと思うのだが・・・

2年後の合同は計画を立てて立つ予定でいこう。

2010-03-11

今更ながら

日本にいます。
先週の土曜日に戻っていました。

現在とりあえず日本を堪能してます。
高速が高い・・・

日本語が話せるっていいなぁ・・・
道とか分からなくてもとりあえずコンビニで聞けるとか便利すぎ!!

一応来週までいます。

2010-02-27

若者の○○離れ

それは無いだろうのある意味究極系。
ずばり、「若者のメンズブラ離れ」!!!
最初から近寄ってねぇし!!!

ちなみにその元となったであろうニュースの一部
ここ
それに対する反応
ここ

ちなみに若者が離れたもののまとめちっくな記事
ここ

いろいろなもの離れたね。
何で離れたかの原因は追求されてないところもポイントかね。

2010-02-26

鞍替え

長年(大学3年の時から)xyzzyを使ってきたが、諸事情によりEmacsを使うことにした。
職場のPCが英語だから文字化けするとか、将来的にLinuxを使う予定があるとか、利用者人口が多いのでスクリプトが充実してるとか、まぁ理由はいろいろ。

xyzzy自体がEmacsのCommonLisp版みたいなものなので鞍替えしてもそんなに違和感はない、っがさすがに個人的な設定とかはしないと些細な違いに戸惑う。
大きなのは、C-hのHelpだろう。
後は今まで使ってきたxyzzy-lispをemacs-lispからみつければ終了。
まぁ時間はそんなにかからない。

個人的にはさくさく動いたxyzzyの方がいいかなぁとも思いながら、Emacsももっさり感を除けばいい感じなので満足。
しばらくは平行して使うことになるかな。
それにしても、xyzzyのフォルダごとグレップとかの昨日ってEmacsにもあるのかな?

2010-02-23

招待状

大学の時に所属していた合唱団から定期演奏会の招待状が届いた。
正直驚き!!
実家の方に届くものだと思っていた。心意気はすばらしい!

ま、呼ばれなくても行くつもりだったけどね。
それはそれと置いておいて、微妙なダメだし。
今日届いても、航空券、有給とうはどう考えても間に合いません。最低2ヶ月はほしいです。

しかし、壮大な曲ばかりで驚いた。
雪花もあるし・・・懐かしい。もう歌えんが・・・
今メンバー何人なんだろう?

2010-02-15

C++: グローバル領域

GCの続き。
スタックからルートを取得する方法は理解したが、グローバル変数はどうするんだろうと調べてみた。
メモリの領域は、スタック、データ、テキストの3つに分かれていて、テキストが実コード、スタックはスタック、っでデータ領域にグローバル変数とかが入るらしい。
じゃあ、これを取得すればいいんじゃん!なんて思ったのだが、調べてもそんなもの頭と底をとる方法がない。普通こんなもん意識しないから、ある意味当たり前か・・・

とりあえず、試してみてだめだったこと。
DSセグメントレジスタを16ビット左シフトした値を頭とし、最初にヒープから取得したアドレスを底として捜査。
→ 無理。よく見るとグローバルなアドレスはヒープよりも下にある。

ちなみに、もう一つ問題があって、こんなコードが不正になる。
int *p = (int*)gc_malloc(sizeof(int) * 4); // とりあえず4つ確保
p[0] = 1;
p[1] = 2;
gc_collect();
// p[0] == 0 !!
コレクターを呼び出さなくても、GCが走れば不正になる。
理由:GCでアドレスが変わるので、例えばpが0x0032fec8を指していて、GC後に0x0033fda8になったとすると、実際に変数pが指している値はそのまま前の値になって不正になる。
スタックポインタの指す値を上書きしてるから大丈夫かと思ったら、甘かった・・・う~ん・・・

2010/02/18追記

実際には上記の不正は違っていて、回収されてはいけない値が回収されていた。
原因はスタックポインタ上にアドレスが無いから。
なぜ?
少し処理を足すとスタックが上書きされたりして、グローバル変数なのに問答無用で回収されたり・・・
なぜだ・・・

2010-02-11

C++: Copy GC

C++ではなくてCの話だが、まぁいいや。
いろいろな理由があってガーベジコレクションの勉強をしている。
BoehmGCを使えばいいのだが、ちょっとした理由からそれができないので・・・

っで、とりあえず保守的GCかPreciseGCしか知らなかったので調べてみた。
結構いろいろ種類があるが、Mostly-copying GCがよさげかなと(根拠なし)思い、その元となったCopy GCを実装してみた。
といってもこのページをとりあえず理解のために写経しただけとも言う。

基本の考え方は、ヒープとルートが分かればなんとかなりそうな感じ。
っが、どうやってルート調べるのかがすごく疑問だった。
それを解決してくれたのがこのページ
一般教養としてのGarbage Collection
ぜんぜん一般教養ではないと思うが・・・
ルートは基本スタック上につまれている変数から辿れるポインタだと思えばよさそう。
なら、ESPの値を引っ張ってくればいいだけじゃん、と思い実装。
動いた!

このままでは使えないのでもう少し調べないとなぁ・・・
(Mostly-copying GCの実装って難しいのかな?ぜんぜん見ない・・・)

2010-02-10

movie: AVATAR

土曜日に観たので、実は4日くらい前・・・
アバターを観てきた。リアルの世界にパンドラがないって言って自殺(?)しちゃう人がでたやつ。

以下、多分にネタバレ注意。



物語は他の星に移民する地球人の一人、ジェイクを中心に進められる。
このジェイク君(といっても、見た目は僕より年上だったから、30以上か?)がものすごくガキ!精神的に。
個人的に副題は、ジェイク成長物語だと思っている。
宣伝(?)どおり彼は下半身不随で車椅子。なので、動く体を手に入れられてはしゃぐ。っで、はしゃぎすぎて他のメンバーとはぐれ、アバターの村にの娘に命を助けられる。
これはチャンスとばかりに地球軍がジェイクにスパイを命じ、ジェイクはアバターの生態(といっても言語とか生活習慣とか)を探る。
正直、この辺までは微妙。いや、アクションとかは多めでいいんだけど、ジェイクが図体の割りにガキっぽくて見てていらいらした。
っで、しばらくすると、地球軍が領地を広げるために木をなぎ倒していく。止めようとするジェイク。相手は鉄の塊、メインカメラを素手で壊して終了。
っが、当然カメラなので自分の姿が映り、謹慎処分をくらう。
地球軍は何故か星を侵略して自分たちの物にしたいらしく、戦争をしかける。
っで、後はお約束の勧善懲悪(ではないが)なアクションで地球軍を倒し、ジェイクがアバターに生まれ変わって終了。

どこに欝になる要素があったのか分からんかった。
個人的には、白人 VS ネイティブアメリカンって感じ。この映画の中では、アバター、自然の動物が一体になって星を侵略から守ったけど、
歴史上では卑怯な白人がネイティブアメリカンから土地を奪い取ったんだよなぁ、とか思いながら観てた。
軍隊とか、地球連合軍なのにすごくアメリカっぽい感じだったし(ものすごく偏見が混じってます)
2度観たいとは思わない感じの映画。でもCGとかアクションとかはよかった。
ストーリーは正直2流だなぁと感じた。
(何様のつもりだ、俺・・・)

2010-02-05

電話

以前はほとんどなかったのに、今更になって結構頻繁(といっても月1程度)にエージェントから電話がかかってくる。
正直今更・・・

たいていMonsterBoardから来てるんだけど、ぜんぜん更新してないのにどうして引っかかるんだ?
(まぁ、未だに職探し中のステータスにしてあるのも問題か・・・)
ようやく景気が上向いてきて求人が増えたか、時期的なものか、単にこの業界が慢性的な人手不足かのどれかだとは思うが。
結構条件いいのが多いのよね・・・本当に何で今頃・・・

2010-02-02

Linux: UbuntuをVirtualBoxで試してみた

会社のPCでだが・・・

とりあえず、デフォルトでインストール。
ものすごく簡単だった。ネットで調べる必要がないくらいに。
デフォルトのWMがGnomeなので、KDEに変更。
初めて触ったWMがKDEなのでKDE好き(^^;

使用感。
Linuxのディストリビューションなんて、Fedora、Redhat(ほぼFedoraと一緒)、Debianくらいしか構ったことないし、
デスクトップLinuxで本格的に使ってたのはDebianだけなのであまり比較はできないが、
個人的には気に入った。
外側がKDEな上にUbuntu自体がDebianを元に作られてるのである意味当たり前か。
いろいろやるのにsudoしなきゃならないところとか、GUI上だとMaxかよって突っ込みを入れたくなる頻度でパスワード求められるけど。

ちなみに、
DebianをVirtualBox上で試そうと思ったんだけど、インストールが上手くいかなかった・・・
これ実機でもこの調子だとしたら、やっぱりきついよなぁ・・・

次にPC買ったらUbuntuかな。
(OSなしのPCが安く売ってればだけど・・・でもWindows7とかに特に魅力を感じないんだよね・・・)

2010-01-30

練習中の曲に関してのメモ

ギターの練習をしている。別に発表会とかはない。
ちなみに、練習してるのはこの曲

激ムズ。ギター暦1年未満がやる曲ではない気がする。しかも、クラシックギターではなく鉄弦のアコースティックギター・・・
それは置いておいて、これをやるにあたって必要そうな奏法のメモ。

ハンマリング、プリングオフ: いたるところで
ラスゲアード: 動画の49秒くらいのところのフレーズで出てくる
タンボーラ: 最後のノリがよくて格好いいところで
ポルタメント、グリッサンド: 結構いたるところでみる
チョーキング: 1分くらいのところで
ゴルベ?: 最後の方

タンボーラってサンピングのことか?
いろいろ無謀な気がするが、ロングスパンでやろう・・・

2010-01-28

OS: メモリ

ここ数日(数週間?)まったく時間が取れなかった。
今も取れているかはよく分からんが。

OSがメモリを割り当てるところで停まっていた。
まぁ、今も停まっていると言えばそうだが・・・

いまいちページングがよく分からない。E820hで取得したメモリーマップ情報からメモリアドレスを取得して、そのアドレスに対してページングOnする。
そこまでは上手くいっている(と思う)
っで、とりあえずmallocもしくはnewが使えないと話しにならない。ということで実装していたのだが、どうも変な挙動をしていた。
今日ふと、ページを初期化してから、アロケータの初期化をしたら、動いた(・A・)

鼻から悪魔が出るコードかもしれんが、とりあえずこれでいこう。
この辺が動けば少しやりやすくなるし・・・

まじめに参考書探さないとなぁ。
だれかお勧めの本とか知りませんか?

2010-01-24

ブリュッセル

ベルギーのブリュッセルに行ってきた。
別に観光情報とかが書かれるわけではない。単に所感。

実は(前に書いたっけ?)ブリュッセルに行くのは2度目。1度目はあまりいい思い出が無く終わったので、少し心配だった。
今回は2泊3日なので、まぁ少しゆっくり見て周れるかなと思いつつ、南駅(?)に到着。
メトロに乗ってホテル近くの駅まで。
一日目はこれで終了。仕事が終わってからなのでまぁこんなものだろう。
ちなみに、ロッテルダムからブリュッセルまで2時間弱くらい。

二日目とりあえず歩く。ショッピングストリートとか。本屋を探したが欲しい本が売っている店は見つからず。
どうでもいいが、ベルギーは一応オランダ語(フラマン語?)が公用語なのだが、ブリュッセルでは見るだけで、主に耳に入ってくるのはフランス語だった。
北部にあるアントワープではオランダ語だったのに、不思議。頻繁に旅行するようならフランス語を覚えた方がよさそうだ・・・
街自体は、新旧が入り混じってる感じ。パリの町並みによく似ているなぁと思わせるところが多々あったし、やはりフランス寄りなのだろう。
歩きつかれたのでホテルに戻って2日目終了。

3日目は日曜日なので店という店は閉まっている。雨も降ってるし、ということで特に何もせず帰る。

ちなみに、本当にどうでもいいことだが、ブリュッセルの平均身長は割りと低めだった。僕が普通か少し高いくらいに分類される感じだったので。
オランダの平均では僕は間違いなく低い方・・・190超えがごろごろいるんだよ・・・
ちょっとだけベルギーを好きになった瞬間だった。

2010-01-17

movie: シャーロックホームズ

映画の話。

予告ではホームズは荒くれ者で、ワトソンが知的って感じで、いまいちじゃねぇのこれって思っていたが、裏切られた(いい意味で)
いろんな新要素というか、見たことないホームズが見れたけど、それはそれでありな感じ。
ホームズ好きもそうじゃない人も楽しめるんじゃないかと。

最後の最後でモリアーティー教授の名前もでてきたし、エピソード2もあるのかね?
出たら見る自信がある。それぐらいよかった。

日本で公開されるか分からんけど。
(多分されるだろう。宣伝されてる?)

C++: 構造体でアドレスを読む

我ながら意味不明なタイトルだ。
やりたいことは、アセンブラが設定した配列をC++(またはC)の構造体に入れるってそれだけなんだけど、何故かはまっている。

アセンブラは適当なアドレスに値を入れる。こんな感じで。
0x00002840: 0x00000000 0x0000000 0x0009fc00 0x00000000
0x00002850: 0x00000001 ...
これが配列の一要素。
っで、まぁこれはE820hで取得したメモリーマップなので、普通にこんな構造体で受け取る。
struct MemoryMapEntry
{
  uint32_t baseAddrLow;
  uint32_t baseAddrHigh;
  uint32_t lengthLow;
  uint32_t lengthHigh;
  uint32_t type;
};

// どこかの関数で
MemoryMapEntry mapEntries = getMemoryMapEntry(); // これはアセンブラ内で定義した。
これで普通ならいけるはずなんだけど、取り出される値がおかしい。上記のアドレスなら、
baseAddrLow  = 0x00000000
baseAddrHigh = 0x00000000
lengthLow    = 0x0009fc00
lengthHigh   = 0x00000000
type         = 0x00000001
になるはずなんだけど、こんな感じに実際にはずれる。
baseAddrLow  = 0x00000000
baseAddrHigh = 0x00000000
lengthLow    = 0x00000000
lengthHigh   = 0x00000000
type         = 0x0009fc00
感じとしては、20バイト取得できてないといけないのだが、12バイトしか取れてない感じ。なぜ?
これが普通の動作なのかなと思い、ちょっと実験してみた。
#include 

struct sample
{
    unsigned int val1;
    unsigned int val2;
    unsigned int val3;
    unsigned int val4;
    unsigned int val5;
};

void* getsample()
{
    static int *addr = (int*)0x404030;
    addr[0] = 0x00000000;
    addr[1] = 0x00000000;
    addr[2] = 0x00000000;
    addr[3] = 0x0009fc00;
    addr[4] = 0x00000001;
    return addr;
}

int main()
{
    sample *s = (sample*)getsample();
    printf("addr: %x\n", s);
    printf("%x, %x, %x, %x, %d\n", s[0].val1, s[0].val2, s[0].val3, s[0].val4, s[0].val5);
    return 0;
}
こんなむちゃくちゃなコードでもなんか動いてるから不思議。
っで、結果は普通に予定通りの値が取れていた。
コンパイラの最適化が効いてるからなのか(何もオプションつけてないけど)、別の要因で直にアドレスから取るのとは違うのかよく分からん。

何より腹が立つのは、以前はまともに動いていたのだ!ページングの実装を終えたらおかしくなった・・・
関係があるのかな、やっぱり・・・

2010/01/17 追記

原因が分かった。
結論: まともに動いていました。
原因: VGAクラスで実装していたprintfメソッドの不具合。
64ビットの数値には%xの書式指定子が対応しておりません・・・
参考にしている人はいないと思うが、
64ビットの整数値を表示したいのに、可変引数のポインタを進める際に(int*)のポインタでやっとりました。つまり、8バイト移動させないといけないところを、4バイトしか進めていなかったっと。
これで2時間悩んだ。printfデバッグの限界やね。と勝手に納得・・・

OS: ページング

メモリ管理をしないと動的にメモリが取れない。
っで、とりあえずページングに手を出してみることにした。

とりあえずここを参考にしつつ、人のコードを見つつ。
っで、ページングONしてやって、qemuで起動すると、何故か無限リスタートしてくれる。
意味が分からんなぁ、と思いながらMonaのソースを見る。
(分からなくなったときのMona頼りというわけではないが・・・)

PageManager.cppのsetupメソッドを見ると、VRAMのアドレスをページング対応してる。何でだろうと思いながら、とりあえず似たようなことをしてみたら、動いた(・д・)
ページングをONにするということはすべてのアドレスをページング対応する必要があるのかな?
よく分からん。
ちなみに、ページング対応させたアドレスの属性を、書き込み可能、ユーザー領域、カレントにしないとだめだった。意味はよく分かっていない・・・(汗
無知っていやだなぁ・・・
勉強しないといけないのだが、こっちじゃ書籍も探し難い・・・ネットの情報だけじゃ厳しくなってきたというのに・・・

っで、これ書いてるときに気がついたのだが。
そういえばバイオスのE820h命令でメモリーマップを取得してるんだから、適当なアドレスを使用すれば、動的メモリーの割り当てができるような気がするなぁ・・・
ページングの前に実装するべきだったか?

2010-01-16

OS: 便利リンク

自分のための便利リンク。
ChangeLogとか、メモとかHDDに置けよという意見は無視。

[Wiki]
OSDev(English)
osdev-j(MMA)(日本語)

[ブログ]
OSのようなもの
Outlandish Watch(日本語)

[BIOS関連]
Ralf Browns Interrupt List

何か見つけたら随時足すことにしよう。

2010-01-14

C++: クラスのサイズ

これをググったのももう何度目かなので、いい加減メモっておこう。

C言語のstructは基本中身のバイト数の合計+パディングになる。例えば下記のような構造体があったとする。
struct Sample {
  int   value1;
  char  value2;
  short value3;
};
この場合だと上記の基本に当てはめて、
int = 4, char = 1, short = 2, total = 7になるが、
7だとキリが悪い(あまりいい表現ではないが)ので、パディングがcharとshortの間に入って8になる。
(詳しくは、バイト境界とか、アライメントとかでググって)

っで、C++の話。
C++のクラスはC言語の構造体と違ってメンバ関数を持つことができる。これが曲者。
例えばこんなクラスがあったとする。
class {
  public:
    void print();
  private:
    int value;
};
この場合は、クラスのサイズは4になる。なぜか?
どれだけメンバ関数が足されてもサイズには影響が無いそうだ。実際、GCCの-Sオプションで吐き出されるアセンブリを見たらなんとなく納得した。

っが、仮想関数が入ってくると別の話。
仮想関数はvtblを不可視のメンバ関数として持つので、そのポインタアドレス分増える。つまり4バイト。

なんでこんなことを調べたかというと、メンバ関数を持つクラスを普通の構造体として扱いたかったから。まったく普通なら問題なんだけど、メモリの内容を直接(例えばmemcpyとか)クラスの中に移したかった。
そうすると、クラスのサイズが重要になるので。
それだけの話。

2010-01-10

感覚が狂ったか?

座頭一がTVでやっていたので見た。
最初から見たわけではないので、序盤の話はよく分からなかったが、まぁ大まかな内容はつかんだと思う。

っが、別に今回は映画の内容ではなく、その中ででた台詞で不思議な感覚を味わったという話。
最後の最後で口縄(これでいいのかな?)の頭が、
「おめえ、メクラじゃねえのか?」と聞くのに対して、座頭一が、
「そうだよ」と答える一節。
これを見たときに、
「やっぱり盲目なんじゃん」と思った矢先に、座頭一が目を開けた!!

あれ?
なんで?

きっと、日本語→英語→理解の順になっていたのだろう。こんな感じで。
「おめえ、メクラじゃねえのか?」 -> "Aren't you blind?"
「そうだよ」 -> "Yes"

う~む、日本語がおかしくなってきたか・・・

2010-01-09

Makefile: 依存関係

自作OSをビルドする際に、当然(?)makeを使うわけだが、ずぼらな僕は「make」って打つだけで全部やってほしいと思うわけだ。

っが、依存関係の問題があって、今まで
「make clean all」
なんて、毎回プロジェクトをリビルドしていたわけだ。
けど、これ今はまだいいが、ファイル数が10とか100とか増えた時に非常に面倒になる。
というか、僕の貧弱なノートPCでは時間がかかりすぎるようになる。
(こんなことやってるのに、使用してるPCがノートかよ、って突っ込みはなしで)

っで、とりあえず、依存関係を自動で解決するようにMakefileを書き直した。
ポイントになるのは、gccの「-MM」オプション。
っが、makeのマニュアルにある方法だと、sedを使う。っが、WindowsでMingwだけで何とかしようという環境の僕にはsedはおろかCygwinもない。
適当に、gccが吐き出す依存関係を編集して上手いこと書き出すプログラムをC++で書いた。
なんでこんなことしなきゃならんのだろうか?

これだけいろいろ便利になってるんだから、こんな変なノウハウじゃなく、もう少しスマートな解決方法があってもいいような気がする。

2010-01-08

C++: 初歩的なこと・・・

VGAのを使って色を変えたり、文字を表示させたりするということ実装していた。
リアルモードからプロテクトモードに移行するとBIOSが使えないので、VGAを使う必要が(ないかもしれないが)ある。
っで、主にこの辺とかMonaの初期のソースとかを参考にしながら、しこしこ書いてみた。

っが、なぜか一行おきに空白がでる(縦に)。なんでだろうと、いろいろVRAMに与える値を変えたりしながら考えてみたが、一向に改善しない。
おかしいなぁと思いながらトイレにいって思いついた。
そういえばVRAMのアドレスはunsigned shortのポインタだなぁと・・・
Monaはunsigned charでサイトはunsigned shortなので、ポインタに加算を行った際のアドレスが1バイトずれる。

これか。

おさらい。

// ちなみに、0xb8000はVRAMのアドレス
unsigned char* ptr = (unsigned char*)0xb8000;
unsigned short* ptr2 = (unsigned short*)0x8b000;
ptr++; // 0xb8001
ptr2++;// 0xb8002

これを行った際に。ptrとptr2のアドレスは異なる。
あほかと思うくらい当たり前だが、はまった。

2010-01-07

OS: IPL

その筋には(というと変な雰囲気がでて格好いい?)有名だが、
2ch発祥のOSでMonaというのがある。最初の会社にいたころに知ったから、2005年くらいか?
あれから、5年。何を思ったのが、僕もOSを作りたいと思ってきた。
(昔から思っていたが、当時は何をしていいのかさっぱり分からなかった。が、最近なんとなく必要なものが見えてきた。暇にかまけて勉強したのが功を奏した感じ)

っで、Monaをはじめ、いろいろ調べてみた。
30日でできる! OS自作入門とかが有名っぽいが、こっちじゃ買えん。
っが、結構実践サイトとかあって、解説が読めないだけでソースは読めたりする。

っで、IPL(OSを起動する前にBIOSが起動する。ブートローダーと同義?)を作ることからはじめることになるのだが、これが難しい(当たり前だが)
アセンブラがよく分からない(アセンブリ言語自体は割りとシンプルなのだが、アドレスとかレジスタとかがいまいち分からん)
あと、GCCとNASMの相性が悪い(というかGASとGCCの相性がよすぎるのか?)というのもあって、とりあえずNASMを選択していた状態ではさっぱり分からんかった。

とりあえず、このサイトの自作OSのタグに書かれているのを参考に(ほとんど丸写し)、IPLを作成。
GASを使うとCの関数がそのまま呼べるので楽!!
リンカスクリプトを使うとコンパイル時にプログラムのサイズが取れるので、FDの読み取りに必要なセクタ数が分かって楽!!!
なんて感じだった。
はじめからこれにしておけばよかった。
回り道は無駄じゃないと信じたい。

2010-01-04

ASM: 勉強中

何を思ってか、アセンブリ言語のお勉強中。
(いや、ちゃんと目標があってだけど)
(Shemeはどうした?勉強してますよ)

どうでもいいけど、アセンブリ言語をアセンブラでアセンブルするんですよ(多分)
AssemblyをAssemblerでAssembleするかね、英単語にするとちと分かりやすい?
(yをeeにすると、employ、interviewと同じ関係やね)

横道どころでなくそれた。
最初(未だに)、NASMを使うか、GASにするか。NASMはIntel標準なので、(ちょっとだけ)汎用性が高い。GASはGCCとの親和性が抜群。
とりあえず、標準という言葉に弱いので、NASMにした。

アセンブリ言語の構造は非常に簡単といってもいいと思う。
基本、こんな感じ
;; 簡単なprint
;; 呼び出しは、
;; mov si, msg_pointer
;; call print
;; こんな感じ
print:
  pusha
  xor bx, bx
.loop:
  lodsb
  or  al, al
  jz  .end
  mov ah, 0x0e
  int 0x10
  jmp short .loop
.end:
  popa
  ret
命令とレジスタの組み合わせでいろいろやる。ここまでは、それなりにいろいろ言語をやってきたので簡単に理解。
問題はこの辺
mov ah, 0x0e
int 0x10
今となっては何か分かっているのだが、最初は何のことやら・・・
これは、上のlodsbでALレジスタにSIレジスタに格納されている文字列の先頭を格納していることを前提に、AHレジスタにBIOSの0x0e(表示)命令を入れて、int 0x10で実行している。
BIOSのint 0x10はビデオ関係の命令を実行するという意味で、
AHレジスタに一文字表示の命令0x0eを格納し、ALレジスタに文字コードを入れる。
BIOSの命令は、使用するレジスタ、命令の種類が決まっているので、それを調べる必要がある。
例えば、こことか。

後は、セグメントとオフセット、各レジスタの意味とかが重要になってくる。
正直、覚えられん(まだ1週間・・・)
とりあえずの、備忘録。

2010-01-01

movie: トワイライト サーガ

邦題は知らん。とりあえずそのままカタカナにしてみた。

新年一発目はこれだった。
エピソード2らしい。

感想(以下はネタバレが含まれる可能性があります)
個人的な感想を最初に書こう。
3流映画で見る価値なし。

無いよう自体は、バンパイアの子孫(?)のエドワードと狼男のジェイコブ、普通の人間のベラの恋模様を波乱万丈っぽく描いた無いよう。
その昔みた、ママレードボーイの三角関係そのままって感じ。
ただ、
エドワード → 貴族な優男
ジェイコブ → 野性味あふれる感じ
ベラ → エドワード一筋なくせに、ジェイコブも捨てがたい超わがまま娘
って感じだった。
う~ん、あんまり批判的な意見を書いて、名誉毀損で訴えられるのも嫌なので、これくらいにしてしまおう。
正直、意味不明だった(英語が理解できないとかではなく、内容が)

あけましておめでとうございます

本年もよろしくお願いいたします。

今年は初詣もなく、なんとも静かな新年であります。
すこし物足りない気分でもあります。

旧年は、行く年来る年を見ることもなく、年が明けた瞬間の花火(と呼ぶにはあまりにやかましい)にはずいぶん驚かされました。
(市がやってるわけじゃなく個人。しかも結構大きめな打ち上げ花火。そりゃ指なくしたり、足なくしたりするわ)

本年は寅年ということで、躍動感あふれる年にしたいと思います。