K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[375] Re:教えてください。
投稿者:774RR
2007/02/20 02:13:25

>M4sugar requires GNU M4. Install it before installing M4sugar or のメッセージを見れば一目瞭然なような気がしますが何がわからないでしょうか。 Cygwin Setup で m4 を追加インストールしてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[374] 教えてください。
投稿者:タイガー
2007/02/20 02:13:25

はじめまして。タイガーです。 「プログラミング言語を作る」のページで、Windows版のソースをダウンロードし、MinGW、bison、flexをインストールして、binのパスを追加したのですが、gmakeを実行すると、以下のエラーが出ます。 M4sugar requires GNU M4. Install it before installing M4sugar or bison: I/O error set the M4 environment variable to its path name 環境は、Windows XP SP1で、「bison crowbar.y」を実行すると同様のエラーが発生します。 なぜこのエラーが発生するのですか?回避方法があれば教えてください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[373] Re:実体渡し
投稿者:kit
2007/02/20 02:13:25

引用の順序を変更しています。 > ただ、「PlayerがBoardの実体を保持していてはいかんでしょ > う。」といった話をするときには、「実体」またはそれに類 > する言葉が要るのではないかと思っています。 そうですね。 念のために言うと、僕も、実体という言葉に対して(ぱ)さんと 同じ感覚を持っています。 > > Python プログラマで一人、"call by object reference" > > のことを指して "call by object" と呼んでいる例が見つ > > かりましたが、これだと、日本語と英語で意味が逆になり > > ますし。 > > 日本人でも、「オブジェクト==参照」という解釈の人もいる > ようですから、「日本語と英語で意味が逆」になるわけでも > ないような気がします。 以下の松本さんの例もそうなんですね。 > http://www.rubyist.net/~matz/?date=20030730 > | もっとも多くの言語には「オブジェクト」でない「値」も > | ある。またCの例を出すと、構造体はオブジェクトではな > | い。代入によってコピーが発生するからだ。 BASICの文字 > | 列もオブジェクトではない。 > 最初読んだとき、かなり違和感がありました。「参照」と > 「値」の話ならその通りですが、上記の文を読む限り、「オ > ブジェクト」が「参照」とほぼ同義で使われているからです。 まったく同様な違和感があります。 > >http://aspn.activestate.com/ASPN/Mail/Message/python-Tutor/509290 > ざっと読みました。 > | (2) there is no pointer type in Python, so you > | *can't* pass "a reference" to an object > Pythonは(Javaと同様)なんでもかんでも参照だと思っていま > したが、 それで合ってると思います。 > これはどういう意味でしょう。変数への参照が取れないって > ことかなあ。 参照への参照が取れないってことでしょうね。 > # でも「you *can't* pass "a reference" to an 『object』」 > # だしなあ。 > ## 私がPythonについて誤解しているようでしたらご指摘く > ## ださいませ。 上の記事の著者である Tim Peters が言う "object" というの は、松本さんの言う object と同じもの、すなわち我々の感じ るところの「object への参照」のことなので、特に矛盾はな いと思います。 Smalltalk や Ruby など、全ての型が object である言語で育 つと、自然にこういう感覚になるのかもしれませんが、機械語 による実装を見て意味を理解するタイプの人間からすると、 ちょっとついていけない感じですね。 で、我々の感覚でいう「オブジェクトへの参照の値渡し (call by object reference)」は、Tim Peters や松本さんのような 感覚を持つ人にとっては、 実体渡し == "call by object" となるわけです。 結局、以下の懸念は、まったく当たっており、注釈をつけたの は正解だということになると思います。 > おっしゃるとおり、術語としてちゃんと定義されてな > さそうなので、誤解を招く可能性があると思うのです > が。そのために、先の投稿で注釈をつけたわけです。 同様に、 > 参照渡しを実体渡しと読んでいるのはその本(および > その本に言及したWebページ)以外では、私は見たこと > ないです。そんなの広く使われてるじゃん、という方 > は情報よろしくお願いします。 についても、(少なくとも Python の世界では?) 広く使われている と考えた方がいいのかもしれません。Tim Peters 氏は、Python の 世界では結構な有名人のようですし。 以下は余談です。 > >ただ、Java を含む多くの GC つき言語では、参照の値 > >渡しをするわけで、この術語は使えませんね。 > ええと、少なくともJavaやCなら「値渡ししかない」で済み > そうな気がするのですけど。 もちろんそうです。 ただ、C++ でオブジェクトを参照渡しすることと、まあだいた い等価なことは、Java でも当然行なわれていることなわけで、 C++ と Java に関する話をするときに、これを意味する術語が 欲しいように思います。 で、これを "call by object" と呼びたくない派の人間として は、"call by object reference" のように呼びたくなるわけ です。 もっとも google によると "call by object reference" の 用例は230件しかないそうなので、こういう欲求は、非常に マイナーなのかもしれませんが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[372] Re:実体渡し
投稿者:(ぱ)
2007/02/20 02:13:25

>「参照渡し (call/passing by reference)」と「値渡し >(call/passing by value)」が標準的な術語だと思うの >で、言葉としては、これを使うのがいいような気がする >んですが。言語も C++ ですし。 同意します。私自身、「ポインタ完全制覇」でも「Java謎+落とし穴~」でも、 「値渡し」という言葉を使用しています(どこかで「実体渡し」という言葉を 使っているかもしれませんが…)。 ただ、「PlayerがBoardの実体を保持していてはいかんでしょう。」といった 話をするときには、「実体」またはそれに類する言葉が要るのではないかと 思っています。 おっしゃるとおり、術語としてちゃんと定義されてなさそうなので、誤解を 招く可能性があると思うのですが。そのために、先の投稿で注釈をつけたわけです。 >ただ、Java を含む多くの GC つき言語では、参照の値 >渡しをするわけで、この術語は使えませんね。 ええと、少なくともJavaやCなら「値渡ししかない」で済みそうな気がするのですけど。 >Python プログラマで一人、"call by object reference" >のことを指して "call by object" と呼んでいる例が見 >つかりましたが、これだと、日本語と英語で意味が逆に >なりますし。 日本人でも、「オブジェクト==参照」という解釈の人もいるようですから、 「日本語と英語で意味が逆」になるわけでもないような気がします。 http://www.rubyist.net/~matz/?date=20030730 | もっとも多くの言語には「オブジェクト」でない「値」もある。 | またCの例を出すと、構造体はオブジェクトではない。代入によって | コピーが発生するからだ。 BASICの文字列もオブジェクトではない。 最初読んだとき、かなり違和感がありました。「参照」と「値」の話なら その通りですが、上記の文を読む限り、「オブジェクト」が「参照」と ほぼ同義で使われているからです。 >http://aspn.activestate.com/ASPN/Mail/Message/python-Tutor/509290 ざっと読みました。 | (2) there is no pointer type in Python, so you *can't* pass "a | reference" to an object Pythonは(Javaと同様)なんでもかんでも参照だと思っていましたが、 これはどういう意味でしょう。変数への参照が取れないってことかなあ。 # でも「you *can't* pass "a reference" to an 『object』」だしなあ。 ## 私がPythonについて誤解しているようでしたらご指摘くださいませ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[371] Re:実体渡し
投稿者:kit
2007/02/20 02:13:25

話題がそれるので、件名を変更しました。 「参照渡し (call/passing by reference)」と「値渡し (call/passing by value)」が標準的な術語だと思うの で、言葉としては、これを使うのがいいような気がする んですが。言語も C++ ですし。 ただ、Java を含む多くの GC つき言語では、参照の値 渡しをするわけで、この術語は使えませんね。Java と C++ で共通に使える用語としては、「オブジェクト参照 渡し (call/passing by object reference)」と「コピー 渡し (call/passing by copy)」が分かりやすいような 気がします。が、google で探すと、使っている例が少 ないなあ… 特に日本語で「オブジェクト参照渡し」を 使っている例が少ないです。あと、コピー渡しは、値渡 しと同じ意味なので、この対比は実は対称じゃないのも イマイチかも。 「実体渡し」に関しては、google で探して上位に出る サイトでは、「コピー渡し」の意味で使っているサイト ばかりのようですね。でも実体渡しって、日本以外でも 使われている用語なんでしょうか? Python プログラマで一人、"call by object reference" のことを指して "call by object" と呼んでいる例が見 つかりましたが、これだと、日本語と英語で意味が逆に なりますし。 http://aspn.activestate.com/ASPN/Mail/Message/python-Tutor/509290 「実体渡し」を英語に訳すとすると、どうなるんでしょう?
[この投稿を含むスレッドを表示] [この投稿を削除]
[370] Re:お邪魔しますー
投稿者:(ぱ)
2007/02/20 02:13:25

>ソースの半分くらいしか理解できてませんが、読んだ感じだとDBフィールド用意して、あのソースを貼り付けるだけで出来そうなんですが(笑) >使用してもよいでしょうか? 使用していただく分にはまったく問題ありません。あのソースのライセンスは、 NYSL↓と思っていただいて結構です。 http://www.kmonos.net/nysl/ ただし、Webページに乗っているものは、いろいろなバージョンが混在していますから、 単純に貼っただけでは動かないと思います。その点はご承知おきください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[369] Re:リバーシゲームのはさみ将棋への改造
投稿者:(ぱ)
2007/02/20 02:13:25

>http://revolver.at.infoseek.co.jp/hasami-vc.lzh  まず、うちにはVC++をコンパイルする環境はないですし、デバッグまで するつもりもないので、ざっと眺めた感想ですが。  BoardがBoard.cppで定義されていて、#include "Board.cpp"してるとかは さておくとしても、PlayerがBoardの実体を保持していてはいかんでしょう。 Playerがふたりいるとき、それぞれがBoardを抱え込んでいては、ゲームに なりません。  先読みのときBoardをヒープにclone()するのなら、以後それはポインタで 持ち歩いたほうがよさそうに思うのですが、実体で引数渡ししていますし。 Boardの中のcellは、実体で持ってよさそうですがポインタで保持してますし、 にもかかわらずBoardにコピーコンストラクタがありません。  それぞれがaccess violationの原因になるかどうかはさておき、 C++を使うのなら、ポインタと実体の区別を意識するのが重要だと思います。 Javaにはポインタしかないので、Javaから移植するのなら、なんでもかんでも ポインタにするのが楽かもしれません(メモリリークを起こしそうですが)。 なお、ここでは「実体」という言葉を、「ポインタではないデータそのもの」 という意味で使っています。 以前読んだC++本では、引数の参照渡しを「実体渡し」と呼んでてびっくりしました。 「コピーではなく、それそのものを渡す」という意味で「実体渡し」なんだろうと 思いますが、一般的かなあ… 私のように「ポインタではないデータそのもの」の意味で「実体」という言葉を 使うのもさほど一般的ではないかもしれませんが、参照渡しを実体渡しと読んでいるのは その本(およびその本に言及したWebページ)以外では、私は見たことないです。 そんなの広く使われてるじゃん、という方は情報よろしくお願いします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[368] Re:リバーシゲームのはさみ将棋への改造
投稿者:SFファン
2007/02/20 02:13:25

前回貼った圧縮ファイルには、圧縮前のフォルダだけ圧縮されていた様です。 たびたびすみません。 http://revolver.at.infoseek.co.jp/hasami-vc.lzh
[この投稿を含むスレッドを表示] [この投稿を削除]
[367] サポートセンター
投稿者:774RR
2007/02/20 02:13:25

掲示板を読んでいたらなんとなく「さぽせん」ホームページを思い出しました。 ... っていやそれだけ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[366] お邪魔しますー
投稿者:hairo
2007/02/20 02:13:25

はじめまして。 ここ数日サイトに訪れさせてもらっています。 最近(ここ2、3年)ですがSQL+PHPで仕事することが多く、それまで無知だった自分がいつのまにやら基本構文(?)を覚えてしまい、無料サーバーを借りてDB組み込みつつ動的なものを作り始めました。 さしあたって、簡単な雑記帳やカウンターなどは楽にできました(それでも丸三日はかかりました)が、BBSはどうしたもんかなーとgoogleで回っていたら。このサイトに来ました。 ソースの半分くらいしか理解できてませんが、読んだ感じだとDBフィールド用意して、あのソースを貼り付けるだけで出来そうなんですが(笑) 使用してもよいでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[365] Re:リバーシゲームのはさみ将棋への改造
投稿者:(ぱ)
2007/02/20 02:13:25

>http://revolver.at.infoseek.co.jp/hasami-vc.lzh  このリンクから.lzhファイルをダウンロードすることはできました。サイズは301バイト。  解凍してみたら、ショートカットのファイルがひとつだけあらわれました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[364] Re:リバーシゲームのはさみ将棋への改造
投稿者:SFファン
2007/02/20 02:13:25

当方がWebについて良く知らないため、ダウンロードして貰えなくてすみません。 今回もうまくいかないかも知れませんが、とりあえず貼って見ます。 http://revolver.at.infoseek.co.jp/hasami-vc.lzh
[この投稿を含むスレッドを表示] [この投稿を削除]
[363] Re:crowbar MEMモジュール
投稿者:tos
2007/02/20 02:13:25

> それだとおっしゃるとおりチェック漏れを起こすと思います。どういうわけか、 また、ボケた質問しているんじゃないかと思って、ドキドキしてましたが、 今回はあってたみたいで安心しました。 >というわけで、私はこの通りポカもミスも人並み以上にしますので、 >全然たいしたことはないです f(^^;;; いえいえ、これからも前橋さんのソースで勉強させていただきます。 ありがとうございました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[362] Re:「プログラミング言語を作る」
投稿者:(ぱ)
2007/02/20 02:13:25

>実装を始めて気がついたのですが、goto文って実はもっとも単純だと >思っていたのですが、実は難しいのですね。  です。crowbarにgotoがないのはそのためです(w。かろうじてbreakとcontinueは ありますが、これも戻り値でちまちま返すことになってしまっています。 # Rubyはこのへんをsetjmpとlongjmpでやっているようですが。 >というように、状況に応じて改行を文の区切り文字と認識したりあるいは >無視したりしています。Ruby では Lex などの字句解析機を使わずに自前の >実装を使われているそうなので、ありものの字句解析機を利用しなかったのは、 >利用できなかったからなのでは?と勝手に想像しています。  いきなり答をばらす行為になるのかもしれませんが、Rubyの実装については、 以下のページに詳細な説明があります。 http://i.loveruby.net/ja/rhg/index.html  「状態付きスキャナ」にも、1章が割り当てられています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[361] Re:リバーシゲームのはさみ将棋への改造
投稿者:(ぱ)
2007/02/20 02:13:25

>はじめまして。  どうもです。  ここを見ている第三者のために経緯を説明すると、SFファンさんは 既にJavaWorld誌経由で質問されていて、私からも一度回答を返しています。 ただあまり編集さんを煩わせるのもなんですし、よろしければ掲示板の方へ、 と私が書いたので、こちらで質問されたようです。 >そこでVC++への移植を試みました。しかし時々盤オブジェクトの参照で >アクセスバイオレーションが起きてしまいます。 >Java版と同じ様に盤(cell)をnewしていますが、別クラスもしくは >Boardクラスの他のメソッドから見れていない様です。 >この件についてJavaWorld経由で前橋氏から解答を貰いましたが >盤オブジェクトは構造体にしなければいけない様な事が書いてありました。  そういうことを書いた覚えはないですが…  私が書いたのは、以下の通りです。 # その他、本当にC++にすれば速くなるかは疑問、という趣旨のことも書きましたが。 >可能性としては、以下のようなことが考えられるでしょうか。 > >・メンバにアクセス修飾子を付けない場合のデフォルトの意味が、JavaとC++では > 異なる(Javaはデフォルトでパッケージ内丸見えだがC++はデフォルトでprivate)。 >・高速化を狙ったのなら、1手先読みするたびにBoardを毎回newするのではなく、 > Boardをスタック上に確保するような変更を加えたのでしょうか? > もしそうだとして、盤面の配列部分をJava版と同じようにヒープに確保して > いるとすれば、コピーコンストラクタを正しく書かないと動作しません。 > # Boardをスタックに置いておきながら、盤面の配列をヒープに取るようなことは > # 普通しないと思うので、この可能性は薄そうですが。  ひとまず「アクセスバイオレーション」とのことなので、コンパイル時のエラー ではなく実行時のエラーなのでしょう。よってひとつめの可能性は排除できます。  「Java版と同じ様に盤(cell)をnewしていますが」とありますが、もしこれが、 「Boardはスタックにとっているのに2次元配列cellはヒープにとっている」という ことなら、ふたつめの可能性は考慮する価値があるかもしれませんが… 私のソースを直接C++で書き直したのなら、Boardこそヒープに取るでしょうし、 やっぱり可能性は薄いように思います。 >http://revolver.at.infoseek.co.jp/hasami-vc  403 Forbiddenです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[360] Re:crowbar MEMモジュール
投稿者:(ぱ)
2007/02/20 02:13:25

> とはならず、「(char*)&header[1] - (char*)header->s.mark)とMARK_SIZEの隙間」 >の方が先に壊れるような気がするのですが、違いますでしょうか?  すみません、勘違いしていました。tosさんが心配しておられるのは、 アプリケーションに返す領域の「前の」MARK部分なのですね。  それだとおっしゃるとおりチェック漏れを起こすと思います。どういうわけか、 後ろのMARKのことだとばかり思い込んでいました。  ご指摘ありがとうございました。次のバージョンで直します。 >ただ、私は前橋さんを勝手に師匠と思って、ソースを勉強させていただいて >いますので、もう少しお付き合いください。 というわけで、私はこの通りポカもミスも人並み以上にしますので、 全然たいしたことはないです f(^^;;;
[この投稿を含むスレッドを表示] [この投稿を削除]
[359] Re:「プログラミング言語を作る」
投稿者:緒方
2007/02/20 02:13:25

>>>・制御構文はとりあえずifとgotoのみ(とほほ・・・) >>>・他の制御構文はifとgotoで実装してライブラリ提供 >> >> どのような形式で実行する言語を想定しておられますでしょうか。 > >むむっ、実はあまり考えていません。あれこれ空想する際には、アセンブリのイメージで考えていて、無条件ジャンプと条件ジャンプがあればとりあえず事足りるかな、という風に思って上記のように書きました。 実装を始めて気がついたのですが、goto文って実はもっとも単純だと思っていたのですが、実は難しいのですね。 今はソースを読み込んだら即構文木を作って評価するインタープリタを作っているのですが、今のインタープリタにgoto文を実装するとすると、上方向にジャンプする場合も下方向にジャンプする場合も、入力ストリームをラベル位置まで巻き戻したりスキップしたりしなければなりません。BASICのgoto文ってどういう実装になっているか調べてみようかと思っています。 >>>b, a = a, b #スワップ 他にも難しい実装に気がつきました。Ruby のように文の区切り文字を省略させたいのですが、これがまたかなり難しいです。Ruby だと 1 + 2 # 1+2 と評価される 1 # 1 と評価される + 2 # +2 と評価される 1 # 1 と評価される + # この時点では式が継続するものと予測されるので評価しない 2 # 上の行と合わせて +2 と評価される 1 + # そういえばこのケースは試してないですが、 2 # 多分 1+2 と評価されるのでは? というように、状況に応じて改行を文の区切り文字と認識したりあるいは無視したりしています。Ruby では Lex などの字句解析機を使わずに自前の実装を使われているそうなので、ありものの字句解析機を利用しなかったのは、利用できなかったからなのでは?と勝手に想像しています。 というのも、上記のような改行仕様を flex で実装しようとしたところ、状態遷移だけでかなり複雑になってしまい、私ではお手上げでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[358] リバーシゲームのはさみ将棋への改造
投稿者:SFファン
2007/02/20 02:13:25

はじめまして。 「JavaWorld」2003年3月号掲載の前橋氏作のリバーシゲームをはさみ将棋に改造しました。 しかし3手読みが限界で強くありません。 そこでVC++への移植を試みました。しかし時々盤オブジェクトの参照でアクセスバイオレーションが起きてしまいます。 Java版と同じ様に盤(cell)をnewしていますが、別クラスもしくはBoardクラスの他のメソッドから見れていない様です。 この件についてJavaWorld経由で前橋氏から解答を貰いましたが盤オブジェクトは構造体にしなければいけない様な事が書いてありました。 以前作りかけていたはさみ将棋に前橋氏作のリバーシゲームを改造したものを上乗せしたので、まだ構造的におかしいですが、問題点があればご指摘をお願いします。 http://revolver.at.infoseek.co.jp/hasami-vc
[この投稿を含むスレッドを表示] [この投稿を削除]
[357] Re:crowbar MEMモジュール
投稿者:tos
2007/02/20 02:13:25

細かい突っ込みで時間を取っていただき、申し訳ありません。 ただ、私は前橋さんを勝手に師匠と思って、ソースを勉強させていただいて いますので、もう少しお付き合いください。 (char*)&header[1] - (char*)header->s.markがパディングを考慮したものだとすると、 (char*)&header[1] - (char*)header->s.markの値は、MARK_SIZEよりも大きい場合が あると思います。 そうすると、 >しかし、このへんが壊れるのはほとんど配列のオーバランで、もしそうなら、 >(char*)&header[1] - (char*)header->s.mark)とMARK_SIZEの隙間より先に、 >MARK_SIZEでチェックしている部分が壊れるはずです。 とはならず、「(char*)&header[1] - (char*)header->s.mark)とMARK_SIZEの隙間」 の方が先に壊れるような気がするのですが、違いますでしょうか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[356] Re:crowbar MEMモジュール
投稿者:(ぱ)
2007/02/20 02:13:25

>check_mark_sub(unsigned char *mark) ... >でチェックしているのは、MARK_SIZEのようです。 はい。これは単に、アプリケーションに返す領域の「前に入れたマーク」と 「後ろに入れたマーク」で同じcheck_mark_sub()を使いたかったため …だったと思います。要するに単なる手抜きです。 関連するソースはこのへん: http://kmaebashi.com/programmer/devlang/crowbar_src_0_1_01/S/5.html#148 >これだと、(char*)&header[1] - (char*)header->s.mark)がMARK_SIZEでは無かった場合、 >チェック漏れが起きてしまいそうな気がするのですが、あっていますでしょうか?(ヨワヨワです) (char*)&header[1] - (char*)header->s.mark)とMARK_SIZEの差にあたる部分を 選択的に破壊するようなバグがあれば、確かにチェック漏れを起こすはずです。 しかし、このへんが壊れるのはほとんど配列のオーバランで、もしそうなら、 (char*)&header[1] - (char*)header->s.mark)とMARK_SIZEの隙間より先に、 MARK_SIZEでチェックしている部分が壊れるはずです。 MEMでできるのはどっちみち確率的なチェックでしかありません。たとえば たまたま0xCDでマーク部分を破壊されたら気付きませんし、MEMで保持している 連結リストをぶっ壊されたら原因の究明は困難になってしまいます。 そう考えれば、この程度のチェックの甘さは許容範囲かなあ、と思っています。 だったら0xCDを詰めるのも、最初からMARKのサイズだけでいいじゃん、という ツッコミはもちろんあり得るわけですが、そんなことでたいして速度が稼げる わけじゃなし、どうでもいいんじゃないかなあ、と。 ただし、もちろんmark_check_head()とmark_check_tail()を別々に 作ってもたいした手間ではありません。チェックの甘さはさておき、 ソースの統一感という点からすると、修正したほうがよいかもしれませんね。 正直、あまり優先度は高くないですが、気が向いたら直しておきます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[355] crowbar MEMモジュール
投稿者:tos
2007/02/20 02:13:25

皆さんこんにちは、tosです。 crowbarのMEMモジュールに関して質問があります。 memory.cの void set_header(Header *header, int size, char *filename, int line) { . . . memset(header->s.mark, MARK, (char*)&header[1] - (char*)header->s.mark); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ } でmemsetのサイズとしてMARK_SIZEでは無く、上記のようなサイズを設定しているのは、 パディングを考慮してのことなのかなと思いますが、 void check_mark_sub(unsigned char *mark) { int i; for (i = 0; i < MARK_SIZE; i++) { if (mark[i] != MARK) { fprintf(stderr, "bad mark\n"); abort(); } } } でチェックしているのは、MARK_SIZEのようです。 これだと、(char*)&header[1] - (char*)header->s.mark)がMARK_SIZEでは無かった場合、 チェック漏れが起きてしまいそうな気がするのですが、あっていますでしょうか?(ヨワヨワです)
[この投稿を含むスレッドを表示] [この投稿を削除]
[354] Re:プログラミング言語を作る
投稿者:mizu
2007/02/20 02:13:25

>クロージャがネストするたびに、配列の要素が増えるのではなく、配列が >増えるわけですよね。つまり2次元配列(配列の配列)が渡ることになる、と。 >あるいは、ネストが増えるたびに引数の数そのものが増えるのかも >しれませんね。 引数の数が増える方を想定していました。2次元配列の方だと、クロージャから 外側の環境の変数にアクセスするたびに2次元配列にアクセスすることになる分、 性能が低下しそうなので。 > >どちらにせよ、それなら納得です。 > >最近本格的に時間がなくて、断片的な疑問の提示しかできなかったため >余計なお手間を取らせてしまいました。すみません。 いえ、こちらこそ、説明が足りなかったせいで余計な手間を取らせてすいません でした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[353] Re:「プログラミング言語を作る」
投稿者:(ぱ)
2007/02/20 02:13:25

>foreach と using を分けた C# もそれはそれで偉い、というか >何でもクロージャよりそっちのほうが個人的にはまっとうな >考え方という気が現在はしていますけどね。 私も基本的にはそう思うんですが、時々思うのは、 「言語仕様がライブラリに依存しているのはなんかヘン」ってことです。 foreachはIEnumerableに依存していますよね。 まあでもそれを言えばピュアなOO言語は数値などのリテラルもクラスの インスタンスですし、Cだってexit()に依存しているとは言えるので、 気にするほうがおかしいのかもしれません。 crowbarも、配列の生成は、配列リテラルを除きネイティブ関数に頼るつもりですし。
[この投稿を含むスレッドを表示] [この投稿を削除]
[352] Re:プログラミング言語を作る
投稿者:(ぱ)
2007/02/20 02:13:25

>すいません。説明不足でした。前の例で配列を1つしかクロージャに渡して >いないのは、あの例ではクロージャがネストしていないため、そうなっている >だけで、クロージャのネストが増えるごとに、クロージャに渡される配列の数 >は1つずつ増えて行く仕組みになっています。つまり、クロージャがn段ネスト >した場合、n個の配列がクロージャに渡されることになります。 クロージャがネストするたびに、配列の要素が増えるのではなく、配列が 増えるわけですよね。つまり2次元配列(配列の配列)が渡ることになる、と。 あるいは、ネストが増えるたびに引数の数そのものが増えるのかも しれませんね。 どちらにせよ、それなら納得です。 最近本格的に時間がなくて、断片的な疑問の提示しかできなかったため 余計なお手間を取らせてしまいました。すみません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[351] Re:プログラミング言語を作る
投稿者:mizu
2007/02/20 02:13:25

>まず前提として、 > >・クロージャはそれ自体が式なので、クロージャの中にも書けるはず。 > よって、クロージャはネスト可能。 >・ということは、内側のクロージャは、外側のクロージャの環境と、 > さらにその外側(普通の関数)の両方の環境が見えなければならない。 > >というのがあって、mizuさんの案だと配列をひとつしか渡していないので、 >いいのかな、と思ったわけです。 すいません。説明不足でした。前の例で配列を1つしかクロージャに渡して いないのは、あの例ではクロージャがネストしていないため、そうなっている だけで、クロージャのネストが増えるごとに、クロージャに渡される配列の数 は1つずつ増えて行く仕組みになっています。つまり、クロージャがn段ネスト した場合、n個の配列がクロージャに渡されることになります。 > 再帰がなければ静的にインデックス計算することも可能でしょうが、 >再帰を許すと、インデックスが動的に変化することになりませんか、 >というのが先の投稿の意図です。 ># 私はクロージャ初心者なので何か勘違いしている可能性はありますが… クロージャのネスト段数は静的に決定され、かつ、クロージャから 参照されている変数がどのクロージャ(関数)のものであるかは、静的に決定 可能なので、再帰の有無に関わらず、(クロージャから参照される)変数の インデックスは静的に計算できるはずだと思うのですが…。何か勘違いしている のかもしれませんので、もう少し考えてみます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[350] Re:「プログラミング言語を作る」
投稿者:Shin
2007/02/20 02:13:25

>> foreach(collection, function(item) { >> print(item); >> }); >> >>こんな感じだと読みにくいですかねえ。 > >そんなことはないですよ。むしろ読みやすいと思います。 Ruby なら collection.foreach { |item| print item } なわけで、メソッド/クロージャによるライブラリ的実装の ほうがよっぽど読みやすいとは言えそうですねぇ。 # 他のに多様な仕組みとの共通性という意味で これはクロージャの構文の勝利ですね。 foreach と using を分けた C# もそれはそれで偉い、というか 何でもクロージャよりそっちのほうが個人的にはまっとうな 考え方という気が現在はしていますけどね。 # Net::HTTP.start(host) { |http| ... } みたいに # 後始末のためにクロージャを使うのってなんか変な感じがしている
[この投稿を含むスレッドを表示] [この投稿を削除]
[349] Re:プログラミング言語を作る
投稿者:(ぱ)
2007/02/20 02:13:25

>> ええと、クロージャが再帰した時はどうなるのでしょうか。Pascalの >>スタティックリンクのような仕掛けがないと困るような気が… >>すみませんよぱらいなので頭動いてないです。 まず前提として、 ・クロージャはそれ自体が式なので、クロージャの中にも書けるはず。  よって、クロージャはネスト可能。 ・ということは、内側のクロージャは、外側のクロージャの環境と、  さらにその外側(普通の関数)の両方の環境が見えなければならない。 というのがあって、mizuさんの案だと配列をひとつしか渡していないので、 いいのかな、と思ったわけです。  再帰がなければ静的にインデックス計算することも可能でしょうが、 再帰を許すと、インデックスが動的に変化することになりませんか、 というのが先の投稿の意図です。 # 私はクロージャ初心者なので何か勘違いしている可能性はありますが… >あと、Pascalはよく知らないのですが、Pascalのスタティックリンクとは >どのようなものなのでしょうか?  Pascalは関数のネストができるので、内側の関数からは外側の関数の ローカル変数が参照できます。かつ再帰を許すため、現状のスタックの トップからの、外側の関数のローカル変数の位置は静的には決まりません。 そこで、最新の環境に、外周の関数の環境へのポインタを保持していて それをスタティックリンクと呼びます。 # Pascalの処理系を読んだわけではないので、「エキスパートCプログラミング」の # 受け売りですが。 >とすると、変数のルックアップは、ある環境を探索して、見つからなければ >外側の環境へのリンクをたどって…という風に行われるのでしょうか。 そのつもりです。JavaScriptではこんな感じらしいですし。 http://www.hawk.34sp.com/stdpls/jsnotes/jssinso/  ただ、グローバル変数を単なる再外周の環境として扱うか、特別扱いするかは 現在悩んでいるところです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[348] Re:プログラミング言語を作る
投稿者:mizu
2007/02/20 02:13:25

> うーん、私はLispはEmacs Lispやxyzzy Lispで遊んだ程度ですので、 >Lispそのものについては何も言いませんが(Paul Grahamのエッセイは日本語訳された >範囲ではたぶん全部読んでますし、Lispを悪く言うつもりはないですが)、 私も、Lispは、Schemeとかで遊んだ程度なので、あまり偉そうには言えないです。 >コンパイラコンパイラが使える環境なら、多少の構文の複雑さは問題にならない >はずです。 確かにそうだと思います。しかし、構文を少しずつ拡張していくという作業は、 いかにパーザジェネレータを使っていても、面倒ではあります。その点、Lisp系なら 一度S式パーサを書いておけば、基本的にはパーザをいじらなくても構文を拡張 できる(まあ、S式で書けるものしか基本的には書けませんが)というのは、嬉しい気が します。それが初心者にとって、どれだけ嬉しいかはわかりませんが。 >だとすれば、初心者さんにとって、馴染みの薄いLispの勉強と、 >言語処理系の作成というふたつのことを同時に勉強させるのは酷というものでは >ないでしょうか。 Lispの核となる概念自体はかなりシンプル(だと思う)なので、覚えるべき事柄は そう多く無い気もします。もちろん、Common LispなりSchemeなりを実装しようと 思うと、勉強しなければならないことがたくさんあるはずですが、処理系作成の 勉強としては、「Lispのようなもの」を作れれば十分ですし。ただ、馴染みが 薄いため、取っ付きが悪いというのはありそうです。 > もっとも、何かを理解しようと思ったら、それを作ってみるのが一番手っ取り早い >とは思っていまして、Lispを勉強したい人に「じゃあLispを作ってみようよ」という >提案は有効だと思います。でも、言語処理系を作ってみたい、という人が、 >本当に作りたいのは、Lispなんでしょうか。 たぶん(多くの人にとっては)違うと思います。しかし、とりあえず練習として 作ってみることで、言語処理系の作成に必要な基礎知識が身につくという効果は あると思います。どうせ、初めて作る言語で、いきなり自分の欲しい言語を作る なんてのは無理ですし。 >>基本的なアイデアとしては、いわゆる「単純委譲」をコンパイラが自動生成する > > 了解です。 > ところで、この形式で、MyListはArrayListなんでしょうか。 > そうだとすれば、多重継承を許そうとすると、「ArrayListインタフェース」のような >インタフェースをたくさん作らなければならないような気がします。 いえ。あくまで委譲コードの自動生成なので、型としては、ArrayListと MyListは何ら関係がありません。ですから、型の継承関係を作りたけ れば、別途クラスを継承するか、インタフェースを実装します。 例えば、MouseListenerとWindowListenerのインタフェースを多重継承して、 それぞれの実装をMouseAdapterとWindowAdapterに委譲するコードは、 class MouseAndWindowAdapter implements MouseListener, WindowListener { /*MouseListenerインタフェースに対する呼び出しを委譲*/ forward MouseListener mouseListener_ = new MouseAdapter(); /*WindowListenerインタフェースに対する呼び出しを委譲*/ forward WindowListener windowListener_ = new WindowAdapter(); } と書けます。 >>で、問題になっている環境へのアクセス方法ですが、クロージャから外側の >>環境にアクセスしていることをコンパイラが検出したら、外側の環境での変数 >>へのアクセスをObject型配列の要素に対するアクセスに変換して、Object型配列 >>への参照を、クロージャに渡すという方法を取ります。 > > ええと、クロージャが再帰した時はどうなるのでしょうか。Pascalの >スタティックリンクのような仕掛けがないと困るような気が… >すみませんよぱらいなので頭動いてないです。 クロージャの中で、自分を再帰的に呼び出したときということでしょうか。 それなら、おそらく問題無いと思います。 例えば、以下のような再帰でフィボナッチ数列を計算するクロージャfibが あったとして(これだと、クロージャにする意味があまりありませんが)、 interface UnaryIntegerFunction { int call(int arg); } class Hoge{ public static void main(String[] args){ UnaryIntegerFunction fib = #(int n){ if(n == 1 || n == 2){ return 1; }else{ return fib.call(n - 1) + fib.call(n - 2); } }; System.out.println(fib.call(3)); } } これは、 class UnaryIntegerFunction$1 implements UnaryIntegerFunction { private Object[] environment_; UnaryIntegerFunction(Object[] environment){ environment_ = environment; } public int call(int n){ if(n < 2){ return 1; }else{ return ((UnaryIntegerFunction)environment_[1]).call(n - 1) + ((UnaryIntegerFunction)environment_[1]).call(n - 2); } } } class Hoge { public static void main(String[] args){ Object[] environment = new Object[2]; environment[0] = args; environment[1] = new UnaryIntegerFunction$1(environment); System.out.println("fib(3) = " + ((UnaryIntegerFunction)environment[1]).call(3)); } } というコードに変換されます(先の投稿の例では、引数をenvironment 配列に入れるのを忘れていたので、若干先の例とは変換のされ方が違っています)。 このコードは問題無く動くと思うのですが、何か勘違いしているでしょうか? あと、Pascalはよく知らないのですが、Pascalのスタティックリンクとは どのようなものなのでしょうか? > ちなみにですが、crowbarはJavaScript的に環境ごとに連想配列を持ち、 > 外側環境へのリンクを持とうと思っています。 とすると、変数のルックアップは、ある環境を探索して、見つからなければ 外側の環境へのリンクをたどって…という風に行われるのでしょうか。
[この投稿を含むスレッドを表示] [この投稿を削除]
[347] Re:プログラミング言語を作る
投稿者:(ぱ)
2007/02/20 02:13:25

>簡単に実装するなら、Lisp系言語などが楽でいいのではと思いましたが、 >どうでしょうか。普通の言語に比べて、構文がちょっと特殊ですが、機能 >拡張がわりと容易ですし、言語設計の面白さは十分に味わうことができるの >ではないかと思います。  うーん、私はLispはEmacs Lispやxyzzy Lispで遊んだ程度ですので、 Lispそのものについては何も言いませんが(Paul Grahamのエッセイは日本語訳された 範囲ではたぶん全部読んでますし、Lispを悪く言うつもりはないですが)、 いわゆる「普通のプログラマ」に馴染みが薄いというのは確かだと思うわけです。  んで、この辺のスレ http://pc8.2ch.net/test/read.cgi/tech/1106129164/ とか見るにつけ、「Lispなら処理系作るの簡単だよ」というアドバイスがちょくちょく あって、それはそれで嘘ではないと思うのですが、yaccなりJavaCCなりの コンパイラコンパイラが使える環境なら、多少の構文の複雑さは問題にならない はずです。だとすれば、初心者さんにとって、馴染みの薄いLispの勉強と、 言語処理系の作成というふたつのことを同時に勉強させるのは酷というものでは ないでしょうか。  もっとも、何かを理解しようと思ったら、それを作ってみるのが一番手っ取り早い とは思っていまして、Lispを勉強したい人に「じゃあLispを作ってみようよ」という 提案は有効だと思います。でも、言語処理系を作ってみたい、という人が、 本当に作りたいのは、Lispなんでしょうか。 >基本的なアイデアとしては、いわゆる「単純委譲」をコンパイラが自動生成する  了解です。  ところで、この形式で、MyListはArrayListなんでしょうか。  そうだとすれば、多重継承を許そうとすると、「ArrayListインタフェース」のような インタフェースをたくさん作らなければならないような気がします。 >で、問題になっている環境へのアクセス方法ですが、クロージャから外側の >環境にアクセスしていることをコンパイラが検出したら、外側の環境での変数 >へのアクセスをObject型配列の要素に対するアクセスに変換して、Object型配列 >への参照を、クロージャに渡すという方法を取ります。  ええと、クロージャが再帰した時はどうなるのでしょうか。Pascalの スタティックリンクのような仕掛けがないと困るような気が… すみませんよぱらいなので頭動いてないです。  ちなみにですが、crowbarはJavaScript的に環境ごとに連想配列を持ち、 外側環境へのリンクを持とうと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[346] Re:プログラミング言語を作る
投稿者:mizu
2007/02/20 02:13:25

今回の投稿は、説明の都合上、大分長くなってしまいました。迷惑でしたら、 すいません。 >やってみるとそんなに難しくはないんですよね。実際、今回の企画はそれを >示そうと思ってはじめました。時間がなくてなかなか思うに任せていませんが。 ># そんなに難しくはない、ということを示したいんだから、あっという間に ># 実装できた方が説得力あるんでしょうけどねえ。 簡単に実装するなら、Lisp系言語などが楽でいいのではと思いましたが、 どうでしょうか。普通の言語に比べて、構文がちょっと特殊ですが、機能 拡張がわりと容易ですし、言語設計の面白さは十分に味わうことができるの ではないかと思います。 >・委譲の言語仕様とか、 基本的なアイデアとしては、いわゆる「単純委譲」をコンパイラが自動生成する というもので、Java風に書くと、 class MyList{ forward List list_ = new ArrayList();//委譲宣言 } というコードから、 class MyList{ List list_ = new ArrayList(); public void add(Object o){ list_.add(o); public Object get(index i){ return list_.get(i); } } というコードをコンパイラが生成します。もちろん、これだけだと メソッド名が衝突したときに問題が発生しますが、経験から言って、 そのような衝突は、おそらくさほど頻度は高くないだろうと思われるので、 コンパイルエラーにして、衝突したメソッドのみ、プログラマにどのフィールドに 委譲するか(あるいはそもそも委譲せず、そのメソッドを新たに定義するか)を 選択させれば良いと考えています。 あと、全部のメソッドを委譲するだけでは不便なので、委譲したくないメソッドを 列挙する機能も必要かなと考えていますが、これはまだ実装するかどうかわかり ません。 >・クロージャの実装方法(環境へのアクセス方法)とか、 実は、クロージャの部分はまだ実装できていないのですが、仕様は大体決まって いて、クロージャは、新たなデータ型を導入するのではなく、インタフェース の実装クラスのインスタンスとして、クロージャを生成するという方法を 取ろうと思っています。 ActionListener n = #(ActionEvent event){ System.out.println("actionPerformed"); }; というコード(#以降がクロージャの定義で、eventはクロージャの仮引数です)は、 class ActionListener$1 implements ActionListener { public void actionPerformed(ActionEvent event){ System.out.println("actionPerformed"); } } ... ActionListener n = new ActionListener$1(); というコードにコンパイルされます。 ここでは、ActionListenerがメソッドを1つしか持っていないため、クロージャ の定義では、メソッド名を指定する必要はありませんが、メソッドを複数持った インタフェースの場合、対応するメソッドを指定する構文を用意しようかと 思っています。 で、問題になっている環境へのアクセス方法ですが、クロージャから外側の 環境にアクセスしていることをコンパイラが検出したら、外側の環境での変数 へのアクセスをObject型配列の要素に対するアクセスに変換して、Object型配列 への参照を、クロージャに渡すという方法を取ります。例えば、 class Hoge{ public static void main(String[] args){ int n = 0; ActionListener listener = #(ActionEvent event){ n++; }; listener.actionPerformed(null); System.out.println("n: " + n); } } というコードは、 class ActionListener$1 implements ActionListener { private Object[] environment_; ActionListener(Object[] environment){ environment_ = environment; } public void actionPerformed(ActionEvent event){ environment_[0] = new Integer(((Integer)environment_[0]).intValue() + 1); } } class Hoge{ public static void main(String[] args){ Object[] environment = new Object[1]; ActionListener listener = new ActionListener$1(environment); listener.actionPerformed(null); System.out.println("n: " + ((Integer)environment[0]).intValue()); } } というコードにコンパイルされます。このようなクロージャの実装方式は、 クロージャを新たなデータ型として導入するのに比べて、正直使い勝手は 悪いですが、既存のライブラリを活用するという点では、この方式の方が 良いのではないかと思っています。 >・型宣言を省略する方法とか(静的型とのことなので、レキシカルな最初の代入から推測?) その通りです。例えば、以下の代入があったとして、 n = 1; 代入があった時点でのスコープで、nが宣言されてされていなければ、それは int n = 1; という宣言とみなされます。代入される値の型が参照型の場合も、同じですが、 nullが代入される場合だけやや特殊で、 n = null; は、 Object n = null; とみなされます。この機能があれば、例えば、よくある String line; while((line = reader.readLine()) != null){ .. } というコードが、変数宣言無しで、 while((line = reader.readLine()) != null){ .. } だけで書けるようになります(lineのスコープはwhile文で閉じています)。 以上、長々と説明を書かせていただきましたが、よろしければツッコミや 意見をいただければ幸いです。 > 公開される日を楽しみにしています。 どうも有難うございます。頑張って開発を進めたいと思います。
[この投稿を含むスレッドを表示] [この投稿を削除]