How to make an extension module
===============================

1. Symbols
----------

An extension module (or shared object module) is a shared object library
that must contains the symbol `argmod_binds' which must be an array
of pointers to text character strings, ended by the null pointer.
In C:

   char *argmod_binds[] = {
     "bindable_1", "bindable_2", /* ... */ NULL
   };

In Argile:

   use std, array
   let argmod_binds be a (raw array of text) = Cdata {
     "bindable_1"; "bindable_2"; (: ... :) nil
   }

Each string is the name of a binding; for each binding, the following symbols
may be optionally defined (replace BINDNAME by the name of the binding):

(+) argmod_BINDNAME_compile

  A function that takes an argile call argument, does some custom compilation
  (like creating new definitions for example).
  In C:
    void argmod_BINDNAME_compile(argile_call_t *call) {...}

  In Argile:
    .:argmod_BINDNAME_compile<argile call call>:. {...}

(+) argmod_BINDNAME_gencode

  A function that takes an argile call argument, generates C code.
  In C:
    void argmod_BINDNAME_gencode(argile_call_t *call) {...}

  In Argile:
    .:argmod_BINDNAME_gencode<argile call call>:. {...}

(+) argmod_BINDNAME_gettype

  A function that takes an argile call argument, and returns the
  value of the return type of the binding.
  In C:
    argile_type_t argmod_BINDNAME_gettype(argile_call_t *call) {...}

  In Argile:
    .:argmod_BINDNAME_gettype<argile call call>:. -> argile type {...}

(+) argmod_BINDNAME_evaltype

  A function that takes an argile call argument, and returns the value
  of the type returned by the binding (the binding returns a type).
  In C:
    argile_type_t argmod_BINDNAME_evaltype(argile_call_t *call) {...}

  In Argile:
    .:argmod_BINDNAME_evaltype<argile call call>:. -> argile type {...}

(+) argmod_BINDNAME_reject

  A function that takes an argile call argument, and returns an integer
  which is either 0 when it passes, 1 when it rejects, -1 when it should
  be retried later (for example, if it depends on definitions not yet made).
  In C:
    int argmod_BINDNAME_reject(argile_call_t *call) {...}

  In Argile:
    .:argmod_BINDNAME_reject<call>:. -> int {...}

(+) argmod_BINDNAME_type

  An Argile type (integer) which is the constant return type of the binding,
  or the value of the type if argmod_BINDNAME_deftype is non-zero.
  In C:
    argile_type_t argmod_BINDNAME_type = ARGILE_TYPE_TEXT; // for example

  In Argile:
    let (argile type) argmod_BINDNAME_type = (Cgen ARGILE_TYPE_TEXT)

(+) argmod_BINDNAME_doc

  A text characters array which documents how to use this binding.
  In C:
    char argmod_BINDNAME_doc[] = "Does this and that...\n";

  In Argile:
    let argmod_BINDNAME_doc be a (raw array of byte) = Cgen ("Blah blah...\n")

(+) argmod_BINDNAME_defmaker

  An integer which means, when set to non-zero, that
  it may produce new definition(s).
  In C:
    int argmod_BINDNAME_defmaker = 1;

  In Argile:
    let argmod_BINDNAME_defmaker = 1;

(+) argmod_BINDNAME_modulable

  An integer which means, when set to non-zero, that
  it should be dumped in Argile module files (.argl library interfaces).
  In C:
    int argmod_BINDNAME_modulable = 1;

  In Argile:
    let argmod_BINDNAME_modulable = 1;

(+) argmod_BINDNAME_deftype

  An integer which means, when set to non-zero, that
  it is a type definition
  In C:
    int argmod_BINDNAME_deftype = 1;

  In Argile:
    let argmod_BINDNAME_deftype = 1

(+) argmod_BINDNAME_isconst

  An integer which means, when set to non-zero, that
  it generates "constant" code (is a safe variable constant initializer).
  In C:
    int argmod_BINDNAME_isconst = 1;

  In Argile:
    let argmod_BINDNAME_isconst = 1


2. Interface with libargile
---------------------------
Currently, modules can read and write directly the fields of classes
defined in libargile, which means the modules are dependant on the
version of libargile (i.e. a change of version of libargile could
require a recompilation of shared object modules).

When libargile uncompiles a call to a binding, it will
call call.del with call.data unless call.keep_data is true or call.del is nil.
Setting call.del and call.data (and optionally call.keep_data) should be done
by the binding code in the shared module; they are initially nil (and false).

-----------------------------------------------------------------------------

Copyright (C) 2009,2010,2011 The Argile authors (See file AUTHORS).

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A
copy of the license is included in the file doc/COPYING distributed
along with the Argile compiler.
