Example #1
0
// FOR who IN what WHERE where DO how
static bool iterate(struct context *context,
                    enum Opcode op,
                    struct program_state *state,
                    struct byte_array *program)
{
    struct byte_array *who = serial_decode_string(program);
    struct byte_array *where = serial_decode_string(program);
    struct byte_array *how = serial_decode_string(program);

#ifdef DEBUG
    DEBUGPRINT("%s %s\n",
               NUM_TO_STRING(opcodes, op),
               byte_array_to_string(who));
    if (!context->runtime) {
        if (where && where->length) {
            DEBUGPRINT("%s\tWHERE\n", indentation(context));
            display_code(context, where);
        }
        DEBUGPRINT("%s\tDO\n", indentation(context));
        display_code(context, how);
        return false;
    }
#endif

    bool comprehending = (op == VM_COM);
    struct variable *result = comprehending ? variable_new_list(context, NULL) : NULL;

    struct variable *what = variable_pop(context);
    uint32_t len = variable_length(context, what);
    for (int i=0; i<len; i++) {

        struct variable *that = list_get_int(context, what, i);
        set_named_variable(context, state, who, that);

        byte_array_reset(where);
        byte_array_reset(how);
        if (where && where->length)
            run(context, where, NULL, true);
        if (!where || !where->length || test_operand(context)) {

            if (run(context, how, NULL, true)) // true if run hit VM_RET
                return true;

            if (comprehending) {
                struct variable *item = (struct variable*)stack_pop(context->operand_stack);
                array_add(result->list, item);
            }
        }
    }

    if (comprehending)
        stack_push(context->operand_stack, result);
    return false;
}
Example #2
0
int compar(struct context *context, const void *a, const void *b, struct variable *comparator)
{
    struct variable *av = *(struct variable**)a;
    struct variable *bv = *(struct variable**)b;

    if (comparator) {

        byte_array_reset(comparator->str);
        vm_call(context, comparator, av, bv, NULL);

        struct variable *result = (struct variable*)stack_pop(context->operand_stack);
        if (result->type == VAR_SRC)
            result = array_get(result->list.ordered, 0);
        assert_message(result->type == VAR_INT, "non-integer comparison result");
        return result->integer;

    } else {

        enum VarType at = av->type;
        enum VarType bt = bv->type;

        if (at == VAR_INT && bt == VAR_INT) {
            // DEBUGPRINT("compare %p:%d to %p:%d : %d\n", av, av->integer, bv, bv->integer, av->integer - bv->integer);
            return av->integer - bv->integer;
        } else
            DEBUGPRINT("can't compare %s to %s\n", var_type_str(at), var_type_str(bt));

        vm_exit_message(context, "incompatible types for comparison");
        return 0;
    }
}
Example #3
0
static inline struct variable *cfnc_serialize(struct context *context)
{
    struct variable *args = (struct variable*)stack_pop(context->operand_stack);
    struct variable *indexable = (struct variable*)array_get(args->list.ordered, 0);

    struct byte_array *bits = variable_serialize(context, NULL, indexable);
    byte_array_reset(bits);
    struct variable *result = variable_new_str(context, bits);
    byte_array_del(bits);
    return result;
}
Example #4
0
void display_program(struct byte_array *program)
{
    struct context *context = context_new(false);

    INDENT
    DEBUGPRINT("%sprogram bytes:\n", indentation(context));

    INDENT
    for (int i=0; i<program->length; i++)
        DEBUGPRINT("%s%2d:%3d\n", indentation(context), i, program->data[i]);
    UNDENT

    DEBUGPRINT("%sprogram instructions:\n", indentation(context));
    byte_array_reset(program);
    display_code(context, program);

    UNDENT
    UNDENT
}
Example #5
0
void execute(struct byte_array *program, find_c_var *find)
{
#ifdef DEBUG
    display_program(program);
#endif

    DEBUGPRINT("execute:\n");
    null_check(program);
    program = byte_array_copy(program);
    byte_array_reset(program);

    struct context *context = context_new(false);
    context->find = find;
#ifdef DEBUG
    context->indent = 1;
#endif
    if (!setjmp(trying))
        run(context, program, NULL, false);

    assert_message(stack_empty(context->operand_stack), "operand stack not empty");
}