picrin-website/www/capi.html

199 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>