nsluaからデフォルトの変数等にアクセスするライブラリ

以下のスクリプトをどっかにはると、いくつかのクラスオブジェクトが追加される。

na

numaliasの略
あらかじめ、*define節で、numalias zero,0などと定義しておく。
そうすると、na.zeroが自動的に0になっている。(変更してはいけない)

sa

straliasの略
nsのstralias版。

exec

NSExecの限定された、かつ豪華なラッパー
nsluaの側からNScripterのネイティブな命令を簡単に実行、また結果を取得しやすくする。

exec.puttext("表示したいテキスト")

これは、以下のスクリプトと(変数の処理以外は)等価である。

NSSetStrValue(999, "表示したいテキスト")
NSExec("_puttext $999")

また、引数に入った結果を取得することもできる。

local x, y = exec.getcursorpos(iRet, iRet)

返り値を取得した引数の部分に、数値が欲しいならばiRet, 文字列が欲しいならば、sRetを置くと、返り値にそれが反映される。

スクリプト

do
	-- numaliasを定義する。
	na = setmetatable({}, {__index=function(na, key)
		rawset(na, key, exec.mov(iRet, {str=key})); return rawget(na, key)
	end})

	-- straliasを定義する。
	sa = setmetatable({}, {__index=function(sa, key)
		rawset(sa, key, exec.mov(sRet, {str=key})); return rawget(sa, key)
	end})

	-- 数値変数オブジェクトを定義する。
	local num_class = {}
	num_class.set = function(ob, val) NSSetIntValue(ob.ref, val) end
	num_class.get = function(ob) return NSGetIntValue(ob.ref) end
	num_class.val = function(ob, val) ob:set(val); return ob:get() end
	num = setmetatable({}, {__index=function(num, key)
		if type(key)=="string" then return num[ns[key]] end
		local ob = setmetatable({}, {__index=num_class})
		ob.ref = key; ob.str = "%"..tostring(key)
		rawset(num, key, ob); return rawget(num, key)
	end})
	
	-- 文字列変数オブジェクトを定義する。
	local str_class = {}
	str_class.set = function(ob, val) NSSetStrValue(ob.ref, val) end
	str_class.get = function(ob) return NSGetStrValue(ob.ref) end
	str_class.val = function(ob, val) ob:set(val); return ob:get() end
	str = setmetatable({}, {__index=function(str, key)
		if type(key)=="string" then return str[ns[key]] end
		local ob = setmetatable({}, {__index=str_class})
		ob.ref = key; ob.str = "$"..tostring(key)
		rawset(str, key, ob); return rawget(str, key)
	end})
	
	-- 配列変数オブジェクトを定義する。
	local dim_class = {}
	dim_class.get = function(ob, ...)
		local temp = temp_num()
		exec.mov(temp, ob:str(...))
		return temp:get()
	end
	dim_class.set = function(ob, ...)
		local arg = {...}
		local new = table.remove(arg)
		exec.mov(ob:str(unpack(arg)), new)
	end
	dim_class.str = function(ob, ...)
		local com = "?"..tostring(ob.ref)
		for i, v in ipairs({...}) do com = com.."["..tostring(v).."]" end
		return com
	end
	dim = setmetatable({}, {__index=function(dim, key)
		if type(key)=="string" then return dim[ns[key]] end
		local ob = setmetatable({}, {__index=dim_class})
		ob.ref = key
		rawset(dim, key, ob); return rawget(dim, key)
	end})
	
	-- 一時数値変数を作成する。
	-- 一時文字列変数を作成する。
	local temp_num_list = {}
	local temp_str_list = {}
	for i=980, 999 do
		temp_num_list[1+#temp_num_list] = num[i]
		temp_str_list[1+#temp_str_list] = str[i]
	end
	
	-- 空いている一時変数を返す関数を定義する。
	function temp_num()
		local res = table.remove(temp_num_list, 1)
		temp_num_list[1+#temp_num_list] = res
		return res
	end
	function temp_str()
		local res = table.remove(temp_str_list, 1)
		temp_str_list[1+#temp_str_list] = res
		return res
	end

	-- NSExecをつかいやすくする。
	iRet = function(res)
		local temp = temp_num()
		res[1+#res] = function() return temp:get() end
		return temp.str
	end

	sRet = function(res)
		local temp = temp_str()
		res[1+#res] = function() return temp:get() end
		return temp.str
	end
	
	local exec_choose = {}
	exec_choose["number"] = function(v, res) return tostring(v) end
	exec_choose["string"] = function(v, res)
		local head = string.char(v:byte(1))
		if head == "*" then return v end
		if head == "#" then return v end
		local temp = temp_str()
		temp:set(v)
		return temp.str
	end
	exec_choose["function"] = function(v, res) return v(res) end
	exec_choose["table"] = function(v, res) return v.str end
	
	exec = setmetatable({}, {__index=function(exec, key)
		local com = "_"..key
		local func = function(...)
			local res = {}
			for i, v in ipairs({...}) do
				if i==1 then com = com .. " " else com = com .. "," end
				local choose = exec_choose[type(v)]
				if choose then com = com .. choose(v, res) end
			end
			NSOkBox(com, "実行中")
			NSExec(com)
			if #res>0 then
				for i, v in ipairs(res) do res[i] = v() end
				return unpack(res)
			end
		end
		rawset(exec, key, func)
		return rawget(exec, key)
	end})
end