Example #1
0
static void *default_copyor(const void *key, void *context)
{
    struct variable *v = (struct variable *)key;
    struct variable *u = variable_copy((struct context *)context, v);
    variable_old(u);
    return u;
}
Example #2
0
static void push_fnc(struct context *context, struct byte_array *program)
{
    uint32_t num_closures = serial_decode_int(program);
    struct map *closures = NULL;

    for (int i=0; i<num_closures; i++) {
        struct byte_array *name = serial_decode_string(program);
        if (context->runtime) {
            if (!closures)
                closures = map_new();
            struct variable *c = find_var(context, name);
            c = variable_copy(context, c);
            map_insert(closures, name, c);
        }
    }

    struct byte_array *body = serial_decode_string(program);

    DEBUGPRINT("FNC %u,%u\n", num_closures, body->length);
    //display_code(context, body);

    if (context->runtime) {
        struct variable *f = variable_new_fnc(context, body, closures);
        variable_push(context, f);
    }
}
Example #3
0
// arguments most recently passed into a function
struct variable *sys_args(struct context *context)
{
    stack_pop(context->operand_stack); // self
    struct program_state *above = (struct program_state*)stack_peek(context->program_stack, 1);
    struct variable *result = variable_copy(context, above->args);
    result->type = VAR_LST;
    return result;
}
Example #4
0
struct variable *sys_listen(struct context *context)
{
    struct variable *arguments = (struct variable*)stack_pop(context->operand_stack);
    struct listen_arguments *la = (struct listen_arguments*)malloc(sizeof(struct listen_arguments));
    la->serverport = param_int(arguments, 1);
    la->listener = variable_copy(context, (struct variable*)array_get(arguments->list, 2));
    
    pthread_t child;
    pthread_create(&child, NULL, sys_listen2, la);
    return NULL;
}
Example #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;
}
Example #6
0
void set_named_variable(struct context *context,
                        struct program_state *state,
                        const struct byte_array *name,
                        const struct variable *value)
{
    // DEBUGPRINT(" set_named_variable: %p\n", state);
    if (!state)
        state = (struct program_state*)stack_peek(context->program_stack, 0);
    struct map *var_map = state->named_variables;
    struct variable *to_var = variable_copy(context, value);
    map_insert(var_map, name, to_var);

    //DEBUGPRINT("SET %s to %s\n", byte_array_to_string(name), variable_value_str(context, value));
    // DEBUGPRINT(" SET %s at %p in {p:%p, s:%p, m:%p}\n", byte_array_to_string(name), to_var, context->program_stack, state, var_map);
}
Example #7
0
struct variable *variable_map_list(struct context *context,
                                   struct variable *indexable,
                                   struct array* (*map_list)(const struct map*))
{
    assert_message(indexable->type == VAR_LST, "values are only for list");
    struct variable *result = variable_new_list(context, NULL);
    if (NULL != indexable->list.map) {
        struct array *a = map_list(indexable->list.map);
        for (int i=0; i<a->length; i++) {
            struct variable *u = variable_copy(context, (struct variable*)array_get(a, i));
            array_add(result->list.ordered, u);
        }
        array_del(a);
    }
    return result;
}
Example #8
0
static struct variable *binary_op_lst(struct context *context,
                                      enum Opcode op,
                                      const struct variable *u,
                                      const struct variable *v)
{
    vm_assert(context, u->type==VAR_LST && v->type==VAR_LST, "list op with non-lists");
    struct variable *w = NULL;

    switch (op) {
        case VM_ADD:
            w = variable_copy(context, v);
            for (int i=0; i<u->list->length; i++)
                array_add(w->list, array_get(u->list, i));
            map_update(w->map, u->map);
            break;
        default:
            return (struct variable*)vm_exit_message(context, "unknown string operation");
    }

    return w;
}
Example #9
0
static struct variable *binary_op_nil(struct context *context,
                                      enum Opcode op,
                                      const struct variable *u,
                                      const struct variable *v)
{
    vm_assert(context, u->type==VAR_NIL || v->type==VAR_NIL, "nil op with non-nils");
    if (v->type == VAR_NIL && u->type != VAR_NIL)
        return binary_op_nil(context, op, v, u); // 1st var should be nil

    switch (op) {
        case VM_EQU:    return variable_new_bool(context, v->type == u->type);
        case VM_NEQ:    return variable_new_bool(context, v->type != u->type);
        case VM_ADD:
        case VM_SUB:    return variable_copy(context, v);
        case VM_LTN:
        case VM_GTN:
        case VM_LEQ:
        case VM_GRQ: return variable_new_bool(context, false);
        default:
            return vm_exit_message(context, "unknown binary nil op");
    }
}
Example #10
0
struct variable *builtin_method(struct context *context,
                                struct variable *indexable,
                                const struct variable *index)
{
    enum VarType it = indexable->type;
    char *idxstr = byte_array_to_string(index->str);
    struct variable *result = NULL;

    if (!strcmp(idxstr, FNC_LENGTH)) {
        int n;
        switch (indexable->type) {
            case VAR_LST: n = indexable->list.ordered->length;  break;
            case VAR_STR: n = indexable->str->length;           break;
            case VAR_NIL: n = 0;                                break;
            default:
                free(idxstr);
                exit_message("no length for non-indexable");
                return NULL;
        }
        result = variable_new_int(context, n);
    }
    else if (!strcmp(idxstr, FNC_TYPE)) {
        const char *typestr = var_type_str(it);
        result = variable_new_str_chars(context, typestr);
    }

    else if (!strcmp(idxstr, FNC_STRING)) {
        switch (indexable->type) {
            case VAR_STR:
            case VAR_BYT:
            case VAR_FNC:
                result = variable_copy(context, indexable);
                break;
            default: {
                struct byte_array *vv = variable_value(context, indexable);
                result = variable_new_str(context, vv);
                byte_array_del(vv);
                break;
            }
        }
    }

    else if (!strcmp(idxstr, FNC_LIST))
        result = variable_new_list(context, indexable->list.ordered);

    else if (!strcmp(idxstr, FNC_KEY)) {
        if (indexable->type == VAR_KVP)
            result = indexable->kvp.key;
        else
            result = variable_new_nil(context);
    }

    else if (!strcmp(idxstr, FNC_VAL)) {
        if (indexable->type == VAR_KVP)
            result = indexable->kvp.val;
        else
            result = variable_new_nil(context);
    }

    else if (!strcmp(idxstr, FNC_KEYS))
        result = variable_map_list(context, indexable, &map_keys);

    else if (!strcmp(idxstr, FNC_VALS))
        result = variable_map_list(context, indexable, &map_vals);

    else if (!strcmp(idxstr, FNC_PACK))
        result = variable_new_cfnc(context, &cfnc_pack);

    else if (!strcmp(idxstr, FNC_SERIALIZE))
        result = variable_new_cfnc(context, &cfnc_serialize);
    
    else if (!strcmp(idxstr, FNC_DESERIALIZE))
        result = variable_new_cfnc(context, &cfnc_deserialize);

    else if (!strcmp(idxstr, FNC_SORT)) {
        assert_message(indexable->type == VAR_LST, "sorting non-list");
        result = variable_new_cfnc(context, &cfnc_sort);
    }

    else if (!strcmp(idxstr, FNC_CHAR))
        result = variable_new_cfnc(context, &cfnc_char);

    else if (!strcmp(idxstr, FNC_HAS))
        result = variable_new_cfnc(context, &cfnc_has);

    else if (!strcmp(idxstr, FNC_FIND))
        result = variable_new_cfnc(context, &cfnc_find);

    else if (!strcmp(idxstr, FNC_PART))
        result = variable_new_cfnc(context, &cfnc_part);

    else if (!strcmp(idxstr, FNC_REMOVE))
        result = variable_new_cfnc(context, &cfnc_remove);

    else if (!strcmp(idxstr, FNC_INSERT))
        result = variable_new_cfnc(context, &cfnc_insert);

    else if (!strcmp(idxstr, FNC_REPLACE))
        result = variable_new_cfnc(context, &cfnc_replace);

    free(idxstr);
    return result;
}