6. Operations

6.1. Append

Append an ftable with sp_ftlist_append. Returns the index position of the table.

<<funcdefs>>=
int sp_ftlist_append(sp_ftlist *ftlst, sp_ftbl *ft);
<<funcs>>=
int sp_ftlist_append(sp_ftlist *ftlst, sp_ftbl *ft)
{
    int pos;
    if (ftlst->size == 0) {
        ftlst->size = 1;
        ftlst->list = malloc(sizeof(sp_ftbl *));
    } else {
        ftlst->size++;
        ftlst->list = realloc(ftlst->list,
                              sizeof(sp_ftbl *) * ftlst->size);
    }

    pos = ftlst->size - 1;
    ftlst->list[pos] = ft;

    return pos;
}

This is implemented as a runt word called ftlist_append. It will push the table position to the stack.

<<words>>=
runt_keyword_define(vm,
                    "ftlist_append",
                    13,
                    rproc_ftlist_append,
                    NULL);
<<wordfuncs>>=
static runt_int rproc_ftlist_append(runt_vm *vm, runt_ptr p)
{
    int rc;
    sp_ftbl *ft;
    sp_ftlist *ftlst;

    rc = rgf_get_ftlist(vm, &ftlst);
    RUNT_ERROR_CHECK(rc);

    rc = rgf_get_ftable(vm, &ft);
    RUNT_ERROR_CHECK(rc);

    sp_ftlist_append(ftlst, ft);
    return RUNT_OK;
}

6.2. Choose

Set the target ftable with sp_ftlist_choose. This takes in an integer value, which is the table position of the table to be chosen. If the table is out of bounds, no operation happens.

<<funcdefs>>=
void sp_ftlist_choose(sp_ftlist *ftlst, int index);
<<funcs>>=
void sp_ftlist_choose(sp_ftlist *ftlst, int index)
{
    sp_ftbl *ft;

    if (index < 0 || index >= ftlst->size) return;

    ft = ftlst->list[index];
    ftlst->target.tbl = ft->tbl;
    ftlst->target.size = ft->size;
}

This is implemented as a runt word called ftlist_choose.

<<words>>=
runt_keyword_define(vm,
                    "ftlist_choose", 13,
                    rproc_ftlist_choose,
                    &c);
runt_cell_data(vm, c, pw);
<<wordfuncs>>=
static runt_int rproc_ftlist_choose(runt_vm *vm, runt_ptr p)
{
    int rc;
    sp_ftlist *ftlst;
    int index;
    runt_stacklet *s;

    rc = rgf_get_ftlist(vm, &ftlst);
    RUNT_ERROR_CHECK(rc);

    rc = runt_ppop(vm, &s);
    RUNT_ERROR_CHECK(rc);
    index = floor(s->f);

    sp_ftlist_choose(ftlst, index);

    return RUNT_OK;
}

A sample accurate choose is done with sp_ftlist_choose_sa. In this argument, the block position must be provided.

<<funcdefs>>=
void sp_ftlist_choose_sa(sp_ftlist *ftlst, int index, int pos);
<<funcs>>=
void sp_ftlist_choose_sa(sp_ftlist *ftlst, int index, int pos)
{
    ftlst->blockpos = pos;
    ftlst->next = index;
    sp_ftlist_choose(ftlst, index);
}

6.3. Target

This returns the target ftable.

<<funcdefs>>=
sp_ftbl* sp_ftlist_target(sp_ftlist *ftlst);
<<funcs>>=
sp_ftbl* sp_ftlist_target(sp_ftlist *ftlst)
{
    return &ftlst->target;
}

It is implemented as a word called ftlist_target, which takes in an ftlist and pushes the ftable onto the stack.

<<words>>=
runt_keyword_define(vm,
                    "ftlist_target",
                    13,
                    rproc_ftlist_target,
                    &c);
runt_cell_data(vm, c, pw);
<<wordfuncs>>=
static runt_int rproc_ftlist_target(runt_vm *vm, runt_ptr p)
{
    sp_ftlist *ftlst;
    sp_ftbl *ft;
    int rc;
    runt_stacklet *out;

    rc = rgf_get_ftlist(vm, &ftlst);
    RUNT_ERROR_CHECK(rc);

    rc = runt_ppush(vm, &out);
    RUNT_ERROR_CHECK(rc);

    ft = sp_ftlist_target(ftlst);
    rgf_stacklet_ftable(vm, out, ft);

    return RUNT_OK;
}

A sample accurate target is retrieved using the function sp_ftlist_target_sa.

<<funcdefs>>=
sp_ftbl* sp_ftlist_target_sa(sp_ftlist *ftlst, int pos);
<<funcs>>=
sp_ftbl* sp_ftlist_target_sa(sp_ftlist *ftlst, int pos)
{
    sp_ftbl *ft;

    ft = &ftlst->target;

    if (ftlst->blockpos >= 0) {
        if (pos < ftlst->blockpos) {
            if (ftlst->prev >= 0) {
                ft = ftlst->list[ftlst->prev];
            }
        } else if (ftlst->next >= 0) {
                ft = ftlst->list[ftlst->next];
        }
    }

    return ft;
}

6.4. Get

Gets an ftable at a specified position. Returns NULL on error.

<<funcdefs>>=
sp_ftbl* sp_ftlist_get(sp_ftlist *ftl, int index);
<<funcs>>=
sp_ftbl* sp_ftlist_get(sp_ftlist *ftl, int index)
{
    if (index < 0 || index >= ftl->size) return NULL;
    return ftl->list[index];
}

Implemented as a runt word ftlist_get.

<<words>>=
runt_keyword_define(vm,
                    "ftlist_get", 10,
                    rproc_ftlist_get, &c);
runt_cell_data(vm, c, pw);
<<wordfuncs>>=
static runt_int rproc_ftlist_get(runt_vm *vm, runt_ptr p)
{
    sp_ftlist *ftlst;
    sp_ftbl *ft;
    int rc;
    int index;
    runt_stacklet *s;
    runt_stacklet *out;

    rc = rgf_get_ftlist(vm, &ftlst);
    RUNT_ERROR_CHECK(rc);

    rc = runt_ppop(vm, &s);
    RUNT_ERROR_CHECK(rc);
    index = floor(s->f);

    rc = runt_ppush(vm, &out);
    RUNT_ERROR_CHECK(rc);

    ft = sp_ftlist_get(ftlst, index);

    if (ft == NULL) {
        runt_print(vm, "ftlist_get: invalid index %d\n", index);
        return RUNT_NOT_OK;
    }

    rgf_stacklet_ftable(vm, out, ft);
    return RUNT_OK;
}



prev | home | next