Пример #1
0
static bool variable_compare(struct context *context, const struct variable *u, const struct variable *v)
{
    if (!u != !v)
        return false;
    enum VarType ut = (enum VarType)u->type;
    enum VarType vt = (enum VarType)v->type;

    if (ut != vt)
        return false;

    switch (ut) {
        case VAR_LST:
            if (u->list->length != v->list->length)
                return false;
            for (int i=0; i<u->list->length; i++) {
                struct variable *ui = (struct variable*)array_get(u->list, i);
                struct variable *vi = (struct variable*)array_get(v->list, i);
                if (!variable_compare(context, ui, vi))
                    return false;
            }
            break;
        case VAR_BOOL:
        case VAR_INT:   if (u->integer != v->integer)           return false; break;
        case VAR_FLT:   if (u->floater != v->floater)           return false; break;
        case VAR_STR:   if (!byte_array_equals(u->str, v->str)) return false; break;
        default:
            return (bool)vm_exit_message(context, "bad comparison");
    }

    return variable_compare_maps(context, u->map, v->map);
}
Пример #2
0
static bool variable_compare_maps(struct context *context, const struct map *umap, const struct map *vmap)
{
    if (!umap && !vmap)
        return true;
    if (!umap)
        return variable_compare_maps(context, vmap, umap);
    struct array *keys = map_keys(umap);
    if (!vmap)
        return !keys->length;

    for (int i=0; i<keys->length; i++) {
        struct byte_array *key = (struct byte_array*)array_get(keys, i);
        struct variable *uvalue = (struct variable*)map_get(umap, key);
        struct variable *vvalue = (struct variable*)map_get(vmap, key);
        if (!variable_compare(context, uvalue, vvalue))
            return false;
    }
    return true;
}
Пример #3
0
static void binary_op(struct context *context, enum Opcode op)
{
    if (!context->runtime)
        VM_DEBUGPRINT("%s\n", NUM_TO_STRING(opcodes, op));

    struct variable *u = variable_pop(context);
    struct variable *v = variable_pop(context);
    enum VarType ut = (enum VarType)u->type;
    enum VarType vt = (enum VarType)v->type;
    struct variable *w;

    if (ut == VAR_NIL || vt == VAR_NIL) {
        w = binary_op_nil(context, op, u, v);
    } else if ((op == VM_EQU) || (op == VM_NEQ)) {
        bool same = variable_compare(context, u, v) ^ (op == VM_NEQ);
        w = variable_new_bool(context, same);
    } else {
        bool floater  = (ut == VAR_FLT && is_num(vt)) || (vt == VAR_FLT && is_num(ut));
        bool inter = (ut==VAR_INT || ut==VAR_BOOL) && (vt==VAR_INT || vt==VAR_BOOL);

        if (floater)                                w = binary_op_float(context, op, u, v);
        else if (inter)                             w = binary_op_int(context, op, v, u);
        else if (vt == VAR_STR || ut == VAR_STR)    w = binary_op_str(context, op, u, v);
        else if (vt == VAR_LST)                     w = binary_op_lst(context, op, u, v);
        else
            vm_exit_message(context, "unknown binary op");
    }

    variable_push(context, w);

    DEBUGPRINT("%s(%s,%s) = %s\n",
               NUM_TO_STRING(opcodes, op),
               variable_value_str(context, v),
               variable_value_str(context, u),
               variable_value_str(context, w));
}
Пример #4
0
static bool default_comparator(const void *a, const void *b, void *context) {
    return variable_compare((struct context *)context, (struct variable *)a, (struct variable *)b);
}