|
|
2019/9/1(Sun) 17:17:10|NO.88286
以下のプログラムだと引数の値は取得できますが、vartypeを使って型を取ろうとするとエラーになります
ユーザー定義命令の仮引数の型を、モジュール内で取得するにはどうすればよいでしょうか?
#module
#define prmstack 207
#deffunc test int _i, str _s, double _d
mref hspctx, 68
; int : 4 byte , 値そのもの
dupptr i, hspctx.prmstack, 4, 4
dupptr pval, ptr(0), 48, 4; PVAL構造体
mes i
; str : 4 byte , 文字列へのポインタ
dupptr ptr, hspctx.prmstack+4, 4, 4
dupptr s, ptr, 64, 2
mes s
; double : 8 byte , 値そのもの
dupptr d, hspctx.prmstack+8, 8, 3
mes d
mes""+vartype(_i)
mes""+vartype(_s)
mes""+vartype(_d)
return
#global
test 100, "ABC", 99.9999
|
|
2019/9/1(Sun) 18:55:08|NO.88288
これ↓を参考にされたのでしょうか?
https://wiki.hsp.moe/%E5%B0%8F%E3%83%AF%E3%82%B6%EF%BC%8F%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%AE%E3%81%82%E3%82%8C%E3%81%93%E3%82%8C.html#r321dd59
ユーザー定義命令(関数)の引数は、varとarray以外は変数としては扱いませんから、
vartypeは使えません。
そこで、仮の変数に代入して、その上でvartypeするというのはどうでしょうか。
#module
#define prmstack 207
#deffunc test int _i, str _s, double _d
mref hspctx, 68
; int : 4 byte , 値そのもの
dupptr i, hspctx.prmstack, 4, 4
mes i
; str : 4 byte , 文字列へのポインタ
dupptr ptr, hspctx.prmstack+4, 4, 4
dupptr s, ptr, 64, 2
mes s
; double : 8 byte , 値そのもの
dupptr d, hspctx.prmstack+8, 8, 3
mes d
tmp=_i : mes""+vartype(tmp)
tmp=_s : mes""+vartype(tmp)
tmp=_d : mes""+vartype(tmp)
return
#global
test 100, "ABC", 99.9999
ただ、引数がvarやarrayの時の区別はこの方法ではできませんし、
やり方はちょっと私にはわかりません。
(そもそも、intとかdoubleとかを指定しているのは自分なのに、
果たしてそれを調べる必要があるのか、という疑問はあるのですが)
|
|
2019/9/1(Sun) 19:56:06|NO.88289
沢渡さん回答ありがとうございます
そうですね、そのサイトのソースコードを流用させてもらいました
例えば引数の数だけrepeat処理を行いint型ならA、str型ならBというプログラムを作りたいんです
varやarrayならPVAL構造体を使えば型を取得できますが、
そのためにはプログラムを以下のようにしないといけません
i = 100
s = "ABC"
d = 99.9999
test i,s,d
これだと引数の数だけ行数が増えるので、呼び出し元の引数を変数じゃなく値で指定できるようにしたいんです
ですが、実引数を変数じゃなく値で指定すると、そもそもvarを使えませんし
intやstrだとPVALを使うことが出来ませんでした(というかやり方が分かりませんでした)
ただ「tmp=_i」とすると、tmpの型が文字列型でも実数型でもなく、整数型になっているので
代入元の変数の型を判定する処理をどっかで行っているのではないかと思います
|
|
2019/9/1(Sun) 23:16:11|NO.88291
雪月夜さんのやりたいことがいまいち理解できていないのですが、
引数に型が不明な値を入れて、モジュール内で型を特定して処理を分岐させる ということがしたいのでしょうか。
もしそうならば、#defineで変数への代入を隠ぺいしてあげることで見た目上は解決することができます。
#module tes
#define global test(%1=dlb@tes) v1@tes=%1 : _test v1@tes
#deffunc _test var p1
switch vartype(p1)
case vartype("str") :
mes "文字列だよ "+p1
swbreak
case vartype("int") :
mes "整数値だよ "+p1
swbreak
case vartype("double") :
mes "実数値だよ "+p1
swbreak
default
mes "省略されたよ"
swend
return
*dummy@tes ;引数省略を検出する用にダミーラベルを利用してみました。
return
#global
dlb@tes = *dummy@tes ;ダミー用の変数(モジュール名を指定して外から直接代入。#defineの初期値にラベルを直接入力できなかったので)
//ここからテスト↓
test 0
test "テキスト"
test 1.25
test
mes
mes "--変数の場合も内容で判別--"
a=10
test a
a="text"
test a
a=2.56
test a
つまりは、雪月夜さんが示された
i = 100
s = "ABC"
d = 99.9999
test i,s,d
これが
i = 100 : s = "ABC" : d = 99.9999 : test i,s,d
と横並びになったものを、#defineで1つの命令(正しくはマクロ)として登録するようなイメージです。(あくまでイメージ)
また、もしこれの引数を複数にしたい場合は
#define global test(%1=dlb@tes,%2=dlb@tes,…) v1@tes=%1:v2@tes=%2,… : _test v1@tes,v2@tes,…
#deffunc _test var p1, var p2, …
という風に後ろにいっぱい書いておけば、書いたところまで使える可変引数みたく出来ると思います。
| |
|
2019/9/3(Tue) 08:28:39|NO.88313
MIZUSHIKIさん回答ありがとうございます
引数の型を取ることが出来たので報告します
libptr関数とhspctx構造体を利用して、パラメータの数と型を取得することが出来ました
ただ今度は値(パラメータの中身)の取得が難しくなってしまいました
以下がそのプログラムです
#module
#deffunc paramget int adr
dupptr sd, adr, 28
prmindex = sd(1)
prmmax = sd(2)
mref hspctx, 68
dupptr hsphed, hspctx.0, 96
minfo_ptr = lpeek( hspctx, 836 )
max_minfo = lpeek( hsphed, 68 )
dupptr minfo, minfo_ptr, max_minfo
repeat prmmax
mptype = wpeek( minfo, ( prmindex + cnt ) * 8 )
offset = lpeek( minfo, ( prmindex + cnt ) * 8 + 4 )
if mptype=65530{
dupptr ptr, hspctx(207)+offset, 4, 4
dupptr val, ptr, 4, 2
type="str"
}else:if mptype=3{
dupptr val, hspctx(207)+offset, 8, 3
type="double"
}else:if mptype=4{
dupptr val, hspctx(207)+offset, 4, 4
type="int"
}
mes"第"+(cnt+1)+"パラメータ"
mes" 型:"+type+"\n 値:"+val+"\n"
loop
return
#deffunc newset \
int h0, \
double h1, \
int h2, \
double h3, \
str h4
paramget libptr(newset)
return
#global
newset 1, 2.0, 3, 4.0, "555"
hspctx(207)+offsetのところで不具合が発生してるのは分かるのですが、
じゃあどうすればいいかというと現状不明です
paramgetをnewset内に書けば問題なく動くので半分解決したようなものですが
冗長性を防ぐためにも出来れば上記のような構成が望ましいです
| |
|