{}無しifが変な動作をする気がする書き方
y.tack 2013/6/19(Wed) 00:21:09|NO.55067
バグか仕様かわからないけど 一応報告です
元は公式BBSに書いたモジュールのリファクタで
指定のbitが1か0か調べるものです
変なerrorになる
#module
#deffunc bit_ls_init
ldim Bs,9
Bs(1)=*bit_1
Bs(2)=*bit_2
Bs(3)=*bit_3
Bs(4)=*bit_4
Bs(5)=*bit_5
Bs(6)=*bit_6
Bs(7)=*bit_7
Bs(8)=*bit_8
return
#defcfunc is_bit int n,int m
;if (n < 1)or(n >8){
;dialog "error",1
;return-1
;}
goto Bs(n)
dialog "error",1
return-1
*bit_1:if m&1:return 1:return 0
*bit_2:if m&2:return 1:return 0
*bit_3:if m&4:return 1:return 0
*bit_4:if m&8:return 1:return 0
*bit_5:if m&$10:return 1:return 0
*bit_6:if m&$20:return 1:return 0
*bit_7:if m&$40:return 1:return 0
*bit_8:if m&$80:return 1:return 0
#global
bit_ls_init
mes is_bit(2,3)
mes is_bit(3,3)
mes
; mes is_bit(0,3)
mes is_bit(1,3)
mes is_bit(8,3)
; mes is_bit(9,3)
こう書けば回避できる
#module
#deffunc bit_ls_init
ldim Bs,9
Bs(1)=*bit_1
Bs(2)=*bit_2
Bs(3)=*bit_3
Bs(4)=*bit_4
Bs(5)=*bit_5
Bs(6)=*bit_6
Bs(7)=*bit_7
Bs(8)=*bit_8
return
#defcfunc is_bit int n,int m
;if (n < 1)or(n >8){
;dialog "error",1
;return-1
;}
goto Bs(n)
dialog "error",1
return-1
*bit_1:if m&1{return 1}return 0
*bit_2:if m&2{return 1}return 0
*bit_3:if m&4{return 1}return 0
*bit_4:if m&8{return 1}return 0
*bit_5:if m&$10{return 1}return 0
*bit_6:if m&$20{return 1}return 0
*bit_7:if m&$40{return 1}return 0
*bit_8:if m&$80{return 1}return 0
#global
bit_ls_init
mes is_bit(2,3)
mes is_bit(3,3)
mes
; mes is_bit(0,3)
mes is_bit(1,3)
mes is_bit(8,3)
; mes is_bit(9,3)
else:if
がたぶん上手く動くってことなんですけど
どうだと上手く動いて
どうだと上手く動かないかの
調査も誰かしないかなー
そういうのがないと安心して使えないです
ツノン 2013/6/19(Wed) 06:59:39|NO.55071
*bit_1:if m&1:return 1:return 0
*bit_2:if m&2:return 1:return 0
*bit_3:if m&4:return 1:return 0
*bit_4:if m&8:return 1:return 0
*bit_5:if m&$10:return 1:return 0
*bit_6:if m&$20:return 1:return 0
*bit_7:if m&$40:return 1:return 0
*bit_8:if m&$80:return 1:return 0
の部分の処理分岐が上手く出来ていないせいか スクリプトに記述されている return 0 が全て無意味な状態です。
if は 最初の改行まで、または { で始まって } で終わる 領域 の内部を、条件に合致した場合の処理に充てる命令なので
このスクリプトでは、条件に合致した場合は return 1 合致しない場合は return 0 を無視して、再び次のラベルへ移動してしまっているようです。
#global プリプロセッサ命令は 実は ただのラベル名で有るので。制御がそこで止まる事は有りません。
おかげで wait を 挟まない無限ループの様な状況が生まれており、こうなると、アプリケーションは応答なしの状態になり止まってしまいます。
起こっている現象の簡単な再現
y.tack さんスクリプトは いうなればこのような状況に有ります。
#module mod
#deffunc test
#global
test
よってプリプロセッサによるスクリプト展開時にこのような形に変換され
goto*mod_eof
#deffunc test
*mod_eof
test
test と #deffunc test の間で無限ループが発生します。
もし 55067 のスクリプトを使用するのであれば、必ず モジュールの最後に wait または await を挟んでください。
ツノン 2013/6/19(Wed) 07:09:59|NO.55073
追記
指定の位置のビットの状態を調べるのでしたら。以下のようなスクリプトで可能です。
// %1 調べる数値
// %2 0 から始まる ビットの位置を示す値。
#define ctype is_bit(%1,%2) %1&(1<<%2)
val = 0b0010 // あえて一番目を立てる。
mes is_bit(val,1) // 戻り値が 0 以外であるなら そのビットは立っている。
ちなみに<< >> はビットシフト演算子と言って、右辺の数値だけ、左辺のビットをずらす作用が有ります。
よって
1<<0 は 1
1<<1 は 2
1<<2 は 4
となります
ツノン 2013/6/19(Wed) 07:16:07|NO.55074
更に追記
一度 マニュアルを読んでみた方が良いかも。
マニュアルには、hspプログラミングをするうえでで知っていた方がよい情報が多く載っています。
y.tack 2013/6/19(Wed) 08:19:52|NO.55078
>if は 最初の改行まで、または { で始まって } で終わる 領域 の内部を、条件に合致した場合の処理に充てる命令なので
なるほど{}なしのifって改行までのブロックだったんですか
一つの式だけが対象だと思ってました
訳のわからないことを書いてしまって悔しいですが
丁寧に説明していただけたので削除しない方が良さそうですね
#module
#deffunc bit_ls_init
ldim Bs,9
Bs(1)=*bit_1
Bs(2)=*bit_2
Bs(3)=*bit_3
Bs(4)=*bit_4
Bs(5)=*bit_5
Bs(6)=*bit_6
Bs(7)=*bit_7
Bs(8)=*bit_8
return
#defcfunc is_bit int n,int m
;if (n < 1)or(n >8){
;dialog "error",1
;return-1
;}
goto Bs(n)
dialog "error",1
return-1
*bit_1:if m&1:return 1
return 0
*bit_2:if m&2:return 1
return 0
*bit_3:if m&4:return 1
return 0
*bit_4:if m&8:return 1
return 0
*bit_5:if m&$10:return 1
return 0
*bit_6:if m&$20:return 1
return 0
*bit_7:if m&$40:return 1
return 0
*bit_8:if m&$80:return 1
return 0
#global
bit_ls_init
mes is_bit(2,3)
mes is_bit(3,3)
mes
; mes is_bit(0,3)
mes is_bit(1,3)
mes is_bit(8,3)
; mes is_bit(9,3)
あえてそうしたいならこうすれ。と