sourcelib/Ffi.xtlm
1⍝# Ffi.xtlm -- the binding macro: a facade function written from the
2⍝# signature of a native function (docs/ffi-macro.md).
3⍝# Import: "ffi:" u_se< "Ffi" (xetal-x puts this directory on XETAL_PATH)
4⍝#
5⍝# "s_hout : text -> text" ffi:b_ind< "hello/shout"
6⍝#
7⍝# expands to the facade function l:s_hout, which speaks the ext: channel
8⍝# (docs/bridge.md). Kinds: unit (no argument), text, chars, int, float
9⍝# (an argument of any rank; as a result, a scalar), and as results also
10⍝# floats and ints (any rank, reshaped by the reply's shape).
11
12⍝# private: the words of a text, and the i-th of them
13ʰw̲ords ← { s → (n̲ot s = f̲irst " ") p̲artition s }
14ʰw̲ord ← { i w → d̲isclose i s̲elect w }
15
16⍝# private: what an argument a of kind k is sent as, and the query that
17⍝# says its kind (and shape)
18ʰv̲alue ← { k a →
19 k m̲atch "text" ? a
20 k m̲atch "chars" ? "(r_avel " c̲at a c̲at ")"
21 k m̲atch "int" ? "(f_ormat r_avel f_loor " c̲at a c̲at ")"
22 "(f_ormat r_avel f_loat " c̲at a c̲at ")"
23}
24ʰq̲uery ← { k a →
25 k m̲atch "text" ? "?text\""
26 k m̲atch "chars" ? "?chars=\" c_at f_ormat s_hape " c̲at a
27 k m̲atch "int" ? "?int=\" c_at f_ormat s_hape " c̲at a
28 "?float=\" c_at f_ormat s_hape " c̲at a
29}
30
31⍝# private: the line putting argument a (kind k) for the native function t
32ʰp̲ut ← { ka t →
33 k ← 1 ʰw̲ord ʰw̲ords ka
34 a ← 2 ʰw̲ord ʰw̲ords ka
35 " p" c̲at a c̲at " := " c̲at (k ʰv̲alue a) c̲at " []N_PUT \"ext:" c̲at t c̲at (k ʰq̲uery a) c̲at "\n"
36}
37
38⍝# private: the lines getting the reply of t as kind k
39ʰg̲et ← { k t →
40 call ← "[]N_GET \"ext:" c̲at t c̲at "\""
41 shape ← "(f_loor n_umbers []N_GET \"ext:" c̲at t c̲at "?shape\") r_eshape v\n"
42 k m̲atch "text" ? " " c̲at call c̲at "\n"
43 k m̲atch "float" ? " f_irst n_umbers " c̲at call c̲at "\n"
44 k m̲atch "int" ? " f_loor f_irst n_umbers " c̲at call c̲at "\n"
45 k m̲atch "floats" ? " v := n_umbers " c̲at call c̲at "\n " c̲at shape
46 k m̲atch "ints" ? " v := f_loor n_umbers " c̲at call c̲at "\n " c̲at shape
47 " v := " c̲at call c̲at "\n " c̲at shape
48}
49
50⍝# private: the parameters and the put lines, by how many arguments there are
51ʰp̲arams ← { w n →
52 n = 0 ? "@"
53 n = 1 ? "a"
54 "a b"
55}
56ʰp̲uts ← { w t →
57 n ← (t̲ally w) − 4
58 (n = 1) × (3 ʰw̲ord w) m̲atch "unit" ? ""
59 n = 1 ? ((3 ʰw̲ord w) c̲at " a") ʰp̲ut t
60 (((3 ʰw̲ord w) c̲at " a") ʰp̲ut t) c̲at ((4 ʰw̲ord w) c̲at " b") ʰp̲ut t
61}
62
63⍝ "NAME : KIND [KIND] -> KIND" ffi:b_ind< "EXTENSION/FUNCTION"
64ᵐb̲ind< ← { sig target →
65 w ← ʰw̲ords sig
66 n ← t̲ally w
67 args ← (n − 4) − (3 ʰw̲ord w) m̲atch "unit"
68 "l:" c̲at (1 ʰw̲ord w) c̲at " := { " c̲at (w ʰp̲arams args) c̲at " ->\n" c̲at (w ʰp̲uts target) c̲at ((n ʰw̲ord w) ʰg̲et target) c̲at "}"
69}