Ejemplo n.º 1
0
struct byte_array *byte_array_part(struct byte_array *within, uint32_t start, uint32_t length) {
    struct byte_array *p = byte_array_copy(within);
    byte_array_remove(p, start+length, within->length-start-length);
    byte_array_remove(p, 0, start);
    byte_array_resize(p, p->length);
    return p;
}
Ejemplo n.º 2
0
struct chr_val_array *chr_val_array_create(struct byte_array *name)
{
        struct chr_val_array *result = check_malloc(sizeof(*result));
        result->refs = 1;
        result->name = byte_array_copy(name);
        result->length = 0;
        result->capacity = START_CAPABILITY;
        result->items = check_calloc(START_CAPABILITY, sizeof(struct chr_val *));

        return result;
}
Ejemplo n.º 3
0
struct byte_array *byte_array_concatenate(int n, const struct byte_array* ba, ...)
{
    struct byte_array* result = byte_array_copy(ba);

    va_list argp;
    for(va_start(argp, ba); --n;) {
        struct byte_array* parameter = va_arg(argp, struct byte_array* );
        if (parameter == NULL)
            continue;
        assert_message(result->length + parameter->length < BYTE_ARRAY_MAX_LEN, ERROR_BYTE_ARRAY_LEN);
        byte_array_append(result, parameter);
    }

    va_end(argp);

    if (result)
        result->current = result->data + result->length;
    return result;
}
Ejemplo n.º 4
0
struct byte_array *byte_array_replace_all(struct byte_array *original, struct byte_array *a, struct byte_array *b)
{
    /*DEBUGPRINT("replace in %s: %s -> %s\n",
               byte_array_to_string(original),
               byte_array_to_string(a),
               byte_array_to_string(b));*/

    struct byte_array *replaced = byte_array_copy(original);
    int32_t where = 0;

    for(;;) { // replace all

        if ((where = byte_array_find(replaced, a, where)) < 0)
            break;
        struct byte_array *replaced2 = byte_array_replace(replaced, b, where++, a->length);
        byte_array_del(replaced);
        replaced = replaced2;
    }
    return replaced;
}
Ejemplo n.º 5
0
static inline struct variable *cfnc_insert(struct context *context) // todo: test
{
    struct variable *args = (struct variable*)stack_pop(context->operand_stack);
    struct variable *self = (struct variable*)array_get(args->list.ordered, 0);
    struct variable *insertion = (struct variable*)array_get(args->list.ordered, 1);
    struct variable *start = args->list.ordered->length > 2 ?
        (struct variable*)array_get(args->list.ordered, 2) : NULL;
    null_check(self);
    null_check(insertion);
    assert_message(!start || start->type == VAR_INT, "non-integer index");

    int32_t position = 0;
    switch (self->type) {
        case VAR_LST: {
            struct array *list = array_new_size(1);
            array_set(list, 0, insertion);
            insertion = variable_new_list(context, list);
            position = self->list.ordered->length;
            array_del(list);
        } break;
        case VAR_STR:
            assert_message(insertion->type == VAR_STR, "insertion doesn't match destination");
            position = self->str->length;
            break;
        default:
            exit_message("bad insertion destination");
            break;
    }

    struct variable *first = variable_part(context, variable_copy(context, self), 0, position);
    struct variable *second = variable_part(context, variable_copy(context, self), position, -1);
    struct variable *joined = variable_concatenate(context, 3, first, insertion, second);
    
    if (self->type == VAR_LST) {
        array_del(self->list.ordered);
        self->list.ordered = array_copy(joined->list.ordered);
    } else {
        byte_array_del(self->str);
        self->str = byte_array_copy(joined->str);
    } return joined;
}
Ejemplo n.º 6
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");
}
Ejemplo n.º 7
0
struct variable* variable_set(struct context *context, struct variable *dst, const struct variable* src)
{
    vm_null_check(context, dst);
    vm_null_check(context, src);
    switch (src->type) {
        case VAR_NIL:                                           break;
        case VAR_BOOL:  dst->boolean = src->boolean;            break;
        case VAR_INT:   dst->integer = src->integer;            break;
        case VAR_FLT:   dst->floater = src->floater;            break;
        case VAR_C:     dst->cfnc = src->cfnc;                  break;
        case VAR_FNC:
        case VAR_BYT:
        case VAR_STR:   dst->str = byte_array_copy(src->str);   break;
        case VAR_MAP:   dst->map = src->map;                    break;
        case VAR_SRC:
        case VAR_LST:   dst->list = src->list;                  break;
        default:
            vm_exit_message(context, "bad var type");
            break;
    }
    dst->map = src->map;
    dst->type = src->type;
    return dst;
}
Ejemplo n.º 8
0
bool run(struct context *context,
         struct byte_array *program,
         struct map *env,
         bool in_context)
{
    null_check(context);
    null_check(program);
    program = byte_array_copy(program);
    program->current = program->data;
    struct program_state *state = NULL;
    enum Opcode inst = VM_NIL;
    if (context->runtime) {
        if (in_context) {
            if (!state)
                state = (struct program_state*)stack_peek(context->program_stack, 0);
            env = state->named_variables; // use the caller's variable set in the new state
        }
        else
            state = program_state_new(context, env);
    }

    while (program->current < program->data + program->length) {
        inst = (enum Opcode)*program->current;
        bool really = inst & VM_RLY;
        inst &= ~VM_RLY;
#ifdef DEBUG
        display_program_counter(context, program);
#endif
        program->current++; // increment past the instruction
        int32_t pc_offset = 0;

        switch (inst) {
            case VM_COM:
            case VM_ITR:    if (iterate(context, inst, state, program)) goto done;  break;
            case VM_RET:    if (ret(context, program))                  goto done;  break;
            case VM_TRO:    if (tro(context))                           goto done;  break;
            case VM_TRY:    if (vm_trycatch(context, program))          goto done;  break;
            case VM_EQU:
            case VM_MUL:
            case VM_DIV:
            case VM_ADD:
            case VM_SUB:
            case VM_NEQ:
            case VM_GTN:
            case VM_LTN:
            case VM_GRQ:
            case VM_LEQ:
            case VM_BND:
            case VM_BOR:
            case VM_MOD:
            case VM_XOR:
            case VM_INV:
            case VM_RSF:
            case VM_LSF:    binary_op(context, inst);                       break;
            case VM_ORR:
            case VM_AND:    pc_offset = boolean_op(context, program, inst); break;
            case VM_NEG:
            case VM_NOT:    unary_op(context, inst);                        break;
            case VM_SRC:    src(context, inst, program);                    break;
            case VM_DST:    dst(context, really);                           break;
            case VM_STX:
            case VM_SET:    set(context, inst, state, program);             break;
            case VM_JMP:    pc_offset = jump(context, program);             break;
            case VM_IFF:    pc_offset = iff(context, program);              break;
            case VM_CAL:    func_call(context, inst, program, NULL);        break;
            case VM_LST:    push_list(context, program);                    break;
            case VM_MAP:    push_map(context, program);                     break;
            case VM_NIL:    push_nil(context);                              break;
            case VM_INT:    push_int(context, program);                     break;
            case VM_FLT:    push_float(context, program);                   break;
            case VM_BUL:    push_bool(context, program);                    break;
            case VM_STR:    push_str(context, program);                     break;
            case VM_VAR:    push_var(context, program);                     break;
            case VM_FNC:    push_fnc(context, program);                     break;
            case VM_GET:    list_get(context, really);                      break;
            case VM_PTX:
            case VM_PUT:    list_put(context, inst, really);                break;
            case VM_MET:    method(context, program, really);               break;
            default:
                vm_exit_message(context, ERROR_OPCODE);
                return false;
        }
        program->current += pc_offset;
    }

    if (!context->runtime)
        return false;
done:
    if (!in_context)
        stack_pop(context->program_stack);
    return inst == VM_RET;
}