aboutsummaryrefslogtreecommitdiff
path: root/docs/spec
diff options
context:
space:
mode:
Diffstat (limited to 'docs/spec')
-rw-r--r--docs/spec/system.html31
1 files changed, 31 insertions, 0 deletions
diff --git a/docs/spec/system.html b/docs/spec/system.html
index 7469fa06..92933a1f 100644
--- a/docs/spec/system.html
+++ b/docs/spec/system.html
@@ -352,6 +352,7 @@
</tbody>
</table>
<h2 id="interface"><a class="header" href="#interface">Interface</a></h2>
+<p>The function <code><span class='Function'>•SH</span></code> allows BQN to call other programs, as an operating system shell would. <code><span class='Function'>•FFI</span></code> allows it to call functions compiled by C or compatible languages—these are stored in files that traditionally have names like <code><span class='Value'>lib*.so</span></code> in Unix. In both cases the callee can run unrestricted code, so only trusted programs and functions should be called this way.</p>
<table>
<thead>
<tr>
@@ -364,9 +365,39 @@
<td><code><span class='Function'>•SH</span></code></td>
<td>Execute shell command and return <code><span class='Value'>exitcode</span><span class='Ligature'>‿</span><span class='Value'>stdout</span><span class='Ligature'>‿</span><span class='Value'>stderr</span></code></td>
</tr>
+<tr>
+<td><code><span class='Function'>•FFI</span></code></td>
+<td>Load a native function from a shared object file</td>
+</tr>
</tbody>
</table>
<p>The argument to <code><span class='Function'>•SH</span></code> is a list of strings giving the command and its arguments (for example <code><span class='String'>&quot;mv&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;old&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;new&quot;</span></code>). The command is executed synchronously, and the result is a list of three elements: the command's exit code, text written to stdout, and text written to stderr. In both cases the text is a plain string containing all text emitted by the program. Text is interpreted as UTF-8, with an error if it's not valid UTF-8.</p>
+<p>The arguments to <code><span class='Function'>•FFI</span></code> are a file path for <code><span class='Value'>𝕨</span></code> (interpreted relative to <code><span class='Value'>•path</span></code> if necessary, like <code><span class='Value'>•file</span></code> functions), and a function descriptor for <code><span class='Value'>𝕩</span></code>, which gives the function name, argument and result types, and information about how to convert these values. The format of <code><span class='Value'>𝕩</span></code> is described in the next section. The result is a BQN function that calls the specified function. This call can crash, mutate values, or invoke other unexpected behavior if the function interferes with memory used by BQN.</p>
+<h3 id="foreign-function-interface"><a class="header" href="#foreign-function-interface">Foreign Function Interface</a></h3>
+<p>In a call to <code><span class='Function'>•FFI</span></code>, <code><span class='Value'>𝕩</span></code> follows the pattern <code><span class='String'>&quot;result&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;fn&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;arg0&quot;</span><span class='Ligature'>‿</span><span class='String'>&quot;arg1&quot;</span><span class='Ligature'>‿</span><span class='Value'>...</span></code>, that is, a string for the <em>result type</em>, one for the <em>function name</em>, and any number of strings indicating <em>argument types</em>. <code><span class='Value'>𝕩</span></code> must always be a list.</p>
+<p>The function name is an arbitrary string. In order to look up the appropriate function in shared object file <code><span class='Value'>𝕨</span></code>, it's encoded as UTF-8.</p>
+<p>Types are to be interpreted according to the C ABI appropriate for the platform used. The grammar for a result or argument type is given below, using BNF as in the BQN grammar. Quoted values here are single characters: the type isn't tokenized and can't contain spaces. A <code><span class='Function'>•FFI</span></code> implementation does not need to support all combinations of types.</p>
+<pre><span class='Value'>conv</span> <span class='Function'>=</span> <span class='Value'>type</span> <span class='Paren'>(</span> <span class='String'>&quot;:&quot;</span> <span class='Value'>bqn</span> <span class='Paren'>)</span><span class='Head'>?</span>
+<span class='Value'>type</span> <span class='Function'>=</span> <span class='Paren'>(</span> <span class='String'>&quot;i&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;u&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;f&quot;</span> <span class='Paren'>)</span> <span class='Value'>nat</span> <span class='Comment'># number
+</span> <span class='Function'>|</span> <span class='String'>&quot;a&quot;</span> <span class='Comment'># BQN object
+</span> <span class='Function'>|</span> <span class='String'>&quot;*&quot;</span> <span class='Comment'># opaque pointer
+</span> <span class='Function'>|</span> <span class='Paren'>(</span> <span class='String'>&quot;*&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;&amp;&quot;</span> <span class='Paren'>)</span> <span class='Value'>type</span> <span class='Comment'># pointer
+</span> <span class='Function'>|</span> <span class='String'>&quot;[&quot;</span> <span class='Value'>nat</span> <span class='String'>&quot;]&quot;</span> <span class='Value'>type</span> <span class='Comment'># array
+</span> <span class='Function'>|</span> <span class='String'>&quot;{&quot;</span> <span class='Paren'>(</span> <span class='Value'>conv</span> <span class='Paren'>(</span> <span class='String'>&quot;,&quot;</span> <span class='Value'>conv</span> <span class='Paren'>)</span><span class='Value'>*</span> <span class='Paren'>)</span><span class='Head'>?</span> <span class='String'>&quot;}&quot;</span> <span class='Comment'># struct
+</span><span class='Value'>bqn</span> <span class='Function'>=</span> <span class='Paren'>(</span> <span class='String'>&quot;i&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;u&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;f&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;c&quot;</span> <span class='Paren'>)</span> <span class='Value'>nat</span>
+
+<span class='Value'>nat</span> <span class='Function'>=</span> <span class='Value'>digit</span><span class='Function'>+</span>
+<span class='Value'>digit</span> <span class='Function'>=</span> <span class='String'>&quot;0&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;1&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;2&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;3&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;4&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;5&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;6&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;7&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;8&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;9&quot;</span>
+</pre>
+<p>By default, the returned function takes a list of arguments <code><span class='Value'>𝕩</span></code>, requires <code><span class='Value'>𝕨</span></code> to be an empty list if present, and returns a value corresponding to the C result. Some argument-specific rules can change this:</p>
+<ul>
+<li>The result type may also be the empty string <code><span class='String'>&quot;&quot;</span></code>, indicating a void or ignored result, or <code><span class='String'>&quot;&amp;&quot;</span></code>, indicating an ignored result, using a mutable argument for the BQN result, as discussed below. It can't contain any instance of the pointer rule <code><span class='Paren'>(</span> <span class='String'>&quot;*&quot;</span> <span class='Function'>|</span> <span class='String'>&quot;&amp;&quot;</span> <span class='Paren'>)</span> <span class='Value'>type</span></code>.</li>
+<li>An argument type may be preceded by up to one <code><span class='Function'>&gt;</span></code>, and up to one <code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code>, in any order. Arguments with <code><span class='Value'>𝕨</span></code> are taken from <code><span class='Value'>𝕨</span></code> in order, and the others from <code><span class='Value'>𝕩</span></code>. If no arguments come from <code><span class='Value'>𝕨</span></code>, the BQN function may be called monadically. If an argument type contains <code><span class='Function'>&gt;</span></code>, it must be the only value in its BQN argument (<code><span class='Value'>𝕨</span></code> or <code><span class='Value'>𝕩</span></code>), and that argument will be treated not as a list but as an entire value.</li>
+</ul>
+<p>Beginning with the type declarations themselves, a <strong>number</strong> such as <code><span class='Value'>f32</span></code> corresponds to a C type with the given quality (<code><span class='Value'>i</span></code> for signed integer, <code><span class='Value'>u</span></code> for unsigned, <code><span class='Value'>f</span></code> for floating-point) and width in bits. The corresponding BQN value is a number, and should be converted exactly for integers and with rounding for decreasing-type conversions. For conversions to or from an integer type, attempting to convert a value to a type that can't contain it, or one outside of the exactly representable integer range (<code><span class='Function'>-</span><span class='Number'>2</span><span class='Function'>⋆</span><span class='Number'>53</span></code> to <code><span class='Number'>2</span><span class='Function'>⋆</span><span class='Number'>53</span></code> for IEEE doubles), results in an error.</p>
+<p>A <strong>pointer</strong> such as <code><span class='Value'>*u8</span></code> comes from a BQN list. If the symbol <code><span class='Value'>&amp;</span></code> is used rather than <code><span class='Value'>*</span></code>, the pointer is called <strong>mutable</strong> and its contents after the function call completes are also returned as an element of the result. If there is any mutable pointer, the result is a list, unless the result type is <code><span class='String'>&quot;&amp;&quot;</span></code>, in which case there must be exactly one mutable pointer and the result is its value alone. These prefixes can only be used in arguments, meaning that a BQN value is provided, and this value determines the length of both the input and the mutable result.</p>
+<p>The letter <code><span class='Value'>a</span></code> indicates that a <strong>BQN value</strong> is to be passed directly, interpreted in whatever way makes sense for the implementation. A plain <code><span class='Value'>*</span></code> indicates an <strong>opaque pointer</strong>, to be mapped to a BQN value of namespace type. The behavior of this value is not yet specified. The <strong>array</strong> and <strong>struct</strong> types indicate C structs and arrays, and correspond to BQN lists.</p>
+<p>The <code><span class='Value'>bqn</span></code> value in a <code><span class='Value'>conv</span></code> term indicates a BQN element type to be used. It can be appear after the whole type, or any member of a struct, and applies to the final component (that is, <code><span class='Value'>type</span></code> term) of the type <em>and</em> one preceding <code><span class='Value'>*</span></code>, <code><span class='Value'>&amp;</span></code>, or <code><span class='Value'>[n]</span></code> if present (if a type ends in <code><span class='Value'>**</span></code>, it applies to both <code><span class='Value'>*</span></code>s). This portion of the type corresponds to a BQN list of the given element type, interpreted much like <a href="#bitwise-operations">bitwise</a> conversion <code><span class='Value'>•bit.</span><span class='Modifier'>_conv</span></code>. The C type is treated as pure data, a stream of bits. For a prefix <code><span class='Value'>*</span></code> or <code><span class='Value'>&amp;</span></code>, the data in question is the region of memory pointed to.</p>
<h2 id="operation-properties"><a class="header" href="#operation-properties">Operation properties</a></h2>
<table>
<thead>