Gauche:Windows/VC++:log:old_2003
GaucheってVC++でコンパイルできますか? 言語のコアに関わりそうな所だけでいいのですが。ちらっと見た所MSWIN32というifdefフラグはあるのですが、 VC++のビルドに関するドキュメントが見つけられませんでした。--有野
Shiro (2003/03/02 18:59:28 PST): 今のところVC++で試したことはありません。 環境も無いので… 誰かがトライしてくれることを期待して別ページを立ててみました。 とりあえず、システム関数関係がPOSIXべったりなんでそこを分離させないと 難しそうではあります。
軽く挑戦してみた所config.hが無い、だそうで(<あたりまえ)
さて、configureの部分はどうするのがこういう場合は正しいんでしょうかね?
WinCEのフラグがある、という事はconfigureの動かない環境での前例があるんでしょうか?--有野
gcはBoehm GCのコードを持って来ていて、その中ではMSWIN32とかMSWINCEとかのフラグは 使われていますが、Gaucheのメイン部分(src以下)にはそういうフラグはないはずです。 一度も試みたことがないので。 MSWINが定義されてたらconfig.hじゃなくてconfig_win32.hを読むとかしておけば 良いのかなあ。--Shiro (2003/03/04 02:23:14 PST)
あれま。gcの中だけだったのですか。
CEでの前例があるのかとふんでいたのですが。
それでは自分で勝手にやってみる事にします。
ただ動かすだけならどうにかなりそうですが、
ちゃんと移植するのは面倒そうです。
thread回りがちょっと骨ですねぇ。
ちなみにこのWiki、日付はどういれるのでしょうか?--有野
日付は$dateというマクロで入ります (cf. WiLiKi:リファレンスマニュアル:マクロ)
thread回り: Windowsのthreadセマンティクスを良く知らないんですが、 mutexとconditional variableに関しては一応マクロにしてあります (src/gauche/pthread.hとsrc/gauche/uthread.h)。
路線
とりあえずコンパイルを通して実行してみる。 必要な機能は後から足す。 あまりコードの変更量を減らすように、という努力はせずに、 総量見積もる程度のつもりで適当にifdefを足していく。
なお、LoadLibraryやらCreateThreadやらはやればそんなに大変でも無さそうですが、後回しという事でoffで行きます。
途中経過、雑感
作業記録とあんましかわらない気もするけど、 こちらは実験とか雑感とか。
2003/03/06 10:28:29 PST
- Scm_SetMasterSigmaskでは、まずは何も考えずにreturnしてみる事にする。
ただしそれだとまずそうな部分が結構あるので、後でもっとまともなダミーに差し替える予定
- そろそろシグナルに関するポリシーを決めなきゃダメかなぁ…
- LoadFileでgauche-init.scmがロードできない、だそうで。そりゃパスとかいいかげんに設定しているからあたりまえなのだが…
シグナル回りはどうすべきか。 適当に存在する奴だけ対応、でもちろん移植は完成なのだが、、、
パス名区切り文字
どうも内部でも/区切りでgaucheはファイル名を持ちたがっているように見える。/等は何かの背後に隠す、というのが正しいのかもしれないけど、綺麗になるだけで面倒さは増す気もする
ファイルに触る回りだけでなんかフィルタかまして¥に変換してもいいんだけど、ちとカコワルイ
LoadFile全面書き換えで内部的にも¥区切りで持たせておくのが好みな気がする
普通に考えるとWinなのだからレジストリにロードパス等は入れるべきだろう。それが嫌なら.exeのあるフォルダと同じ所に初期化ファイルを置く、とか。あんまし特定パスを環境変数で設定させて、それを変更するとでどこでもおっけー、というのはWinっぽく無い気がする
でも複数のインタプリタを同居させるならslibのパス等は環境変数で設定したいかもしれない。うーん。
- Shiro (2003/03/06 13:21:22 PST): pathnameに関しては当初抽象化すべきかどうか 迷ったのですが、CommonLispのpathnameオブジェクト(えらく立派な仕様で 大抵のOSに対応できるようになっている)が、面倒だという印象しか なかったので、思い切って単純にしました。
- 文字列エンコーディングと同様、Gaucheの内部世界と外部世界を分けて、 内部ではスラッシュ区切りで統一、システムに渡すところで変換、というのが 良いように思います。入力に関してはstring->pathnameみたいな バックスラッシュ区切りが入って来たらスラッシュ区切りに変換するという 手続きを用意しておくとか。
有野 2003/03/06 14:07:09 PST うーん、やっぱりそっちの方がいいですかねぇ。そうするとネットワークドライブとかドライブの変更とかそういう事が少し面倒になりそうなのがいまいち乗り気にならない所ですが。
個人的にはこういう所はWindowsべったりの方が好みですが、そうするとスクリプト側も変更しなきゃいけなかったり、変更箇所も多くなったりで悩ましい所です。
ただ、とりあえずの実験ならシステムに渡す所で変換、が一番楽そうなのでそれでいきます。
- Shiro(2003/03/06 21:43:03 PST): そう、走っているプラットフォームによって 区切り文字を切替えてる処理系もあるんですが、そうするとスクリプトの 互換性が問題になります。スクリプト内に書かれるリテラルのパス名は 統一しとくに越したことはないと思うのです。
- shelarcy(2003/03/07 21:11:09 PST): ビルドシステムですが、Boost.Build では環境で設定された変数を設定ファイルに書いてあるもので上書きする(さらにコマンドラインからの入力でまた上書きする)というスタイルでやっています。
- 有野 2003/03/08 11:14:01 PST う、それは面倒そうだ(^^;
有野 2003/03/08 11:14:01 PST パス文字、ドラッグアンドドロップでファイル名を取るとC:¥から始まってしまうのですが、どうするのがいいですかね?
- Windowsファイルパスも内部的に扱えるようにする
- ドライブ指定は無条件で取る
- 適当にエンコーディングしてUnixのファイルシステムのように見せる
そもそも_openってロングファイルネーム対応だったか知らないのですが。 やっぱり男らしくCreateFileHandleにするべきかなぁ。
- Shiro(2003/03/08 20:34:58 PST): 文字エンコーディングと同じく、 外部表現/内部表現の区切りを徹底するなら、Cのレベルで 外部表現パス⇔内部表現パスの変換ルーチンを提供しておいて、 受け取ったパス名をScm_Loadに渡すところなんかにかませてやるのが いいかなあ。`
- 内部表現としてはやっぱりドライブ名も階層の一部に組み込んで処理するのが
美しいとは思うのですが(内部表現→外部表現変換ルーチンでドライブ名に戻る)、
実用上それで困るケースというのはどんなものがあるでしょうか。
- 有野 2003/03/08 21:21:27 PST 名前が重なる時位な物だと思いますけどね。実用上、という観点からすれば大して困らないかもしれません。
ただ、Schemeプログラマにとっては自然かもしれませんが、
WindowsのVBプログラマとかからすると奇異に見えるかもしれません。
特にシステム寄りな事をガリガリやろうとすると、
本質的で無い事に手間がかかる恐れがあるかもしれない、
と少し危惧してます(具体的に何か思いついている訳ではありませんが)。
なお、VBプログラマがScheme使うかは知りません(^^;
/gauche_drive/c/とかならC:とかでとりあえずは実装してみるかなぁ。
- 有野 2003/03/08 21:21:27 PST 名前が重なる時位な物だと思いますけどね。実用上、という観点からすれば大して困らないかもしれません。
ただ、Schemeプログラマにとっては自然かもしれませんが、
WindowsのVBプログラマとかからすると奇異に見えるかもしれません。
特にシステム寄りな事をガリガリやろうとすると、
本質的で無い事に手間がかかる恐れがあるかもしれない、
と少し危惧してます(具体的に何か思いついている訳ではありませんが)。
なお、VBプログラマがScheme使うかは知りません(^^;
- とおりすがり(2003/08/29 22:37:14 PDT) あのー盛り上がってるとこわるいんですがWindowsは/区切りも認識しますよ。まあ変換自体はたいした手間じゃないだろうけど、#ifdefやら変換漏れやらが面倒そう。
コンソール
Window作ってメッセージ送信をWindow宛てに行う、とかの方がまだWindowsアプリっぽい気がする。 イベントドリブンに直さなきゃいけないけど。
コンソールアプリってかっこ悪いから嫌いなんだよなぁ…
Windows的に考えるならIActiveScriptを実装してCScriptで実行する、 という方が正しい気がする。
でも面倒だからまずはUnix臭くてもいいかな(ぉ
- Shiro (2003/03/06 21:37:22 PST): read-eval-print loopは本来Gaucheの
オプショナルな機能ですんで、こだわらなくても良いです
(そもそもgoshは「サンプルアプリケーション」なのです)。
goshはWindowsではスクリプト実行用と割り切って、 インタラクティブなやつは別にWinネイティブなアプリケーションを 作っちゃったほうが良いかもしれません。あんまりgoshをごちゃごちゃに したくないので。
一応、イベントドリブンなアプリでのインタラクティブセッションを 作成するベースとして、gauche.listenerというモジュールがあります (lib/gauche/listener.scm)。- 有野 それがよさそうですね。goshはサンプル、というのを見て考えが変わりました。なんかそれっぽいアプリケーションを作ってみます。
シグナル
作業記録
- cygwin用にconfigure
- 足りない型を適当にtypedef
- pthreadはさしあたってoff
- includeのパスが間違っているのをいくつか修正
2003/03/05 07:35:54 PST
- arch.hがなぜか良く解らないけど出来てないので適当にdefine。文字列は"undefined_arch_dir"とか適当な名前をつけておく
- 大量の存在しないシグナル系を適当にifdef
getoptやらgetgrgidやらひっかかるので適当によきにはからう。 いくつかシグナル系で面倒な物は関数自体をダミーにさしかえてしまう。
- unwindではまり中。sigsetjmpなんか無いしなぁ。どうしたもんか。
- setjmpでごまかす事に
2003/03/05 12:11:29 PST
- いろいろ適当に定義してsyslib.cとsystem.cを外して他のから参照されているのだけ入れる、という感じで進める
- リンクは通ったけど、Scm_SetMasterSigmaskでパニック。先頭でScm_Error呼び出すように変更してるので当然の結果
2003/03/07 00:03:43 PST
- stat等やopenを呼んでる所でパス名を変換する
- arch.hの中身をgauch-ini.scm等がある場所にちゃんとあわせる
- WinMainから従来のmainを引数適当で呼んでやる
- mainの中でオプションとか見はじめる前の所でScm_Loadでファイル名直指定してやる
ここまでで一応動くようになります。 ただ、これだと途中のデバッグが不可能なので、途中で
- Scm_ErrorやPutzやらいろいろな所でstderrに出力しているのをOutputDebugStringに変更
というのが必要だと思います。
2003/03/08 21:21:27 PST
- main.cは使わない事にしてWinMainでウィンドウを作って、ドラッグアンドドロップがあったらそのファイルをScm_Loadするようにしました
以上で動く事は動きます。 DllのロードとかThreadとか残っている物はいろいろありますが、 Win32APIでゴリゴリ書くのがもうたくさんなので今後は小さい変更をちょろちょろしたら、たぶんATLに進みます。 レジストリ使いまくりで皆様お嫌いでしょうから、ここらでこのバージョンは終了、 という感じにする予定。
2003/03/09 09:05:31 PST
- コンパイルフラグをWIN32_NATIVEに変更
- パスの扱いをC:を/gauche_drive/c/に変換する事で対応
- パッチを作成してひとまず区切りとするつもり
成果物
問題はどこで公開するか、だけど…パッチでいいかなぁ。
- Shiro (2003/03/09 02:26:11 PST): パッチにして頂ければこちらに取り込みます。 (うちにはビルド環境が無いので確認できないのですが)。
- 有野 2003/03/09 05:43:36 PST 了解です。ifdefが全てWIN32なので、このままだとcygwinでコンパイルが通らなくなる事に今気づきました(^^;
直したらどっかに置きます。
作ってみました。
http://members.tripod.co.jp/k_arino/patch.txt
そのうち消すかもしれません。
- shelarcy (2003/03/09 16:10:47 PST): 今更ですがコンソールアプリケーションとしてビルドできるものも用意してもらえませんか? 「ヒューメイン・インターフェース」のアイデアに基づいて、エディタ上で動くものとしてインターフェースを改良していくという方向もあるわけで、私はその方向を追及していきたいので。
- 有野 2003/03/09 16:35:05 PST エディタ、というのがWindowsのエディタであるなら、コンソールよりこのバージョンの方が使いやすいと思いますが。curses等を使って何かやるならまずいですが、それならcygwin版の方がメリットがあるはず(シグナルが使えるので)。
そもそも最初はemacsもどき(というかxyzzyもどき)を作ろう、としてこの作業が始まったので、エディタに組み込むならここらへんからやるのが良いと私は思ってます(今は違う方向に進んでますが)。
なお、コンソールバージョンは今の所私はあんまり作る気はありません。 今回のコンセプトはなるべくWindowsべったり、なので。
ただ、 main.cをちょろちょろ書き換えればすぐに動かす事は出来ます。 初期の頃はそれでテストしていたので確かです。コードは捨ててしまいましたが。 - Shiro (2003/03/09 17:19:00 PST): インタラクティブな開発の根っ子はread-eval-print
loopにあるわけですが、それがstdioにつながっているというところは
あまり本質的ではないと思います。unixではたまたまstdioでコンポーネントを
組み合わせるのが楽だったというだけで。
それも少し複雑になってくると、例えばAllegro Common LispのEmacsを使った
IDEではデバッグ用に別にソケットを開いたりして結構ごちゃごちゃやってるので、
必ずしもstdioがベストとは限らないわけですしね。
私はWindowsにあまり触らないのですが、(例えば)COMがWindowsのコンポーネントの 組み方のベースにあるならそれを基礎にして、コンソールが欲しければ その上に作る、という方向が何かと便利なように思います。 - shelarcy (2003/03/09 21:51:20 PST): ええと、既存のIDEと違うパラダイムを実験してみようかなと思ったので、その実験を見れるものとして Cygwin 抜きでコンソールアプリを利用できればいいかなと考えたその程度です。実際に本当に使えるものを作ろうとした場合のアイデアは色々とあるにはあるんですが、まだ形になってないので……(とりあえず、 COM がいいとは思わない、xyzzy もどきにするよりは xyzzy で直接相互に呼び出して使えるようにした方がいいかも、とだけ言っておきます。)
- 戯 2003/03/10 02:57:15 PST IDEか否かによらず、stdioはpoorなProgram間Interfaceなのは確かですね。Object(OOP風に言えば)同士の参照し合いやMethod呼び合いに比べれば貧弱貧弱ぅ。 手続きプログラムは、外界との「接点」が1つしかないのが問題です。起動という接点だけ(藁)。 unixなstdioモデルはまさにこの問題を抱えてる。unix filter的プログラムを作る理由はむしろそれのInterfaceが低機能過ぎるから(そのぶん作るのも楽だから)でしかないなぁ俺。
- 戯 2003/03/10 03:06:16 PST コンポモデルの個人的嗜好。Delphi信者としては(^^;、Win上だからってWin提供の仕組でなくても良いし(Unix上のXみたいに後付けする)、壁越え( Omicron:COMとBonoboとKParts )もオプショナルでいいや。そういうノリでDelphiのコンポーネントとして実装されてるScript言語エンジンも幾つか有ります。
- shelarcy(2003/03/10 03:40:16 PST): (C++ で ObjectIO をやろうと思い描くような)インターフェースの探求者としては、増井 俊之さんが何度か薦めている Linda で使われている Tuple Space model が最高だと思うわけですけど。……この話長くなりますね。別のところに移しませんか?
- 有野 2003/03/10 06:01:59 PST 何をやりたいのかはさっぱり理解してませんが、コンソール版の欲しい理由がcygwinよりも多くの人に試してもらえる、なのなら、自分で作ってしまうのが一番早いと思います。私は多くの人に試してもらいたい、とはあまり思っていないし、main.cをVC++でコンパイルするのに必要な変更なんてたかだか20行位ですし、私がやるよりも何をやるのか理解している人がやる方がよっぽどいい予感。
- shelarcy (2003/03/10 12:07:08 PST) その程度の理由に過ぎないので、絶対に用意してもらいたいというわけではない、ということを書き損ねてましたね。了解です。話をぐちゃぐちゃにしてしまってすみません。
問題点
- HAVE_A 系のifdefはconfigureに入れるのが正しい?
- DebugTerm等は実質まだ使われていない
- evalした結果の表示手段が今の所message-boxしか無い
- いくつかいいかげんにifdef入れた所がある
- GC関係は一切テストしていない
- この変更を加えた結果、他の環境でコンパイルできなくなってるかも
- そのほかいろいろ
今後の標準的な路線
こんな事を書くのは有野は違う方向に進むつもりだからですが。
- なんらかのターミナル(DebugTerminalでもいいか?)を作る
- evalした結果はターミナルに出力するようにする
- ウィンドウのメニューからライブラリのパスを指定出来るようにして、結果はiniファイルに吐く
- その他メニューはもっと充実させる
- LoadLibraryやCreateThreadにちゃんと対応する
- ターミナルやDebugTerminalをちゃんとSchemeのオブジェクトに対応させる
- パス名やドライブ名等、そこらへんをきっちり扱うようなユーティリティをそろえる(これはSchemeのレイヤーでいいと思う)
という感じでしょうか。 たぶんどれもそんなに大変では無いと思いますし、 そこそこ需要もあるとは思います。
ATL版のインターフェース
とりあえず実装前に考えておく。
- Scm_Load
- Scm_Eval
- Scm_Apply
- Scm_Compile(?)
- Scm_ReadFromCString
徐々に足していく予定。
ここまで来て、Scm_Applyを使いやすくするには、 なんかまともに機能するwrite可能なポートが欲しい事に気づく。 それを設定してやれば、Scm_Writeでちまちま書いていく、 という作戦が取れるので。
また、Scm_MakeSubrのような類の物は含めるべきだろうか?
Scm_MakePortWithFdのようなあたりをうまく扱わないと、 VMをnewしてもいろいろ使いにくいんだよなぁ。
ここらへんを考えると、むしろScm_VM関係をちゃんとそろえる方がいいのかな?
2003/03/16 18:31:05 PST 戻り値をVARIANTにしようとしたら、C的に基本型じゃない型の場合を綺麗に扱う方法が思いつかなかったので、 ATL路線は中止する事に。
2003/03/17 21:35:21 PST 一応動く所までいった残骸があるのでIDLだけ置いておきます。欲しい人がいれば公開方法は考えますが、 最低でもIDispatchを実装しないと使い道は無いと思う。 本気でやるならどちらにしろVARIANTへの変換をまじめにやらないとダメでしょうけど。IDL