Exemple #1
0
/**
 * 複製
 */
int map_dup(Value *vret, Value *v, RefNode *node)
{
    RefMap *src = Value_vp(*v);
    RefNode *type = FUNC_VP(node);
    int i;
    int max = src->entry_num;
    RefMap *dst = buf_new(type, sizeof(RefMap));

    *vret = vp_Value(dst);
    dst->count = src->count;
    dst->entry_num = max;
    dst->entry = malloc(sizeof(HashValueEntry*) * max);

    for (i = 0; i < max; i++) {
        HashValueEntry *hsrc = src->entry[i];
        HashValueEntry **hdst = &dst->entry[i];
        for (; hsrc != NULL; hsrc = hsrc->next) {
            HashValueEntry *he = malloc(sizeof(HashValueEntry));

            he->key = Value_cp(hsrc->key);
            he->val = Value_cp(hsrc->val);
            he->hash = hsrc->hash;
            *hdst = he;
            hdst = &he->next;
        }
        *hdst = NULL;
    }

    return TRUE;
}
Exemple #2
0
static int textio_new(Value *vret, Value *v, RefNode *node)
{
    RefTextIO *tio;
    RefCharset *cs = Value_vp(v[2]);
    Ref *r = ref_new(fs->cls_textio);
    *vret = vp_Value(r);

    tio = buf_new(NULL, sizeof(RefTextIO));
    r->v[INDEX_TEXTIO_TEXTIO] = vp_Value(tio);
    r->v[INDEX_TEXTIO_STREAM] = Value_cp(v[1]);

    tio->in.ic = (void*)-1;
    tio->out.ic = (void*)-1;
    tio->cs = cs;
    tio->trans = FALSE;

    if (fg->stk_top > v + 3 && Value_bool(v[3])) {
        tio->trans = TRUE;
    }
    if (fg->stk_top > v + 4) {
        r->v[INDEX_TEXTIO_NEWLINE] = Value_cp(v[4]);
    }

    return TRUE;
}
Exemple #3
0
static int mapentry_new(Value *vret, Value *v, RefNode *node)
{
    Ref *r = ref_new(fv->cls_entry);
    *vret = vp_Value(r);
    r->v[INDEX_ENTRY_KEY] = Value_cp(v[1]);
    r->v[INDEX_ENTRY_VAL] = Value_cp(v[2]);
    return TRUE;
}
Exemple #4
0
static void v_ctextio_init(void)
{
    Ref *ref = ref_new(fs->cls_textio);

    fg->v_ctextio = vp_Value(ref);
    ref->v[INDEX_TEXTIO_STREAM] = Value_cp(fg->v_cio);
    ref->v[INDEX_TEXTIO_TEXTIO] = vp_Value(fv->ref_textio_utf8);
}
Exemple #5
0
static int stdout_printf(Value *vret, Value *v, RefNode *node)
{
    if (fg->v_ctextio == VALUE_NULL) {
        v_ctextio_init();
    }
    *v = Value_cp(fg->v_ctextio);

    return textio_printf(vret, v, node);
}
Exemple #6
0
// a.get("hoge", "Not Exist") -> "Not Exist"
int map_get(Value *vret, Value *v, RefNode *node)
{
    RefMap *rm = Value_vp(*v);
    HashValueEntry *ep = NULL;
    Value key = v[1];

    if (!refmap_get(&ep, rm, key)) {
        return FALSE;
    }
    if (ep != NULL) {
        // 一致
        *vret = Value_cp(ep->val);
    } else {
        if (v + 2 < fg->stk_top) {
            *vret = Value_cp(v[2]);
        }
    }
    return TRUE;
}
Exemple #7
0
/**
 * 検索して見つかった場合/見つからなかった場合は
 * 1.true/falseを返す
 * 2.index/nullを返す
 */
int map_index_of(Value *vret, Value *v, RefNode *node)
{
    RefMap *rm = Value_vp(*v);
    int ret_index = FUNC_INT(node);
    Value v1 = v[1];
    RefNode *type = Value_type(v1);
    int i;

    RefNode *fn_eq = Hash_get_p(&type->u.c.h, fs->symbol_stock[T_EQ]);
    if (fn_eq == NULL) {
        throw_error_select(THROW_NO_MEMBER_EXISTS__NODE_REFSTR, type, fs->symbol_stock[T_EQ]);
        return FALSE;
    }

    rm->lock_count++;
    for (i = 0; i < rm->entry_num; i++) {
        HashValueEntry *ep = rm->entry[i];
        for (; ep != NULL; ep = ep->next) {
            Value va = ep->val;

            if (Value_type(va) == type) {
                if (type == fs->cls_str) {
                    if (refstr_eq(Value_vp(v1), Value_vp(va))) {
                        break;
                    }
                } else {
                    Value_push("vv", v1, va);
                    if (!call_function(fn_eq, 1)) {
                        goto ERROR_END;
                    }
                    fg->stk_top--;
                    if (Value_bool(*fg->stk_top)) {
                        unref(*fg->stk_top);
                        if (ret_index) {
                            *vret = Value_cp(ep->key);
                        } else {
                            *vret = VALUE_TRUE;
                        }
                        return TRUE;
                    }
                }
            }
        }
    }
    if (!ret_index) {
        *vret = VALUE_FALSE;
    }

    rm->lock_count--;
    return TRUE;
ERROR_END:
    rm->lock_count--;
    return FALSE;
}
Exemple #8
0
static int mapiter_next(Value *vret, Value *v, RefNode *node)
{
    Ref *r = Value_ref(*v);
    RefMap *map = Value_vp(r->v[INDEX_MAPITER_VAL]);
    int idx = Value_integral(r->v[INDEX_MAPITER_IDX]);
    HashValueEntry *ep = Value_ptr(r->v[INDEX_MAPITER_PTR]);

    if (ep != NULL) {
        ep = ep->next;
    }
    while (ep == NULL && idx < map->entry_num) {
        ep = map->entry[idx];
        idx++;
    }

    r->v[INDEX_MAPITER_IDX] = int32_Value(idx);
    r->v[INDEX_MAPITER_PTR] = ptr_Value(ep);

    if (ep != NULL) {
        switch (Value_integral(r->v[INDEX_MAPITER_TYPE])) {
        case ITERATOR_KEY:
            *vret = Value_cp(ep->key);
            break;
        case ITERATOR_VAL:
            *vret = Value_cp(ep->val);
            break;
        default: {
            Ref *r2 = ref_new(fv->cls_entry);
            *vret = vp_Value(r2);
            r2->v[INDEX_ENTRY_KEY] = Value_cp(ep->key);
            r2->v[INDEX_ENTRY_VAL] = Value_cp(ep->val);
            break;
        }
        }
    } else {
        throw_stopiter();
        return FALSE;
    }
    return TRUE;
}
Exemple #9
0
int map_iterator(Value *vret, Value *v, RefNode *node)
{
    RefMap *rm = Value_vp(*v);
    int type = FUNC_INT(node);
    Ref *r = ref_new(cls_mapiter);

    rm->lock_count++;
    r->v[INDEX_MAPITER_VAL] = Value_cp(*v);
    r->v[INDEX_MAPITER_TYPE] = int32_Value(type);
    r->v[INDEX_MAPITER_PTR] = ptr_Value(NULL);
    r->v[INDEX_MAPITER_IDX] = int32_Value(0);
    *vret = vp_Value(r);

    return TRUE;
}
Exemple #10
0
static int map_add_entry(Value *vret, Value *v, RefNode *node)
{
    RefMap *rm = Value_vp(*v);
    Ref *r = Value_ref(v[1]);
    HashValueEntry *ve;

    if (rm->lock_count > 0) {
        throw_error_select(THROW_CANNOT_MODIFY_ON_ITERATION);
        return FALSE;
    }
    ve = refmap_add(rm, r->v[0], TRUE, FALSE);
    if (ve == NULL) {
        return FALSE;
    }
    ve->val = Value_cp(r->v[1]);
    return TRUE;
}
Exemple #11
0
/**
 * 同じキーがあれば上書き
 * なければ追加
 * 例外発生時はNULLを返す
 * keyのカウンタを増やす
 */
HashValueEntry *refmap_add(RefMap *rm, Value key, int overwrite, int raise_error)
{
    HashValueEntry *ep, **epp;
    uint32_t hash;

    if (!map_search_sub(&epp, &hash, rm, key)) {
        return NULL;
    }

    ep = *epp;
    if (ep != NULL) {
        if (overwrite) {
            // 一致(上書き)
            if (Value_isref(ep->val)) {
                RefHeader *rh = Value_ref_header(ep->val);
                if (rh->nref > 0 && --rh->nref == 0) {
                    Value_release_ref(ep->val);
                }
            }
            ep->val = VALUE_NULL;
            return ep;
        } else {
            if (raise_error) {
                throw_errorf(fs->mod_lang, "IndexError", "Duplicate key detected");
                return NULL;
            } else {
                return ep;
            }
        }
    } else {
        // 一致しない(追加)
        ep = malloc(sizeof(HashValueEntry));
        ep->next = NULL;
        ep->hash = hash;
        ep->key = Value_cp(key);
        ep->val = VALUE_NULL;
        *epp = ep;
        rm->count++;

        if (rm->count > rm->entry_num) {
            map_grow_entry(rm);
        }
        return ep;
    }
}
Exemple #12
0
// a["hoge"]
int map_index(Value *vret, Value *v, RefNode *node)
{
    RefMap *rm = Value_vp(*v);
    HashValueEntry *ep = NULL;
    Value key = v[1];

    if (!refmap_get(&ep, rm, key)) {
        return FALSE;
    }
    if (ep != NULL) {
        // 一致
        *vret = Value_cp(ep->val);
    } else {
        throw_errorf(fs->mod_lang, "IndexError", "No keys exists %v", key);
        return FALSE;
    }

    return TRUE;
}
Exemple #13
0
static int stdout_print(Value *vret, Value *v, RefNode *node)
{
    int new_line = FUNC_INT(node);
    Value *varg = v + 1;

    if (fg->v_ctextio == VALUE_NULL) {
        v_ctextio_init();
    }
    *v = Value_cp(fg->v_ctextio);

    while (varg < fg->stk_top) {
        if (!textio_print_sub(*v, NULL, *varg, NULL)) {
            return FALSE;
        }
        varg++;
    }
    if (new_line && !stream_write_data(fg->v_cio, "\n", 1)) {
        return FALSE;
    }

    return TRUE;
}
Exemple #14
0
static int map_new_elems(Value *vret, Value *v, RefNode *node)
{
    Value *src = v + 1;
    int argc = fg->stk_top - src;
    int i;
    RefMap *rm;

    if (argc % 2 != 0) {
        throw_errorf(fs->mod_lang, "ArgumentError", "Argument count must be even");
        return FALSE;
    }

    rm = refmap_new(argc / 2);
    *vret = vp_Value(rm);
    for (i = 0; i < argc; i += 2) {
        HashValueEntry *ve = refmap_add(rm, src[i], FALSE, TRUE);
        if (ve == NULL) {
            return FALSE;
        }
        ve->val = Value_cp(src[i + 1]);
    }

    return TRUE;
}