Creating your own Ballista® data type:
Simple Example

How do data types fit into the Ballista testing methodology?
Ballista can test a function by calling the function with various values for input parameters. Templates are where those values are defined.

What is a data type template?
A template is a file that is interpreted by the ballista compiler. The template enumerates values that should be tested for a given data type. The best way to understand templates is to learn by example.

Example template file: b_float.tpl
Ballista data type template files end in ".tpl". The file name must match the name of the dataType being defined with the addition of the suffix .tpl. Naturally, b_float.tpl is a template for a very basic data type...float. Let's look at the b_float.tpl. Comments beginning with "//" are used to explain what is going on.

//This line defines the name of the Ballista data type
//being implemented by this template file. "name" is a
//directive to the Ballista data type compiler, and
//must be present at the top of the file. "float" tells
//the compiler that all values generated by the template
//code for b_float will be float. We named the data type
//"b_float".
name float b_float;

//Ballista data types are object oriented, and must have a
//parent data type. "parent" is a compiler directive and
//must be present. Since b_float really has no parent data type
//outside the compiler, the default parent "paramAccess" is
//used.
parent paramAccess;

includes
[
{
#include "values.h" //for digital unix
#include "bTypes.h"
#include <math.h>
}
]

//All Ballista data types should include the file "bTypes.h".
//Any system dependent headers should also be listed here.
//Any headers required for code executed by a data type should
//be included. For example, if I wanted to generate a
//value later in this file with sqrt(64), I would have to
// include math.h.

global_defines
[
{

//Any defines used in code later in this file should be defined
//here.

}
]

//"dials" is a keyword that tells the compiler that a list of dial settings for
//the b_float data type will follow. The primary kind of dial is an "enum_dial"
//(enumerated dial). In the following code, an enumerated dial named HVAL is
// created, and the names of the dial settings are specified. "HVAL"is an
//arbitrary name. It might just as well be called "BOB". Each of the dial
//settings are given a name that is indicative of the value that b_float will
//hold when Ballista fills in its value. As you can see, these are all common
//values for a float, for example, ONE or ZERO.
dials
[

enum_dial HVAL : ZERO, ONE, NEGONE, FMINEXP, MLN2, MPI, HALF_PI, QUARTER_PI, TWO_PI, MSQRT2, E, MAXFLOAT, MINFLOAT, NEGMAXFLOAT, NEGMINFLOAT;

]

//"access" is a keyword telling the Ballista compiler that a bunch of code
//fragments will follow. The code fragments are used to generate values when
// the compiler tries to access a dial setting (enumerated above) for b_float.
access
[
//the following code fragments assign a value for each of the dial settings.
//you can put any code you want inside the curly braces. But, the final result
//must assign a value to "_theVariable" which is literally the variable that
//the compiler stores the value of b_float in.

ZERO
{
_theVariable = 0.0;
}

ONE
{
_theVariable = 1.0;
}

NEGONE
{
_theVariable = -1.0;
}

FMINEXP
{
_theVariable=_theVariable=FMINEXP; // (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
}

MLN2
{
_theVariable=_theVariable=M_LN2; // 6.9314718055994530942E-1 /*Hex 2^-1 * 1.62E42FEFA39EF */
}

MPI
{
_theVariable=M_PI;// 3.1415926535897932385E0 /*Hex 2^ 1 * 1.921FB54442D18 */
}

HALF_PI
{
_theVariable=M_PI/2;
}

QUARTER_PI
{
_theVariable=M_PI/4;
}

TWO_PI
{
_theVariable=M_PI * 2.0;
}

MSQRT2
{
_theVariable=M_SQRT2;// 1.4142135623730950488E0 /*Hex 2^ 0 * 1.6A09E667F3BCD */
}

E
{
_theVariable=M_E; //2.718281828459045235360287
}

MAXFLOAT
{
_theVariable=MAXFLOAT;
}

MINFLOAT
{
_theVariable=MINFLOAT;
}

NEGMAXFLOAT
{
_theVariable=-MAXFLOAT;
}

NEGMINFLOAT
{
theVariable=-MINFLOAT;
}

]

//"commit" is not used in this template but will be explained in a more
//detailed example.
commit
[
]

//"cleanup" is a keyword that tells the compiler that code used to cleanup
//any resources allocated previously, follows. In this simple example, b_float
//uses no resources, so there is nothing to cleanup.
cleanup
[
]

Congratulations! You now know how to write a simple Ballista datatype. To learn how to use inheritance in your data types, or to see examples of datatypes that allocate resources and then free them, move forward.