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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0912
nepisat#deffuncで設定した名前を変数に入れ、その変数を#deffuncの命令のように動かしたい。19未解決


nepisat

リンク

2014/9/12(Fri) 19:22:32|NO.64858

例えから

まず、このような命令を宣言したとします。

#deffunc HELLO str strin mes strin+"Hello,World" return

そして、これを


func = HELLO func ,"TEST"
としたいです。



この記事に返信する


KOMARI

リンク

2014/9/12(Fri) 19:29:53|NO.64859

関数ポインタみたいなものでしょうか。
もし出来るのなら是非やりたいもんですが。
私は出来ないものとして認識しています。



Flat

リンク

2014/9/12(Fri) 19:57:17|NO.64861

HSPに可変長引数が実装されない限り変数に代入して使うことは出来ないと思います。
が、こんな実装でよろしければどうぞ。動作保証対象外。

// 魔法のコード(笑) // スクリプトの先頭に入れておいてください #define setfunc(%1,%2) dupptr a@funcloader,libptr(%1),28,2:dupptr b@funcloader,libptr(%2),28,2:memcpy a@funcloader,b@funcloader,28 if${ // 関数をここに並べます #deffunc func #deffunc func2 return } #module #deffunc HELLO str strin mes strin+"Hello,World" return #deffunc HELLO2 str strin mes strin+"Hi guys!" return #global setfunc func, HELLO func "TEST" setfunc func, HELLO2 func "TEST" setfunc func2, func func2 "TEST"



Flat

リンク

2014/9/12(Fri) 20:10:16|NO.64862

変数にこだわるなら(関数ポインタ的に使いたいなら)こちらを。

// 魔法のコード(笑) // スクリプトの先頭に入れておいてください #module funcloader #deffunc callback return #deffunc local _flinit dupptr a, libptr(callback), 28, 2 return #define global loadfunc(%1) dupptr b@funcloader,%1,28,2:memcpy a@funcloader,b@funcloader,28 #global _flinit@funcloader // 関数を呼び出す側 #module #deffunc cbtest int fnptr, int value loadfunc fnptr mes callback(value) return #global // 関数が呼び出される側 #module // 3倍した数値を返す関数 #defcfunc testfunc int val return val * 3 #global funcptr = libptr(testfunc) cbtest funcptr, 123



ぴょぴょ(科学太郎)

リンク

2014/9/12(Fri) 21:44:44|NO.64868

nepisatさん
KOMARIさん
あとFlatさんへ
> 関数ポインタみたいなものでしょうか。
> もし出来るのなら是非やりたいもんですが。
> 私は出来ないものとして認識しています。
工夫次第で出来ると思います。
*Main
pfunc=*Jump3 HELLO "あいうえお" stop #deffunc HELLO str strin gosub pfunc return *Jump1 HELLO1 strin return *Jump2 HELLO2 strin return *Jump3 HELLO3 strin return *Jump4 HELLO4 strin return #deffunc HELLO1 str strin mes strin+"Hello1,World" return #deffunc HELLO2 str strin mes strin+"Hello2,World" return #deffunc HELLO3 str strin mes strin+"Hello3,World" return #deffunc HELLO4 str strin mes strin+"Hello4,World" return

ラベル数はユーザ定義命令だけ増えますが、
C/C++のような関数ポインタみたいに使えます。

pfunc に *Jump2 を代入すると HELLO 命令で HELLO2 が実行されます。
この pfunc がユーザ定義命令を記憶してる変数ですね。



ぴょぴょ(科学太郎)

リンク

2014/9/12(Fri) 21:57:12|NO.64871

追記。
*Main
pfunc=*Jump3 HELLO "あいうえお" stop #deffunc HELLO str strin gosub pfunc return *Jump1:HELLO1 strin:return *Jump2:HELLO2 strin:return *Jump3:HELLO3 strin:return *Jump4:HELLO4 strin:return #deffunc HELLO1 str strin mes strin+"Hello1,World" return #deffunc HELLO2 str strin mes strin+"Hello2,World" return #deffunc HELLO3 str strin mes strin+"Hello3,World" return #deffunc HELLO4 str strin mes strin+"Hello4,World" return

ラベル、命令実行、returnの3行を1行に出来るみたいです。



Flat

リンク

2014/9/12(Fri) 22:58:30|NO.64875

ミス。可変長引数なくても予め引数の数を指定できるのであれば先ほどの方法で使えます。黒魔術臭い方法ですが。



KOMARI

リンク

2014/9/13(Sat) 12:22:41|NO.64883

Flatさんすごい(・ω・)・・・
callbackの中身を無理やり書き換えてる感じなのはわかりました。
これは使えそうかも・・・



nepisat

リンク

2014/9/13(Sat) 18:31:09|NO.64890

手元にPCがないのでわからないのですが、

1、 他の.hsp内で#deffunc (.hspの個数は可変)
2、 メインのスクリプトで すべての#deffuncを読み込む
3、 メインスクリプトで読み込まれた#deffncの名前を指定すると自動的に
それが実行されるようにする。

こういう処理ができるでしょうか?



Flat

リンク

2014/9/20(Sat) 14:20:41|NO.65080

すいません、質問の意図がわかりませんでした。
「#deffuncを読み込む」と「#deffncの名前を指定する」とは
どういったことを指すのでしょうか。

// a.hsp #module #deffunc abc mes "xyz" return #global // b.hsp #module #deffunc def mes "123" return #global // main.hsp #include "a.hsp" #include "b.hsp" abc def



さっくん

リンク

2014/9/20(Sat) 14:44:12|NO.65082

#deffunc内に動作させる命令を入れればいいんじゃ((簡単すぎじゃい
でも一応方法を。

#deffunc Test neturl "http://sampleurl.com/sample/" mes "お待ちください..." netload "1.html" mes "完了" return



nepisat

リンク

2014/9/22(Mon) 18:24:44|NO.65132

わかりにくかったですね。
おそらくHSP標準についていないような気がします。

ファイルはMain.hspとIncludeフォルダにa.hsp b.hsp ....とあったとします。
まず、Includeフォルダ内は可変的にインクルードするファイルが増えたり減ったりします。
さらに、includeフォルダ内の.hspはすべて#deffuncです。

たとえば、
HELLO.hspといファイル内は

#deffunc HELLO mes "HELLO" return;
CLS.hsp内は

#deffunc CLS; cls return;

みたいな感じです。

あとは
Main.hspでincludeフォルダ内すべて読み込みして
ついでにファイル名も変数に代入、.hsp拡張子を切り捨てます。 (こうすると#deffuncの名前に)
ここからがわからないのですが、

変数に入れた関数名をそのまま呼び出せますか?

仮コード的なもの

//ロードしたファイル変数はdefinc //ここでファイルロード(略します) filenam = definc //note命令でdefincを一行ごとに分割(略 //たとえばファイル名&deffncがHELLOの場合 if (cin(a) == definc.1){ //cinとは入力してaに代入 definc.1はdefincの一行目(HELLO) filenam.1 (HELLO) }

こんな感じです。
わかりにくいかも?



cats

リンク

2014/9/22(Mon) 18:56:06|NO.65134

コンパイル後に実行ファイルからでもスクリプトが参照できて
.hspを実行したいのならこのようなものが。
http://www.onionsoft.net/hsp/v33/doclib/hspcmp.txt
http://dev.onionsoft.net/seed/info.ax?id=765
前者はコンパイルして別プロセスとして実行できます。
後者は内部で構文解析して内部で実行できます。



m

リンク

2014/9/22(Mon) 20:10:04|NO.65135

hspcmpは読み込んだスクリプト内で定義されている命令を直接呼べず、
GSは#deffuncのような命令定義に対応していません。
なので現状ではmistを使用するのが妥当かと思います。
http://dev.onionsoft.net/seed/info.ax?id=754

外部スクリプトをmstcompileで読み込み、
呼び出すときは関数名を文字列で指定する感じになります。


#include "mist.hsp" mstinit mstopenhsplib sdim loadbuf ;bload "HELLO.hsp",loadbuf loadbuf ={" #deffunc HELLO mes "HELLO" return "} mstcompile loadbuf mstcall "hello" // 小文字でないと呼び出しに失敗するらしい stop



ななし

リンク

2014/9/22(Mon) 23:28:16|NO.65139

こんばんは。
黒魔術?正式な方法ではありませんが、#deffuncの命令を文字列で呼び出せる
モジュールを作ってみました。

▼ StrCmd.hsp

// HSP ver 3.32b にて確認。 // 文字列から#deffuncモジュール(仮) : 最初にインクルードしてください。 #ifndef StrCmd #module StrCmd #define global registerCommand(%1) registerCommandImpl libptr(%1) /* 命令を「登録」する */ #deffunc registerCommandImpl int pStructDat //-- 文字列を取得する dupptr structDat, pStructDat, 28 nameidx = lpeek(structDat, 12) dupptr funcNameBuf, mem_mds + nameidx, 64 //少し多めに funcName = "" repeat char = peek(funcNameBuf, cnt) if (char == 0) : break funcName += strf("%c", char) loop //-- 登録 cmdFuncPtr(cmdCount) = pStructDat cmdString(cmdCount) = funcName cmdCount++ return /* プレースホルダ */ #deffunc dummyCommand /* 文字列を引数にして命令を呼び出す */ #deffunc callCommand str _cmd cmd = _cmd cmd = toLowerCase(strtrim(cmd, 0, ' ')) i = 0 repeat cmdCount if (cmd == cmdString(i)) { // 命令をコール dupptr f_from, cmdFuncPtr(i), 28 dupptr f_to, libptr(DummyCommand), 28 memcpy f_to, f_from, 28 dummyCommand break } i++ loop if (i == cmdCount) { // コマンドが見つからない(登録されていない)ときの警告 // とりあえず dialog を表示するようにしましたが、適宜変えてください。 dialog "コマンド '" + _cmd + "' が見つかりません" } return /* 半角アルファベットを小文字にする */ #defcfunc toLowerCase str _string string = _string count = 0 repeat char = peek(string, count) if (char == 0 || count >= strlen(string)) : break if (0 < char && char < 128) { if ('A' <= char && char <= 'Z') { poke string, count, (char + ('a' - 'A')) } count++ } else { count += 2 } loop return string /* 初期化 */ #deffunc local init cmdCount = 0 cmdFuncPtr = 0 cmdString = "" mref hspctx, 68 mem_mds = lpeek(hspctx, 12) return #global init@StrCmd #endif


このモジュールを使うには、#deffuncの命令を定義する.hspファイル内において、
その命令をregisterCommandで「登録」する必要があるので、その部分を書き加える必要があります。
具体的には、次のように書きます。(#moduleの内部にインクルードすると動きません)。

▼ test1.hsp

goto *@f #deffunc Test1 mes "Test1が呼び出されました" return *@ // 命令を登録する registerCommand Test1
▼ test2.hsp

goto *@f #deffunc Test2 mes "Test2が呼び出されました" return *@ // 命令を登録する registerCommand Test2

で、実際に使うには、最初にStrCmd.hspをインクルードしてから、
可変的にインクルードする.hspファイルをインクルードしてください。
callCommand "p1"
で、p1で指定した文字列に対応する#deffunc命令を呼びだそうとします。

▼例:main.hsp

// まず StrCmd.hsp をインクルードします。 #include "StrCmd.hsp" // ここで可変的にインクルードするものをインクルードします。 #include "test1.hsp" #include "test2.hsp" // 文字列から↑で読み込んだ命令を呼び出してみる callCommand "test1" callCommand " TEST2 " // 登録していない命令を呼び出してみる(警告) callCommand "test100"

とりあえずここまでですが、こんなもので良ければ自己責任にてお使いください^^。



Flat

リンク

2014/9/23(Tue) 09:10:55|NO.65146

>>nepisatさん
もしかしてコンパイル後にもincludeファイルが変わるような仕様にしたいのですか?



fortunehill

リンク

2014/9/23(Tue) 14:16:57|NO.65157

/*蛇足(ななしさんのスクリプトを整理して見た)*/

#module StrCmd #define global registerCommand(%1) registerCommandImpl libptr(%1) #deffunc registerCommandImpl int pStructDat dupptr structDat ,pStructDat ,28 nameidx = lpeek(structDat, 12) dupptr funcNameBuf,lpeek(hspctx,12)+nameidx,64 getstr funcName,funcNameBuf ; 文字列の取得 cmdFuncPtr(cmdCount) = pStructDat cmdString(cmdCount) = funcName cmdCount++ return #deffunc callCommand str _cmd cmd = _cmd cmd = getpath((strtrim(cmd,0,' ')),16) ; 小文字化 repeat cmdCount if (cmd == cmdString(cnt)) {i = 0 dupptr f_from,cmdFuncPtr(cnt) ,28 dupptr f_to ,cmdDummyPtr ,28 memcpy f_to ,f_from ,28 dummyCommand break} :i = 1 loop if (i) {mes _cmd + "が見つかりません"} return #deffunc dummyCommand return #deffunc local init cmdCount = 0 cmdFuncPtr = 0 cmdString = "" cmdDummyPtr = libptr(DummyCommand) ; ダミー関数ポインタ mref hspctx, 68 return #global init@StrCmd registerCommand Test1 ; ローカルジャンプ registerCommand Test2 callCommand "test1" callCommand " TEST2 " callCommand "Test3" stop #deffunc Test1 mes "Test1が呼び出されました" return #deffunc Test2 mes "Test2が呼び出されました" return



nepisat

リンク

2014/9/23(Tue) 14:49:53|NO.65159

.
http://hsp.tv/play/pforum.php?mode=all&num=64814
こいつで 定義ファイルを読み込み、
定義ファイルの拡張子抜きファイル名を読み込む。

string@mod0 = "" exstring@mod0 = "" draw onkey *jump stop #module mod0 #deffunc draw redraw 0 color : boxf // 黒で塗りつぶし pos 0, 0 color 255,255,255 mes string redraw 1 return #deffunc keyInput int wp, int ip switch wp case 13 // Enter string += "\n" //文字列を実行する excuteString exstring exstring = "" swbreak case 8 // BackSpace if (strmid(string, -1, 2) != "\n") { string = strmid(string, 0, strlen(string)-1) exstring = strmid(exstring, 0, strlen(exstring)-1) } swbreak default // その他 string = string + strf("%c", ip) // ↓実行する文字列を覚えておく exstring = exstring + strf("%c",ip) swbreak swend // 再描画する draw return // 文字に合わせて実行 #deffunc excuteString str cmd // たとえば... switch cmd case "読み込んだ定義ファイル名1" 読み込んだファイル名と同じ関数実行 swbreak case "定義ファイル名2" // あいさつ 読み込んだファイル名と同じ関数実行 swbreak case "ファイル名3" // 終了する 読み込んだファイル名と同じ関数実行 swbreak swend draw return #global *jump keyInput wparam, iparam stop


↑で、読み込んだファイル名がHELLOで
HELLO.hsp内に
#deffnc
string += "HELLO"
と書かれていれば、
コマンド画面でHELLOと入力すると
HELLOと出るみたいなことがしたい。



Flat

リンク

2014/9/23(Tue) 15:56:29|NO.65161


#module str_libptr #deffunc local _initslibptr \ local hspctx, local hsphed mref hspctx, 68 dupptr hsphed, hspctx(0), 96 dssize = hsphed(7) dsptr = hspctx(3) fiptr = hspctx(210) finum = hsphed(15) / 28 return #deffunc local getdsstr int offset, \ local statv, local data mref statv, 64 if offset<0 || offset>=dssize { statv = -1 return "" } dupptr data, dsptr+offset, dssize-offset, 2 statv = strlen(data) return data #defcfunc libptr_s str funcname, \ local finfo, local ptr, local found ptr = fiptr found = 0 repeat finum dupptr finfo, ptr, 28 getdsstr@str_libptr finfo(3) if stat >= 0 { if getpath(refstr, 16) == getpath(funcname, 16) { found = 1 break } } ptr += 28 loop if found == 0 : return -1 return ptr #global _initslibptr@str_libptr

libptr_s("関数名")で関数ポインタが得られるので、このモジュールと
http://hsp.tv/play/pforum.php?mode=all&num=64862
を組み合わせればできるかも。



Flat

リンク

2014/9/23(Tue) 16:34:34|NO.65162

忘れてましたがlibptr_sは全ての関数に対して動作します。
ユーザーが関数名を指定する場合はサニタイズを忘れないようにしてください。



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