2008年7月30日水曜日

軽量版、gotoを使用したサブルーチン:ver04

軽量版、gotoを使用したサブルーチン の命令も
衝突しにくいように書き換えました

FILE名:FILE_manage_label_mini_0_4.hsp
#include "FILE_set_get_label_mini_0_2.hsp"
#module manage_label
#deffunc init_at_manage_label
now=-1
init_at_set_get_label_mini
return
#deffunc set_at_manage_label
now++
set_label_at_set_get_label_mini now
return
#deffunc back_of_st_at_manage_label
get_label_at_set_get_label_mini now
now--
return
#define global ctype inner_call(%1,%2):\
tmp_l@set_get_label_mini=*%2:set_at_manage_label:goto %1:*%2
#define global ctype call(%1)%tlabel_call inner_call(%1,%n)
#define global back:\
back_of_st_at_manage_label:goto tmp_r@set_get_label_mini
#global


テストコード
#include "FILE_manage_label_mini_0_4.hsp"
init_at_manage_label
call(*s_a)
mes "OK"

stop
*s_a
mes "a"
call(*s_b)
call(*s_d)
back
*s_b
mes "b"
call(*s_c)
back
*s_c
mes "c"
back
*s_d
mes "d"
back

軽量版、ラベル格納用変数の管理モジュール:ver02

軽量版、ラベル格納用変数の管理モジュール の命令も
衝突しにくいように書き換えました

FILE名:FILE_set_get_label_mini_0_2.hsp
#module set_get_label_mini
*null
stop
#define ctype def_l(%1):\
l_%1_0=*null:l_%1_1=*null:l_%1_2=*null:l_%1_3=*null:l_%1_4=*null:\
l_%1_5=*null:l_%1_6=*null:l_%1_7=*null:l_%1_8=*null:l_%1_9=*null

#deffunc init_at_set_get_label_mini
tmp_l=*null
tmp_r=*null
def_l(0):def_l(1):def_l(2):def_l(3):def_l(4)
def_l(5):def_l(6):def_l(7):def_l(8):def_l(9)
return
#define ctype set_c(%1,%2):\
if c==0{l_%1_0=tmp_l}:\
if c==1{l_%1_1=tmp_l}:\
if c==2{l_%1_2=tmp_l}:\
if c==3{l_%1_3=tmp_l}:\
if c==4{l_%1_4=tmp_l}:\
if c==5{l_%1_5=tmp_l}:\
if c==6{l_%1_6=tmp_l}:\
if c==7{l_%1_7=tmp_l}:\
if c==8{l_%1_8=tmp_l}:\
if c==9{l_%1_9=tmp_l}
#define ctype set_b:\
if b==0{set_c(0)}:\
if b==1{set_c(1)}:\
if b==2{set_c(2)}:\
if b==3{set_c(3)}:\
if b==4{set_c(4)}:\
if b==5{set_c(5)}:\
if b==6{set_c(6)}:\
if b==7{set_c(7)}:\
if b==8{set_c(8)}:\
if b==9{set_c(9)}
#deffunc set_label_at_set_get_label_mini int index
if index<0: dialog "error ネストが浅すぎます",1:stop
if index>99: dialog "error ネストが深すぎます",1:stop
b=index/10
c=index\10
set_b()
return
#define ctype get_c(%1):\
if c==0{tmp_r=l_%1_0}:\
if c==1{tmp_r=l_%1_1}:\
if c==2{tmp_r=l_%1_2}:\
if c==3{tmp_r=l_%1_3}:\
if c==4{tmp_r=l_%1_4}:\
if c==5{tmp_r=l_%1_5}:\
if c==6{tmp_r=l_%1_6}:\
if c==7{tmp_r=l_%1_7}:\
if c==8{tmp_r=l_%1_8}:\
if c==9{tmp_r=l_%1_9}
#define ctype get_b:\
if b==0{get_c(0)}:\
if b==1{get_c(1)}:\
if b==2{get_c(2)}:\
if b==3{get_c(3)}:\
if b==4{get_c(4)}:\
if b==5{get_c(5)}:\
if b==6{get_c(6)}:\
if b==7{get_c(7)}:\
if b==8{get_c(8)}:\
if b==9{get_c(9)}
#deffunc get_label_at_set_get_label_mini int index
if index<0: dialog "error ネストが浅すぎます",1:stop
if index>99: dialog "error ネストが深すぎます",1:stop
b=index/10
c=index\10
get_b()
return
#global

2008年7月29日火曜日

gotoを使用したサブルーチン:ver05

set_get_labelモジュールに続いて
manage_labelモジュールの名前も変更します

タイプがめんどくさい命令名になった気もしますが
直接呼ばれる可能性は低いので大丈夫でしょう

ちなみにcallマクロとbackマクロは
このモジュールを使う場合何度も呼び出す可能性があるので、そのままです
変な名前をつけると、使ったあと読みにくそうですからね

init_at_manage_label
変数の初期化処理

call(p1)
gosubのようにサブルーチンを呼び出します
p1:呼び出すサブルーチンのラベル

back
call命令でジャンプした場所に戻る命令

FILE名:FILE_manage_label_0_5.hsp
#include "FILE_set_get_label_0_2.hsp"
#module manage_label
#deffunc init_at_manage_label
now=-1
init_at_set_get_label
return
#deffunc set_at_manage_label
now++
set_label_at_set_get_label now
return
#deffunc back_of_st_at_manage_label
get_label_at_set_get_label now
now--
return
#define global ctype inner_call(%1,%2):\
tmp_l@set_get_label=*%2:set_at_manage_label:goto %1:*%2
#define global ctype call(%1)%tlabel_call inner_call(%1,%n)
#define global back:\
back_of_st_at_manage_label:goto tmp_r@set_get_label
#global


テストコード
#include "FILE_manage_label_0_5.hsp"
init_at_manage_label
call(*s_a)
mes "OK"

stop
*s_a
mes "a"
call(*s_b)
call(*s_d)
back
*s_b
mes "b"
call(*s_c)
back
*s_c
mes "c"
back
*s_d
mes "d"
back

ラベル格納用変数の管理モジュール:ver02

今まで書きためていたものを読んで思いました
命令の名前が安易で競合の可能性がある!

適当にsetとかつけるもんだから
これ絶対、後でsetとかいう名前の命令を作るだろう。とか思いました

やったことは命令の後ろに_at_モジュール名 をつけただけ
でもこれだけで、かなり命令の名前の競合が減るんですよね
ちなみにglobalキーワードをつけていないマクロは
@モジュール名をつける必要があるんで変更していません

FILE名:FILE_set_get_label_0_2.hsp
#module set_get_label
*null
stop
#define ctype def_l(%1,%2):\
l_%1_%2_0=*null:l_%1_%2_1=*null:l_%1_%2_2=*null:l_%1_%2_3=*null:\
l_%1_%2_4=*null:l_%1_%2_5=*null:l_%1_%2_6=*null:l_%1_%2_7=*null:\
l_%1_%2_8=*null:l_%1_%2_9=*null
#define ctype def_l_b(%1):\
def_l(%1,0):def_l(%1,1):def_l(%1,2):def_l(%1,3):def_l(%1,4):\
def_l(%1,5):def_l(%1,6):def_l(%1,7):def_l(%1,8):def_l(%1,9)

#deffunc init_at_set_get_label
tmp_l=*null
tmp_r=*null
def_l_b(0):def_l_b(1):def_l_b(2):def_l_b(3):def_l_b(4)
def_l_b(5):def_l_b(6):def_l_b(7):def_l_b(8):def_l_b(9)
return
#define ctype set_c(%1,%2):\
if c==0{l_%1_%2_0=tmp_l}:\
if c==1{l_%1_%2_1=tmp_l}:\
if c==2{l_%1_%2_2=tmp_l}:\
if c==3{l_%1_%2_3=tmp_l}:\
if c==4{l_%1_%2_4=tmp_l}:\
if c==5{l_%1_%2_5=tmp_l}:\
if c==6{l_%1_%2_6=tmp_l}:\
if c==7{l_%1_%2_7=tmp_l}:\
if c==8{l_%1_%2_8=tmp_l}:\
if c==9{l_%1_%2_9=tmp_l}
#define ctype set_b(%1):\
if b==0{set_c(%1,0)}:\
if b==1{set_c(%1,1)}:\
if b==2{set_c(%1,2)}:\
if b==3{set_c(%1,3)}:\
if b==4{set_c(%1,4)}:\
if b==5{set_c(%1,5)}:\
if b==6{set_c(%1,6)}:\
if b==7{set_c(%1,7)}:\
if b==8{set_c(%1,8)}:\
if b==9{set_c(%1,9)}
#define ctype set_a_1:\
if a==0{set_b(0)}:\
if a==1{set_b(1)}:\
if a==2{set_b(2)}:\
if a==3{set_b(3)}:\
if a==4{set_b(4)}
#define ctype set_a_2:\
if a==5{set_b(5)}:\
if a==6{set_b(6)}:\
if a==7{set_b(7)}:\
if a==8{set_b(8)}:\
if a==9{set_b(9)}
#deffunc set_label_at_set_get_label int index
if index<0: dialog "error ネストが浅すぎます",1:stop
if index>999: dialog "error ネストが深すぎます",1:stop
a=index/100
b=(index\100)/10
c=index\10
set_a_1()
set_a_2()
return
#define ctype get_c(%1,%2):\
if c==0{tmp_r=l_%1_%2_0}:\
if c==1{tmp_r=l_%1_%2_1}:\
if c==2{tmp_r=l_%1_%2_2}:\
if c==3{tmp_r=l_%1_%2_3}:\
if c==4{tmp_r=l_%1_%2_4}:\
if c==5{tmp_r=l_%1_%2_5}:\
if c==6{tmp_r=l_%1_%2_6}:\
if c==7{tmp_r=l_%1_%2_7}:\
if c==8{tmp_r=l_%1_%2_8}:\
if c==9{tmp_r=l_%1_%2_9}
#define ctype get_b(%1):\
if b==0{get_c(%1,0)}:\
if b==1{get_c(%1,1)}:\
if b==2{get_c(%1,2)}:\
if b==3{get_c(%1,3)}:\
if b==4{get_c(%1,4)}:\
if b==5{get_c(%1,5)}:\
if b==6{get_c(%1,6)}:\
if b==7{get_c(%1,7)}:\
if b==8{get_c(%1,8)}:\
if b==9{get_c(%1,9)}
#define ctype get_a_1:\
if a==0{get_b(0)}:\
if a==1{get_b(1)}:\
if a==2{get_b(2)}:\
if a==3{get_b(3)}:\
if a==4{get_b(4)}
#define ctype get_a_2:\
if a==5{get_b(5)}:\
if a==6{get_b(6)}:\
if a==7{get_b(7)}:\
if a==8{get_b(8)}:\
if a==9{get_b(9)}
#deffunc get_label_at_set_get_label int index
if index<0: dialog "error ネストが浅すぎます",1:stop
if index>999: dialog "error ネストが深すぎます",1:stop
a=index/100
b=(index\100)/10
c=index\10
get_a_1()
get_a_2()
return
#global

2008年7月28日月曜日

gotoを使用したサブルーチン:ver04

軽量版のスクリプトを不要な部分を削ってみると
大分すっきりしたのでもう一方の方も
不要な部分を削ります

注:スクリプトは書き換えたので削除

軽量版、gotoを使用したサブルーチン:ver03

下書きを整理していて思いました
数値の配列とアクセスいらんやん

ラベルが順に上から下に蓄積され
下から上に破棄される仕組みが
予想はしつつも、上手くのみこめなくて
数値の配列とアクセスを使用していました

例外は起きるかな?と思っていましたが
起こらなそうなので
数値の配列とアクセスを取り除いてみました

注:スクリプトは書き換えたので削除

gotoを使用したサブルーチン:下書き

スクリプトを単にダダダーッと並べても
動作がよくわからないかもしれないので
下書きをテキスト形式で表現してみます

01:call(s_a)
02:*l_a
03:stop
04:
05:*s_a
06:mes "a"
07:call(s_b)
08:*l_b
09:call(s_c)
10:*l_c
11:back
12:
13:*s_b
14:mes "b"
15:back
16:
17:*s_c
18:mes "c"
19:back

1.
01:call(s_a)
02:*l_a
;*s_aにジャンプし
;*l_aをスタックに積む
;call命令の後ろにラベル

-stackの内容
0
*l_a
prev:-1

現在地 0

2.
05:*s_a
06:mes "a"
07:call(s_b)
08:*l_b
;*s_bにジャンプし
;*l_bをスタックに積む
;call命令の後ろにラベル

-stackの内容
0
*l_a
prev-1

1
*l_b
prev0
現在地 1

3.
13:*s_b
14:mes "b"
15:back
;*l_bをスタックから取り出す
;スタックを上の位置に移動(ここでは0)
;現在地の値をprevの値に書き換える
;取り出した*l_bへジャンプ

-stackの内容
0
*l_a
prev-1
現在地 0

4.
09:call(s_c)
10:*l_c
;*s_cにジャンプし
;*l_cをスタックに積む
;call命令の後ろにラベル

-stackの内容
0
*l_a
prev-1

1
*l_c
prev0
現在地 1

5.
17:*s_c
18:mes "c"
19:back
;*l_cをスタックから取り出す
;スタックを上の位置に移動(ここでは0)
;現在地の値をprevの値に書き換える
;取り出した*l_cへジャンプ

-stackの内容
0
*l_a
prev-1
現在地 0

6.
11:back
;*l_aをスタックから取り出す
;スタックを上の位置に移動(ここでは-1)
;現在地の値をprevの値に書き換える
;取り出した*l_aへジャンプ

-stackの内容
現在地 -1

軽量版、gotoを使用したサブルーチン:ユニークラベル使用

999回ネストできるversionにユニークラベルを使う変更をほどこしたので
ネストは99回versionにも、同様の変更を行います

注:スクリプトは書き換えたので削除

gotoを使用したサブルーチン:ユニークラベル使用

call命令の引数をユニークラベルを使用して減らすことは
現在の課題でしたが
マクロのタグは一時期、色々試行錯誤して遊んでいたので
実際に使ってみると、すんなり使えました
というわけで
gotoを使用したサブルーチン:ユニークラベル使用 の
スクリプトです

注:スクリプトは書き換えたので削除

gotoを使用したサブルーチン軽量版:ネストは99回まで

ラベルを99個、定義、入力、値の取得ができるモジュールを
書いたので、gotoを使用したサブルーチンを
軽量版ラベル格納用変数の管理モジュール を使用したversionに変更してみる

注:スクリプトは書き換えたので削除

2008年7月27日日曜日

軽量版、ラベル格納用変数の管理モジュール

ラベルを格納する変数を999個用意した状態で
デバッグウィンドゥを見てみましょう
ハイ。似たような変数でデバッグウィンドゥがいっぱいですね
デバッグウィンドゥのみやすさ。という観点から
スクリプトを見ると変数を999個用意するのは
よくないかもしれません

という訳で
そんなに頻繁にたくさんネストする訳でもないので
ネストが99回まで。ということで
軽量版ラベル格納用変数の管理モジュール を作成してみました

注:スクリプトは書き換えたので削除

gotoを使用したサブルーチン:ネストが999回まで可能

さっきラベルを999個、定義、入力、値の取得ができるモジュールを
書いたので、さっそくgotoを使用したサブルーチンを
ネストが999回できるように変更してみる

注:スクリプトは書き換えたので削除

大量のラベル格納用変数の管理モジュール

下記のスクリプトはネストが10までしかできません
ネスト10回じゃ、やっぱ少ないっすよね
labelを配列に格納できたら
ネストの回数を増やすことも簡単なのでしょうが
できないもんは仕方ありません

というわけで
ネストの回数を増やすべく
macroを駆使して、999個の、ラベルを確保するための変数を用意しました
これでネストが999回まで対応できます

注:スクリプトは書き換えたので削除

gotoを使用したサブルーチン裏話

このスクリプトは実は下書きがあります

サブルーチンなんか使わなくてもgotoで飛んで、帰ってくればいいじゃないか?
とか。考えてて
でもサブルーチンの最後にgoto文があるのは
イマイチやなぁ。
とか。考えてて
考えても、考えても、考えがまとまらないものだから
紙に書いて整理してみました
すると、自分の考えていたことが上手く整理できました
で、ヨーシいっちょうスクリプトを組んでみようか!
ってなって
スクリプトを試行錯誤しながら組んでみると
きちんと動きました

整理しきれないことは紙に書いて整理してみる
ちょっと無理そうな動作でも
やってみれば、なんとかなる
といった教訓を改めて感じました。とさ

gotoを使用したサブルーチン:テストコード

どこをどうすればきちんとテストできるのか
全然わかんなくて量は少しですが
一応、テストコードです
#include "FILE_manage_label.hsp"
m_init
call(*s_a,*l_a)
mes "OK"

stop
*s_a
mes "a"
call(*s_b,*l_b)
call(*s_d,*l_d)
back
*s_b
mes "b"
call(*s_c,*l_c)
back
*s_c
mes "c"
back
*s_d
mes "d"
back

gotoを使用したサブルーチン

最近、gotoにはまっていて
繰り返しをgotoによって行う。というmacroを作成したりしています
で、そんなことをしているうちに思った
HSPってサブルーチン呼び出し、命令呼び出し、関数呼び出し、信用ならない
いやいや。僕が仕様をよくわかってなくてerrorが起こるって話ですが
サブルーチンの中でgotoを使ったら
ネストの返り場所とか、そのまんまなんだろうか?
とか考えたら
自分で、gotoを使ったサブルーチン呼び出しを作ってみました
なんかcall命令のp2が冗長で、p2のラベルをユニークラベルにおきかえることは
今後の課題です

m_init
変数の初期化処理

call(p1,p2)
gosubのようにサブルーチンを呼び出します

p1:呼び出すサブルーチンのラベル
p2:帰ってくる時の目印
(なんでもいいです。ただし、衝突に注意)

back
call命令でジャンプした場所に戻る命令

FILE名:FILE_manage_label.hsp
#module manage_label
*a
stop
#deffunc m_init
now=-1
max=0
back_l=*a
back_r=*a
dim num,16
l_0=*a:l_1=*a:l_2=*a:l_3=*a:l_4=*a
l_5=*a:l_6=*a:l_7=*a:l_8=*a:l_9=*a
return
#deffunc set_num int index,int m
num.index=m
if index>=10{
dialog "error ネストが深すぎます",1:stop
}
return
#deffunc get_num int index
if index<0{
dialog "error ネストが浅すぎます",1:stop
}else{
now=num.index
}
return
#deffunc set_lb int index
if index==0:l_0=back_l
if index==1:l_1=back_l
if index==2:l_2=back_l
if index==3:l_3=back_l
if index==4:l_4=back_l
if index==5:l_5=back_l
if index==6:l_6=back_l
if index==7:l_7=back_l
if index==8:l_8=back_l
if index==9:l_9=back_l
if index>=10{
dialog "error ネストが深すぎます",1:stop
}
return
#deffunc get_lb int index
if index<0{
dialog "error ネストが浅すぎます",1:stop
}else{
if index==0:back_r=l_0
if index==1:back_r=l_1
if index==2:back_r=l_2
if index==3:back_r=l_3
if index==4:back_r=l_4
if index==5:back_r=l_5
if index==6:back_r=l_6
if index==7:back_r=l_7
if index==8:back_r=l_8
if index==9:back_r=l_9
}
return
#deffunc set
set_num max,now: set_lb max
now=max: max++
return
#deffunc back_of_st
get_lb now
get_num now
max--
return
#define global ctype call(%1,%2):\
back_l@manage_label=%2:set:goto %1:%2
#define global back:\
back_of_st:goto back_r@manage_label
#global