Beispiel #1
0
// this is the fn parameter passed into file_list()
int file_list_callback(const char *path, bool dir, long mod, void *fl_context)
{
    // -> /
    path = remove_substring(path, "//");
    //printf("file_list_callback %s\n", path);
    size_t size = file_size(path);
    path = remove_substring(path, hal_doc_path(NULL));

    struct file_list_context *flc = (struct file_list_context*)fl_context;
    struct variable *path3 = variable_new_str_chars(flc->context, path);

    struct variable *key2 = variable_new_str_chars(flc->context, RESERVED_DIR);
    struct variable *value = variable_new_bool(flc->context, dir);
    struct variable *metadata = variable_new_list(flc->context, NULL);
    variable_map_insert(flc->context, metadata, key2, value);

    key2 = variable_new_str_chars(flc->context, RESERVED_MODIFIED);
    value = variable_new_int(flc->context, (int32_t)mod);
    variable_map_insert(flc->context, metadata, key2, value);
    variable_map_insert(flc->context, flc->result, path3, metadata);

    key2 = variable_new_str_chars(flc->context, RESERVED_SIZE);
    value = variable_new_int(flc->context, (int32_t)size);
    variable_map_insert(flc->context, metadata, key2, value);
    variable_map_insert(flc->context, flc->result, path3, metadata);

    return 0;
}
Beispiel #2
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;
}
Beispiel #3
0
struct variable *sys_file_list(struct context *context)
{
    struct variable *arguments = (struct variable*)stack_pop(context->operand_stack);
    struct variable *path = array_get(arguments->list.ordered, 1);
    const char *path2 = hal_doc_path(path->str);

    struct variable *result = variable_new_list(context, NULL);
    struct file_list_context flc = {context, result};

    file_list(path2, &file_list_callback, &flc);
    return flc.result;
}
Beispiel #4
0
struct variable *sys_new(struct context *context)
{
    struct variable *sys = variable_new_list(context, NULL);

    for (int i=0; i<ARRAY_LEN(builtin_funcs); i++)
    {
        struct variable *key = variable_new_str_chars(context, builtin_funcs[i].name);
        struct variable *value = variable_new_cfnc(context, builtin_funcs[i].func);
        variable_map_insert(context, sys, key, value);
    }

    return sys;
}
Beispiel #5
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;
}
Beispiel #6
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;
}
Beispiel #7
0
static void push_list(struct context *context, struct byte_array *program)
{
    int32_t num_items = serial_decode_int(program);
    DEBUGPRINT("LST %d", num_items);
    if (!context->runtime)
        VM_DEBUGPRINT("\n");
    struct array *items = array_new();

    struct map *map = NULL;
    while (num_items--) {
        struct variable* v = variable_pop(context);
        if (v->type == VAR_MAP) {
            if (!map)
                map = map_new(context, NULL);
            map_update(map, v->map); // mapped values are stored in the map, not list
        }
        else
            array_insert(items, 0, v);
    }
    struct variable *list = variable_new_list(context, items);
    list->map = map;
    DEBUGPRINT(": %s\n", variable_value_str(context, list));
    variable_push(context, list);
}
Beispiel #8
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;
}