|
|
2022/11/26(Sat) 20:49:01|NO.97395
この度、このようなものを作りましたので
僣越ながら宣伝させて下さい。
多次元配列変数に格納されているすべての値を
複数行文字列として指定変数に格納するものです。
https://github.com/YUZRANIUM/02_myarray
こちらのサイトの Code という緑色のボタンからDownload ZIP
でダウンロードできます。
すべての次元に対応しています。
対応している変数の型は、文字列に変換できる型
実数型、整数型、文字列型です。
実体のない型(ラベル型など)には対応しておりません。
モジュール型の使用については想定していません。
デバッグ用、確認用としてお使い下さい。
|
|
2022/11/27(Sun) 11:43:23|NO.97399
出力サンプルです。
表示(2) L=49
(0) = ちゃんと変数名も行数も表示できますよ
(1) = そう、マクロならね
使い方(13) L=50
(0) = 第一パラメータには文字列型変数を指定して下さい。
(1) = 第二パラメータに中身を見たい多次元配列変数を指定して下さい
(2) = こんなふうに変数名と要素の総数、マクロを呼び出した行数
(3) = そして各配列要素に対応した値が一覧として表示できます
(4) =
(5) = デバッグウィンドウで確認できるって?
(6) = ログ表示をテキストに出力できるって?
(7) = ......
(8) = うっあっあっうわぁぁぁぁぁぁぁぁぁぁぁぁぁぁ
(9) = あっ!!、でっ、でっ、でも明示的にスクリプト内でこういった事が
(10) = できるだけでも存在価値はあるんじゃない?
(11) = ほっ、ほら!
(12) = ログ出力みたいに上書きされずに済むよ(;゚∀゚)=3ハァハァ
aray1(4, 6) L=57
(0, 0) = 0.000000
(1, 0) = 0.000000
(2, 0) = 0.000000
(3, 0) = 0.000000
(0, 1) = 0.000000
(1, 1) = 0.000000
(2, 1) = 0.000000
(3, 1) = 0.000000
(0, 2) = 0.000000
(1, 2) = 0.000000
(2, 2) = 0.000000
(3, 2) = 0.000000
(0, 3) = 0.000000
(1, 3) = 0.000000
(2, 3) = 0.000000
(3, 3) = 0.000000
(0, 4) = 0.000000
(1, 4) = 0.000000
(2, 4) = 0.000000
(3, 4) = 0.000000
(0, 5) = 0.000000
(1, 5) = 0.000000
(2, 5) = 0.000000
(3, 5) = 0.000000
aray2(3, 3, 3) L=58
(0, 0, 0) = 0
(1, 0, 0) = 0
(2, 0, 0) = 0
(0, 1, 0) = 0
(1, 1, 0) = 0
(2, 1, 0) = 0
(0, 2, 0) = 0
(1, 2, 0) = 0
(2, 2, 0) = 0
(0, 0, 1) = 0
(1, 0, 1) = 0
(2, 0, 1) = 0
(0, 1, 1) = 0
(1, 1, 1) = 0
(2, 1, 1) = 0
(0, 2, 1) = 0
(1, 2, 1) = 0
(2, 2, 1) = 0
(0, 0, 2) = 0
(1, 0, 2) = 0
(2, 0, 2) = 0
(0, 1, 2) = 0
(1, 1, 2) = 0
(2, 1, 2) = 0
(0, 2, 2) = 0
(1, 2, 2) = 0
(2, 2, 2) = 0
aray3(3, 2, 3, 2) L=58
(0, 0, 0, 0) = 0
(1, 0, 0, 0) = 0
(2, 0, 0, 0) = 0
(0, 1, 0, 0) = 0
(1, 1, 0, 0) = 0
(2, 1, 0, 0) = 0
(0, 0, 1, 0) = 0
(1, 0, 1, 0) = 0
(2, 0, 1, 0) = 0
(0, 1, 1, 0) = 0
(1, 1, 1, 0) = 0
(2, 1, 1, 0) = 0
(0, 0, 2, 0) = 0
(1, 0, 2, 0) = 0
(2, 0, 2, 0) = 0
(0, 1, 2, 0) = 0
(1, 1, 2, 0) = 0
(2, 1, 2, 0) = 0
(0, 0, 0, 1) = 0
(1, 0, 0, 1) = 0
(2, 0, 0, 1) = 0
(0, 1, 0, 1) = 0
(1, 1, 0, 1) = 0
(2, 1, 0, 1) = 0
(0, 0, 1, 1) = 0
(1, 0, 1, 1) = 0
(2, 0, 1, 1) = 0
(0, 1, 1, 1) = 0
(1, 1, 1, 1) = 0
(2, 1, 1, 1) = 0
(0, 0, 2, 1) = 0
(1, 0, 2, 1) = 0
(2, 0, 2, 1) = 0
(0, 1, 2, 1) = 0
(1, 1, 2, 1) = 0
(2, 1, 2, 1) = 0
test1(15) L=60
(0) = 0
(1) = 0
(2) = 0
(3) = 0
(4) = 0
(5) = 0
(6) = 0
(7) = 0
(8) = 0
(9) = 0
(10) = 0
(11) = 0
(12) = 0
(13) = 0
(14) = 0
test1(15) L=64
(0) = 0
(1) = 1
(2) = 2
(3) = 3
(4) = 4
(5) = 5
(6) = 6
(7) = 7
(8) = 8
(9) = 9
(10) = 10
(11) = 11
(12) = 12
(13) = 13
(14) = 14
| |
|
2022/11/29(Tue) 12:16:18|NO.97406
ぷちアップデートしました v0.21
わざわざあんな記述しなくても行数渡せることに後から気づいた。
今後のアップデート方針は、"配列の書き出す範囲の指定" です。
3次元、4次元配列をすべて書き出すともなると
PCに結構な負荷をかけてしまいかねないので
見たい範囲だけ、確認したい範囲だけ書き出せるように
改良していく予定です。
|
|
2022/12/1(Thu) 06:56:49|NO.97417
マクロで変数名表示させる発想面白いですね。
私よくprintデバッグするのですが、こういうマクロ用意しておくと便利だなと思いました。
(logmesちょっと重いし)
不具合報告でたまたま変数名aaで使ってみたら変数名の表示がバグってしまいました。
それでモジュール見させていただいたのですが、strrepで置換する所を先にstrf等で追加してしまうのは如何でしょうか。
(文字列長くなると複数回の置換が重くなりますし、他の文字列にも置換の影響ありそうなので)
たとえば以下とか
p1 += strf("%s(%d) L=%d\n", p3, length(p2)+1, p4)
repeat length(p2)
p1 += "(" + i(0) + ") = " + p2(i(0)) + "\n"
i(0)++
loop
|
|
2022/12/1(Thu) 11:33:27|NO.97418
返信有難うございます。
>usagiさん
strrepを使っているのは私の癖といいますか
管理が楽だからと甘えてしまっていましたね。
確かに変数名が置換用文字列と被ってしまうと
以降の置換にも影響してしまいますね(なぜ気づかなかったし汗
置換による表示からご提示頂いた様に追加していく方法に切り替えていきます。
ダウンロードして頂いて有難うございます。
|
|
2022/12/1(Thu) 21:31:25|NO.97423
今後のアップデートの予定
1.配列の書き出し範囲の指定機能
2.配列変数への一括代入命令(なんとなく)
2番目に関しては完全に個人的なもので、
dim や ddim に関してはすべて0で初期化されるのですが、
sdim に関しては完全に空っぽの状態になリ、
動作チェックのために repeat〜loop を用意して = "..."
とするのは少々面倒だなと思ってしまったからです。
空っぽの状態が正常なのは理解しているのですが、
出力ファイルを確認したときに毎度毎度びっくりするんで
#deffunc func array p1, var p2
i = 0, 0, 0, 0
repeat length3(p1)
i(1) = 0
repeat length2(p1)
i(0) = 0
repeat length(p1)
p1(i(0), i(1), i(2)) = p2
i(0)++
loop
i(1)++
loop
i(2)++
loop
return
|
|
2022/12/3(Sat) 10:22:10|NO.97432
ありそうでなかった命令ですね、デバッグの時とかに役立ちそうです。
ただ気になった点として、1〜4次元配列を個別に書くのは冗長に思えます。
とりあえず一個でn次元配列に対応した命令を書いてみましたが、どうでしょうか。
以下の処理は配列の要素を桁に見立て、n桁目がオーバーしたらn+1桁目が繰り上がる、という流れになってます。
#module
;半加算器
#deffunc half_adder var c,var s,int a,int b
c=a&b
s=a^b
return
#global
#module
;配列書き出し処理(整数型配列のみ対応)
#deffunc priarray array arr
;初期設定
maxlen=length(arr),length2(arr),length3(arr),length4(arr)
dim nowlen,length(maxlen)
dim dimwlen,length(maxlen)
dimwlen(0)=4
repeat length(maxlen)-1
dimwlen(cnt+1)=maxlen(cnt)*dimwlen(cnt)
loop
;書き出し処理
chkid=0
repeat
half_adder c,s,nowlen(chkid),maxlen(chkid)
if c>=maxlen(chkid){
chkid++
if chkid>=length(maxlen):break
nowlen(chkid)++
memset nowlen,0,chkid*4
if nowlen(chkid)<maxlen(chkid){
chkid=0
}
continue
}
h="("
repeat length(maxlen)
if maxlen(cnt)=0{
break
}else{
if cnt>0:h+=","
}
h+=nowlen(cnt)
loop
h+=") = "
id=0
repeat length(dimwlen)
id+=dimwlen(cnt)*nowlen(cnt)
loop
h+=lpeek(arr,id)
mes""+h
nowlen(chkid)++
loop
return
#global
dim arr,2,3,3
;テスト用
arr(0,2,0)=2
arr(1,0,1)=4
arr(0,1,2)=8
priarray arr
| |
|
2022/12/3(Sat) 13:03:19|NO.97437
>雪月夜さん
返信有難うございます。
>一個でn次元配列に対応した命令
凄いですね!
桁が繰り上がる様に見立てる発想は私にはありませんでした。
確かに、同じ処理を行なうにも判別して適応する内部命令を
呼び出すより遥かにスマートですね。
しかも dim系で宣言していない通常の変数でも
arr(0) = 0
としっかり表示してくれますね。
今後のアップデートに活用させて頂ければと思います。
|
|
2022/12/3(Sat) 19:31:06|NO.97441
置換バグ修正確認できました。やっぱり変数名でるの便利だなぁ。
私も触発されて。。。除算、剰余とonで分岐するパターンもとかも管理しやすいかもです。
(スマートではないけど、同じ場所に短く書けるので)
#module
#defcfunc priarray array _arr
; 各配列の数
len = length(_arr),length2(_arr),length3(_arr),length4(_arr)
; 使用次元
use = (len(0)!=0)+(len(1)!=0)+(len(2)!=0)+(len(3)!=0)
; 配列数合計
sum = 1 : repeat 4 : if len(cnt) = 0 { break } : sum *= len(cnt) : loop
; 結果(仮確保)
sdim _result, varsize(_arr)
; 書き出し
repeat sum : i=cnt
repeat use : num = i : repeat cnt : num/=len(cnt) : loop : d(cnt) = num\len(cnt) : loop
on use gosub *L_0,*L_1,*L_2,*L_3,*L_4
loop
return _result
*L_0 ; dummy
_result+="null\n" : return
*L_1
_result+=strf("(%d) = %s\n", d.0, _arr(d.0)) : return
*L_2
_result+=strf("(%d,%d) = %s\n", d.0, d.1, _arr(d.0, d.1)) : return
*L_3
_result+=strf("(%d,%d,%d) = %s\n", d.0, d.1, d.2, _arr(d.0, d.1, d.2)) : return
*L_4
_result+=strf("(%d,%d,%d,%d) = %s\n", d.0, d.1, d.2, d.3, _arr(d.0, d.1, d.2, d.3)) : return
#global
; テスト
dim a, 1,2,3 : dup _a,a : _a = 0,1,2,3,4,5
ddim b, 2,2 : dup _b,b : _b = 0.0,1.0,2.0,3.0
sdim c, 16,4 : repeat length(c) : c.cnt = "..." : loop
res = priarray(a) : mes res
res = priarray(b) : mes res
res = priarray(c) : mes res
しかしながら、Yuzraniumさんのソースの見やすさやGitHubの整理された感じ良いですね。
ただし表現が分かりませんが、なにか文字に美しさを感じます。見習いたいと思いました。
(なんだろう、スペースや改行の感じ?)
| |
|
2022/12/3(Sat) 22:31:02|NO.97445
>除算、剰余とonで分岐...
・・・まじっすか!(笑)
除算と剰余で配列の次元要素を抽出...!?!?
理解するのにちょっと時間がかかるかもしれないです(汗
まさかこんな方法があったとは...
有難うございます、めちゃくちゃ勉強になります!
> on use gosub *L_0, *L_1, ...
こんな便利な命令があったんですね。
恥ずかしながら今HDLでon命令を確認してきました。
>usagiさん
私、かなり変なところにこだわりを持つタイプでして(汗
例えば、コロン(:)の両側はスペース1つ以上ただし、else:if は例外
などマイルールのようなものがありますね。
逆にこだわらないところはかなり表記ゆれがあったり(仕切り線やコメントなどが...)
直さないとなぁと思いながら後回しにしちゃっています。
HSP始めてまだ半年ほどしか経過しておらず、
それ以前にもプログラミングらしい経験はほとんどないので
その様に言って頂けるとは、とても嬉しいです。有難うございます。
|
|
2022/12/4(Sun) 01:03:33|NO.97449
>除算と剰余で配列の次元要素を抽出...!?!?
いえいえループにしているので分かりにくいだけで、よくある時間を求める計算と一緒ですよ。
時計の場合は各桁が”分:60進数、秒:60進数、ミリ秒:1000進数”なので、
; ミリ秒
time = 123456
;進数 |分,秒,ミリ秒
dec = 60,60,1000
; ここをループで書き下して共通部分をまとめてるいるだけ
m = time / dec(2) / dec(1) \ dec(0)
s = time / dec(2) \ dec(1)
ms = time \ dec(2)
mes strf("%dミリ秒 = %d分:%d秒:%dミリ秒", time, m, s, ms)
この分、秒、ミリ秒の進数を配列の次元要素に置きかえて、繰り返しを割って余りを求めている感じです。
on は単純な分岐なら比較がなく else:if よりめちゃくちゃ速度が早いので呼び出しが多い時は使ってます。
しかしながら半年でここまでってすごいですねぇ。。。 マクロの使い方とかきっと柔軟な考えをお持ちなんでしょうね。
|
|
2022/12/4(Sun) 11:05:53|NO.97453
>usagiさん
おぉ、わかりやすいサンプルまで示して頂いて大変恐縮です。
なるほどこの方法を利用するために各配列要素の合計を用意していたのですね。
参考にさせて頂きます。
>on は単純な分岐なら比較がなく else:if よりめちゃくちゃ速度が早い
確かに else:if より記述も簡素にできますしちょっとした分岐なら
on命令でラベル分岐のほうが管理しやすそうですね。
私のスクリプトもon命令に改修しておきます。
|
|
2022/12/4(Sun) 17:52:20|NO.97457
大型アップデートしました。v 0.23
https://github.com/YUZRANIUM/02_myarray
* 条件分岐をラベルを用いて行なうように変更。
* 各次元配列ごとの内部命令を一つの内部命令で行えるように変更。
* ラベル型、モジュール型の変数は情報表示のみで実装。
お陰様でかなり勉強させて頂きました。
雪月夜さん、usagiさん本当にありがとうございました。
|
|
2022/12/6(Tue) 01:53:01|NO.97468
アップデート v0.24
* 値の書き出しができないラベル型、モジュール型、COMオブジェクト型を指定された場合に
変数の使用状況(varuse)の表示と"未サポートの型である"との旨を表示するように
(エラーレポート機能)
* 多次元配列変数への一括代入を行なう setarray命令の追加
* setarray命令でモジュール型変数、COMオブジェクト型変数が指定された場合に、
直後の priarray命令にて"未サポートの型への代入を試みた"との旨を表示する
エラーレポート機能の追加(ついでにその行数も表示。)
→ priarray命令を呼び出さなければ確認できないという問題を包含
エラーレポート機能サンプル
[ ie ] comobj(1) L=114
not supported var-type
varuse = 0
[ v ] struct(2) L=119
not supported var-type input -> line : 115
not supported var-type
varuse = 1
上記の例ではモジュール型変数vの項目内で、
115行目で何かしらの未サポートの型に対して代入を試みたと表示
実際は newcom命令での変数指定にieを指定し、その後setarrayにて文字列"test"を代入
setarray ie, "test"
|
|
2022/12/6(Tue) 02:05:22|NO.97469
setarray命令の正しい使い方
ldim ary0, 3, 2, 1
sdim ary1, 126, 5, 5, 5, 5
ddim ary2, 4, 4
dim ary3, 10
setarray ary0, *main // 配列内のすべてのラベルを*mainに
setarray ary1, "ABCDE" // 文字列"ABCDE"で統一
setarray ary2, 3.141592 // 同じく3.141592で統一
setarray ary3, -1 // トグルフラグ用に-1指定
インデックスや添字等を付加する機能はございません。
今後のアップデートにご期待下さい。
|
|
2022/12/8(Thu) 15:34:45|NO.97484
大型アップデートプレビュー版 v0.25.1
* priarray命令に第3パラメータオプションとしてコメント機能を追加
* setarray命令に念願の増減機能を追加
* エイリアス名をp1, p2, p3,・・・からhyouj, ary, coment,・・・など
その役割を読んである程度わかるものに変更
* モジュール内部命令で使用するstrf関数の書式文字列を配列変数で管理し、
_myarray_init_命令内で一括管理するように(書式変更をしやすくするため)
※なお、_myarray_init_命令はヘッダファイル最下部グローバル空間にて
呼び出しているため特別呼び出す必要はありません。
#global // myarray
_myarray_init_@myarray
#endif // __myarray__
02_myarray.hspにも記載していますが、書式変更等を行いたい場合は
_myarray_init_命令内のsrfor変数の方で書式文字列の編集をして下さい。
次元ごとに分けている他、コメントアウトで使用箇所等記載していますので
命令・関数・ラベル一覧機能を活用して下さい。
エディターで画面分割等の機能を利用して実際の使用箇所を確認しながら
の編集をお勧め致します。
|
|
2022/12/8(Thu) 15:41:55|NO.97485
setarray命令の使い方
setarray <代入先の配列>, <代入値>, <増減機能使用フラグ(0:off,1:on)>, <増減値>
※.hsファイルにも記載しています。
; 例)整数型、0〜、+1ずつ連続代入する場合
setarray int_ary, 0, 1, 1
; (結果)
int_ary(0・・・) = 0
int_ary(1・・・) = 1
int_ary(2・・・) = 2
:
; 例)実数型、100〜、-0.125ずつ連続代入する場合
setarray dobl_ary, 100.0, 1, -0.125
; (結果)
dobl_ary(0・・・) = 100.00000
dobl_ary(1・・・) = 99.875000
dobl_ary(2・・・) = 99.750000
:
; 例)文字列型、abc_、+1ずつ連続代入する場合
setarray str_ary, "abc_", 1, 1
; (結果)
str_ary(0・・・) = "abc_"
str_ary(1・・・) = "abc_1"
str_ary(2・・・) = "abc_2"
str_ary(3・・・) = "abc_3"
:
; * 文字列型の場合はインデックスとして機能します
; * 前方につけることはできません。上記のように後方に付きます
; 例)文字列型、ABCDE、(`・ω・´)ゞずつ連続代入する場合
setarray str_ary, "ABCDE", 1, "(`・ω・´)ゞ"
; (結果)
str_ary(0・・・) = "ABCDE"
str_ary(1・・・) = "ABCDE(`・ω・´)ゞ"
str_ary(2・・・) = "ABCDE(`・ω・´)ゞ(`・ω・´)ゞ"
str_ary(3・・・) = "ABCDE(`・ω・´)ゞ(`・ω・´)ゞ(`・ω・´)ゞ"
:
; * 増減値に文字列を指定した場合は足していくことしかできません
setarray lab_ary, *hoge
; (結果)
lab_ary(0・・・) = *hoge // すべて同じものになります
lab_ary(1・・・) = *hoge
lab_ary(2・・・) = *hoge
:
; * ラベル型の場合は増減機能を使用することはできません
; 連続代入のみです
|
|
2022/12/8(Thu) 16:18:07|NO.97486
次なるアップデート内容は値の生書き出しです。
現状、priarray命令では文字列型、実数型、整数型の配列情報とその値一覧、
未対応型と位置づけているラベル型、モジュール型、COMオブジェクト型に関しては
各要素ごとのvaruse及びvarptrを表示
(この値にどんな意味があるのかは理解できていません)
と、完全にデバッグ用、確認用としての仕様に振り切っています。
需要があるのか否か、わかりませんが、文字列型、実数型、整数型に関しては
値を文字列として書き出すことができるので値のみを複数行文字列に
書き出す命令を追加しようかなと。
もう複数行文字列で値のみの書き出しをやってしまっては
読み込みもセットでなければっ!!!と思ってしまったので
このタイミングで、この内容でのプレビュー版ということになりました。
また、なにかご要望や不具合等あればこちらにお願い致します。
|
|
2022/12/9(Fri) 05:40:33|NO.97491
おぉ、かなりアップデートされてますね。
>varptrを表示(この値にどんな意味があるのかは理解できていません)
たとえばラベルだったらメモリ上の中間コード(CS)のジャンプ位置をさしてます。
sdkとかopnehspとにらめっこすることになりますが。。。ポインタを元に欲しい値を取得する事はできるかと思います。
一例ですがどうぞ、
; ラベル名取得モジュール
; 構造体の詳細はhspsdkフォルダのhsp3code.txt,hspdll.txtを参考
; ※言語仕様としての注意※
; 1)リリース時にはデバック情報はobj(ax)ファイルに
; 書き込まれない(#cmpopt varname 1は使えない?)
; 2)隣接するラベルはまとまる(ジャンプ先が同一になるので判定不能)
; 3)小文字になる
; ※hsp3_64未対応※
#module
#deffunc load_hsphed
mref hspctx, 68 ; HSPのシステム情報(HSPCTX構造体)
mem_mcs = hspctx.2 ; code segment ptr
mem_mds = hspctx.3 ; data segment ptr
mem_di = hspctx.4 ; Debug info ptr
mem_ot = hspctx.5 ; object temp segment ptr
dupptr hsphed, hspctx.0, 96 ; AXヘッダ情報の詳細(HSPHED構造体)
allsize = hsphed.3 ; total file size
dupptr hsphed, hspctx.0, allsize
max_ds = hsphed.7 ; size of DS
max_ot = hsphed.9 ; size of OT
max_dinfo = hsphed.11 ; size of DI
dupptr ds, mem_mds, max_ds, 2 ; DS
dupptr ot, mem_ot, max_ot, 4 ; OT
dupptr di, mem_di, max_dinfo, 2 ; DI
; ラベル名とCSのオフセット値をリスト化
sdim m_label_name_list, 64, length(ot)
dim m_label_ofs_list, length(ot)
i = 0
repeat max_dinfo
d = peek(di, cnt)
if d = 251 { ; ラベル名
getstr name, ds, (lpeek(di, cnt+1) & $00FFFFFF)
m_label_name_list.i = name
m_label_ofs_list.i = mem_mcs + ot(wpeek(di, cnt+4))*2
i++
continue cnt+6
}
; データ終端 (無視)
if d = 255 { continue cnt+1 }
; ソースファイル指定 (無視)
if d = 254 { continue cnt+6 }
; 変数名 (無視)
if d = 253 { continue cnt+6 }
; 16bit値CSオフセット(無視)
if d = 252 { continue cnt+3 }
; 次行までのCSオフセット(無視)
loop
return
#defcfunc label2str var _lb
dupptr pt, varptr(_lb), 4
res = ""
repeat length(m_label_ofs_list) ; FIXME:愚直に検索しない
if pt = m_label_ofs_list.cnt : res = m_label_name_list.cnt : break
loop
return "*"+res
#global
load_hsphed
; サンプル ---------------------------
*l0
lb = *l0, *l1, *l2
*l1
repeat length(lb)
mes strf("lb(%d) = %s", cnt, label2str(lb.cnt))
loop
*l2
hoge
stop
#module mod
#deffunc hoge
*l0
lb = *l0, *l1
*l1
repeat length(lb)
mes strf("lb(%d) = %s", cnt, label2str(lb.cnt))
loop
return
#global
| |
|
2022/12/9(Fri) 14:42:03|NO.97494
>usagiさん
おおぉ!こんなものまで作って頂き本当に感謝しかないです。
何から何まで頼りっぱなしで申し訳ないです(汗
>構造体の詳細は...
...やっぱりそこなのですね。
デバッグウィンドウや標準エディタの命令・関数・ラベル一覧機能で
文字列として表示されているので表面上の文字列を取得できるのでは?
と思いHDLを読み漁ってhspsdkにたどり着いたのですが、
通常ではあまり立ち入らない領域といいますか、少し敬遠してしまい
そっ閉じしてしまったところに
翌日、まさかこのような形でusagiさんに突きつけられるとは
思ってもいませんでした。
これを機に提示して頂いたモジュール、サンプルと共にsdkについても
学んでいこうと思います。
|
|
2022/12/9(Fri) 21:52:48|NO.97496
即席のもので申し訳ありません。
また、label2str関数についてはまだ手を付けていません。
#include "02_myarray.hsp"
#module
#deffunc labltest_ var hyoj, array ary
repeat length(ary)
hyoj += strf("testlabl(%d) = %s\n", cnt, label2str@myarray(ary(cnt)))
loop
return
#global
sdim lmoni, 1024
/*** 表示用 ***/
mesbox lmoni, 640, 480, 0
hmes = objinfo(stat, 2)
testlabl = *main0, *main1, *main2, *main3, *submain
labltest_ lmoni, testlabl
priarray lmoni, m_label_ofs_list@myarray
priarray lmoni, m_label_name_list@myarray
notesel lmoni
notesave "myhspctx_data.txt"
sendmsg hmes, $C, 0, lmoni
stop
*main0
return
*main1
return
*main2
return
*main3
return
*submain
return
|
|
2022/12/9(Fri) 22:19:56|NO.97498
こちらが上のスクリプトで出力されたテキストファイルです。
(ごめんなさい、長すぎるので一部割愛&手書きコメントさせて頂きます)
testlabl(0) = *main0
testlabl(1) = *main1
testlabl(2) = *main2
testlabl(3) = *main3
testlabl(4) = *submain
[ m_label_ofs_list@myarray ] int(73) L=20
(0) = 6442904
(1) = 6436798
:
: ; myarrayモジュール内の分岐用ラベル(1)〜(30)
:
(30) = 6442816
(31) = 6443044
(32) = 6443252 ; ここから
(33) = 6443256 ;
(34) = 6443260 ;
(35) = 6443264 ;
(36) = 6443268 ; ここまで
// (37) = 6442904
: ; myarrayモジュール内deffunc等のエイリアス名
// (63) = 6442018
(64) = 6442644
(65) = 6442648
//(66〜72) = 0
[ m_label_name_list@myarray ] str(73) L=21
(0) = _myarray_exit
(1) = notvarinfo@myarray
:
: ; myarrayモジュール内の分岐用ラベル(1)〜(30)
:
(30) = labarray_4@myarray
(31) = _m0_exit
(32) = main0 ; ここから
(33) = main1 ;
(34) = main2 ;
(35) = main3 ;
(36) = submain ; ここまでが欲しい物リスト
// (37〜63) ; myarrayモジュール内deffunc等のエイリアス名
(64) = hyoj@m0
(65) = ary@m0
// (66〜72) =
|
|
2022/12/9(Fri) 23:43:13|NO.97499
当然のことだと思うのですが、自分自身(myarrayモジュール内のラベル)
まで取得した状態では少々不要な部分が多いので、
m_label_ofs_listとm_label_name_listと2つのリストから
myarrayモジュールに関するものを削除してしてしまうことで動作速度UP...
になるのかな?
まさか使用した命令・関数のエイリアス名まで取得できるとは
(しかもlocal変数まで)
エイリアス名まで取ってきてしまうと凄まじい量の配列になるので
hsp3code.txtを参考にリストの縮小をしなければ実用化できないですね。
喫緊の課題は上記2つのリストの縮小化と増えに増えすぎたモジュールの
変数とエイリアス名の整理ですね()
|
|
2022/12/10(Sat) 20:05:49|NO.97502
混乱させて申し訳ございません。
参考例程度だったものでちゃんと取得してませんでした。
DegubInfoの中は$FF(終端文字)で分けられる形で
1)ファイル、変数、ラインの情報
2)ラベル
3)モジュール関係
と順になってるようですから、
私の例だと分け隔てなくつるっと取得してしまったので、
本来は$FB情報での取得をラベルに限定する必要があったかと思います。
モジュールも取られるならprimindex値が取れますから、
それをを参照すればモジュール名も取れるかと思います。
が、、、FINFOからとってきた方がエイリアス名が含まれないので
早いかとは思います。※下部にお詫び
上記整理をし、検索はリストをソートしておいて
2分木探索などでおこなえば1000程度ラベルがあっても
10回くらいの探索で見つかるので速度はあまり気にならないかとは考えてます。
>翌日、まさかこのような形で
いえ、もともと変数名をデバッグでコンソール表示したいと思ってまして、
その時のなれの果てスクリプトでございます。。。悲
なにやら面倒でやめてしまったのですが、
Yuzraniumさんのマクロで、「こうしておけば良かったんだ」
と驚き、思い出したようにごみ箱をあさった感じです。
■お詫びの品■
; 適当にモジュール変数準備
#module ball x, y
#modinit int _x, int _y
x = _x : y = _y : return
#modfunc local d
mes strf("%d, %d", x, y) : return
#global
#module point x, y
#modinit int _x, int _y
x = _x : y = _y : return
#modfunc local d
mes strf("%d, %d", x, y) : return
#global
; モジュール変数
newmod mv, ball, 10,20 : newmod mv, point, 10,20
; モジュール変数の中身
foreach mv
dupptr p, varptr(mv.cnt), 16
mes strf("STRUCT ID%d-%d PTR$%p", p.0>>16, p.1, p.3)
loop
; ↓ここから
mref hspctx, 68 : dupptr _, hspctx.0, 16 : allsize = _.3
dupptr hsphed, hspctx.0, allsize
dupptr ds, hspctx.3, hsphed.7, 2 ; データセグメント
dupptr fi, hspctx.210, hsphed.15 ; ファンクションインフォ
mes "FINFO (STRUCTDAT) ---------------------------------------------"
mes "\tindex\tsubid\tprimidx\tprmmax\tnameidx\tsize\totindex\t"
repeat hsphed.15 / 28 ;STRUCTDAT size(28)
dupptr sdat, varptr(fi)+cnt*28, 28
index = sdat&$FF // base LIBDAT index
subid = sdat>>16 // struct index
primindex = sdat.1 // STRUCTPRM index(MINFO)
prmmax = sdat.2 // number of STRUCTPRM
nameidx = sdat.3 // name index (DS)
size = sdat.4 // struct size (stack)
otindex = sdat.5 // OT index(Module) / cleanup flag(Dll)
getstr name, ds, nameidx
mes strf("%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d",name,index,subid,primindex,prmmax,nameidx,size,otindex)
loop
mes "---------------------------------------------------------------"
| |
|
2022/12/11(Sun) 14:02:54|NO.97504
返信遅くなってしまい申し訳ございません。
>混乱させて申し訳ございません。
いえいえ、サンプルを頂けるだけでも有り難いです。
何よりhspの根幹部分は私にとって未知の世界で、
右も左も分からない状況で学びの機会を得ることができています。
お気になさらず。
>お詫びの品
何から何まで頼りっぱなしで申し訳ないです。
このところ、私にとって新しい領域の知識が急激に増えており、
てんやわんやしておりますのでモジュールの情報取得に関しては
次期アップデートに...というわけには行きそうにないです。
ちょっと先になりそうです、すみません。
ただ、近いうちに、と言うか今年もあと半月程になりますが、
今年中にラベル名の取得とラベル型(色々と画策中です)
に決着をつけて来年1月あたりでモジュール情報の取得、表示となるかもです。
|
|
2022/12/11(Sun) 14:27:55|NO.97505
※今後の実装予定※
# 機能追加
* priarray命令
* ラベル名の取得・表示(現在進行50%)
* モジュールに関する情報(未着手)
* setarray命令
* 文字列(ASCIIコード)の増減機能の追加(未着手・妄想のみ)
ABC_, ABC_1, ABC_2, ABC_3,...(←数値が増える既存の機能)
ABC_, ABC_a, ABC_b, ABC_c,...(←文字列をASCIIコード順に追加)
# 新規追加命令
* outarray命令(仮)
* 多次元配列の値のみを複数行文字列にする(現在進行80%)
* redarray命令(仮)
* 複数行文字列を多次元配列に連続代入(現在進行80%)
setarray命令はスクリプト内で、
こちらは外部テキストファイルからという立ち位置
* labarray命令(仮)
* ラベル型多次元配列の生成(現在進行50%)
あくまでも予定で、変更や追加、削除、取り消しなど十分にあります。
また、それぞれの追加実装時期につきましては未定です。
今しばらくお待ちを。
|
|
2022/12/12(Mon) 01:38:40|NO.97511
#module "test_lab"
// モジュール内変数初期化
#deffunc labinit
dim i, 5 : i = 0, 0, 0, 0, 0
ldim jump_, 5
jump_ = *not_varlab, *labarray_1, *labarray_2, *labarray_3, *labarray_4
sdim srfor, 126, 4
srfor(0) = "%s(%d) = %s\n", "%s(%d, %d) = %s\n"
srfor(2) = "%s(%d, %d, %d) = %s\n", "%s(%d, %d, %d, %d) = %s\n"
return
#deffunc local labarray_ var hyouj, array ary, var in_val, var index, str vname, local str_tmp
str_tmp = vname : str_tmp = strtrim(str_tmp, 3, )
strbuf_ = in_val : indexbuf_ = index
prinfo_ = (length(ary) != 0) + (length2(ary) != 0) + (length3(ary) !=0) + (length4(ary) != 0)
alldim_ = length(ary), length2(ary), length3(ary), length4(ary)
sum_ = 1
repeat 4
if (alldim_(cnt) == 0) : break
sum_ *= alldim_(cnt)
loop
repeat sum_
i(4) = cnt
repeat prinfo_
num_ = i(4)
repeat cnt
num_ /= alldim_(cnt)
loop
i(cnt) = num_ \ alldim_(cnt)
loop
gosub jump_(prinfo_) ; ラベルジャンプで分岐
; 文字列に対してインデックスの付与
in_val = strbuf_ ; 足される方を元データに上書き
in_val += "" + indexbuf_ ; インデックスの追加
indexbuf_ += index ; インデックスカウントアップ
loop
hyouj += "\n"
return
//--------------------------------- 配列代入 ---------------------------------//
*not_varlab
return
*labarray_1
ary(i(0)) = in_val
hyouj += strf(srfor(0), str_tmp, i(0), in_val)
return
*labarray_2
ary(i(0), i(1)) = in_val
hyouj += strf(srfor(1), str_tmp, i(0), i(1), in_val)
return
*labarray_3
ary(i(0), i(1), i(2)) = in_val
hyouj += strf(srfor(2), str_tmp, i(0), i(1), i(2), in_val)
return
*labarray_4
ary(i(0), i(1), i(2), i(3)) = in_val
hyouj += strf(srfor(3), str_tmp, i(0), i(1), i(2), i(3), in_val)
return
#define global labarray(%1,%2,%3,%4)\
midlevar_@test_lab=%3:\
increase_@test_lab=%4:\
labarray_@test_lab %1,%2,midlevar_@test_lab,increase_@test_lab,"%2"
#global //test_lab
labinit ; モジュール初期化
sdim lmoni, 1024 ; 確認表示用
sdim test_l, 126, 10 ; これからラベル型になる文字列型配列
sdim text_lab, 512 ; .hsp 出力用
/*** 表示用 ***/
mesbox lmoni, 350, 480, 0
hmes = objinfo(stat, 2)
pos 400, 0 : button "chack", *ch
labarray text_lab, test_l, "*main_", 1
/*** 結果確認 ***/
lmoni += "\n" + text_lab
sendmsg hmes, $C, 0, lmoni
/*** ファイル出力 ***/
notesel text_lab
notesave "label.hsp"
stop
; 配列の確認
*ch
#addition "C:\\Users\\user\\Desktop\\label.hsp"
gosub test_l(0)
stop
*main_
dialog "vartype( test_l ) = " + vartype(test_l), 0, "vartype"
return
*main_1
return
*main_2
return
*main_3
return
*main_4
return
*main_5
return
*main_6
return
*main_7
return
*main_8
return
*main_9
return
| |
|
2022/12/12(Mon) 02:16:46|NO.97512
上記のスクリプトで出力したlabel.hsp
test_l(0) = *main_
test_l(1) = *main_1
test_l(2) = *main_2
test_l(3) = *main_3
test_l(4) = *main_4
test_l(5) = *main_5
test_l(6) = *main_6
test_l(7) = *main_7
test_l(8) = *main_8
test_l(9) = *main_9
labarray <出力先変数>, <代入先配列変数>, <代入する文字列>, <増減値(index)>
labarray命令(仮)は代入する文字列にインデックスを付与し、
多次元配列変数に格納した後、上記の書式で配列の値を複数行文字列として出力。
この複数行文字列をファイルとして出力し、includeないしadditionすることで
ラベル型として、以降利用することが可能です。
一言で言えば、文字列型の多次元配列変数をラベル型に変換する、
とでも言いましょうか。
この、"文字列を出力し、出力したファイルをインクルードしてラベル型とする"
アイディアは私のものではありません。いつかの掲示板で見かけたものです。
* すべての次元に対応しています。
* 指定する配列変数は必ず sdim命令で初期化して下さい。
* sdim命令で初期化する際の各パラメータ値がそのまま、
ラベル型への変換後の次元となります。
※注意事項※
今現在制作中のものです。変更や修正、削除等の可能性も十分あります。
出力フォーマット、コメント追加などその他の機能追加を検討中です。
モジュールへの実装時期は未定ですが、今年中のアップデート、実装を
目指しています。
|
|
2022/12/20(Tue) 12:43:24|NO.97556
大変遅くなりまして申し訳ございません。
超大型アップデート v0.26.1
https://github.com/YUZRANIUM/02_myarray
*** 更新内容 ***
# 機能追加・変更 #
* priarray命令
ラベル型配列変数のラベル名の表示 (最適化てきておらず)
コメント追加時の書式をHSPのブロックコメント形式(/**/)に変更
# 新規追加命令 #
* outarray命令 (アウトアレイ)
多次元配列変数の値のみを複数行文字列に変換
--priarrayから情報表示を削減した文字列操作仕様
* cnvarray命令 (コンバートアレイ)
テキストファイル、複数行文字列または多次元配列から別の多次元配列へ変換
多次元配列どうしの文字列型、実数型、整数型の相互変換
多次元配列どうしの次元を超えた変換(4次元→1次元,1次元→3次元など制約なし)
* labarray命令 (ラブアレイ)
文字列型配列と複数行文字列を出力し、文字列型配列変数を
ラベル型配列変数として扱うことを可能にする
(おまけ)
* objprh命令
objprm命令のハンドル指定版
ウィンドウオブジェクトのIDの代わりにハンドルを指定する。
--メリット: gsel命令での操作先、描画先の管理をしなくて良い
--複数のウィンドウで複数のオブジェクトを扱う際に効果を発揮します
# その他 #
labarray追加に伴いコメントの処理部をpriarrayから内部関数ainfo_へ移設
それに伴いモジュール内部で雑多処理を行うainfo_関数を命令化
strf関数用の書式文字列変数srforにlabarray用書式を追加
サンプルの追加
一部スクリプトの改修など
|
|
2022/12/20(Tue) 13:23:21|NO.97557
今回はラベル名の表示と追加の新規命令 outarray, cnvarray, labarray
が大きな目玉になりますが、priarray命令のラベル名の表示に関しては
最適化が間に合っておりません。
3つの新規追加命令が控えていたのでpriarrayというか
hspctxに注力できなかったんですよね (言い訳乙)
現状のpriarray命令でも問題なく表示が可能ですが、
数が多くなると処理的に厳しくなる可能性も...
ここはNO.97502のusagiさんがおっしゃっていたソートと2分木探査
それからhspctxとモジュール変数の情報表示機能の追加・実装を目指そうかなと
ただ、その前にずぅ〜っと放置して来てしまった"書き出し範囲の指定機能"
書き出し範囲とは言わず、実行範囲の指定
こちらもすべての命令に実装したいかな。
せっかくの多次元配列変数ですから、型による変数全体数の増加ならまだしも
単純に種類が増えてしまうのはその良さを消してしまっている
ように思えて仕方ないので。
次期アップデートは
ラベル名表示機能の最適化、
モジュール変数の情報表示仮実装
全命令の実行範囲指定機能
となる予定です。
|
|
2022/12/21(Wed) 19:30:13|NO.97561
*** 不具合報告 ***
1. labarray命令にて作成した複数行文字列を拡張子.hspで保存し、
別スクリプトでそのファイルをインクルードすると配列要素のエラーが発生する。
#include "02_myarray.hsp"
sdim text_data, 2048
sdim labl_ary, 1024, 10, 10, 10
labarray text_data, labl_ary, "*main_", 1
notesel text_data : notesave "labl.hsp"
stop
;-------------------------------------------
; 書き出されたファイル(ここでは labl.hsp)を
; このままインクルードすると...
;-------------------------------------------
//[ labl_ary ] str(10, 10, 10)
labl_ary(0, 0, 0) = *main_
labl_ary(1, 0, 0) = *main_1 ; ← この行でエラー
labl_ary(2, 0, 0) = *main_2
labl_ary(3, 0, 0) = *main_3
:
原因:多次元配列変数の配列要素未確保
|
|
2022/12/21(Wed) 19:38:59|NO.97562
1.の対処
02_myarray.hspの182行目〜185行目
(176行目以降 配列の情報表示labarray仕様...のあたり)
srfor@myarray(0, 3) = "//[ %s ] %s(%d)%d"
srfor@myarray(1, 3) = "//[ %s ] %s(%d, %d)%d"
srfor@myarray(2, 3) = "//[ %s ] %s(%d, %d, %d)%d"
srfor@myarray(3, 3) = "//[ %s ] %s(%d, %d, %d, %d)%d"
こちらを下記のように修正
srfor@myarray(0, 3) = "\tdimtype %s, /*%s*/, %d %d"
srfor@myarray(1, 3) = "\tdimtype %s, /*%s*/, %d, %d %d"
srfor@myarray(2, 3) = "\tdimtype %s, /*%s*/, %d, %d, %d %d"
srfor@myarray(3, 3) = "\tdimtype %s, /*%s*/, %d, %d, %d, %d %d"
また、同じく02_myarray.hspの354行目
(内部命令 #defunc local ainfo_ ...)
if cl == -2 : hyouj = strtrim(hyouj, 2, '0') : hyouj += "\n"
こちらを下記のように修正
if (cl == -2) {
hyouj = strtrim(hyouj, 2, '0')
hyouj = strtrim(hyouj, 2,)
strrep hyouj, "/*str*/", "1"
hyouj += "\n"
}
以上の修正で出力したファイルは下記の結果となる
; 修正前
;--------------------------
//[ labl_ary ] str(10, 10, 10)
labl_ary(0, 0, 0) = *main_
labl_ary(1, 0, 0) = *main_1 ; ← この行でエラー
labl_ary(2, 0, 0) = *main_2
:
; 修正後
;--------------------------
dimtype labl_ary, 1, 10, 10, 10
labl_ary(0, 0, 0) = *main_
labl_ary(1, 0, 0) = *main_1
labl_ary(2, 0, 0) = *main_2
:
これでエラーが回避できるはずです。
| |
|
2022/12/24(Sat) 18:27:25|NO.97583
おっ、なんかいろいろ増えてますねぇ〜!。
>NO.97502のusagiさんがおっしゃっていたソートと2分木探査
前回私、ちゃんと検索してなかたので、参考修正してみました。(下部記載)
オマケでモジュール変数はクラスっぽい使い方をする方が多いかと思ったので、
自身で定義できるアプローチも面白そうかとおもい、
せっかくctx参照するのですから裏技的に書いてみました。
(私あまりモジュール変数使わないので、分かりませんが)
>全命令の実行範囲指定機能
最初にYuzraniumさんがrepeatで行っていた方法も次元ごとに書く必要はありますが、
シンプルで良いなぁと思ってまして、repeat とlimitで簡潔にできそうですね。
dim array, 10 : foreach array : array(cnt) = cnt : loop
range = 2, 8
st = limit(0, range(0)) : ed = limit(length(array)-1, length(array)-1, range(1))
repeat ed-st, st : mes ""+cnt+":"+array(cnt) : loop
しかしならが、相変わらずソースきれいですね。
;------------------------------------------------
; ラベル名、モジュール変数取得モジュール
#module debug_string
#define SIZE_OF_STRUCTDAT 28
;------------------------------------------------
; 公開
#defcfunc lab2str var _var
; ラベル変数を文字列に
dupptr pt, varptr(_var), 4
idx = bisearch(m_label_ofs_list, pt) ; NOTE: 二分木探索にしました。
if idx >= 0 { return "*"+m_label_name_list(idx) } else { return "unknown" }
#defcfunc mod2str var _var
; ラベル変数を文字列に
dupptr pt, varptr(_var), 16
return m_module_name_list(pt.1)
#defcfunc moddesc var _var
; モジュール変数に #modcfunc local description を定義しておいた説明を出力 ※オマケ※
dupptr pt, varptr(_var), 16
if m_module_ptr_list(pt.1) = 0 : return "" ; TODO:定義無しの時はPValから取ってきても面白いかも
dupptr from, m_module_ptr_list(pt.1), SIZE_OF_STRUCTDAT
dupptr to, libptr(dummyfunc@debug_string_dummy), SIZE_OF_STRUCTDAT
memcpy to, from, SIZE_OF_STRUCTDAT
return dummyfunc@debug_string_dummy(_var)
;------------------------------------------------
; 非公開
#deffunc local load_hsphed
; メンバ変数
sdim m_label_name_list, 64 ; ラベル名リスト
dim m_label_ofs_list ; ラベルのCSオフセットリスト
sdim m_module_name_list, 63 ; モジュール名リスト
dim m_module_ptr_list ; モジュールポインタリスト
; 情報取得
mref hspctx, 68 ; HSPCTX構造体
dupptr hsphed, hspctx.0, 96 ; HSPHED構造体
dupptr ds, hspctx.3, hsphed.7, 2 ; DS
dupptr ot, hspctx.5, hsphed.9, 4 ; OT
dupptr di, hspctx.4, hsphed.11, 2 ; DI
; **** ラベルリストを取得 ****
sdim tmp, 64 : i = 0 : j = 0
repeat ; デバックインフォの行データ終端まで移動(使わないので無視)
on peek(di, i)-252 goto *L_OFS16, *L_NAME, *L_NAME, *L_END
i++ : continue
*L_NAME : i+=6 : continue
*L_OFS16 : i+=3 : continue
*L_END : i++ : break
loop
repeat ,i ; ラベル名を取得
if peek(di, cnt) = 255 : break
tmp(j) = getname(lpeek(di, cnt+1) & $00FFFFFF)
m_label_ofs_list(j) = getofs(wpeek(di, cnt+4))
j++
continue cnt+6
loop
sortval m_label_ofs_list ; ソートしておく(二分木検索する為)
foreach m_label_ofs_list : sortget i, cnt : m_label_name_list.cnt = tmp.i : loop
; **** モジュール名,関数名リストを取得 ****
if hsphed.15 <= 0 : return
dupptr fi, hspctx.210, hsphed.15 ; FI
i = 0
repeat hsphed.15 / SIZE_OF_STRUCTDAT
ptr = varptr(fi)+cnt*SIZE_OF_STRUCTDAT
dupptr sd, ptr, SIZE_OF_STRUCTDAT
if sd.1 < 0 : continue
name = getname(sd.3)
m_module_name_list(sd.1) = name
; ※オマケ部分※
m_module_ptr_list(sd.1) = 0 ; 仮ぬるぽ
if instr(name, 0, "description@") != -1 { ; モジュール変数のポインタ書き換え(description用)
modvarname = strmid(name, 12, 18)
foreach m_module_name_list
if m_module_name_list.cnt != modvarname : continue
m_module_ptr_list.cnt = ptr
loop
}
loop
return
#defcfunc local getofs int _idx
return hspctx.2 + ot(_idx)*2
#defcfunc local getname int _idx
getstr s, ds, _idx : return s
#defcfunc local bisearch array _arr, int _in
lo = 0 : hi = length(_arr)-1
*@
if lo>hi : return -1
mid = (lo+hi)/2
if _arr(mid) = _in : return mid
if _arr(mid) < _in { lo = mid+1 } else { hi = mid-1 }
goto *@back
#global
; ダミーモジュール変数
#module debug_string_dummy _
#modcfunc local dummyfunc
return ""
#global
load_hsphed@debug_string
;------------------------------------------------
; サンプル
#module ball a, b
#modinit int _a, int _b
a = _a : b = _b : return
#modcfunc local description
return strf("a:%d b:%d", a, b)
#global
#module point x, y, z
#modinit int _x, int _y, int _z
x = _x : y = _y : z = _z : return
#modcfunc local description
return strf("x:%d y:%d z:%d", x, y, z)
#global
#module box _
#global
lb = *l0, *l1
foreach lb : mes strf("lb(%d) = %s", cnt, lab2str(lb.cnt)) : loop
newmod mv, ball, 1, 2 : newmod mv, ball, 3, 4
newmod mv, point, 5, 6, 7 : newmod mv, box
foreach mv : mes strf("mv(%d) = %s %s", cnt, mod2str(mv.cnt), moddesc(mv.cnt)) : loop
stop
*l0 : return
*l1 : return
| |
|
2022/12/25(Sun) 16:36:11|NO.97603
>usagiさん
うぉぉぉ〜!!かなり最適化されてますね!
こちら側はパーツを提供して、ユーザーが自身で
デバッグ環境を構築するというものも面白いですね。
>#defcfunc local bisearch array _arr, int _in
二分木探索を関数にしてしまう発想は良いですね!
これだと汎用性も高く取り回しが利きますね (私は直に組んでいました)
ということでこんなものを
#module
; sortgetの関数バージョン
;
#defcfunc sortgetc int p1
sortget res, p1
return res
; ary1 : ソートしたい1次元配列変数 (メイン)
; ary2 : ary1と連動してソートさせたい配列変数
; p1 : 昇降順 (0:昇順, 1:降順)
;
#deffunc twinsortary array ary1, array ary2, int p1
; 一時保存用
dimtype tmp, vartype(ary2), length(ary2)
; 一時保存
repeat length(ary2)
tmp(cnt) = ary2(cnt)
loop
; メインとなる配列変数のソート
if (vartype(ary1) == 4) {sortval ary1, p1}
else:if (vartype(ary1) == 2) {sortstr ary1, p1}
; ary1と連動してary2をソート(?)
repeat length(ary2)
ary2(cnt) = tmp(sortgetc(cnt))
loop
return
#global
/////////////////////////// サンプル /////////////////////////////
dim list1, 10
sdim list2, 64, 10
repeat length(list1)
list1(cnt) = cnt
list2(cnt) = "ABCD_" + cnt
loop
twinsortary list1, list2, 1
repeat length(list1)
mes strf("list1(%d) = %d : list2(%d) = %s\n", cnt, list1.cnt, cnt, list2.cnt)
loop
twinsortary list1, list2, 0
repeat length(list1)
mes strf("list1(%d) = %d : list2(%d) = %s\n", cnt, list1.cnt, cnt, list2.cnt)
loop
stop
| |
|
2022/12/27(Tue) 12:34:01|NO.97628
動作制御命令ctrarrayとしてこんな感じになっていますがどうでしょうか?
内容としてはループ回数(以下の sum)とループ内のカウントアップの
初期値(以下の i(4))を弄ることで動作範囲を制御する、
というものです。
まだ実験段階というか試作初号機です。
気になる点や他にもアイディアや等々あれば遠慮なくして頂けると幸いです。
サンプルなので少し雑ですが何卒ご容赦下さい。
#module "myarray"
#deffunc local _myarray_init_
ldim jump, 5, 2
jump(0, 0) = *not_pri@myarray, *pri_D1@myarray, *pri_D2@myarray, *pri_D3@myarray, *pri_D4@myarray
jump(0, 1) = *not_set@myarray, *set_D1@myarray, *set_D2@myarray, *set_D3@myarray, *set_D4@myarray
dim srfor@myarray, 64, 4
srfor@myarray(0) = "%S(%d) = %s\n"
srfor@myarray(1) = "%s(%d, %d) = %s\n"
srfor@myarray(2) = "%s(%d, %d, %d) = %s\n"
srfor@myarray(3) = "%s(%d, %d, %d, %d) = %s\n"
return
//============================================================================//
; 動作制御用
;
; d1 : 配列の開始要素数
; d2 : 配列の終了要素数
#deffunc ctrarray int d1, int d2
dim ctr_ary, 6
ctr_ary(0) = d1, d2
ctr_ary(2) = 0 ; (制御ID) == (動作ID) の真偽値格納用
ctr_ary(3) = ((0 <= d1) & (0 <= d2) & (d1 <= d2))
ctr_ary(4)++ ; 制御ID
ctr_ary(5) = 0 ; 動作ID (動作命令側でカウントアップ)
return
//============================================================================//
#deffunc local priarray_ str vname, var hyouj, array ary
dim i, 7
hogestr = vname : hogestr = strtrim(hogestr, 3,)
alldim = length(ary), length2(ary), length3(ary), length4(ary)
prinfo = (alldim.0 != 0) + (alldim.1 != 0) + (alldim.2 != 0) + (alldim.3 != 0)
sum = 1
; この値は配列の各次元要素を一直線に並べたもので、
; 配列全体数であり、書き出しループのループ回数でもある。
; これを弄ることで終端を操作することができる
repeat 4
if alldim(cnt) == 0 : break
sum *= alldim(cnt)
loop
; 動作IDのカウント
; 動作制御命令ctrarrayの制御が別の配列変数に適用されるのを防ぐため
; (なんかイマイチと言うか、何と言うか...)
ctr_ary(5)++ : ctr_ary.2 = (ctr_ary.4 == ctr_ary.5)
; i(4)は簡単に言うと、書き出す配列の現在位置
; これを弄ることで始点を操作することができる
if (ctr_ary.2 & ctr_ary.3) {
i.4 = ctr_ary(0)
sum = ctr_ary(1) - ctr_ary(0) ;←コメントアウトすると循環して飛ばした分動作する
}
repeat sum
repeat prinfo
num = i(4)
repeat cnt
num /= alldim(cnt)
loop
i(cnt) = num \ alldim(cnt)
loop
gosub jump(prinfo, 0)
i(4)++
loop
hyouj += "\n"
return
//----------------------------------------------------------------------------//
*not_pri@myarray
return
*pri_D1@myarray
hyouj += strf(srfor.0, hogestr, i.0, ary(i.0))
return
*pri_D2@myarray
hyouj += strf(srfor.1, hogestr, i.0, i.1, ary(i.0, i.1))
return
*pri_D3@myarray
hyouj += strf(srfor.2, hogestr, i.0, i.1, i.2, ary(i.0, i.1, i.2))
return
*pri_D4@myarray
hyouj += strf(srfor.3, hogestr, i.0, i.1, i.2, i.3, ary(i.0, i.1, i.2, i.3))
return
//============================================================================//
#define global priarray(%1,%2) priarray_@myarray "%2",%1,%2
//============================================================================//
#deffunc local setarray_ array ary, var p1, var p2
dim i, 7
alldim = length(ary), length2(ary), length3(ary), length4(ary)
prinfo = (alldim.0 != 0) + (alldim.1 != 0) + (alldim.2 != 0) + (alldim.3 != 0)
sum = 1
repeat 4
if alldim(cnt) == 0 : break
sum *= alldim(cnt)
loop
ctr_ary(5)++ : ctr_ary.2 = (ctr_ary.4 == ctr_ary.5)
if (ctr_ary.2 & ctr_ary.3) {i.4 = ctr_ary.0 : sum = (ctr_ary.1 - ctr_ary.0)}
repeat sum
repeat prinfo
num = i(4)
repeat cnt
num /= alldim(cnt)
loop
i(cnt) = num \ alldim(cnt)
loop
gosub jump(prinfo, 1)
p1 += p2
i(4)++
loop
hyouj += "\n"
return
//----------------------------------------------------------------------------//
*not_set@myarray
return
*set_D1@myarray
ary(i.0) = p1
return
*set_D2@myarray
ary(i.0, i.1) = p1
return
*set_D3@myarray
ary(i.0, i.1, i.2) = P1
return
*set_D4@myarray
ary(i.0, i.1, i.2, i.3) = p1
return
//============================================================================//
#define global setarray(%1,%2,%3)\
midlevar_@myarray=%2:\
increase_@myarray=%3:\
setarray_@myarray %1,midlevar_@myarray,increase_@myarray
#global ; "myarray"
////////////////////////////// サンプル //////////////////////////////
_myarray_init_@myarray ; 内部変数の初期化
font "メイリオ", 12 : objmode 2, 1
sdim moni0, 1024 : sdim moni1, 1024 : dim hmes, 2 ; 表示用
pos 0, 0 : mesbox moni0, 320, 480 : hmes(0) = objinfo(stat, 2)
pos 320, 0 : mesbox moni1, 320, 480 : hmes(1) = objinfo(stat, 2)
dim test_ary, 8, 7, 6, 5
; まずは通常動作
setarray test_ary, 0, 1
priarray moni0, test_ary
; 書き出す範囲を配列の25番目〜100番目に絞る
ctrarray 25, 100
priarray moni1, test_ary
dim test_ary, 8, 7, 6, 5
; 連続代入を配列の5番目〜15番目までに制御
ctrarray 5, 15
setarray test_ary, 0, 1
; 15番目〜25番目までに制御
ctrarray 15, 25
setarray test_ary, 11, 2
; 25番目〜35番目までに制御
ctrarray 25, 35
setarray test_ary, 32, 3
; 4番目〜40番目だけを書き出し
ctrarray 4, 40
priarray moni1, test_ary
sendmsg hmes(0), $C, 0, moni0
sendmsg hmes(1), $C, 0, moni1
stop
| |
|
2023/1/7(Sat) 15:24:55|NO.97668
>ctrarrayの制御が別の配列変数に適用されるのを防ぐ
あけおめです。
私が理解できず間違っているかもしれませんが、たとえば関数内のローカル変数に退避しておくのは如何でしょうか?
#module "myarray"
#deffunc local _myarray_init_
ldim jump, 5, 2
jump(0, 0) = *not_pri@myarray, *pri_D1@myarray, *pri_D2@myarray, *pri_D3@myarray, *pri_D4@myarray
dim srfor@myarray, 64, 4
srfor@myarray(0) = "%S(%d) = %s\n"
srfor@myarray(1) = "%s(%d, %d) = %s\n"
srfor@myarray(2) = "%s(%d, %d, %d) = %s\n"
srfor@myarray(3) = "%s(%d, %d, %d, %d) = %s\n"
dim ctr_ary, 2 ; ★初期化しておく
ctr_ary(0) = -1,-1
return
#deffunc local iterator array _i, int _cnt, array _dim ; ★イテレーターは関数化しておく
repeat prinfo : num = _cnt : repeat cnt : num /= _dim(cnt) : loop : _i(cnt) = num \ _dim(cnt) : loop
return
#deffunc ctrarray int d1, int d2
ctr_ary(0) = d1, d2
return
#define global priarray(%1,%2) priarray_@myarray "%2",%1,%2
#deffunc local priarray_ str vname, var hyouj, array ary, /*★ローカル変数*/local ctr_ary_0, local ctr_ary_1
dim i, 7 : hogestr = vname : hogestr = strtrim(hogestr, 3,)
alldim = length(ary), length2(ary), length3(ary), length4(ary)
prinfo = (alldim.0 != 0) + (alldim.1 != 0) + (alldim.2 != 0) + (alldim.3 != 0)
sum = 1 : repeat prinfo : sum *= alldim(cnt) : loop
; ★ローカル変数へコピー
if ctr_ary(0)<0 | ctr_ary(1)<0 {
ctr_ary_0 = 0 : ctr_ary_1 = sum;★-1はとりあえず全部
} else { ; ★制限を掛けておく
ctr_ary_0 = limit(ctr_ary(0), 0, sum)
ctr_ary_1 = limit(ctr_ary(1), ctr_ary_0, sum)
}
repeat ctr_ary_1 - ctr_ary_0, ctr_ary_0
iterator i, cnt, alldim
gosub jump(prinfo, 0)
loop
hyouj += "\n"
return
//----------------------------------------------------------------------------//
*not_pri@myarray
return
*pri_D1@myarray
hyouj += strf(srfor.0, hogestr, i.0, ary(i.0))
return
*pri_D2@myarray
hyouj += strf(srfor.1, hogestr, i.0, i.1, ary(i.0, i.1))
return
*pri_D3@myarray
hyouj += strf(srfor.2, hogestr, i.0, i.1, i.2, ary(i.0, i.1, i.2))
return
*pri_D4@myarray
hyouj += strf(srfor.3, hogestr, i.0, i.1, i.2, i.3, ary(i.0, i.1, i.2, i.3))
return
//============================================================================//
#global ; "myarray"
_myarray_init_@myarray
////////////////////////////// サンプル //////////////////////////////
sdim moni0, 1024 : sdim moni1, 1024 : dim hmes, 2 ; 表示用
pos 0, 0 : mesbox moni0, 320, 480 : hmes(0) = objinfo(stat, 2)
pos 320, 0 : mesbox moni1, 320, 480 : hmes(1) = objinfo(stat, 2)
dim test_ary, 8, 7, 6, 5
repeat 8*7*6*5 : dupptr a, varptr(test_ary)+cnt*4, 4 : a=cnt : loop ; ★セットアレイを作ってないので仮
priarray moni0, test_ary
; 書き出す範囲を配列の25番目〜100番目に絞る
ctrarray 25, 100
priarray moni1, test_ary
; 4番目〜40番目だけを書き出し
ctrarray 4, 40
priarray moni1, test_ary
; 20000番目〜 40000番目だけを書き出し(書き出されない)
ctrarray 20000, 40000
priarray moni1, test_ary
sendmsg hmes(0), $C, 0, moni0
sendmsg hmes(1), $C, 0, moni1
stop
| |
|
2023/1/8(Sun) 15:34:47|NO.97676
usagiさん明けましておめでとうございます。
>間違っているかもしれませんが...
いえいえ、その解釈で合っています。
ごめんなさい、先に謝っておきます。大変申し訳ございませんでした。
少し話は脱線するのですが、私は自分のNO.97628のサンプルを投稿後、
そもそも配列変数を、皆さん要素数で管理されているのでは?と思い、
先頭からのオフセット値(?)と言いますか、ある種のインデックスのような
一つの値で配列(要素数)を管理するということをあまり聞いたことがなく、
このままでは要素数を都度計算するなど少々難易度の高いものになってしまうのでは
という疑問がふと頭をよぎりまして、、、
そこで、配列の要素数とイテレーターで使用する数値、
これらを相互変換できれば直接、配列の要素数で範囲指定が可能になるだろうと
試行錯誤していたのですが、幾分数字に弱く、(致命的過ぎる;;
ネットでいろいろ検索しながら組み立てては修正して、、、
結局、かなりの時間が進み、今現在はNO.97628のサンプルとはかけ離れたものになってしまいました。
その点、usagiさんには貴重なお時間を取らせてしまったこと、大変申し訳なく思っております。
もっと早い段階で方針転換の旨、現状の報告、考えていること等々投稿しておくべきでした。
GitHubも利用して、幾らでもやりようが有ったことは私の失態です。
#module "myarray"
#deffunc local _myarray_init_
ldim jump, 5
jump(0) = *not_pri@myarray, *pri_D1@myarray, *pri_D2@myarray, *pri_D3@myarray, *pri_D4@myarray
dim srfor@myarray, 64, 4
srfor@myarray(0) = "%s(%d) = %s\n"
srfor@myarray(1) = "%s(%d, %d) = %s\n"
srfor@myarray(2) = "%s(%d, %d, %d) = %s\n"
srfor@myarray(3) = "%s(%d, %d, %d, %d) = %s\n"
dim ctl_ary, 11 ; 動作制御配列
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; 指定配列の情報
; ary_inf(0) : length() (1次元要素数) (旧alldim)
; ary_inf(1) : length2() (2次元要素数)
; ary_inf(2) : length3() (3次元要素数)
; ary_inf(3) : length4() (4次元要素数)
;
; ary_inf(4) : 使用次元数 (1, 2, 3, 4) (旧prinfo)
; ary_inf(5) : 配列合計数 (旧sum)
;
; ary_inf(6) : 配列の現在位置 (旧num)
; 配列情報用
#deffunc local dim_info_ array ary
dim ary_inf, 7
ary_inf(0) = length(ary), length2(ary), length3(ary), length4(ary)
ary_inf(4) = (ary_inf(0) != 0) + (ary_inf(1) != 0) + (ary_inf(2) != 0) + (ary_inf(3) != 0)
ary_inf(5) = 1
repeat ary_inf(4): ary_inf(5) *= ary_inf(cnt) :loop
return
; 配列の各次元要素数から直線番号へ(多次元配列の平坦化・先頭からのオフセット値)
#defcfunc local dim_num_linec_ array ary_inf_, int d1, int d2, int d3, int d4
return (d1 + (ary_inf_.0 * d2) + (ary_inf_.0 * ary_inf_.1 * d3) + (ary_inf_.0 * ary_inf_.1 * ary_inf_.2 * d4))
; 配列の直線番号から各次元要素数へ
#deffunc local dim_line_num_ array ary_inf_, array i_, int dim_line_
repeat ary_inf_(4)
ary_inf_(6) = dim_line_
repeat cnt
ary_inf_(6) /= ary_inf_(cnt)
loop
i_(cnt) = ary_inf_(6) \ ary_inf_(cnt)
loop
return
; 多次元配列の直線番号から各次元要素数を格納する
;
; ary : 多次元配列変数
; i_ : 次元要素数を受け取る変数
; dim_line_ : aryに対する直線番号
#deffunc linedim array ary, array i_, int dim_line_
dim_info_@myarray ary
if ary_inf(5) < dim_line_ : return -1
dim i_, 4
dim_line_num_@myarray ary_inf, i_, dim_line_
return
; 多次元配列を平坦化(1次元に変換した際の要素数を返す)
;
; ary : 多次元配列変数
; d1,d2,d3,d4 : 各次元要素数
#defcfunc dimlinec array ary, int d1, int d2, int d3, int d4
dim_info_@myarray ary
/***** 条件分岐用 *****/
dim prm_ch, 4
; 各パラメータが(0以上)または(length値未満) (0 < d1 < ary_inf.0)
prm_ch(0) = ((0 <= d1) & (d1 < ary_inf.0)) & ((0 <= d2) | (d2 < ary_inf.1))
prm_ch(1) = ((0 <= d3) | (d3 < ary_inf.2)) & ((0 <= d4) | (d4 < ary_inf.3))
prm_ch(2) = (d1 == 0) & (d2 == 0) & (d3 == 0) & (d4 == 0)
prm_ch(3) = (prm_ch.0 & prm_ch.1)
; prm_ch(2) 配列の "長さ" を返す
; prm_ch(3) 配列の "直線番号" を返す
if prm_ch(2) {return ary_inf(5)}
else:if prm_ch(3) {return dim_num_linec_@myarray(ary_inf, d1, d2, d3, d4)}
else {return -1}
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; 配列動作制御関連
; ctl_ary(0): 複数制御フラグ
;
; ctl_ary(1): 対象となる動作を開始する 多次元配列変数の直線番号
; ctl_ary(2): 対象となる動作を終了する //
;
; ctl_ary(3): 単体制御フラグ
; ctl_ary(4): 除外フラグ
;
; ctl_ary(5): 真偽値 (直線番号: (0 <= 開始値) & (開始値 <= 終了値) )
;
; ctl_ary(6): 真偽値 (制御なし) | (複数制御あり & 除外あり & 制御コア1回目の呼び出し)
; ctl_ary(7): 真偽値 (複数制御あり & 除外あり & 制御コア2回目の呼び出し)
; ctl_ary(8): 真偽値 (複数制御なし & 単体制御あり & 制御コア2回目の呼び出し)
;
; ctl_ary(9):
; ctl_ary(10):
; 複数制御開始命令
#deffunc ctlarray_start
dim ctl_ary, 11
ctl_ary(0) = 1
return
; 動作制御命令
;
; ctl_strat_ : 動作を開始する 開始値 (直線番号)
; ctl_end_ : 動作を終了する 終了値 (直線番号) ※回数ではない
#deffunc ctlarray int ctl_start_, int ctl_end_
; 複数制御フラグがOFF で呼び出された -> 単体制御とみなして呼び出される都度dimで初期化
if (ctl_ary(0) == 0) {dim ctl_ary, 11 : ctl_ary(3) = 1}
ctl_ary(1) = ctl_start_, (ctl_end_ + 1 - ctl_start_)
ctl_ary(5) = (0 <= ctl_start_) & (ctl_start_ <= ctl_end_)
return
; 動作除外命令
;
; 動作の除外フラグを立てる
#deffunc ctl_excld
if (ctl_ary(0) == 1) {ctl_ary(4) = 1}
return
; 内部動作制御コア (条件式やlimitのあたりが未完、不必要な条件等混ざっているかも)
;
; p1 : 開始値と終了値の2回呼び出すことになるための識別フラグ
; v1 : 制御フラグが立っていない場合は何もせずにそのまま返すため
#defcfunc local ctlarray_core_ int p1, var v1
; (P1 = 1が指定配列での最後の呼び出しの合図になる)
/***** 条件の整理 *****/
ctl_ary(6) = (ctl_ary(0) == 0) & (ctl_ary(3) == 0) | (ctl_ary(0) == 1) & (ctl_ary(4) == 1) & (p1 == 0)
ctl_ary(7) = (ctl_ary(0) == 1) & (ctl_ary(4) == 1) & (p1 == 1)
ctl_ary(8) = (ctl_ary(0) == 0) & (ctl_ary(3) == 1) & (p1 == 1)
/***** 制御フラグの操作 *****/
if ctl_ary(5) != 1 { return 0 } ;異常値処理 (repeat 0 で実行させないため)
else:if ctl_ary(6) { return v1} ;制御されていないor除外の場合はそのまま返す
else:if ctl_ary(7) {ctl_ary(4) = 0 : return v1} ;複数制御で除外指定かつ最後の呼び出しは除外フラグを下ろす
else:if ctl_ary(8) {ctl_ary(3) = 0 } ;単体制御の終了合図があれば単体フラグを下ろす
;---------------------------------------------------------------------------
/***** 条件の整理 *****/
; ctlarray命令内ctl_ary(5)に開始値と終了値の大小関係の真偽値が既に
; 代入されているのでここで考えることは配列の終端の処理。
; [配列の終端]
; ============ v1
; |____________|
; ^ |__________|
; ctl_ary(1) --^
ctl_ary(9) = ctl_ary(1), (v1 - ctl_ary(1))
/***** 制御値の置き換え操作 *****/
; 最大値側に負の値を指定すると本来は大小関係が逆転するが(0が最大値になるが)、
; このlimit関数はどうも第3引数に指定した値を最大値として扱っている
; (内部で検証はしていない?)ようで、なぜか0ではなく負の値が返ってくる?(よくわかっていない)
;
if ctl_ary(5) {return limit(limit(ctl_ary(p1 + 1), 0, ctl_ary(p1 + 9)), 0)}
; 動作制御終了
#deffunc ctlarray_end
dim ctl_ary, 11
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; 配列書き出し
#deffunc local priarray_dx str vname, var hyouj, array ary
; 半角スペースのトリミング
hogestr = vname : hogestr = strtrim(hogestr, 3)
; 配列処理の下準備
dim_info_@myarray ary
dim i, 7
; ctlarray_core_による動作制御
i(4) = ctlarray_core_@myarray(0, i(4)) ; 1回目の呼び出し (開始値)
ary_inf(5) = ctlarray_core_@myarray(1, ary_inf(5)) ; 2回目の呼び出し (終了値)
; 書き出し
repeat ary_inf(5)
dim_line_num_@myarray ary_inf, i, i(4)
gosub jump(ary_inf(4))
i(4)++
loop
hyouj += "\n"
return
//------------------------------- 配列書き出し -------------------------------//
*not_pri@myarray
return
; 1次元配列
*pri_D1@myarray
hyouj += strf(srfor(0), hogestr, i.0, ary(i.0))
return
; 2次元配列
*pri_D2@myarray
hyouj += strf(srfor(1), hogestr, i.0, i.1, ary(i.0, i.1))
return
; 3次元配列
*pri_D3@myarray
hyouj += strf(srfor(2), hogestr, i.0, i.1, i.2, ary(i.0, i.1, i.2))
return
; 4次元配列
*pri_D4@myarray
hyouj += strf(srfor(3), hogestr, i.0, i.1, i.2, i.3, ary(i.0, i.1, i.2, i.3))
return
#define global priarray(%1,%2) priarray_dx@myarray "%2",%1,%2
#global // myarray
_myarray_init_@myarray
////////////////////////////// サンプル //////////////////////////////
/***** 表示用 *****/
dim hMes, 2 : dim i, 4 : sdim moni, 1024
mesbox moni, 640, 480 : hMes(0) = objinfo(stat, 2)
/***** 配列変数用意 *****/
dim iary1, 17, 7, 5
dim iary2, 10, 5
repeat length3(iary1)
i(1) = 0
repeat length2(iary1)
i(0) = 0
repeat length(iary1): iary1(i(0), i(1), i(2)) = i(3) : i(0)++ : i(3)++ :loop
i(1)++
loop
i(2)++
loop
dim i, 4
repeat length2(iary2)
i(0) = 0
repeat length(iary2): iary2(i(0), i(1)) = i(2) : i(0)++ : i(2)++ :loop
i(1)++
loop
/***** 以下、実践 *****/
moni += "配列の先頭からオフセット、25番目から30番目までに制限\n"
ctlarray 25, 30
priarray moni, iary1
moni += "要素数での指定 iary2(0, 3) から iary2(5, 3) まで\n"
ctlarray dimlinec(iary2, 0, 3), dimlinec(iary2, 5, 3)
priarray moni, iary2
moni += "------------------------------------\n"
// ここから 制御命令としての本領発揮 //
range(0) = 45
range(1) = 60
moni += strf("動作開始:range(0) = %d\n動作終了:range(1) = %d\n\n", range(0), range(1))
//// 制御開始命令 ////
ctlarray_start
ctlarray range(0), range(1) ; ctlarray_startの直後に必ず範囲指定する
moni += "配列の先頭からのオフセット値から各次元要素数を返す(?)\n"
linedim iary1, i, range(0)
; 動作制御の除外命令 **直後の1回だけ** 制御対象から外す
ctl_excld
priarray moni, i ; この命令だけは制御から外れる (通常通りすべて書き出し)
;;;; <--この行以降は制御がかかる
priarray moni, iary1
linedim iary1, i, range(1)
ctl_excld : priarray moni, i ; 制御から除外
; 動作の終了値が「配列の長さ」より長い場合は指定された配列の終端で止まる
priarray moni, iary2
; 再度、ctlarray命令を呼び出すと動作範囲の設定が更新される。以降、新しい範囲で動作を制御できる
ctlarray 15, 35
priarray moni, iary1
priarray moni, iary2
//// 制御終了命令 ////
ctlarray_end
; 終了時は必ず end を呼ぶこと!!
sendmsg hMes(0), $C, 0, moni
stop
| |
|
2023/1/8(Sun) 16:03:19|NO.97677
すみません、多次元配列の直線番号から各次元要素数を格納する
linedim命令の
#deffunc linedim array ary, array i_, int dim_line_
dim_info_@myarray ary
if ary_inf(5) < dim_line_ : return -1
dim i_, 4
dim_line_num_@myarray ary_inf, i_, dim_line_
return
4行目の return -1 はまずかったですね。return 0 に修正でお願いします。
ここはlength2,length3,length4に合わせるべきでしたね。
>直線番号
>先頭からのオフセット値
>配列変数の平坦化
>配列の長さ
なかなか変な言葉を並べてしまって申し訳ないです。
>> 配列変数の平坦化
2, 3, 4次元(多次元)配列変数を1次元配列変数に変換すること
(例 : 2次元配列変数 dim a, 3,...の場合
a(0, 0) ==> b(0)
a(1, 0) ==> b(1)
a(2, 0) ==> b(2)
a(0, 1) ==> b(3)
a(1, 1) ==> b(4)
a(2, 1) ==> b(5)
a(0, 2) ==> b(6)
: :
>> 先頭からのオフセット値, 直線番号
多次元配列変数を1次元配列変数に変換した際の要素数
上記の例で1次元配列変数b の要素数のこと
(※直線番号とは私が個人的にそう呼んでいるだけです。)
>> 配列の長さ
多次元配列変数を1次元配列変数に変換した際の要素数のうち、最大となるもの
(※こちらも私が勝手にそう呼んでいるだけです。)
|
|
2023/1/9(Mon) 12:53:09|NO.97679
NO.97676のサンプルの修正です。
内部制御コアctlarray_core_のフラグ操作の部分
/***** 制御フラグの操作 *****/
if ctl_ary(5) != 1 { return 0 }
else:if ctl_ary(6) { return v1}
else:if ctl_ary(7) {ctl_ary(4) = 0 : return v1}
else:if ctl_ary(8) {ctl_ary(3) = 0 }
こちらを以下のように修正
/***** 制御フラグの操作 *****/
if ctl_ary(6) { return v1}
else:if ctl_ary(7) {ctl_ary(4) = 0 : return v1}
else:if ctl_ary(8) {ctl_ary(3) = 0 }
そして制御値の置き換え部分
/***** 制御値の置き換え操作 *****/
if ctl_ary(5) {return limit(limit(ctl_ary(p1 + 1), 0, ctl_ary(p1 + 9)), 0)}
こちらの末尾に else {return 0} を追加して修正
/***** 制御値の置き換え操作 *****/
if ctl_ary(5) {return limit(limit(ctl_ary(p1 + 1), 0, ctl_ary(p1 + 9)), 0)} else {return 0}
まとめると ctlarray_core_ は以下のようになります。
#defcfunc local ctlarray_core_ int p1, var v1
/***** 条件の整理 *****/
ctl_ary(6) = (ctl_ary(0) == 0) & (ctl_ary(3) == 0) | (ctl_ary(0) == 1) & (ctl_ary(4) == 1) & (p1 == 0)
ctl_ary(7) = (ctl_ary(0) == 1) & (ctl_ary(4) == 1) & (p1 == 1)
ctl_ary(8) = (ctl_ary(0) == 0) & (ctl_ary(3) == 1) & (p1 == 1)
/***** 制御フラグの操作 *****/
if ctl_ary(6) { return v1}
else:if ctl_ary(7) {ctl_ary(4) = 0 : return v1}
else:if ctl_ary(8) {ctl_ary(3) = 0 }
ctl_ary(9) = ctl_ary(1), (v1 - ctl_ary(1))
/***** 制御値の置き換え操作 *****/
if ctl_ary(5) {return limit(limit(ctl_ary(p1 + 1), 0, ctl_ary(p1 + 9)), 0)} else {return 0}
間違ったものを投稿してしまい申し訳有りませんでした。
年始早々、頭が動いていないですね。すみません。
| |
|
2023/1/14(Sat) 16:28:52|NO.97710
遅くなって申し訳ないです。大型アップデート v0.27です。
https://github.com/YUZRANIUM/02_myarray
今バージョンから配列の動作範囲を制御することが可能になりました。
また、制御フィールドなるものの中ではctlarrayの設定が複数の命令に
まとめて適用されるようになり、途中から連続代入や途中だけ書き出したり
といったことが可能になります。
新規追加要素
* ctlarray 命令
* ctlarray_start 命令
* ctlarray_end 命令
* ctlexcld 命令
* dimlinec 関数
* linedim 命令
また、これ以外にも追加命令や関数がありますが、
HDLのヘルプファイルが追いついていません。
ヘルプファイルについては完成次第アップデートします。
priarray命令のモジュール型変数対応についても工事中となっています。
|
|
2023/1/14(Sat) 16:54:46|NO.97711
02_myarray.hspのコメントの記述とヘルプファイルでの言い回しや用語に
差異が生じています。申し訳ないです。
今後は用語や言い回しをヘルプファイルの方に統一していこうと考えています。
また、正直なところctlarray命令系は様子見と言った感じです。
指定値の特性上、どうしてもdimlinec関数とlinedim命令とは切り離して
説明することが個人的に難しく、そこからヘルプファイルでの説明も
複雑になってしまっているかもしれないです。
この部分も含めてヘルプファイル、コメントの記述を修正していきます。
### 今後のアップデート ###
こんな状況で次期アップデートについて語るのはどうかとも思いますが、
とりあえず書くだけ書いておきますです。
1. priarray命令のモジュール型変数の情報表示
2. dimlinec関数とlinedim命令を駆使した辞書?(リスト?)の導入
3. 多次元配列どうしの四則演算
と言った感じになっています。
2,3については完全に妄想です。全く着手していません。
|
|