K.Maebashi's BBS

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

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

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

[1265] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:(ぱ)こと管理人
2009/05/16 22:40:50

>その論理で行くと、マルチプロセスやマルチスレッドはオブジェクト指向になると >思いますが、 ならないと思いますが…… まあ、オセロの例で注記したように、マルチプロセスにはオブジェクト指向と似た面は ありますけど。「その論理で行くと」の「その論理」がどういう論理か、教えて いただきたいです。 >例えばこれを修正して、大文字に変換して返す物を使いたいとします。 >----------------------------------------------------------- >public class UpperStack extends Stack { >  public String get(){ >    return super.get().toUpperCase(); >  } >} >----------------------------------------------------------- 774RRさんがすでに書いていますけど、これは典型的な「ダメな実装継承の例」でしょう。 # 「実装継承」でGoogleしてみることをお勧めします。 実のところ「要素を大文字に変換して返すスタック」がどんな時に役に立つのか 想像できませんが、それはまあ、「あくまで例だから」ということにしても、 このケースは、 「要素をgetする側は、大文字が欲しいとき、そのことを意識している」 のでしょうか。 意識しているのであれば、そもそも「stack.get().toUpperCase();」で済む話です。 大文字に変換する、という単純な処理でないのなら、ユーティリティメソッドを 作ればよいでしょう。 そこでわざわざ継承してクラスを作ったって、以下のような問題が起きるだけです。 ・Stackが引数かなにかで渡されたとき、本家StackなのかUpperStackなのか  わからなくて危険。 ・別の誰かがLowerStackを作ったら、いつかマージするの? ・ユーティリティメソッドではprivateメンバにアクセスできないが、  継承なら、protectedにしておけばサブクラスからアクセスできる、というのが  趣旨なら、それはカプセル化の破壊以外の何者でもない。 ところで、SEさんの例では、get()メソッドがオーバーライドされています。 「要素をgetする側は、大文字が欲しいとき、そのことを意識している」のであれば、 仮に継承を使うとしても、getUpper()メソッドをつけることでしょう。 オーバーライドしているということは、 「要素をgetする側は、大文字が欲しいとき、そのことを意識しないで済む」 ということにしたいのでしょうか? # それにしては、get(boolean up)と対比しているのでよくわかりませんが。 もしそうなら、 >そのため、変更により以前の機能のまま使用したい場所には影響がありません。 というわけにはいきません。 この改修により、プログラムにUpperStackという「異物」が実行時に紛れ込むわけで、 「Stackにputしたんだから、当然同じものがgetできるだろう」と思い込んでいる 既存コード(Stackそのものを含む)にはおもいっきり影響を与えます。 しかも、get(boolean up)とは違い、実際に動かしてみなければ検出できない バグになりますからさらにタチが悪いです。 上のほうで『実のところ「要素を大文字に変換して返すスタック」がどんな時に 役に立つのか想像できません』と書きましたが、結城浩さんが「例は嘘をつかない」 と書いておられるように、こういうところで現実のプログラムに即した適切な例が 出てこないなら、おそらくそれは考え方のほうが間違っています。 ひとつ伺いたいのですが、SEさんはどんな本でオブジェクト指向の勉強をされたの でしょうか。 いまどきこんなバリバリの実装継承でオブジェクト指向を説明している教科書は そうそうないと思っていたので、もし新しい本にそういうことが書いてあったのなら 興味があります。ぜひ書名を教えてください。 ところで、私が現在作っているクラスベースオブジェクト指向言語Diksamでは、 「concreteクラスは継承できない」ということにしてしまっています。これは 実装の手抜きではなく、意図して行っています。 ここまでやってしまうと異論はあるかもしれませんが、Effective Javaとか GoFのデザパタ本とかで、かなり昔から、散々「抽象クラス以外は継承するな」と 言われてますし、SEさんのような誤解を防止するためにもこの方がよいのではないかと。 http://java-house.jp/ml/archive/j-h-b/050862.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1264] [業務連絡]掲示板が復旧したようです
投稿者:(ぱ)こと管理人
2009/05/16 21:47:05

原因は不明ですが、しばらくこの掲示板が投稿できない状態になっていました。 閲覧は通常通り可能でしたが、送信ボタンを押してもプレビュー画面に遷移しない、という状態でした。 それでしばらくテスト掲示板で様子を見ていましたが、どうも直ったようです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1263] 状況その3
投稿者:
2009/05/15 18:56:21

 yacc,lecの修正とプリプロセッサの作成が終わりました。ファイルの多重#includeと 多重の#define宣言を処理できるようになりました。  次の3つのファイルをt001.dkmで起動すると。 --ファイルt001.dkm--------------------------- // aaaaaaaa #include "t001-01.dkm" #define DEF1 DEF2 + "def1 " // aa int main() { string str; str = DEF1; str = DEF2; str = DEF3; } --ファイルt001-01.dkm------------------------ //ssssssssssss #define DEF2 DEF3 + "def2 " // bb #include "t001-02.dkm" //aaaa int print (string str); --ファイルt001-02.dkm------------------------ //ssssssssssss #define DEF3 "def3 " // cc int printnl(string str) { print(str + "\n"); } -------------------------------------   ↓  プリプロセッサ   ↓ ------------------------------------- int printnl (string str ) { print (str +"\n"); } int print (string str ); int main () { string str ; str ="def3 "+"def2 "+"def1 " ; str ="def3 "+"def2 " ; str ="def3 " ; } -------------------------------------  になってコンパイラに渡されます。もちろんメモリ渡し、エラーもファイル名+行番号で出さ れます。コメントやインデントは内部的に不要なので無くなっています。  最上位の制御構造がマルチスレッドを意識した構造を作りこみ、コンパイラは単独で動作する 構造になりつつあります。ジェネレータは関数単位で実行される予定です。  これでようやく中断前に戻れます。  関数のリンクは総て動的リンクにする予定です。最初の1回だけ動的リンクが行われ、その後 コンパイラが起動されるか、中間コードが破棄された時のみ再度動的リンク試験が行われます。 これでほとんどの関数コールは、直接起動されることになり。スピード的に問題ないと思って います。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1262] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:
2009/05/15 18:53:09

 私にとってOOPを使う最大の理由は。  「カプセル化により見透視のよさ!」これに尽きます。  継承や多態化はそのサポートのために。再利用性は設計の問題であり。OOとは 関係が薄い場合がある。ただし、OOを使っても見透視の悪いコードはいくらでも かける。が、よく整理されたクラスの見透視の良さは、OOが無い言語に比べて 格段にいい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1261] Re:疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:774RR
2009/05/15 14:56:25

「再入門」のそのあたりの記述は、そもそも「インスタンスが複数あっていい」というあたりを理解していないプログラマ向けの文書。 SE氏の指摘は「インスタンスが複数あるのは当たり前」と理解しているプログラマの視点なわけで。 そういう意味で、対象読者層が異なるだけのことだと思う。 あえて言わせていただくと、提示例はやっちゃダメな「実装継承」の典型例であって 俺の後輩君がこんなコードかいてたら0点つけるですよ。 > そして、大文字で取得したい場所では、このUpperStackを使うようにします。 これは、実体が Stack であるインスタンスに対して UpperStack にダウンキャストして使う、としか読めない。 そんな危険なことをさせるわけにはいかないと思うのだが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1260] 疑りぶかいあなたのための「オブジェクト指向再入門」を読んで
投稿者:SE
2009/05/15 14:06:45

疑りぶかいあなたのための「オブジェクト指向再入門」を読みました。 部分的に同意できる所もありますが、オブジェクト指向の「本質」はマルチプル インスタンスだと言うのは全く違うと思います。 その論理で行くと、マルチプロセスやマルチスレッドはオブジェクト指向になると 思いますが、これらはオブジェクト指向云々以前から存在する、別の話だと思います。 オブジェクト指向プログラミングの利点は、 「変更がしやすい」事と「変更しても以前の機能が失われない」事です。 簡単に説明します。 先入れ後出し形式のデータ(スタック)をクラス化したとします。 エラー処理を考慮しなければ、大体以下のようになるでしょう。 ----------------------------------------------------------- public class Stack {   private String[] data = new String[100];   private int index = 0;   public Stack(){   }   public void put(String val){     data[index] = new String(val);     index++;   }   public String get(){     String ret = "";     index--;     ret = data[index];     return ret;   } } ----------------------------------------------------------- 例えばこれを修正して、大文字に変換して返す物を使いたいとします。 ----------------------------------------------------------- public class UpperStack extends Stack {   public String get(){     return super.get().toUpperCase();   } } ----------------------------------------------------------- そして、大文字で取得したい場所では、このUpperStackを使うようにします。 ここで重要なのは、基のクラスのStackには全く修正が入らない事です。 そのため、変更により以前の機能のまま使用したい場所には影響がありません。 ちなみに、Stackに別名の大文字で返すメソッドを追加すると言う方法もありますが、 基のソースに修正が入るため、デグレートの危険が発生します。 やたらに継承をしたくない場合は、それでも構いませんが、以下の方式はダメです。 ----------------------------------------------------------- public class Stack {   private String[] data = new String[100];   private int index = 0;   public Stack(){   }   public void put(String val){     data[index] = new String(val);     index++;   }   public String get(boolean up){     String ret = "";     index--;     if(up){       ret = data[index].toUpperCase();     }else{       ret = data[index];     }     return ret;   } } ----------------------------------------------------------- なぜダメかは、構造化プログラミングを行っていて、度重なる修正で スパゲッティープログラム化しているのを見た事のある人なら分かるでしょう。 これを使用している所で、変更の必要ない既存部分にも手が入り、処理にも分岐が 入って複雑化するためです。 適切にオブジェクト指向プログラミングされていれば、修正が入っても劣化せず、 むしろ抽象化され使いやすいクラスになっていきます。 オブジェクト指向プログラミングの目的はこれだけです。 カプセル化、継承や多態化もこれを実現するための手段に過ぎません。 そのため「オブジェクト指向の目的は、再利用性を高める事」は正しいです。 しかしこの場合の再利用性は、関数化などの話ではなく、変更の時の使いやすさを 指しています。 新人が誤解するので「オブジェクト指向はマルチプルインスタンス」と言う記述は 修正か注意書きをしてほしいです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1259] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/12 02:16:16

>> 見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ >見間違いかと思います (^^; >了解しました、構文解析の所を今見た所確かにそうです。失礼いたしました。 >しかし、以前メモリートラブルでと話したとき、いつもmallocの中でこけてた >んです。 補足ですが、構文解析部分はMEM_Storageを使用してまとめて開放していますが、 コンパイルにより作られるDVM_Executableは各オブジェクトを個々にMEM_malloc()して 作っています。こちらは、配列のオーバーランなどすると、次のmalloc()で こける可能性が高いと思います(いまどきはそうでもないかも)。 malloc()で確保した領域を配列のオーバーランで壊したことを検出するために、 MEMではアプリケーションに渡す領域の前後を0xCDで埋めていて、これをチェックする 関数MEM_check_all_blocks()を用意しています。実際これでバグを見つけたことも 多いのですが、最近はLinux環境ではとっととvalgrindを使っていたりします。 Windowsで、フリーなvalgrind相当品があるかどうかは不勉強にて知りません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1257] Re:状況(日記?)
投稿者:
2009/05/10 23:54:32

>見間違いかと思います (^^; 了解しました、構文解析の所を今見た所確かにそうです。失礼いたしました。 しかし、以前メモリートラブルでと話したとき、いつもmallocの中でこけてた んです。それで思い違いをしたかな、結局追いきれなくてあきらめたんですけ ど。いや、相当粘ったんですよこれでも… >fix_tree.cでは主にTypeSpecifierを解析木に付加しますが、おっしゃるとおり、 >たとえばある式がintのTypeSpecifierを持っていて、それにマイナス演算子を適用した >このへんのことは以下にちょっとだけ書いてありました。 了解しました、と言うかまとめて開放だから無問題です。単に私がちょっとfixtree で手間取ったのが、それが理由だったんです。結局、メモリー監視デバックルーチ ンが、shared_ptrのような機能を持ってメモリー管理になってしまいましたんです。 もともとスマートポインターは重いからやめようと思ってた矢先の出来事で。 ええ、Boostのpoolに変えます… >「一番外側のブロック」ではなく、その名のとおり「現在のブロック」です。 了解しました。実はコメントを書き換えなおすの忘れてた。昔のままだった。 何も考えずに、有るのそのままコピペしてました。 >> ST_MemberExpression member_expression; // 使用していない? >クラスを導入していないver.0.2では確かに使っていませんね。 了解しました。ありがとうございます。これなんだろう?調べなきゃと思っていました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1256] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/10 19:05:32

> 見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ 見間違いかと思います (^^; create.cで解析木のノードを確保する際も、fix_tree.cで主にTypeSpecifierを 確保する際も、最終的にはdkc_malloc()を呼んでいますし、dkc_malloc()は コンパイラが保持してるMEM_Storageを使用してメモリ確保しています。 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/S/11.html#22 > 実は、構文解析で構文ツリーが出来た時点では、TOPのCT_Compilerのオブジェクトを >deleteすればディストラクタ繋がりできれいに総てのメモリーを解放できたのですが >Fixtreeを作ってみると、多重リンクはするはリンクが切れてフリーが山ほど出てくる >はで。 fix_tree.cでは主にTypeSpecifierを解析木に付加しますが、おっしゃるとおり、 たとえばある式がintのTypeSpecifierを持っていて、それにマイナス演算子を適用した ような場合には、マイナス演算子の式のTypeSpecifierは、その子ノードのものを 直接使用していたはずです(多重リンク)。また、[]演算子を適用するとTypeDeriveが 1段階外されますが、この時、[]演算子のノードのTypeSpecifierは、TypeDeriveの 連結リストの途中のノードを指します(その下のノードでは根元を参照していますが)。 このへんのことは以下にちょっとだけ書いてありました。 http://kmaebashi.com/programmer/devlang/diksam_0_1_comp.html | コンパイル時のTypeSpecifierは、なにしろ解析木のすべての式のノードに | 割り当てられます。たとえば「a + 1」という式がありaがint型の時、 | intを表現するためのTypeSpecifierが(「a」と「1」と「a + 1」のために) | (現状の実装では)3つ確保されています。でもよく考えれば「a + 1」のノードの | TypeSpecifier は左辺か右辺かどっちかのを直接参照してもよいはずで、 | 実際マイナス演算子ではそうしています。 | このように、TypeSpecifier構造体は、誰が所有者なのかわけがわからんような | こんがらがった参照で保持されているので、解析木の他の部分同様、 | コンパイル終了時に(MEM_Storageの機能を使用して)一括で破棄しています。 >class CT_Compiler : public CBase >{ >public: > CT_Block * current_block; // 一番外側のブロック 微妙に気になるのですが、current_blockは、少なくとも元のソースでは、 「一番外側のブロック」ではなく、その名のとおり「現在のブロック」です。 create.cにおいてBlockを生成する際に、親のブロックへの参照をセットするために 使用しています。 >class CT_Expression : public CBase >{ ... > union { > ST_MemberExpression member_expression; //    使用していない? これは、オブジェクトのメンバを参照するためのノードですが、 クラスを導入していないver.0.2では確かに使っていませんね。 ていうかソースには一応入っていたことに私の方が驚きました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1255] Re:状況(日記?)
投稿者:
2009/05/09 22:51:48

お疲れ様です。返事をもらえると嬉しいのですが、ごゆっくりどうぞ。  ↓のクラスを見てわかるとおりに、ほとんどstructをクラスにしたままです。内部 データが少し変わっていますが、structの全体接続構造はほとんどそのままです。  私も意味もなくポリモルフィズムするのは好きではないし。本来の目的は クラスでパッキングして見通しを良くしよう。そして、書くことによる自身の 理解、そして必要機能の追加のためです。それと、diksamもほぼ同じ量のメモリー 確保をしていますよ。  見間違いかもしれないけど、0.2.0はメモリーストレージを使ってないような・・・ class CT_Compiler : public CBase { public: int function_count; // 関数の数 CT_FunctionDefinition * function_list; // 関数のリスト CT_DeclarationList * declaration_list; // トップの宣言リスト CT_StatementList * statement_list; // トップのステートメントのリスト CT_Block * current_block; // 一番外側のブロック //== 式のツリーノード =========================================== class CT_Expression : public CBase { public: CT_TypeSpecifier *type; // E_ExpressionKind kind; // 式の種類 int line_number; union { E_Boolean boolean_value; // boolデータ リテラル int int_value; // intデータ リテラル double double_value; // doubeデータ リテラル string *string_value; // stringデータ リテラル ST_IdentifierExpression identifier; // 関数又は宣言文の識別子 ST_CommaExpression comma; // カンマ(,)式 ST_AssignExpression assign_expression; // 代入式 ST_BinaryExpression binary_expression; // 演算式 CT_Expression *minus_expression; // マイナス式 CT_Expression *logical_not; // 論理否定式 ST_FunctionCallExpression function_call_expression; // 関数式 ST_MemberExpression member_expression; //    使用していない? CT_ExpressionList *array_literal; // 配列データ リテラル ST_IndexExpression index_expression; // 配列の添え字式 ST_IncrementOrDecrement inc_dec; // ++,--,式 ST_CastExpression cast; // キャスト演算式 ST_ArrayCreation array_creation; // 配列生成式 } u;  実は、構文解析で構文ツリーが出来た時点では、TOPのCT_Compilerのオブジェクトを deleteすればディストラクタ繋がりできれいに総てのメモリーを解放できたのですが Fixtreeを作ってみると、多重リンクはするはリンクが切れてフリーが山ほど出てくる はで。メモリー監視・チェック・報告のデバックプログラムが、一躍メモリー管理 プログラムに昇格して、多重リンクや放置されたメモリーを管理して、きれいに掃除 することになりました。思わぬ副作用が・・・  今大改造中で動かせなかったのですが、構文解析時点で5千数百のnewをしていました。  実は、ジェネレータとVM部分を始めていたのですが、ほしい仕様のための変更部分が 目立って見えてきたため、yacc,lex部分から大きく改造を始めてしまいました。 いま、#include #define 構文の追加と最外枠のステートメント禁止、main()関数起動 を組み込み始めました。そして上の二つの構文のためにプリプロセッサを書いています。 だから、コンパイルは+1増えて4ステージになりました。#includeは単に外部ファイルを 同一ファイルとしてコンパイルできる普通の機能です。でも、その為にライン数管理が ファイル名+ライン数になってその部分が全体的改造に。  本当は、一通り終わるまで新機能は入れないつもりでしたが、チョコチョコ変えている 時点で、もう全体変更しようと思ってしまった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1254] Re:状況(日記?)
投稿者:(ぱ)こと管理人
2009/05/09 02:35:53

世間では連休で私も会社は休みだったはずですが何かとどたばたしてまして お返事が遅れましてすみません。 > ちなみに、test.dkmで最高6800ぐらいnewします。 これで速度低下しないかと心配して、crowbarやDiksamではMEMモジュールを作って MEM_storage_malloc()を使ったのですが、C++でクラスを使おうとすると単純に 置き換えはできませんね(newのオーバーロードで置き換えはできますが、私には、 演算子のオーバーロード自体相当に腰が引けます。boostのように、汎用的で 一般的に知られたライブラリを使うのなら、だいぶ軽減されると思いますけど)。 ところで、DiksamをC++で書き直し、fix_tree.cppでたくさんnewが起きるということは、 DiksamでのExpressionやStatementの構造体をクラスにしておられるのだと思いますが、 これはやっぱり、fix_tree.cppではfix()、generate.cppではgenerate()という メンバ関数を作って、クラスごとにポリモルフィズムで呼び出しているのでしょうか? オブジェクト指向の教科書にはそう書いてありますが、実際にやってみると クラスごとに細かい制御ができなかったりモデルにロジックが侵食したりして あまりうまくいかない、と経験上思っておりますので。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1253] 状況(日記?)
投稿者:
2009/05/07 19:00:06

 fix_treeのところで多少手間取っていますが一応終了。トータルの結合 試験で多分たくさんのがバグが・・・  少し長いプログラムを読み込ませるだけで、細かいサイズのメモリーを 7千ぐらい、newとdeleteしているのを見るにつけ、これは結構システムに 負担ではないと思いつつ、区切りが出来たらboostの高速メモリー管理poolに 変えようとかと考えています。一括削除が可能だし。また、メモリー上のトラ ブルが起こったら追うだけでも大変だと思う、今のところそのトラブルには 遭遇していないのが救いです。バグは当たり前のようにありますが・・・  ちなみに、test.dkmで最高6800ぐらいnewします。  特に新しいところがなく日記的なので、不要だったら削除してください。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1252] Re:関数実装について
投稿者:
2009/05/04 22:30:19

>Diksam ver.0.4以降だと、ファイルをrequireしておけば、 >呼ぶ際は普通の関数呼び出しですけれど、 そうなんですか、同じものを再発明しそうですね。 >Emacs Lispはダイナミックロードですが、私としては初回呼び出しのタイムラグは >気にならないと思っているので、まあ問題ないと思っているのですけれども。 私の場合、スレッドが必要だと思うほどクリティカルな部分を意識しているので やはり、利用者がコンパイラ起動を意識したほうがいいかなと思っています。 >ということはDVMはひとつでグローバル変数とヒープ領域は共有ですね。 >結構ロックが大変そうな気はします。  この辺はまだ希望的観測の部分が多いので、実際に作りこんでみないと なんともいえない感じです。  今現在はfix_tree部分を作っていますが、途中でnew、deleteが頻発するので 思わず。new、deleteに被せて、newのアドレスとサイズをコンテナMAPに総て入れ、 deleteで検証する監視プログラムやサポ-トプログラムばかり作ってて脱線気味 です。目的プログラム70%残り30%は監視やデバックプログラムです・・・ 文字列リテラルも、wchar_tを使ってもポータビリティーが上がらないのでstring に変えてしまったし、diksam言語部分だけでも一通り動くようになるのはまだまだ 先です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1251] Re:関数実装について
投稿者:(ぱ)こと管理人
2009/05/04 19:33:38

> 言語仕様から見ると、Aプログラムの内部からBファイル内にある関数B1を普通に >コールすることです。当初は、ファイル名.関数名();で起動しようか、関数プロ >タイプ宣言で"ファイル名":関数名();で内部的には普通の関数記述と思いましたが。 Diksam ver.0.4以降だと、ファイルをrequireしておけば、 呼ぶ際は普通の関数呼び出しですけれど、 >いつ重いコンパイラが走るかコントロール出来ないので、 .dkhにシグニチャ宣言だけ書いて.dkmに実装を書くと、関数呼び出し時にコンパイラが 動きますから、状況によって問題になるかもしれません(実装まで.dkhに書いてしまえば いいわけですけど)。 Emacs Lispはダイナミックロードですが、私としては初回呼び出しのタイムラグは 気にならないと思っているので、まあ問題ないと思っているのですけれども。 >スレッド起動の仕様 >普通に関数名(P1,,,Pn);を書くと戻ってくるまでコール元は待ちます。 >start(関数名,起動P,,,Pn);と書くとスレッド起動となります。 ということはDVMはひとつでグローバル変数とヒープ領域は共有ですね。 結構ロックが大変そうな気はします。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1250] 関数実装について
投稿者:
2009/05/02 18:30:12

>これは、CからDiksamの関数を関数名を指定して呼び出すということですよね。 内部的に見るとそうです。  言語仕様から見ると、Aプログラムの内部からBファイル内にある関数B1を普通に コールすることです。当初は、ファイル名.関数名();で起動しようか、関数プロ タイプ宣言で"ファイル名":関数名();で内部的には普通の関数記述と思いましたが。 いつ重いコンパイラが走るかコントロール出来ないので、プログラムファイル読込 み関数と破棄関数(中間コードリソースの破棄)を作ることにしました。  この仕様でVMの変更が発生します。それは、1ファイル内の関数コールはコンパ イラで関数アドレスを生成しますが。ファイル外の場合、関数アドレスではなく関 数名を持って、実行時リンクして関数コールする仕様が追加になります。 (最外枠ブロックの実行構文はなくなり、ファイル名起動ではmain()が実行) 中間コードの構造は。 親 ファイル1  ファイル親ー>子    ファイルn ↓   |----------¬    |----------¬ 子   関数1 ・・・・・・ 関数n  関数1 ・・・・・・ 関数n  の様に、階層構造の親子関係で関数置きに分離した中間コードになる予定です。 この、ファイルnの部分が必要時にコンパイルされ中間コードに追加される感じです。  この構造はちょうど関数単位のマルチスレッドに適応できます。 スレッド起動の仕様 普通に関数名(P1,,,Pn);を書くと戻ってくるまでコール元は待ちます。 start(関数名,起動P,,,Pn);と書くとスレッド起動となります。 例   thread_ID1 = start(fnc1,,,);   thread_ID2 = start(fnc1,,,);   thread_ID3 = start(fnc1,,,); と書くとメインスレッドと3つのfnc1スレッドが同時に動きます。 関数については、この様な仕様を組込みたいと考えています。 また、グローバルシステム変数とスレッド起動された関数は一般的なCのグローバ ル変数やスレッドとは、かなり性格が違ったものになります。でも、この点は実物 のめどが出来そうなときにでも、評価していただければ嬉しいと思っています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1249] Re:その後の状況
投稿者:(ぱ)こと管理人
2009/05/02 03:39:28

訂正します。 >と思って見ていたらbaseが初期化されていない >ことに気付きました。またバグです。すみません (_o_) いくらなんでもこれじゃ動かないよな、と思ってよく考えると baseはローカル変数の参照に使うので関数内でしか使用されず、 関数を読んだ際にセットされるので問題ありませんでした。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1248] Re:その後の状況
投稿者:(ぱ)こと管理人
2009/05/02 03:14:14

>追加したい機能 >・関数指定起動、スクリプトファイル名と関数名を指定して起動 > (スクリプトファイル間の連携したプログラミングのために) これは、CからDiksamの関数を関数名を指定して呼び出すということですよね。 特定の関数を実行するには、dvm/execute.cのexecute()関数を、 http://kmaebashi.com/programmer/devlang/diksam_src_0_2/S/18.html#544 ・事前にdvmのcurrent_executableとcurrent_functionとpcを設定して  (プログラムカウンタは関数ごとなのでpcは0に設定)、 ・execute()関数を、適切な引数で呼び出す ことで可能なはずです。 ただ、実際にはDiksamからネイティブ関数を呼び出して そのネイティブ関数からさらにDiksamの関数を呼び出す、というケースも あるので、スタックポインタを設定の上、execute()関数のローカル変数 baseも引数で渡してやらないと… と思って見ていたらbaseが初期化されていない ことに気付きました。またバグです。すみません (_o_) gccの-Wallでは当てにならないですし、山さんがされたようにVisual Studioでも コンパイルしたいのですがなかなか時間が取れない状態です。明日からは連休ですが、 連休は連休でまた色々と… 編集さんはゲラを発送されたとのことですし(ん?) >その結果、diksam0.2.0の系譜をもつ別の言語になってしまいます。 >なので、言語名は別のものになります。そこでお聞きしたいので >す。diksam0.2.0の系譜をもつ別のものを作ることになりましたが、 >ここでお話しすることは可能でしょうか? まったく問題ありません。 > ぶちゃけて言います。気分を害したりしませんか?>< それはないです(^^) Diksamベースで新しい言語ができるのであれば、 どこをどう直されるのか興味深いです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1247] その後の状況
投稿者:
2009/05/01 07:40:30

 各種機能を追加しようとdiksam0.2.0を解析修正をトライしていましたが、メモリ破壊トラブル に数回遭遇しメモリーダンプ解析を行う状態になってしまいました。さすがにこれは私の手に負え る状態ではないと感じ、diksam0.2.0を元にOOで新たに言語を作るほうが早いと思い、現在作成し ています。今は構文解析ツリーの生成まで終了しています。 ちなみに、yaccはkmyaccを使用、lex部分は自作です。 追加したい機能 ・グローバルシステム変数への透過的アクセス ・関数指定起動、スクリプトファイル名と関数名を指定して起動  (スクリプトファイル間の連携したプログラミングのために) ・関数単位でのスレッドセーフなマルチスレッド起動 ・関数単位でのスレッドセーフな通信 ・#define構文の追加(別名定義のみ)  等の、APとして必要な要件を組み込む必要がありました。その結果、diksam0.2.0の系譜をもつ 別の言語になってしまいます。なので、言語名は別のものになります。そこでお聞きしたいので す。diksam0.2.0の系譜をもつ別のものを作ることになりましたが、ここでお話しすることは可能 でしょうか?  ぶちゃけて言います。気分を害したりしませんか?><
[この投稿を含むスレッドを表示] [この投稿を削除]
[1246] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/28 00:49:20

>ちなみにlex.zz.cを見ればわかりますが >トークンを漢字に変えると、なでしこのようにすぐになってしまいます。 それだけだと、ぴゅう太の日本語BASICとか http://labs.yaneu.com/20090401/ 年刊Ah!SKI第1号のアレみたいなのになりそうです。 トシがばれますねえ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1245] Re:日本語対応diksam
投稿者:
2009/04/27 19:56:19

>ただ、書くのはともかく、読むほうは「あそこまで日本語化」したほうが >よいというニーズはあるかと思います。 なでしこのHP見に行きましたが、結構すごいことになっていますね。 私のイメージが古かった。ちなみにlex.zz.cを見ればわかりますが トークンを漢字に変えると、なでしこのようにすぐになってしまいます。 それが良いか悪いかは別の話ですが。  言語の意味合いをもう少し膨らませて、len.zzで「if」と「もし」を同じ 意味にして、プログラムを日本語変換するソフトを作ると・・・ 日本語英語両用自由自在のなでしこをこ・・・ げほんげほん  今は目的を先に
[この投稿を含むスレッドを表示] [この投稿を削除]
[1244] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/26 23:24:49

>なでしこは知っていますが、あそこまで日本語化するのは反対の立場です。 確かに。わかります (^^; ただ、書くのはともかく、読むほうは「あそこまで日本語化」したほうが よいというニーズはあるかと思います。 >>よろしければPXU00211@nifty.ne.jpまで送付ください。 >送りました。内容はメールにて書いています。 受け取りました。ありがとうございます。 さっそく購入以来数度しか使っていないVisual Studio2005でビルドしてみました。 includeパスが絶対指定されていましたが、相対に直したらビルドできました。 >>(例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも >>しれません。 >この辺が今の課題の一つです、 ver.0.4系だと例外処理機構があるのですが、ビルドが難航しているわけですよね。 >手を着けていないものに、「初期値が設定されていない変数が使われています」が >数十出ています。 これがそんなに出るようではいけないわけですが… こちらでも調べてみたほうがよさそうです。 >コンパイラも何かあるとexitで落ちてしまいます。 ダイナミックリンクである以上確かにこれも問題です。 実用に使い始める前にコンパイルエラーぐらいは取ってくれるだろう、と思うので、 優先度は下げているのですけれども。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1243] Re:diksam0.4.03のトラブル
投稿者:
2009/04/25 22:27:43

ご返答ありがとうございます。  う~~ん、ある程度予測をして、場所を下に移すも等いろいろやってはいたのですが・・・  うまく動かずにここに書き込みました。しかし、いまだにdiksam4.0.3はトラブル で落ちてしまいます。VC++への移植にミスがあると思うのですが。エラーが数百近く 出たのを端からつぶしていったのに問題があるのかもしれません、いまだにワーニン グエラーはたくさん残っています。手を着けていないものに、「初期値が設定されて いない変数が使われています」が数十出ています。対処しないといけないのですがい まだにそこまでは。  やはり、4.0は一時保留にして、いまは2.0で問題なく動いています。2.0ソースの 拡張子を.cから.cppに総て変えて、ワーニングも総てつぶして、diksam内部からclass を扱えるようにしました。私が使用しているデバッククラスも使えるようになったの で、多少楽になりました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1242] Re:diksam0.4.03のトラブル
投稿者:(ぱ)こと管理人
2009/04/25 19:56:21

>1.argcの中身は初期化されていません。 これは明らかにおかしいですね。ご指摘ありがとうございます。 argcによる判定は、parse_parameter()実行後に行うべきことです。 今までは偶然動いてしまっていたようです…… >2.GetCommandLine();は何もやっていない・・・ GetCommandLine()はコマンドライン引数を取得するWindowsの関数です。 http://msdn.microsoft.com/ja-jp/library/cc429108.aspx これの戻り値はワイド文字列なので、 >3.DVM_wcstombs(command_line_wc);のcommand_line_wcはアドレスなのですが・・・ DVM_wcstombs()により、マルチバイト文字列に変換し、parse_parameter()で 引数列に分解しています。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1241] diksam0.4.03のトラブル
投稿者:
2009/04/24 22:22:17

再度、diksam0.4.03のコンパイルを試していますが。 どう見てもWinmMainがおかしいように思います。 WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow ) { DKC_Compiler *compiler; FILE *fp; DVM_ExecutableList *list; DVM_VirtualMachine *dvm; int argc; char **argv; DVM_Char *command_line_wc; char *command_line_mb; if (argc < 2) { fprintf(stderr, "usage:%s filename arg1, arg2, ...", argv[0]); exit(1); } command_line_wc = GetCommandLine(); command_line_mb = DVM_wcstombs(command_line_wc); argv = parse_parameter(command_line_mb, &argc); MEM_free(command_line_mb); 1.argcの中身は初期化されていません。 2.GetCommandLine();は何もやっていない・・・ 3.DVM_wcstombs(command_line_wc);のcommand_line_wcはアドレスなのですが・・・ やはり、私には手に余りそうです。何をしたいのかわからないので対処が出来そうに ありません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1240] Re:日本語対応diksam
投稿者:
2009/04/24 19:41:03

追記、ソースはタブ4スペースできれいに見えます。タブ8だとがたがたに・・・ 上に出したソースもがたがただった。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1239] Re:日本語対応diksam
投稿者:
2009/04/24 19:35:33

>ご存知かと思いますが、日本語プログラミング言語としては「なでしこ」が有名です。 >http://nadesi.com/ なでしこは知っていますが、あそこまで日本語化するのは反対の立場です。わざと やっているのではないかと思うぐらい読みづらいです。日本語の中にも和製英語が かなりたくさん入っています。それが当たり前に使われている現状を考えてみるに、- なでしこは、古文を読むような感じで現代的では有りません。日本語プログラミン グにおいても、和英混合で問題がないと私は思っています。 >よろしければPXU00211@nifty.ne.jpまで送付ください。 送りました。内容はメールにて書いています。 >http://kmaebashi.com/programmer/devlang/diksam_src_0_1_01/S/20.html ありがとうございます。意外と簡単に組み込めそうです。 >(例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも >しれません。 この辺が今の課題の一つです、コンパイラも何かあるとexitで落ちてしまいます。 堅牢なシステムを作る予定なのでこの改善が必要です。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1238] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/24 03:22:22

>うわぁ、これはなかなか破壊力がありますね。ずっと半角英数でプログラムを書いてきた >ロートルな私などからするとかなり違和感がありますが、メールとかで「Windows」 >みたいに書くおじさんは実際いましたから、需要はあるかもしれません。 >ていうかプロポーショナルフォントのおかげで全角と半角の区別がつきにくくなったのは >よいことなのか悪いことなのか… 投稿後にちょっと考えたのですが、 私の世代の感覚からすると、全角英数字と半角英数字の区別がつかないのは コンピュータリテラシの欠けたおっさんであり、そもそも全角英数字なんか いらんだろ、ぐらいに思っているのですが、 そんなふうに思うこと自体、端境期のおっさんの戯言かもしれませんねえ。 http://onisci.com/802.html
[この投稿を含むスレッドを表示] [この投稿を削除]
[1237] Re:日本語対応diksam
投稿者:(ぱ)こと管理人
2009/04/24 03:12:38

> 下記のような半角全角入り混じったようなプログラムも意味的に言語仕様と有って >いれば動くようになりました。 うわぁ、これはなかなか破壊力がありますね。ずっと半角英数でプログラムを書いてきた ロートルな私などからするとかなり違和感がありますが、メールとかで「Windows」 みたいに書くおじさんは実際いましたから、需要はあるかもしれません。 ていうかプロポーショナルフォントのおかげで全角と半角の区別がつきにくくなったのは よいことなのか悪いことなのか… そういえば、失敗プロジェクトとして名高い「Σプロジェクト」はUNIXベースのOSだった のですが、全角で「ls」とか書いても通ったという話を聞いたことがあります。 裏は取っていませんが。 なお、せっかくの(数少ない)Diskamユーザをなくしたくはないですし有名なので ご存知かと思いますが、日本語プログラミング言語としては「なでしこ」が有名です。 http://nadesi.com/ >ソース必要でしたらVCのソリューションごと送りましょうか? 私はロートルプログラマなので本体に取り込むことはないと思いますが、 一般公開してよいものでしたら、興味を持つ方がいるかもしれません。 よろしければPXU00211@nifty.ne.jpまで送付ください。 > 次は関数の組み込みおよびVMのスレッドセーフ化かな。関数の組み込みの仕方を >習得したら、本格的にdiksamを組み込んだアプリケーションの作成に入れます。 ネイティブ関数の自作についてであれば、dvm/native.cが参考になるかと思います。 http://kmaebashi.com/programmer/devlang/diksam_src_0_1_01/S/20.html ただ、ver.0.1ベースだと、引数に変な値が渡されたりしたときに (例外処理機構がないため)exit()以外に選択肢がなく、実用上問題が出るかも しれません。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1236] 日本語対応diksam
投稿者:
2009/04/23 19:29:57

 下記のような半角全角入り混じったようなプログラムも意味的に言語仕様と有って いれば動くようになりました。もちろん総て全角で書いても動きます。付属の test.dkmも問題なく動作しました。 ------------------------------------------------- int print (string str); string 今時; int 時間;  今時="朝"; 挨拶(今時);  今時="昼"; 挨拶(今時);  今時="夜"; 挨拶(今時);  今時="わからん"; 挨拶(今時); int 挨拶(string 今 ) { print("パラメータ 今=" + 今 + "\n"); if(今=="朝")  { print("------ おはようございます\n"); }elsif(今=="昼")  { print("------ こんにちは\n"); }elsif(今=="夜")  { print(”------ こんばんは¥n”); }else  { print ( "------ おいすー\n" ) ;  } } ---(注:デバック用に故意に半角全角入り乱れています)------------- lex部分を独自に書くことで問題がないようです。ソース必要でしたらVCのソリュー ションごと送りましょうか? VC++2005で書かれてSJIS専用になっています。またdiksam1.0対応のみです。  次は関数の組み込みおよびVMのスレッドセーフ化かな。関数の組み込みの仕方を 習得したら、本格的にdiksamを組み込んだアプリケーションの作成に入れます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[1235] Re:VM間排他制御について
投稿者:
2009/04/22 22:41:02

>これなんですが、「誰にとって」簡単であることを目指しているのでしょうか。  う~~ん、正直言いまして、私の方法論もいいのか悪いのか、わからない結果となりました。やっぱり聞いてみて正解です。したがってアプリがある程度で来た時点で両方を実装して実際に使ってみてから判断がよさそうであると考えました。だいぶ先になるかもしれませんが、実装して使ってみて感想・批評・訂正・修正・駄目押し、ぜひよろしくお願いします。  この他にも、いろいろ、単純に出来るのではないかと構想しています。なにぶん逆の目から見た発想なので実際に実装してみるまでは評価は難しいのかもしれません。複雑なことを意識せずに複雑な操作をプログラムするアプリケーションなので、お暇がありましたらお付き合いください。特に言語の構造に深くかかわる可能性もあります。よろしくお願いいたします。  また、現在字句解析が7割ほどかけました。書き終わった後接続試験です。ifもifも10も10も123400も受け付ける字句解析は結構大変です。漢字を受け付ける以上、10と10は同じ意味なのでやはり数字リテラルとして処理しなければ^^;
[この投稿を含むスレッドを表示] [この投稿を削除]