FFI: permit 𝕨≡⟨⟩, require 𝕩≡⟨⟩ if no arguments are on 𝕩, check list rank

This commit is contained in:
dzaima 2023-08-05 16:05:57 +03:00
parent fd4477992f
commit 7fe1ab930a
4 changed files with 18 additions and 9 deletions

View File

@ -824,20 +824,22 @@ B libffiFn_c2(B t, B w, B x) {
BoundFn* bf = c(BoundFn,t);
B argObj = c(HArr,bf->obj)->a[0];
#define PROC_ARG(L, U, S, NG) \
#define PROC_ARG(ISX, L, U, S) \
Arr* L##a ONLY_GCC(=0); \
AS2B L##f ONLY_GCC(=0); \
if (bf->L##Len>0) { \
if (FFI_CHECKS) { \
if (!isArr(L)) thrM("FFI: Expected array " S); \
if (isAtm(L) || RNK(L)!=1) thrM("FFI: Expected list " S); \
if (bf->L##Len>0 && IA(L)!=bf->L##Len) thrF("FFI: Wrong argument count in " S ": expected %s, got %s", bf->L##Len, IA(L)); \
} \
L##a = a(L); \
L##f = TIv(L##a,getU); \
} else { NG }
} else if (FFI_CHECKS && bf->L##Len==0 && (ISX? 1 : !q_N(w)) && (isAtm(L) || RNK(L)!=1 || IA(L)!=0)) { \
thrF("FFI: " S " must %S", ISX? "be an empty list" : "either be an empty list, or not present"); \
}
PROC_ARG(w, W, "𝕨", if (FFI_CHECKS && bf->wLen==0 && !q_N(w)) thrM("FFI: Unnecessary 𝕨 given");)
PROC_ARG(x, X, "𝕩", )
PROC_ARG(0, w, W, "𝕨")
PROC_ARG(1, x, X, "𝕩")
i32 idxs[2] = {0,0};
@ -999,7 +1001,6 @@ B ffiload_c2(B t, B w, B x) {
c(BQNFFIType,argObj)->staticAllocTotal = ffiTmpAlign(staticAlloc);
if (count[0]>1 && whole[0]) thrM("FFI: Multiple arguments on 𝕩 specified, some with '>'");
if (count[1]>1 && whole[1]) thrM("FFI: Multiple arguments on 𝕨 specified, some with '>'");
if (count[0]==0 && count[1]>0) thrM("FFI: At least one argument should be in 𝕩");
#else
i32 mutCount = 0;
for (usz i = 0; i < argn; i++) ffi_parseType(GetU(x,i+2), false);

View File

@ -26,7 +26,6 @@
!"FFI: Too many arguments" % @•FFI"""bqn_init"70000<"i32"
# >/𝕨/𝕩
!"FFI: At least one argument should be in 𝕩" % @•FFI"""bqn_init""𝕨i32""𝕨i32"
!"FFI: Multiple occurrences of '>' within one argument" % @•FFI"""bqn_init"">>i32"
!"FFI: Multiple occurrences of argument side specified" % @•FFI"""bqn_init""𝕨𝕨i32"
!"FFI: Multiple occurrences of argument side specified" % @•FFI"""bqn_init""𝕩𝕩i32"
@ -82,6 +81,7 @@
%USE defs f@•FFI"&""memcpy""&i32""*i16:u1"size_t F 5, 321, 4 %% ¯1
%USE defs f@•FFI"&","memcpy","&i8","*i8",size_t":u1" F ¯100+10, 10, size_tw001 %% (4)4¯100+10
%USE defs f@•FFI"&""memcpy""&i16""*i16:i32"size_t F ¯100+10, 123+456×216, ¯2, 8 %% 123456¯2¯14¯100+10
%USE defs f@•FFIsize_t,"strlen","*i8" F 1230 %% 3
@ -109,11 +109,17 @@
# bad overall argument separation
!"FFI: Expected array 𝕩" % f@•FFI"""bqn_init""i32""i32" F @
!"FFI: Unnecessary 𝕨 given" % f@•FFI"""bqn_init""i32""i32" @ F 12
!"FFI: Expected list 𝕩" % f@•FFI"""bqn_init""i32""i32" F @
!"FFI: Expected list 𝕩" % f@•FFI"""bqn_init""i32""i32" F 2, 2
!"FFI: Expected list 𝕨" % f@•FFI"""bqn_init""𝕨i32""𝕨i32" (12) F
!"FFI: Wrong argument count in 𝕩: expected 2, got 3" % f@•FFI"""bqn_init""i32""i32" F 2, 2, 2
!"FFI: Wrong argument count in 𝕩: expected 2, got 1" % f@•FFI"""bqn_init""i32""i32" F 2
!"FFI: Wrong argument count in 𝕨: expected 2, got 3" % f@•FFI"""bqn_init""i32""𝕨i32""𝕨i32" 2, 2, 2 F 4
!"FFI: 𝕩 must be an empty list" % f@•FFI"""bqn_init" F 1
!"FFI: 𝕩 must be an empty list" % f@•FFI"""bqn_init" F @
!"FFI: 𝕩 must be an empty list" % f@•FFI"""bqn_init""𝕨i32""𝕨i32" 12 F @
!"FFI: 𝕨 must either be an empty list, or not present" % f@•FFI"""bqn_init""*i8" 1,2 F 1230
!"FFI: 𝕨 must either be an empty list, or not present" % f@•FFI"""bqn_init""*i8" @ F 1230

View File

@ -18,6 +18,7 @@ bind ← "lib.so" •FFI "a"‿"bindAdd"‿">a" ⋄ g ← Bind 4 ⋄ •Show G 1
Section "# namespaces"
f "lib.so" •FFI "a""getField"">𝕨a""a""a" •Show {ab12 cd34} F "ab" "default"
f "lib.so" •FFI "a""getField"">𝕨a""a""a" •Show {ab12 cd34} F "ef" "default"
f "lib.so" •FFI "a""getField""𝕨a""𝕨a""𝕨a" •Show {ab12 cd34} "ef" "default" F
Section "# print args"
f "lib.so" •FFI """printArgs""i8""i16""i32""u8""u16""u32""f32""f64" •Show F ¯123¯12323¯212312312250500003123456789π÷3

View File

@ -31,6 +31,7 @@
# namespaces
⟨ 1 2 ⟩
"default"
"default"
# print args
args: -123 -12323 -212312312 250 50000 3123456789 3.141592741012573242 0.333333333333333315