HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0327
y.tack代入した覚えのない数字を代入してるような8解決


y.tack

リンク

2014/3/27(Thu) 00:19:46|NO.60987


sdim dt_op_text,64000 dt_op_text={"[this]:@a@ bstr1:A next1:@aa@ bstr2:B next2:@ab@ nm_bt:2 cl_text ptext:ボタンを押してください show_text [this_end]"} #module stock_sc m_ID,m_ar_contents #modinit; str p_id,str p_con ; m_ID=p_id m_ID="" ; m_contents=p_con sdim m_ar_contents,64,8 return #modfunc set_ID str p_s m_ID=p_s return #modcfunc show_ID return m_ID ;#modfunc add_con int p_index,str p_s ; m_ar_contents.p_index=p_s ; return #modfunc split_and_set_con str p_s tmp_s=p_s split tmp_s,"\n",m_ar_contents ;#modcfunc show_con int p1 ;p1変だw ;logmes ""+p1 ; return m_ar_contents(p1) #modcfunc show_con_p2 int p1,int p2 ;p2使うと大丈夫 logmes ""+p2 return m_ar_contents(p2) #modcfunc get_con_length return length(m_ar_contents) #global notesel dt_op_text newmod one_sc,stock_sc;,"this:@a@" tmp_sc_con="" j1=0 for j1,0,notemax,1 tmp="" noteget tmp,j1 if instr(tmp,0,"[this]")==-1{ }else{ tmp_sc_con=tmp+"\n" _break } next j1++ j2=0 for j2,j1,notemax,1 tmp="" noteget tmp,j2 if instr(tmp,0,"[this_end]")==-1{ tmp_sc_con+=tmp+"\n" }else{ tmp_sc_con+=tmp _break } next split_and_set_con one_sc(0),tmp_sc_con ;add_con one_sc(0),tmp_sc_con set_ID one_sc(0),"this:@a@" j2++ mes "・ID\n"+show_ID(one_sc(0))+"\n" mes "・con" repeat get_con_length(one_sc(0)) ;mes ""+cnt+" "+show_con(one_sc(0),1)+"\n" mes ""+cnt+" "+show_con_p2(one_sc(0),0,cnt) loop
のスクリプトを実行すると
(怪しいとこコメントアウトしてます)
show_conのp1に405万とか見に覚えのない数値を代入したことになっています
ちょっとスクリプト変えるとまた値が違うような
呼び出してないはずなのに命令をコメントアウトしないとerror出ます
手違いで呼び出した箇所忘れてるなら
コメントアウトしたら命令定義がありません。とerror出してくれるような



この記事に返信する


YSR

リンク

2014/3/27(Thu) 00:58:05|NO.60988

とりあえず何をしているコードなのかを説明して下さい。
それに、どの部分に問題があるのかが分かりづらいです。
(複数行改行は/*〜*/を使用しましょう)



暇人

リンク

2014/3/27(Thu) 01:15:17|NO.60989

returnが足りない
>#modfunc split_and_set_con str p_s
のreturnが無い



YSR

リンク

2014/3/27(Thu) 01:44:28|NO.60990

理解のため、ソースコードを自己流に書き換えてみました。
恐らくですが、期待通りの動きをしているかと思います。
内容はよく分かりませんでしたが、ひょっとしてスクリプトエンジンですか?

// 定数宣言(分かりやすくするために新設) #const global m_ar_contents_sizeof 64 ;m_ar_contentsの最大長 #const global m_ar_contents_length 8 ;m_ar_contentsの要素数 #const global dt_op_text_maxsize 64000 ;dt_op_textの最大サイズ // モジュール #module stock_sc m_ID, m_ar_contents // コンストラクタ #modinit str p_id, str p_con m_ID = p_id m_contents = p_con sdim m_ar_contents, m_ar_contents_sizeof, m_ar_contents_length return // m_IDを設定 #modfunc set_ID str p_s m_ID = p_s return // m_IDを返す #modcfunc show_ID return m_ID // m_ar_contentsに要素を追加(?) #modfunc add_con int p_index, str p_s m_ar_contents(p_index) = p_s return // p_sの内容を改行で分割してm_ar_contentsに代入 // (ここでm_ar_contentsは自動的に初期化されてしまうので、 // コンストラクタでの記述は不要?) #modfunc split_and_set_con str p_s tmp_s = p_s split tmp_s, "\n", m_ar_contents return // m_ar_contents(p1)を返す #modcfunc show_con int p1 logmes "" + p1 return m_ar_contents(p1) // m_ar_contentsの要素数を返す #modcfunc get_con_length return length(m_ar_contents) #global // メインルーチン ;テキスト初期化(シナリオデータ?) sdim dt_op_text, dt_op_text_maxsize dt_op_text = {"[this]:@a@ bstr1:A next1:@aa@ bstr2:B next2:@ab@ nm_bt:2 cl_text ptext:ボタンを押してください show_text [this_end]"} ;解析準備 notesel dt_op_text newmod one_sc, stock_sc , "", "this:@a@" ;コンストラクタの引数がおかしいので修正 ;確保するバイト数は適当(コードを読む限りではdt_op_textと同じぐらい必要か?) sdim tmp_sc_con, dt_op_text_maxsize ;"[this]"が出てくるまで読み飛ばす for j1, 0, notemax ;j1の使用範囲が広すぎるので読みづらい気がする noteget tmp, j1 ;notegetの引数はいちいち初期化する必要がない if (instr(tmp,,"[this]") != -1){ ;読みだした行に"[this]"が存在した場合 tmp_sc_con = tmp + "\n" _break } next j1++ ;"[this_end]"が出てくるまでひたすら読み込む for j2, j1, notemax noteget tmp, j2 if (instr(tmp,,"[this_end]") == -1){ ;読みだした行に"[this_end]"が存在しなかった場合 tmp_sc_con += tmp + "\n" }else{ ;読みだした行に"[this_end]"が存在した場合 tmp_sc_con += tmp _break } next split_and_set_con one_sc(0),tmp_sc_con ;add_con one_sc(0),tmp_sc_con ;結局何がしたかったのかが不明なコード set_ID one_sc(0), "this:@a@" j2++ ;インクリメントした動機が不明 ;結果表示(?) mes "・ID\n" + show_ID(one_sc(0)) + "\n" mes "・con" repeat get_con_length(one_sc(0)) ;「show_con(one_sc(0), 1)」だと先頭要素しか表示されないため書き換え mes "" + cnt + " " + show_con(one_sc(0), cnt) + "\n" loop stop



y.tack

リンク

2014/3/27(Thu) 07:49:19|NO.60991

>returnが足りない
>>#modfunc split_and_set_con str p_s
>のreturnが無い
うわー やっちまった
恥ずかしすぎます

でも命令でreturn忘れると p_sの値がp1に代入されるんですね
奇妙だなぁ
returnせず別の命令に突入したら
それっぽいerror吐いてくれてもいいのになぁ



y.tack

リンク

2014/3/28(Fri) 05:09:44|NO.61010

敗因としては、ちゃんとテストしなかったことにありそうです
僕がモジュール書く時は 組み合わせなければ動作しないからって
ある程度出来上がるまでテストしなかったり
結局 returnしてないという初歩的なミスがあった訳で

して欲しい動作に辿り着くまでに 一個づつ
動作はどうより 動かしてみるのは必要かもしれません
余計なこと考えないで テストは一回出力してからって考え方もあるみたいなんですけど

HSPってテストに関してあんまり語られないよねって
ご教授いただきたいというか
参考LINKあれば教えていただきたいかんじです

自分、ググるの苦手なので



y.tack

リンク

2014/3/28(Fri) 10:46:47|NO.61012

なんかミントさんが細かくレス書いてるので
僕も細かくレス書いた方がいいのかなー?って

// m_ar_contents(p1)を返す
#modcfunc show_con int p1
この上にreturnがなくて
p1が誤作動起こしてたみたいです
#modcfunc とか #defffunc に上から処理が突撃してくるんだー。みたいな
命令に宣言なしで前方に参照できるのはそのおかげっぽくもあって
何とも言えないですけど

実行する度にp1の値が変わって びっくりしました
大きい数で文字列っぽくもあって
文字列代入したか ちょっと不安だったんですけど
上の命令のp_sのdupっぽくなってた。と

>スクリプトエンジン
ハイ。作成しはじめたばかりですけど
スクリプトエンジンというくくりに入ると思います

>(複数行改行は/*〜*/を使用しましょう)
複数と言っても3行くらいだから そんなに必然性ないような
YSRさんは//簡単な注釈;解説
ってかんじします
僕は//解説;コメントアウトってかんじです
UNDO/REDOっぽいかんじで
バージョン管理マメじゃないです
/* */はテストケースにまとめてコメントアウトします
逆に細かく使うとまとめてコメントアウトしたい時*/がひっかかるので嫌です

// モジュール
さすがにコレは見ればわかるかとw
if (instr(tmp,,"[this]") != -1){
;読みだした行に"[this]"が存在した場合
コレもinstrよく使う人なら 見ればわかるような
僕も以前は細かくコメント書いてましたが、だんだん書かなくなり
見ればわかるようになってきたようなって自分で書いたのオンリーですけど

でも他人の書いたスクリプトを理解するためにってのは
有意義だとは思います

// 定数宣言(分かりやすくするために新設)
#const global m_ar_contents_sizeof 64 ;m_ar_contentsの最大長
//文字列なのでコレより長く入れてもerror起きないでしょう
#const global m_ar_contents_length 8 ;m_ar_contentsの要素数
//配列って伸びるので意味ないような
#const global dt_op_text_maxsize 64000 ;dt_op_textの最大サイズ
//癖で大きめに確保してますが たぶんコレ以上入っても大丈夫

;インクリメントした動機が不明
こんなかんじのブロックがとりあえず3つあって
さすがに冗長なので削りました
まだブロックを繰り返し形式にするとこまでいってないかんんじです

;結果表示(?)
dumpみたいなかんじですね
とりあえずtestとして中身を吐き出してみました

なんかこう書くのが
いったん止まってみると
スクリプトの形式が決まってなくて

ただデータだけ入ってるのか
ってなら作る必要がなく
あんまり汎用化させてミニ言語に持っていく力量もなく
データを実行する部分もスクリプトにした方がいいのか
やっぱりデータだけのブロックがあって
エンジン側でデータを解釈すべきなのか

例えば数式なんかだと
$0001$,$0002$,+,4
//$000x$ は変数用として確保した配列のx番目だと思ってください
とかの書式にすると","でsplitかけて関数に放り込めば実行できるので
ソレくらいの機能なら作れそうなんですけど
条件分岐とかjumpになっちゃうと
ラベル機能付けれるかな?みたいな
データがブロックで固まっちゃってるので
ブロックの中に飛んで行けるかな?みたいな
逆に
ブロックをラベルとラベルの間って決めちゃえばいいような

今回書いたデータに処理混ぜちゃっていいのかな?とか

未定の部分はHSPと同じにすれば?って
ならHSPで書いてるエンジン部分で処理すればいい訳で
色々考えちゃって止まってるのです

今回のテーマとして
もっとHSPに翻訳しようというのがありまして
bstr1:A
next1:@aa@
bstr2:B
next2:@ab@
nm_bt:2
の部分なんか
bstr1="A"
next1="@aa@"
bstr2="B"
next2="@ab@"
nm_bt=2
とかまんま翻訳したいんですが
やりすぎると実は何の処理も書いてないみたいなかんじになってきて
それも嫌でありw

とりあえず言語処理は巨大なswitch文の繰り返しみたいな面があって
switch文で分岐させれるとこは分岐させようってのを原則にしようかな?なんですけど
s="bstr1:A"
split s,":",t
code=""+t.0+"=\""+t.1+"\""
のどこがswitch文やねん!みたいとこもあるのです



YSR

リンク

2014/3/28(Fri) 12:18:53|NO.61015

 やはりスクリプトエンジンでしたか……。
 定数を#constしたのはC系に倣いました。もちろんHSPでは自動的に拡張される(場合が多い)
のですが、おんぶに抱っこなコードだとバグが分かりづらくなることもままあるので。
 文法の仕様、なんていうのはスクリプトだけでなくプログラミング言語全体に
関わってくる問題だったりします。現にHSPも、2.x系から3.x系に移った際、
大幅な仕様変更がありましたし。
 そもそもスクリプトエンジンなんて組むのは修正しやすいようにするのが目的
ですので、コードそのまま書く必要があるなんてのはもってのほか(=バグの温床)です。
選択肢にしても、フラグによって分岐させるにしても、分かりやすい文法にすべきですね。
 もっとも、スクリプトエンジンを組むからには走らせるスクリプト(ストーリー)が
あるかと思われますので、先にそちらを仕上げてから移植する方向で考えてもいいのかも
しれません。具体的な作品があれば、それを表しやすいようにスクリプトの仕様を
考えればいいので。



y.tack

リンク

2014/3/28(Fri) 19:37:36|NO.61026

返信ありがとうございます
個人でやるプログラミングは孤独な作業になりがちなので
ホンマ嬉しいです

今日は全然やれてないんですが

>コードそのまま書く必要
(否定形ですね)
>バグが分かりづらくなることも
>(=バグの温床)
Object-CがCコンパイラ上で走らせてるっぽかったり
初期のC++もそんなかんじします
RubyやPerlもCのコード動くっぽいですし
コードそのまま書くことに否定的な感じは持っておりません

ベースとして自作言語が確立してるならいいんですけど
そっち全然なので、仕方ないかんじします
http://hsp.tv/play/pforum.php?mode=pastwch&num=50679
コレを利用させていただくとerror表示出来るっぽいので
エンジン上の場所を表示すると デバッグは出来そうです

>走らせるスクリプト(ストーリー)が あるかと思われますので
あるにはあるんですけど
何年か前に書いた 単純エンジンで
それを今書き直すとしたら どうなるだろう?ってかんじなので
スクリプトの方も手を加えたり
少しは規模を大きくする努力をするべきであるかもしれませんが

もう一つのきっかけとして
某TOOLがエンジン自作が必須なので
その形式に合わせるにはどうすべきか?
やってみてる感じでもあります
なので模索しながらの作業だったりもします
某TOOLとエンジンとの連携の仕方も手探りなので

走らせるスクリプトをどうするかは置いとくとしても
こういう作業は簡単なデータの処理を目指しながらやるのも
一つの手段だと思うので あんまりせっかちにやると
完成しない可能性も大なんですが
何年か前に書いた時は一ヶ月くらいで書いた気がして
ノッテルならイケイケであるべきなんですが
現在あんまりノッてはいなかったりして難しいです

とりあえず 個人のテーマなので
たくさん仕様に関する文章を載せるのは止めておきますね



ONION software Copyright 1997-2018(c) All rights reserved.