任意の型の引数を任意の数だけ取る関数(可変長引数を取る関数)の実装

タイトル通りです。
ちなみにマクロは使用していません。

タイトル通りです。
ちなみにマクロは使用していません。

//-----------------------------------------------------------------------------------------
// |
// 2015/07/04 Flat |
//-----------------------------------------------------------------------------------------
/*
使
HSP
vfunc
HSP
vfuncvfuncreturn
vfunc
vfunc使
vfunc
vfunc
使
使
*/
//
// -1
#module ParameterStore m_type, m_var
#modinit int p_type, array p_var
m_type = p_type
if m_type == -1 {
dup m_var, p_var
} else {
m_var = p_var
}
return
#modcfunc gettype
return m_type
#modcfunc getparam
return m_var
#modfunc dupparam var p_var
dup p_var, m_var
return
#global
//
#module Variadic
// PVal
// http://d.hatena.ne.jp/chaperatta/20081012/1223803468
#defcfunc local getpval var
#deffunc local _getpval int p_pval
return p_pval
//
#deffunc local callback
return
//
// vfunc , 1, 2, 3, …
#deffunc vfunc \
local param, local param_index, local param_num, \
local hspctx, local hsphed, local mcs, local cs, local callback_st, \
local pcs, local old_pcs, local code_num, \
local info, local is48, local ex0, local ex1, local ex2, local type, local code, \
local params, local size, local label, local vtype, local bytecode, local func_st, \
local flag, local t_offset, local t_type, local t_code, \
local func
// param
// param
newlab label, 0
param = 0
//
dupptr cs, lpeek(label, 0), 6, 2
// =Code
if wpeek(cs, 0) & 0x8000 {
param_index = lpeek(cs, 2)
} else {
param_index = wpeek(cs, 2)
}
// CS
// HSPCTX
mref hspctx, 68
// HSPHED
dupptr hsphed, hspctx(0), 96, 4
// CS
dupptr mcs, hspctx(207) - 16, 4
// CSCS
dupptr cs, mcs, hsphed(5) - (hspctx(2) - mcs)
// CS
// http://codetter.com/?p=1165
pcs = 0
old_pcs = 0
param_num = 0
code_num = 0
repeat
// ExType
info = wpeek(cs, pcs)
is48 = info & 0x8000
ex2 = info & 0x4000
ex1 = info & 0x2000
ex0 = info & 0x1000
type = info & 0x0FFF
//
if ex1 | ex2 {
//
size = pcs - old_pcs
//
vtype = 0
switch wpeek(cs, old_pcs) & 0x0FFF
//
case 0
if wpeek(cs, old_pcs) & 0x8000 {
t_code = lpeek(cs, old_pcs + 2)
} else {
t_code = wpeek(cs, old_pcs + 2)
}
if t_code != 0x3F : swbreak
// 0
param = 0
// vtype
vtype = -3
swbreak
//
case 1/*TYPE_VAR*/
flag = 0
if code_num == 1 {
//
flag = 1
} else : if code_num >= 4 {
//
// TYPE_VAR'('')'
// a(3) * a(2) a(3) a(2) *
flag = 1
t_offset = old_pcs
repeat code_num
t_type = wpeek(cs, t_offset) & 0x0FFF
if wpeek(cs, t_offset) & 0x8000 {
t_code = lpeek(cs, t_offset + 2)
t_offset += 6
} else {
t_code = wpeek(cs, t_offset + 2)
t_offset += 4
}
if type == 11/*TYPE_CMPCMD*/ {
t_offset += 2
}
switch cnt
//
case 1
if t_type == 0x000 : swbreak
if t_code == 0x0028 : swbreak
flag = 0
break
//
case code_num - 1
if t_type == 0x000 : swbreak
if t_code == 0x0029 : swbreak
flag = 0
break
swend
loop
}
if flag {
//
sdim bytecode, size + 18
wpoke bytecode, 0, 0x200F // dup
wpoke bytecode, 2, 0x000E
wpoke bytecode, 4, 0x8005 // param
lpoke bytecode, 6, param_index
memcpy bytecode, cs, size, 10, old_pcs //
wpoke bytecode, size + 10, 0x200F // return
wpoke bytecode, size + 12, 0x0002
wpoke bytecode, size + 14, 0x200F // return
wpoke bytecode, size + 16, 0x0002
// Ex2
wpoke bytecode, 10, wpeek(bytecode, 10) | 0x4000
//
newlab label, 0
lpoke label, 0, varptr(bytecode)
gosub label
// vtype
vtype = -1
}
swbreak
//
case 12/*TYPE_MODCMD*/
if code_num != 1 : swbreak
//
sdim bytecode, size + 20
wpoke bytecode, 0, 0x200F // return
wpoke bytecode, 2, 0x0002
wpoke bytecode, 4, 0x0011 // libptr
wpoke bytecode, 6, 0x0103
wpoke bytecode, 8, 0x0000 // (
wpoke bytecode, 10, 0x0028
memcpy bytecode, cs, size, 12, old_pcs //
wpoke bytecode, size + 12, 0x0000 // )
wpoke bytecode, size + 14, 0x0029
wpoke bytecode, size + 16, 0x200F // return
wpoke bytecode, size + 18, 0x0002
// Ex2
wpoke bytecode, 12, wpeek(bytecode, 12) & 0xBFFF
//
newlab label, 0
lpoke label, 0, varptr(bytecode)
gosub label
// paramvtype
param = stat
vtype = -2
swbreak
swend
if vtype == 0 {
//
sdim bytecode, size + 18
wpoke bytecode, 0, 0xA005 // param
lpoke bytecode, 2, param_index
wpoke bytecode, 6, 0x0000 // =
wpoke bytecode, 8, 0x0008
memcpy bytecode, cs, size, 10, old_pcs //
wpoke bytecode, size + 10, 0x200F // return
wpoke bytecode, size + 12, 0x0002
wpoke bytecode, size + 14, 0x200F // return
wpoke bytecode, size + 16, 0x0002
// Ex2
wpoke bytecode, 10, wpeek(bytecode, 10) & 0xBFFF
//
newlab label, 0
lpoke label, 0, varptr(bytecode)
gosub label
// vtype
vtype = vartype(param)
}
//
if param_num < 1 {
// vfunc使
switch param_num
//
case 0
if (vtype != -2) && (vartype(param) != 4) {
//
_errorfunc@Variadic 123
}
func = param
swbreak
swend
} else {
//
newmod params, ParameterStore, vtype, param
}
// param
dim param
//
code_num = 0
old_pcs = pcs
param_num++
}
//
if ex1 {
break
}
//
pcs += 2
// Code
if is48 {
code = lpeek(cs, pcs)
pcs += 4
} else {
code = wpeek(cs, pcs)
pcs += 2
}
// TYPE_CMPCMD
//
if type == 11/*TYPE_CMPCMD*/ {
pcs += 2
}
//
;mes strf("%08X %d %d %d %d %4d %08X", pcs, is48!=0, ex0!=0, ex1!=0, ex2!=0, type, code)
// 使
code_num++
loop
//
if param_num < 1 {
//
_errorfunc@Variadic
return
}
// callback
dupptr callback_st, libptr(callback@Variadic), 28, 2
dupptr func_st, func, 28, 2
memcpy callback_st, func_st, 28
// callback
callback@Variadic params
//
foreach params
delmod params(cnt)
loop
//
mcs += pcs
return
#deffunc local _errorfunc str a
return
#global
// #if 0#if 1
#if 0
//
#module
#deffunc testfunc array p_params, \
local type, local var
mes strf("NUM OF PARAMS: %d", length(p_params))
foreach p_params
//
type = gettype(p_params(cnt))
//
dupparam p_params(cnt), var
//
switch type
case -3
mes strf("TYPE: EMPTY")
swbreak
case -2
mes strf("TYPE: FUNCTION, PTR TO STRUCTDAT: %08X", var)
swbreak
case -1
if length(var) > 1 {
mes strf("TYPE: ARRAY[%d], DATA[0]: %s", length(var), str(var(0)))
} else {
mes strf("TYPE: VARIABLE, DATA: %s", str(var))
}
swbreak
case 1
mes strf("TYPE: LABEL, DESTINATION: %08X", lpeek(var, 0))
swbreak
case 2
mes strf("TYPE: STRING, DATA: %s", var)
swbreak
case 3
mes strf("TYPE: DOUBLE, DATA: %g", var)
swbreak
case 4
mes strf("TYPE: INTEGER, DATA: %d", var)
swbreak
default
mes strf("TYPE: %d", var)
swbreak
swend
loop
return
#global
*label
abc = "a", "b", "c"
def = 1, 2, 3, 4
vfunc testfunc, 2, "xyz", 3.14, *label, 4 * 5, "3" + 4, 4.6
mes
vfunc testfunc, abc, def, abc(1), def(2), testfunc
mes
vfunc testfunc, , , , 5
mes
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX