Author: | Raphael Poss |
---|---|
Contact: | raph@lrde.epita.fr |
Date: | January 2005 |
Version: | $Id$ |
The file build-process.txt describes how to use Vaucanswig to create a wrapper for Vaucanson in a scripting language. (read it first)
This document instead describes how Vaucanswig itself is generated, currently using the infamous expand.sh script.
Once generated, Vaucanswig is a set of SWIG modules. This list of modules is algorithmically generated. The overall process to build the list of module names is as follows:
put "core" in the MODULES list.
create an auxiliary list ALGS of algorithm families.
(detailed below, gives alg_sum, alg_complete, ...)
create an auxiliary list KINDS of algebra contexts
(contains boolean, z, z_max_plus, ...)
extend ALGS with "context", "algorithms" and "automaton".
make the cross product of KINDS and ALGS putting a "_" between the two parts of each generated name.
add the results of this cross product to the MODULES list.
In Vaucanswig, an "algorithm family" is the set of algorithms declared in a single Vaucanson header file. Most families declare only one algorithm, but usually with several forms (using overloading). In Vaucanswig, each algorithm family is related to a SWIG source file: src/vaucanswig_alg_NAME.i where NAME is the name of the algorithm family.
Each family source file contains the following items:
To create the list of algorithm families and associated SWIG sources, the geneeration script proceeds as follows:
Find all files in the Vaucanson includes that declare algorithms using the "// INTERFACE:" construct.
For each such include file, proceed as follows:
- Prepend the base name of the file with "alg_" to make a "family name".
- Create src/vaucanswig_(family_name).i containing the relevant SWIG code
- Put the generated family name (with prefix) in the ALGS list.
This is where you find all the magic. :)
This is the step where real code (i.e. non-template) is produced.
The goal of this step is to build the list of SWIG modules names and the source file for each SWIG module. The basic idea is simple. It relies on the following two facts:
Now the rest is quite simple. Since we have two lists KINDS (contexts) and ALGS (algorithm families), proceed as follows:
for each K of KINDS, do: for each A of ALGS, do: # Step 5.1 instanciate macros... ... from src/vaucanswig_alg_${A}.i ... using ${K} ... into src/vaucanswig_${K}_${A}.i # Step 5.2 add "${K}_${A}" to the MODULES list. # the following step is not fundamental, but required for later # compilation: # Step 5.3 (still in the K loop) add "${K}_context" to src/${K}_automaton.deps for each algorithm family F, do: # Step 5.4 add "${K}_automaton" to src/${K}_${F}.deps # Step 5.5 add "${K}_${F}" to src/${K}_algorithms.deps
The result of steps 5.3, 5.4 and 5.5 above can later be used to create dynamic link dependencies between object code for modules (see build-process.txt). It creates the following dependency graph:
core -> K1_context -> K1_automaton -> K1_F1 -> K1_algorithms -> K1_F2 -> -> K1_F3 -> -> K2_context -> K2_automaton -> K2_F1 -> K2_algorithms -> K2_F2 -> -> K2_F3 -> (and so on)
At every level, a property can be recognized. If an algorithm foo() is declared (C++) in bar.h, then:
"bar" is the "algorithm family" of foo()
for each selected context K, exactly one SWIG module exists and is called called "K_bar".
the goal is that at the end of the compilation, in the target scripting language you can write:
K_bar.foo() # (or equivalent)
Some work is required from the part of the developer:
In this section, K stands for any algebra context.
The set of K -dependent types available in wrapper code in the "// INTERFACE:" tags is not yet easily configurable, because it involves a huge piece of hand-written dedicated code.
For the moment, the following types are available for each context K:
Name of type | Description |
---|---|
Automaton | the automaton type labeled by series |
GenAutomaton | the corresponding type labeled by expressions |
Series | the type of series in K |
Exp | the type of expressions in K |
HList | a type for lists of unsigned integer (to be used as automaton handlers where required) |
Adding more of these is not difficult, but very tedious. It involves adding a new argument in various argument list in various SWIG macros in the code. These will be documented later.
But still, it remains very difficult to bind in Vaucanswig any algorithm that operates on more than one algebra context at the same time. "Very difficult" here means that some major work is required to change Vaucanswig to support this case.