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


HSPTV!掲示板


未解決 解決 停止 削除要請

2022
1126
Yuzranium多次元配列変数を複数行文字列に41解決


Yuzranium

リンク

2022/11/26(Sat) 20:49:01|NO.97395

この度、このようなものを作りましたので
僣越ながら宣伝させて下さい。


多次元配列変数に格納されているすべての値を
複数行文字列として指定変数に格納するものです。

https://github.com/YUZRANIUM/02_myarray

こちらのサイトの Code という緑色のボタンからDownload ZIP
でダウンロードできます。

すべての次元に対応しています。

対応している変数の型は、文字列に変換できる型
実数型、整数型、文字列型です。

実体のない型(ラベル型など)には対応しておりません。
モジュール型の使用については想定していません。


デバッグ用、確認用としてお使い下さい。



この記事に返信する


Yuzranium

リンク

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



Yuzranium

リンク

2022/11/29(Tue) 12:16:18|NO.97406

ぷちアップデートしました v0.21
わざわざあんな記述しなくても行数渡せることに後から気づいた。

今後のアップデート方針は、"配列の書き出す範囲の指定" です。

3次元、4次元配列をすべて書き出すともなると
PCに結構な負荷をかけてしまいかねないので
見たい範囲だけ、確認したい範囲だけ書き出せるように
改良していく予定です。



usagi

リンク

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



Yuzranium

リンク

2022/12/1(Thu) 11:33:27|NO.97418

返信有難うございます。

>usagiさん
strrepを使っているのは私の癖といいますか
管理が楽だからと甘えてしまっていましたね。

確かに変数名が置換用文字列と被ってしまうと
以降の置換にも影響してしまいますね(なぜ気づかなかったし汗

置換による表示からご提示頂いた様に追加していく方法に切り替えていきます。

ダウンロードして頂いて有難うございます。



Yuzranium

リンク

2022/12/1(Thu) 21:05:53|NO.97422

遅くなりまして申し訳ございません。

修正アップデート v0.22

変数名と置換用文字列が被ることによる不具合の修正

変数の型、及びバッファサイズの表示を追加
https://github.com/YUZRANIUM/02_myarray/tree/master

また何か不具合等あればお知らせ頂けると幸いです。



Yuzranium

リンク

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



Yuzranium

リンク

2022/12/3(Sat) 13:03:19|NO.97437

>雪月夜さん
返信有難うございます。

>一個でn次元配列に対応した命令
凄いですね!
桁が繰り上がる様に見立てる発想は私にはありませんでした。
確かに、同じ処理を行なうにも判別して適応する内部命令を
呼び出すより遥かにスマートですね。

しかも dim系で宣言していない通常の変数でも

arr(0) = 0
としっかり表示してくれますね。

今後のアップデートに活用させて頂ければと思います。



usagi

リンク

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の整理された感じ良いですね。
ただし表現が分かりませんが、なにか文字に美しさを感じます。見習いたいと思いました。
(なんだろう、スペースや改行の感じ?)



Yuzranium

リンク

2022/12/3(Sat) 22:31:02|NO.97445

>除算、剰余とonで分岐...
・・・まじっすか!(笑)

除算と剰余で配列の次元要素を抽出...!?!?
理解するのにちょっと時間がかかるかもしれないです(汗

まさかこんな方法があったとは...
有難うございます、めちゃくちゃ勉強になります!


> on use gosub *L_0, *L_1, ...
こんな便利な命令があったんですね。
恥ずかしながら今HDLでon命令を確認してきました。


>usagiさん
私、かなり変なところにこだわりを持つタイプでして(汗
例えば、コロン(:)の両側はスペース1つ以上ただし、else:if は例外
などマイルールのようなものがありますね。
逆にこだわらないところはかなり表記ゆれがあったり(仕切り線やコメントなどが...)
直さないとなぁと思いながら後回しにしちゃっています。

HSP始めてまだ半年ほどしか経過しておらず、
それ以前にもプログラミングらしい経験はほとんどないので
その様に言って頂けるとは、とても嬉しいです。有難うございます。



usagi

リンク

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 よりめちゃくちゃ速度が早いので呼び出しが多い時は使ってます。

しかしながら半年でここまでってすごいですねぇ。。。 マクロの使い方とかきっと柔軟な考えをお持ちなんでしょうね。



Yuzranium

リンク

2022/12/4(Sun) 11:05:53|NO.97453

>usagiさん
おぉ、わかりやすいサンプルまで示して頂いて大変恐縮です。
なるほどこの方法を利用するために各配列要素の合計を用意していたのですね。
参考にさせて頂きます。

>on は単純な分岐なら比較がなく else:if よりめちゃくちゃ速度が早い
確かに else:if より記述も簡素にできますしちょっとした分岐なら
on命令でラベル分岐のほうが管理しやすそうですね。
私のスクリプトもon命令に改修しておきます。



Yuzranium

リンク

2022/12/4(Sun) 17:52:20|NO.97457

大型アップデートしました。v 0.23
https://github.com/YUZRANIUM/02_myarray

* 条件分岐をラベルを用いて行なうように変更。
* 各次元配列ごとの内部命令を一つの内部命令で行えるように変更。
* ラベル型、モジュール型の変数は情報表示のみで実装。

お陰様でかなり勉強させて頂きました。
雪月夜さん、usagiさん本当にありがとうございました。



Yuzranium

リンク

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"



Yuzranium

リンク

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指定
インデックスや添字等を付加する機能はございません。
今後のアップデートにご期待下さい。



Yuzranium

リンク

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変数の方で書式文字列の編集をして下さい。
次元ごとに分けている他、コメントアウトで使用箇所等記載していますので
命令・関数・ラベル一覧機能を活用して下さい。
エディターで画面分割等の機能を利用して実際の使用箇所を確認しながら
の編集をお勧め致します。



Yuzranium

リンク

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 : ; * ラベル型の場合は増減機能を使用することはできません ; 連続代入のみです



Yuzranium

リンク

2022/12/8(Thu) 16:18:07|NO.97486

次なるアップデート内容は値の生書き出しです。

現状、priarray命令では文字列型、実数型、整数型の配列情報とその値一覧、
未対応型と位置づけているラベル型、モジュール型、COMオブジェクト型に関しては
各要素ごとのvaruse及びvarptrを表示
(この値にどんな意味があるのかは理解できていません)

と、完全にデバッグ用、確認用としての仕様に振り切っています。

需要があるのか否か、わかりませんが、文字列型、実数型、整数型に関しては
値を文字列として書き出すことができるので値のみを複数行文字列に
書き出す命令を追加しようかなと。

もう複数行文字列で値のみの書き出しをやってしまっては
読み込みもセットでなければっ!!!と思ってしまったので
このタイミングで、この内容でのプレビュー版ということになりました。

また、なにかご要望や不具合等あればこちらにお願い致します。



usagi

リンク

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



Yuzranium

リンク

2022/12/9(Fri) 14:42:03|NO.97494

>usagiさん
おおぉ!こんなものまで作って頂き本当に感謝しかないです。
何から何まで頼りっぱなしで申し訳ないです(汗

>構造体の詳細は...
...やっぱりそこなのですね。

デバッグウィンドウや標準エディタの命令・関数・ラベル一覧機能で
文字列として表示されているので表面上の文字列を取得できるのでは?
と思いHDLを読み漁ってhspsdkにたどり着いたのですが、
通常ではあまり立ち入らない領域といいますか、少し敬遠してしまい
そっ閉じしてしまったところに

翌日、まさかこのような形でusagiさんに突きつけられるとは
思ってもいませんでした。

これを機に提示して頂いたモジュール、サンプルと共にsdkについても
学んでいこうと思います。



Yuzranium

リンク

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



Yuzranium

リンク

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) =



Yuzranium

リンク

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つのリストの縮小化と増えに増えすぎたモジュールの
変数とエイリアス名の整理ですね()



usagi

リンク

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 "---------------------------------------------------------------"



Yuzranium

リンク

2022/12/11(Sun) 14:02:54|NO.97504

返信遅くなってしまい申し訳ございません。

>混乱させて申し訳ございません。
いえいえ、サンプルを頂けるだけでも有り難いです。
何よりhspの根幹部分は私にとって未知の世界で、
右も左も分からない状況で学びの機会を得ることができています。
お気になさらず。

>お詫びの品
何から何まで頼りっぱなしで申し訳ないです。


このところ、私にとって新しい領域の知識が急激に増えており、
てんやわんやしておりますのでモジュールの情報取得に関しては
次期アップデートに...というわけには行きそうにないです。
ちょっと先になりそうです、すみません。

ただ、近いうちに、と言うか今年もあと半月程になりますが、
今年中にラベル名の取得とラベル型(色々と画策中です)
に決着をつけて来年1月あたりでモジュール情報の取得、表示となるかもです。



Yuzranium

リンク

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%)

あくまでも予定で、変更や追加、削除、取り消しなど十分にあります。
また、それぞれの追加実装時期につきましては未定です。

今しばらくお待ちを。



Yuzranium

リンク

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



Yuzranium

リンク

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命令で初期化する際の各パラメータ値がそのまま、
ラベル型への変換後の次元となります。

※注意事項※
今現在制作中のものです。変更や修正、削除等の可能性も十分あります。
出力フォーマット、コメント追加などその他の機能追加を検討中です。
モジュールへの実装時期は未定ですが、今年中のアップデート、実装を
目指しています。



Yuzranium

リンク

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用書式を追加
サンプルの追加
一部スクリプトの改修など



Yuzranium

リンク

2022/12/20(Tue) 13:23:21|NO.97557

今回はラベル名の表示と追加の新規命令 outarray, cnvarray, labarray
が大きな目玉になりますが、priarray命令のラベル名の表示に関しては
最適化が間に合っておりません。

3つの新規追加命令が控えていたのでpriarrayというか
hspctxに注力できなかったんですよね (言い訳乙)

現状のpriarray命令でも問題なく表示が可能ですが、
数が多くなると処理的に厳しくなる可能性も...
ここはNO.97502のusagiさんがおっしゃっていたソートと2分木探査
それからhspctxとモジュール変数の情報表示機能の追加・実装を目指そうかなと

ただ、その前にずぅ〜っと放置して来てしまった"書き出し範囲の指定機能"
書き出し範囲とは言わず、実行範囲の指定
こちらもすべての命令に実装したいかな。

せっかくの多次元配列変数ですから、型による変数全体数の増加ならまだしも
単純に種類が増えてしまうのはその良さを消してしまっている
ように思えて仕方ないので。


次期アップデートは
ラベル名表示機能の最適化、
モジュール変数の情報表示仮実装
全命令の実行範囲指定機能

となる予定です。



Yuzranium

リンク

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 :
原因:多次元配列変数の配列要素未確保



Yuzranium

リンク

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 :
これでエラーが回避できるはずです。



usagi

リンク

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



Yuzranium

リンク

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



Yuzranium

リンク

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



usagi

リンク

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



Yuzranium

リンク

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



Yuzranium

リンク

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次元配列変数に変換した際の要素数のうち、最大となるもの
(※こちらも私が勝手にそう呼んでいるだけです。)



Yuzranium

リンク

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}
間違ったものを投稿してしまい申し訳有りませんでした。
年始早々、頭が動いていないですね。すみません。



Yuzranium

リンク

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命令のモジュール型変数対応についても工事中となっています。



Yuzranium

リンク

2023/1/14(Sat) 16:54:46|NO.97711

02_myarray.hspのコメントの記述とヘルプファイルでの言い回しや用語に
差異が生じています。申し訳ないです。
今後は用語や言い回しをヘルプファイルの方に統一していこうと考えています。


また、正直なところctlarray命令系は様子見と言った感じです。

指定値の特性上、どうしてもdimlinec関数とlinedim命令とは切り離して
説明することが個人的に難しく、そこからヘルプファイルでの説明も
複雑になってしまっているかもしれないです。

この部分も含めてヘルプファイル、コメントの記述を修正していきます。


### 今後のアップデート ###

こんな状況で次期アップデートについて語るのはどうかとも思いますが、
とりあえず書くだけ書いておきますです。

1. priarray命令のモジュール型変数の情報表示
2. dimlinec関数とlinedim命令を駆使した辞書?(リスト?)の導入
3. 多次元配列どうしの四則演算

と言った感じになっています。
2,3については完全に妄想です。全く着手していません。



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