picrin-website/www/capi.html

199 lines
12 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>C API &#8212; Picrin 0.1 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="Standard Libraries" href="libs.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="libs.html" title="Standard Libraries"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Picrin 0.1 documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">C API</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="c-api">
<h1>C API<a class="headerlink" href="#c-api" title="Permalink to this heading"></a></h1>
<p>You can write Picrins extension by yourself from both sides of C and Scheme. This page describes the way to control the interpreter from the C world.</p>
<section id="extension-library">
<h2>Extension Library<a class="headerlink" href="#extension-library" title="Permalink to this heading"></a></h2>
<p>If you want to create a contribution library with C, the only thing you need to do is make a directory under contrib/. Below is a sample code of extension library.</p>
<ul class="simple">
<li><p>contrib/add/nitro.mk</p></li>
</ul>
<div class="highlight-cmake notranslate"><div class="highlight"><pre><span></span>CONTRIB_INITS += add
CONTRIB_SRCS += contrib/add/add.c
</pre></div>
</div>
<ul class="simple">
<li><p>contrib/add/add.c</p></li>
</ul>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;picrin.h&quot;</span>
<span class="k">static</span><span class="w"> </span><span class="n">pic_value</span>
<span class="nf">pic_add</span><span class="p">(</span><span class="n">pic_state</span><span class="w"> </span><span class="o">*</span><span class="n">pic</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="kt">double</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">;</span>
<span class="w"> </span><span class="n">pic_get_args</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;ff&quot;</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">b</span><span class="p">);</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pic_float_value</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span>
<span class="nf">pic_init_add</span><span class="p">(</span><span class="n">pic_state</span><span class="w"> </span><span class="o">*</span><span class="n">pic</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">pic_deflibrary</span><span class="w"> </span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;(picrin add)&quot;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">pic_defun</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;add&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pic_add</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>After recompiling the interpreter, the library “(picrin add)” is available in the REPL, which library provides a funciton “add”.</p>
<section id="user-data-vs-gc">
<h3>User-data vs GC<a class="headerlink" href="#user-data-vs-gc" title="Permalink to this heading"></a></h3>
<p>When you use dynamic memory allocation inside C APIs, you must be caseful about Picrins GC. Fortunately, we provides a set of wrapper functions for complete abstraction of GC. In the case below, the memory (de)allocators <em>create_foo</em> and <em>finalize_foo</em> are wrapped in pic_data object, so that when an instance of foo losts all references from others to it picrin can automatically finalize the orphan object.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cm">/** foo.c **/</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&lt;stdlib.h&gt;</span>
<span class="cp">#include</span><span class="w"> </span><span class="cpf">&quot;picrin.h&quot;</span>
<span class="cm">/*</span>
<span class="cm"> * C-side API</span>
<span class="cm"> */</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">foo</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="c1">// blah blah blah</span>
<span class="p">};</span>
<span class="k">struct</span><span class="w"> </span><span class="nc">foo</span><span class="w"> </span><span class="o">*</span>
<span class="n">create_foo</span><span class="w"> </span><span class="p">()</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="nc">foo</span><span class="p">));</span>
<span class="p">}</span>
<span class="kt">void</span>
<span class="n">finalize_foo</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">foo</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">foo</span><span class="w"> </span><span class="o">*</span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">foo</span><span class="p">;</span>
<span class="w"> </span><span class="n">free</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
<span class="p">}</span>
<span class="cm">/*</span>
<span class="cm"> * picrin-side FFI interface</span>
<span class="cm"> */</span>
<span class="k">static</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">pic_data_type</span><span class="w"> </span><span class="n">foo_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="s">&quot;foo&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">finalize_foo</span><span class="w"> </span><span class="p">};</span>
<span class="k">static</span><span class="w"> </span><span class="n">pic_value</span>
<span class="nf">pic_create_foo</span><span class="p">(</span><span class="n">pic_state</span><span class="w"> </span><span class="o">*</span><span class="n">pic</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="nc">foo</span><span class="w"> </span><span class="o">*</span><span class="n">f</span><span class="p">;</span>
<span class="w"> </span><span class="n">pic_get_args</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="p">);</span><span class="w"> </span><span class="c1">// no args here</span>
<span class="w"> </span><span class="n">f</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">create_foo</span><span class="p">();</span>
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pic_data_value</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="n">md</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">foo_type</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span>
<span class="nf">pic_init_foo</span><span class="p">(</span><span class="n">pic_state</span><span class="w"> </span><span class="o">*</span><span class="n">pic</span><span class="p">)</span>
<span class="p">{</span>
<span class="w"> </span><span class="n">pic_defun</span><span class="p">(</span><span class="n">pic</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;create-foo&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">pic_create_foo</span><span class="p">);</span><span class="w"> </span><span class="c1">// (create-foo)</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<div>
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">C API</a><ul>
<li><a class="reference internal" href="#extension-library">Extension Library</a><ul>
<li><a class="reference internal" href="#user-data-vs-gc">User-data vs GC</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="libs.html"
title="previous chapter">Standard Libraries</a></p>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/capi.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="libs.html" title="Standard Libraries"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Picrin 0.1 documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">C API</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2014, Yuichi Nishiwaki and other picrin contributors.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 6.1.3.
</div>
</body>
</html>