カレンダー

10 | 2016/11 | 12
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 - - -

プロフィール

YOS G-spec

ハンドルネーム:YOS G-spec
もう一つの名:んらとらん
性別:男
生息地:千葉県
職業:社会人3年生

好きなゲームシリーズ
・ロックマン全般
・モンスターハンター
・討鬼伝
・太鼓の達人
・ドラムマニア
・モンスターファーム
・サルゲッチュ
・チョロQ
・マリオカート
・DJMAX Potable
・リズム天国
・グランツーリスモ
・ポケットモンスター

【フレンドコードまとめ】
【所持ゲーム表】

なんか色々と適当で中途半端な人です。

ついったー(気まぐれ更新)
ついろぐ(ついったーまとめログ)
ギガスペックツール
ギガスペックチャット
過去の産物

メール
スカイプID:yos_g-spec

新太鼓番:3348-9507-7550
3DSフレンドコード:1289-8444-6710
とび森夢番地:3500-0140-1697



最近の記事

最近のコメント

  • 01/01:YOS G-spec

  • 12/17:ばぜるこあ

  • 01/04:YOS G-spec

  • 11/15:暇神

  • 12/06:YOS G-spec

  • 12/05:くま☆

  • 08/22:YOS G-spec

カテゴリー

SleepSort on yield【ES6/JavaScript】

JavaScriptのyieldを実践してみた。
js yield で検索するとcoばっかり出てくるけど、生でも結構使えそう。
PromiseもAwait/Asyncを封印しても結構あっさり書ける。
感覚的にはAwaitとほぼ同じ感じかなぁ。
yield(func)で値が返ってくる原理はいまいち把握していないけれども。

あとは、待ち合わせ処理はしんどそうだからそこだけはPromiseにした方がいいかもね。
試してないけど、

yield new Promice(hoge);

みたいな感じでも行けるのかな。
行けたら凄く夢が広がるなぁ。
 -> 行けました。yield強い。その代わり、thenチェーンでg.next()するまでが1セット。


const rl=require("readline")
.createInterface(process.stdin,process.stdout);

const g=main();
g.next();
function* main(){
var sortResult=[];

const delayWait=function(wait){
setTimeout(()=>{
sortResult.push(wait);
g.next();
},wait*10);
};

rl.setPrompt("【SleepSort JavaScript yield】\n> ");
rl.prompt();
input=yield rl.once("line",str=>g.next(str));
const items=input.split(" ");
items.forEach(val=>delayWait(parseInt(val,10)));

for(var i in items){
yield;
}

console.log("done!");
console.log(sortResult);
rl.setPrompt("");
rl.prompt();
rl.once("line",process.exit);
}

HSP マルチプロセスモジュール ver0.01

HSPでマルチスレッドならぬマルチなプロセスを比較的簡単に扱うためのモジュール。
いまだ値の取り交わしにtxtファイルのごみを残す仕様かつ超不安定版。
もうそろそろ心が折れそうなのでソース全部置いておきます。

共有メモリ使えたらもう少し安定しそうだけど、モジュール使っても難しいんだなぁ。
なごみコネクトやメモリ共有モジュールも使ったけれど、それぞれ別の問題が残ってしまう…
グローバル変数みたいのはメモリ共有モジュールで行けるけども、配列に突っ込むとエラーになり、
なごみコネクトではグローバルな変数を恐らく扱えない…

サンプル

#packopt name "TestHSProcess"
#runtime "hsp3cl"
#include "HSProcess.as"

#module Program
#uselib "msvcrt"
#func printf "printf" str

//関数リスト
#deffunc ProcessFuncList array funcList
funcList=*delayWait,*delayWait2

funcArea {
#enum fn(delayWait)=0
def(delayWait,_wait)
ints _wait
await _wait*10

notesel sortResult
noteload "sortResult"
unzipArray sortResult,sortResultList
sortResultList(length(sortResultList))=str(_wait)
sortResult=zipArray(sortResultList)
notesave "sortResult"

resolve _wait
endf

#enum fn(delayWait2)
def(delayWait2,_wait)
ints _wait
wait _wait
mes this_PID@
resolve this_PID@
endf
}
return

//メインプロセス
#deffunc main
notesel sortResult
notesave "sortResult"
printf("【MultiProcessExec】\n> ")
input _input,256,1
split _input," ",items

foreach items
new_Process itemProcesses,fn(delayWait),items(cnt)
loop

Process_StartAll itemProcesses
Process_WaitAll itemProcesses

mes "done!"
notesel sortResult
noteload "sortResult"
delete "sortResult"
unzipArray sortResult,sortResultList
foreach sortResultList
if cnt=0: continue
if cnt!=1: printf ","
printf sortResultList(cnt)
loop
input exit,,1
return
#global
main


モジュール本体
HSProcess.as

ProcessEntry

#module gofunc
#define global funcArea if 0
//命令・関数呼び出し
#define global call funcall
#define global ctype funcall(%1, \
%2="null",%3="null",%4="null",%5="null",%6="null",%7="null",%8="null",%9="null",%10="null",%11="null") \
(callf@gofunc(%1, \
""+%2+"$ParamS$"+%3+"$ParamS$"+%4+"$ParamS$"+%5+"$ParamS$"+%6+"$ParamS$"+%7+"$ParamS$"+%8+"$ParamS$"+%9+"$ParamS$"+%10+"$ParamS$"+%11))
#define global subcall(%1, \
%2="null",%3="null",%4="null",%5="null",%6="null",%7="null",%8="null",%9="null",%10="null",%11="null") \
%tfunc %i=%1:%i%o0=callf@gofunc(%o, \
""+%2+"$ParamS$"+%3+"$ParamS$"+%4+"$ParamS$"+%5+"$ParamS$"+%6+"$ParamS$"+%7+"$ParamS$"+%8+"$ParamS$"+%9+"$ParamS$"+%10+"$ParamS$"+%11)
#defcfunc local callf var flabel,str pAll
paramStr@gofunc=pAll
gosub flabel
return result

//関数定義
#define global ctype fn(%1) Function_%1
#define global ctype def(%1, \
%2=nul@gofunc,%3=nul@gofunc,%4=nul@gofunc,%5=nul@gofunc,%6=nul@gofunc, \
%7=nul@gofunc,%8=nul@gofunc,%9=nul@gofunc,%10=nul@gofunc,%11=nul@gofunc) \
*%1: split paramStr@gofunc,"$ParamS$",%2,%3,%4,%5,%6,%7,%8,%9,%10,%11
#define global resolve(%1) result@gofunc=%1:return
#define global endf return

//型変換
#define global ints(%1=nul@gofunc,%2=nul@gofunc,%3=nul@gofunc,%4=nul@gofunc,%5=nul@gofunc, \
%6=nul@gofunc,%7=nul@gofunc,%8=nul@gofunc,%9=nul@gofunc,%10=nul@gofunc) \
ints@gofunc %1,%2,%3,%4,%5,%6,%7,%8,%9,%10
#deffunc local ints var p1,var p2,var p3,var p4,var p5,var p6,var p7,var p8,var p9,var p10
p1=int(p1):p2=int(p2):p3=int(p5):p4=int(p4):p5=int(p5)
p6=int(p6):p7=int(p7):p8=int(p8):p9=int(p9):p10=int(p10)
return

#define global doubles(%1=nul@gofunc,%2=nul@gofunc,%3=nul@gofunc,%4=nul@gofunc,%5=nul@gofunc, \
%6=nul@gofunc,%7=nul@gofunc,%8=nul@gofunc,%9=nul@gofunc,%10=nul@gofunc) \
doubles@gofunc %1,%2,%3,%4,%5,%6,%7,%8,%9,%10
#deffunc doubles var p1,var p2,var p3,var p4,var p5,var p6,var p7,var p8,var p9,var p10
p1=double(p1):p2=double(p2):p3=double(p5):p4=double(p4):p5=double(p5)
p6=double(p6):p7=double(p7):p8=double(p8):p9=double(p9):p10=double(p10)
return

//配列変換
#defcfunc zipArray array arr
switch vartype(arr(0))
case 2:
deli="$StrArraY$"
swbreak
case 3:
deli="$DoubleArraY$"
swbreak
case 4:
deli="$IntArraY$"
swbreak
default:
mes "error"
swend

arrStr=""
foreach arr
if cnt!=0:arrStr+=deli
arrStr+=str(arr(cnt))
loop
return arrStr

#deffunc unzipArray str _arrstr,array arr
arrstr=_arrstr
if 0<=instr(arrstr,,"$StrArraY$") {
split arrstr,"$StrArraY$",arr
}
else:if 0<=instr(arrstr,,"$DoubleArraY$") {
split arrstr,"$DoubleArraY$",_arr
ddim arr,length(_arr)
foreach _arr
arr(cnt)=double(_arr(cnt))
loop
}
else:if 0<=instr(arrstr,,"$IntArraY$") {
split arrstr,"$IntArraY$",_arr
dim arr,length(_arr)
foreach _arr
arr(cnt)=int(_arr(cnt))
loop
}
else {
arr=_arrstr
}
return
#global

count@HSProcess=0
#module HSProcess PID,paramStr
#define global new_Process(%1,%2, \
%3="null",%4="null",%5="null",%6="null",%7="null", \
%8="null",%9="null",%10="null",%11="null",%12="null") \
newmod %1,HSProcess,%2,""+%3+"$ParamS$"+%4+"$ParamS$"+%5+"$ParamS$"+%6+"$ParamS$"+%7+"$ParamS$"+%8+"$ParamS$"+%9+"$ParamS$"+%10+"$ParamS$"+%11+"$ParamS$"+%12

#modinit int funcID,str pAll
count++
PID=count
paramStr=ExeName@HSProcess+" $ProcesS$$FuncID$"+funcID+"$FuncID$"+PID+"$ProcessID$"+pAll

//共有
notesel Result
Result="null"
notesave "Result"+PID

notesel IsRunning
IsRunning="false"
notesave "IsRunning"+PID
return

#modcfunc Process_ID
return PID

#modcfunc Process_paramStr
return paramStr

#modfunc Process_Start
exec paramStr
notesel IsRunning
IsRunning="true"
notesave "IsRunning"+PID
return

#deffunc Process_StartAll array ProcessList
foreach ProcessList
exec Process_paramStr(ProcessList(cnt))
loop
notesel IsRunning
foreach ProcessList
IsRunning="true"
notesave "IsRunning"+Process_ID(ProcessList(cnt))
loop
return

#modfunc Process_Wait
notesel IsRunning
repeat
noteload "IsRunning"+PID
if IsRunning="false": break
loop
delete "IsRunning"+PID
delete "Result"+PID
return

#deffunc Process_WaitAny array ProcessList
notesel IsRunning
repeat
modcnt=cnt\length(ProcessList)
noteload "IsRunning"+Process_ID(ProcessList(modcnt))
if IsRunning="false": return
loop
delete "IsRunning"+Process_ID(ProcessList(modcnt))
delete "Result"+Process_ID(ProcessList(modcnt))
return

#deffunc Process_WaitAll array ProcessList
notesel IsRunning
foreach ProcessList
do
noteload "IsRunning"+Process_ID(ProcessList(cnt))
until IsRunning="false"
delete "IsRunning"+Process_ID(ProcessList(cnt))
delete "Result"+Process_ID(ProcessList(cnt))
loop
return

#modcfunc Process_Result
repeat
if IsRunning: return Result
wait 1
loop

#deffunc ProcessEntry
//exeファイル位置
#uselib "kernel32"
#func GetModuleFileName "GetModuleFileNameA" int,int,int
sdim fullExePath, 256
GetModuleFileName,varptr(fullExePath),256
ExeName=getpath(fullExePath,8)

cmd=dir_cmdline
//サブプロセスの判別
if 0<=instr(cmd,,"$ProcesS$") {
subProcess cmd
end
}
this_PID@=0
return

//サブプロセス
#deffunc subProcess var _cmd
//関数の取得
split _cmd,"$FuncID$",nul,this_funcID,this_paramStr
ProcessFuncList funcList
callBack=funcList(int(this_FuncID))

split this_paramStr,"$ProcessID$",this_PID@,this_paramStr
this_PID@=int(this_PID@)

notesel this_Result
this_Result=call(callBack,this_paramStr)
notesave "Result"+this_PID@

notesel IsRunning
IsRunning="false"
notesave "IsRunning"+this_PID@
return
#global

HSP gofunc.as

gosubを隠蔽して引数や戻り値っぽいやり取りを行うための代物。こんな風に書ける。

#runtime "hsp3cl"
#include "gofunc.as"
#cmpopt ppout 1

#module Program
def(hoge,a,b,c,d,e)
ints a,b,c,d,e
resolve a+b+c+d+e
endef

def(huga,a,b,c,d,e)
mes a+b+c+d+e
endef

#deffunc main
fl=*hoge
mes call(fl,1,2,3,4,5)
subcall *huga,1,2,3,4,5
return
#global
main

注意点
 あくまでも実体はラベルであるため、モジュールを跨ぐには小細工が必要。
 引数に見えるものは全てstr型となるためキャストが必須。
 そのため一括キャスト用にintsとdoubulesを用意。
->zipArray、unzipArray追加。その他配列補助命令、関数大幅追加。
 渡せる型はint,double,str型のみ。
 引数最大個数10個まで。
 使いたい人がもしいればご自由に。ライセンスはパブリックドメインです。
 そのほかバグ未保障。

【モジュール仕様】
gofuncモジュール<命令・関数>一覧

#define funcArea { ... }
この中にdef文を配置するとブロックを作り、
関数の起動を阻止することができる。

#define fn(funcName)
関数名から固有の定義名を生成する。
#enumで関数と紐づけたい時などに使用。

#define def(funcName [, str p1, str p2, ...str p10])
関数の開始を示す。
p1~p10は与えられた引数となるが、str型固定となる。
必要に応じて個別にキャスト(型変換)を行う。

#define resolve var Result
def文の返り値を指定する。

#define endef
def文の終了を明示する。

str #defcfunc call(variable label funcName [, var p1,var p2, ...var p10])
str #defcfunc funcall(variable label funcName [, var p1, var p2, ...var p10])
def文で定義された関数を呼ぶ。
返り値にresolveで指定された値が返る。
labelは変数に代入された状態である必要がある。

#deffunc subcall [, var p1, var p2, ...var p10]
def文で定義された関数を呼ぶ。
返り値を取得しない。
素のlabelを指定可。
なお、引数としてstr、int、double型以外の型は受け付けない。
配列はzipArrayを用いて渡すこと。

#deffunc ints [ref int p1, int p2, ...int p10]
#deffunc doubles [ref double p1, double p2, ...double p10]
引数に含めた物をintまたはdouble型にキャスト(変換)して返す。

str #defcfunc zipArray(array anyArray)
配列を可逆的変換可能な文字列へ変換する。

#deffunc unzipArray str zipString, ref array ResultArray
zipArrayで変換された文字列を配列に復元して、
ResultArrayに返す。

#deffunc pushArray array anyArray, var addItem
配列の最後にaddItemで指定した値を追加する。

#deffunc unshiftArray array anyArray, var addItem
配列の最前にaddItemで指定した値を追加する。

#deffunc popArray array anyArray [, ref var removeItem]
配列の最後を削除し、removeItemに削除した値を返す。

#deffunc shiftArray array anyArray [, ref var removeItem]
配列の最前を削除し、removeItemに削除した値を返す。

#deffunc copyArray array baseArray, ref array cloneArray
配列をcloneArrayへコピーして返す。

#deffunc addRange ref array array1, array array2
配列 array1の後に配列 array2を結合する

str #defcfunc joinStr(array anyArray [, str delimiter]
配列を任意の文字列で区切った文字列に変換する。
デフォルトでは","で区切られる。


実際のモジュールは追記より。

追記を読む »

HSPでオプション引数

題目の通り。
何故か"HSP オプション引数"で検索しても引っかからなかったからまとめておく。
define文はまともに使ったの多分初めてだなぁ。
C言語の授業で触ったことあった気がしないでもないけど。


#runtime "hsp3cl"
//HSPでオプション引数を使用する。
#module Optional
#define global Test( \
%1="ズン",%2="ドコ",\
%3="キ・ヨ・シ!") \
Test@Optional %1,%2,%3
// \を使用すると任意の位置で改行できる。
// 使わなくても良い。

#deffunc local Test str x,str y,str z
mes x+" "+y+" "+z
return
#global

Test
Test "hoge"
Test ,"huga"
Test ,,"bar"
Test "ほげ","ふが","ばー"

input exit,,1

/*
ズン ドコ キ・ヨ・シ!
hoge ドコ キ・ヨ・シ!
ズン huga キ・ヨ・シ!
ズン ドコ bar
ほげ ふが ばー
*/

HSP mist

HSP mistプラグイン

HSPのmistプラグインの魔力にヤバさを感じたので色々テスト。
ラムダ式みたいな使い方ができるのが一番うれしい。
ちなみにマルチスレッド機能についてはこちらで使用しています。



#runtime "hsp3cl"
#include "mist.hsp"
mstOpenHspLib

#module Program
#defcfunc callback str func
mstCompile func
return mstLoad("return infunc(\""+"hoge"+"\","+365+")")
//即時関数もどき
#defcfunc fn str func,str funcrun
mstCompile func
return mstLoad(funcrun)
#global

mes callback({"
#defcfunc infunc str x,int y
return \"\"+x+\":\"+y
"})

mes fn({"#defcfunc f str x,int y
return \"\"+x+\":\"+y
"},"return f(\"foo\",500)")

mes fn({"#defcfunc f str x,int y
return "bas"+x+y
"},"return f(\"foo\",500)")

mes fn({"
#defcfunc fact int i,int max
if i\\3=0 && i\\5=0 {
mes \"Fizz Buzz\"
} _ //アンダーバーが無いとエラー
else:if i\\3=0 {
mes \"Fizz\"
} _
else:if i\\5=0 {
mes \"Buzz\"
} _
else {
mes i
}
return (if i then fact(i+1,max)
else "End Fizz Buzz!!")
"},"return fact(0,100)")

mstDestroy

| TOP | NEXT