Next: A Better Sequence Library, Up: Sample Libraries [Index]
The sequence library provides a single ‘sequence’ function, admitting no arguments and evaluating to an ever greater integer.
The value to which the ‘sequence’ function last evaluated is stored with the sequence library object (storing the value is the sole reason for which a library object exists).
The only three required methods of the struct x1f4_lxnote_type
library
definition are the library object constructor and destructor, and the list of
functions provider:
static struct x1f4_lxnote_type sequence_note;
sequence_note.fini = fini_sequence; sequence_note.fset = fset_sequence; sequence_note.tile = tile_sequence;
The library object stores the sequence current and the function definitions (which are not constant, for they refer the library object):
typedef struct library_type { int sequence; struct x1f4_linetext_type functions[2]; } library_type;
The library destructor frees reserved memory:
static int fini_sequence(void **sequence) { free(*sequence); return 0; }
The list of functions provider stores the functions array address:
static int fset_sequence(void *sequence, const struct x1f4_linetext_type **linetext) { *linetext = ((struct library_type *) sequence)->functions; return 0; }
The library object constructor reserves memory and sets the sequence initial value and the function definitions:
static int tile_sequence(void **sequence, unsigned wide_bits, struct x1f4_lxwide_type *lxwide_data, unsigned bits, const void *data) { int status; struct library_type *library_data; library_data = malloc(sizeof(struct library_type)); if (library_data) {
Sequence initial value is 0:
library_data->sequence = 0;
Only one function is made available by the library. The second definition serves as an end of list marker:
See struct x1f4_function_type.
See struct x1f4_linetext_type.
library_data->functions[0].context = library_data; library_data->functions[0].function.args = NULL; library_data->functions[0].function.count = 0;
Add to the function description that its calls cannot be skipped (optimized away, etc) and that is has a specific execution context:
See Function Flags.
See Per Function Execution Context.
library_data->functions[0].function.flags = X1f4_E4_KEEP_CALL | X1f4_E4_TEXT_LINK; library_data->functions[0].function.function = mode_sequence; library_data->functions[0].function.length = 8; library_data->functions[0].function.name = "sequence"; library_data->functions[0].function.type = X1f4_E4_MODE; library_data->functions[1].function.name = NULL; *sequence = library_data; status = 0; } else { status = -1; } return status; }
The C routine supporting the exported aime function stores the sequence current value before incrementing it:
static int mode_sequence(void *context, void *output, void **input) { X1f4_E4_C_MODE *l; struct library_type *library_data; library_data = *(void **) context; l = output; *l = library_data->sequence; library_data->sequence++; return 0; }
The library object interface provider as required by the executive assembler:
See Executive Assembler.
int note_sequence(const struct x1f4_lxnote_type **lxnote) { *lxnote = &sequence_note; return 0; }
Next: A Better Sequence Library, Up: Sample Libraries [Index]