3.1 Constructing ECLiPSe data
3.1.1 ECLiPSe atoms and functors
/* ECLiPSe code */
S = book("Gulliver's Tales","Swift",hardback,fiction),
In the above structure 'hardback' and 'fiction' are atoms. 'book'
is the functor of that structure, and it has an arity (number
of arguments) of 4.
Each functor and atom is entered into a dictionary, and is always
referred to by its dictionary entry. Two classes, EC_atom
and EC_functor
are used to access such dictionary entries.
The 'Name' method applies to both, to get their string form.
The 'Arity' method can be used to find out how many arguments
a functor has.
/* C++ code */
EC_functor book("book",4);
EC_atom hardback("hardback");
if (book.Arity()) == 4) .. /* evaluates to true */
if (book == hardback) .. /* evaluates to false */
s = hardback.Name(); /* like s = "hardback"; */
3.1.2 Building ECLiPSe terms
The pword
C data type is used to store ECLiPSe terms. In C++ the
EC_word
data type is used. This is used for any C type as well
as for ECLiPSe structures and lists. The size remains fixed in all
cases, since large terms are constructed on the ECLiPSe global stack.
The consequences of this are that terms will be garbage collected
or moved so terms do not survive the execution of ECLiPSe. In
particular, one cannot build such terms asynchronously while
ECLiPSe is running, for example this precludes building terms from
within a signal handler unless it can make sure that ECLiPSe has
yielded when it is running.
3.1.3 Building atomic ECLiPSe terms
It is possible to simply cast from a number of simple C++ types to
build an EC_word
In addition, functions exist for creating
new variables, and for the nil which terminates ECLiPSe lists.
In C++ you can just cast.
/* making simple terms in C++ */
EC_word w;
EC_atom hardback("hardback");
w = (EC_word) "Swift";
w = (EC_word) hardback;
w = (EC_word) 1.002e-7;
w = (EC_word) 12345;
w = (EC_word) nil();
w = (EC_word) newvar();
/* ECLiPSe equivalent code */
P1 = "Swift",
P2 = hardback,
P3 = 1.002e-7,
P4 = 12345,
P5 = [],
P6 = _,
3.1.4 Building ECLiPSe lists
The list(head,tail)
function builds a list out of two terms. Well
formed lists have lists as their tail term and a nil ("[]") at the end, or a
variable at the end for difference lists.
/* making the list [1, "b", 3.0] in C++ */
EC_word w = list(1, list("b", list(3.0, nil())));
The following example shows how you can write functions to build
variable length lists.
/* function to build a list [n,n+1,n+2,.....,m-1,m] */
EC_word fromto(int n, int m)
{
EC_word tail = nil();
for(int i = m ; i >= n ; i--)
tail = list(i,tail);
return tail;
}
The list is constructed starting from the end, so at all points during its
construction you have a valid term. The interface is designed to
make it hard to construct terms with uninitialised sub-terms, which is
what you would need if you were to construct the list starting with
the first elements.
3.1.5 Building ECLiPSe structures
The term(functor,args..)
function is used to build ECLiPSe
structures. A number of different functions each with a different
number of arguments is defined so as not to disable C++ casting
which would be the case if we defined a function with variable
arguments.
/* making s(1,2,3) in C++ */
EC_functor s_3("s",3);
EC_word w = term(s_3,1,2,3);
The above interface is convenient for terms with small fixed arities,
for much larger terms an array based interface is provided.
/* making s(1,2,..,n-1,n) */
EC_word args[n];
for(int i=0 ; i<n ; i++)
args[i] = i+1;
EC_word w = term(EC_functor("s",n),args);