8. Metaprogramming

Rather than use some kind of assembly language parser, seqvm is designed to be metaprogrammed from an already existing programming environment via C commands.

8.1. Insert

seqvm_insert is used to insert a command at a specified position. It will return the next position, usually pos + 1. If there is no next position, a negative value is returned.

<<funcdefs>>=
int seqvm_insert(seqvm *svm, int pos, int cmd, int a, int b, int c);
<<funcs>>=
int seqvm_insert(seqvm *svm, int pos, int cmd, int a, int b, int c)
{
    if (pos < 0) return -1;
    if (pos >= (svm->size - 1)) return -1;

    svm->pool[pos].cmd = cmd;
    svm->pool[pos].p[0] = a;
    svm->pool[pos].p[1] = b;
    svm->pool[pos].p[2] = c;
    return pos + 1;
}

seqvm_insert0, seqvm_insert1, seqvm_insert2, and seqvm_insert3 wrap the seqvm_insert command and insert N arguments, making the extra arguments 0.

<<funcdefs>>=
int seqvm_insert0(seqvm *svm, int pos, int cmd);
int seqvm_insert1(seqvm *svm, int pos, int cmd, int a);
int seqvm_insert2(seqvm *svm, int pos, int cmd, int a, int b);
int seqvm_insert3(seqvm *svm, int pos, int cmd, int a, int b, int c);
<<funcs>>=
int seqvm_insert0(seqvm *svm, int pos, int cmd)
{
    return seqvm_insert(svm, pos, cmd, 0, 0, 0);
}

int seqvm_insert1(seqvm *svm, int pos, int cmd, int a)
{
    return seqvm_insert(svm, pos, cmd, a, 0, 0);
}

int seqvm_insert2(seqvm *svm, int pos, int cmd, int a, int b)
{
    return seqvm_insert(svm, pos, cmd, a, b, 0);
}

int seqvm_insert3(seqvm *svm, int pos, int cmd, int a, int b, int c)
{
    return seqvm_insert(svm, pos, cmd, a, b, c);
}

8.2. cmd

Adding a command via text string is done via seqvm_cmd. Useful for things like LIL integration.

<<funcdefs>>=
int seqvm_cmd(seqvm *svm, int *pos,
              const char *cmd,
              int a, int b, int c);
<<funcs>>=
#define ISCMD(val) else if (!strcmp(cmd, val))
int seqvm_cmd(seqvm *svm, int *pos,
              const char *cmd,
              int a, int b, int c)
{
    if (*pos >= svm->size || *pos < 0) return 2;

    if (0) {
        /* this makes patterning easier */
    }
<<seqvm_cmd>>
    else {
        /* can't find anything */
        return 1;
    }

    return 0;
}
#undef ISCMD



prev | home | next