示例#1
0
文件: val.c 项目: luikore/nabla
static Klass* _klass_new(uint32_t klass_id, Val name, uint32_t parent_id) {
  Klass* k = val_alloc(KLASS_KLASS, sizeof(Klass));
  k->id = klass_id;
  k->name = name;
  k->parent_id = parent_id;

  IdMethods.init(&k->id_methods);
  Includes.init(&k->includes, 0);
  IdFieldIndexes.init(&k->id_field_indexes);
  Fields.init(&k->fields, 0);

  k->hash_func = NULL;
  k->eq_func = NULL;
  k->destruct_func = NULL;
  k->delete_func = NULL;
  k->debug_func = NULL;
  val_perm(k);

  ConstSearchKey key = {.parent = k->parent_id, .name_str = VAL_TO_STR(k->name)};
  KlassSearchMap.insert(&runtime.klass_search_map, key, k->id);
  ConstSearchMap.insert(&runtime.const_search_map, key, (Val)k);

  return k;
}

static void _klass_delete(Klass* k) {
  ConstSearchKey key = {.parent = k->parent_id, .name_str = VAL_TO_STR(k->name)};
  KlassSearchMap.remove(&runtime.klass_search_map, key);
  ConstSearchMap.remove(&runtime.const_search_map, key);

  IdMethods.cleanup(&k->id_methods);
  Includes.cleanup(&k->includes);
  IdFieldIndexes.cleanup(&k->id_field_indexes);
  Fields.cleanup(&k->fields);

  val_free(k);
}

static Method* _method_new(uint32_t method_id, int32_t min_argc, int32_t max_argc, bool is_final) {
  Method* meth = val_alloc(KLASS_METHOD, sizeof(Method));
  METHOD_ID(meth) = method_id;
  METHOD_IS_FINAL(meth) = is_final;
  METHOD_MIN_ARGC(meth) = min_argc;
  METHOD_MAX_ARGC(meth) = max_argc;
  val_perm(meth);
  return meth;
}
示例#2
0
/* range([start],end,[step]) */
static inline MUST_CHECK value_t function_range(value_t vals, linepos_t epoint) {
    struct values_s *v = vals->u.funcargs.val;
    size_t args = vals->u.funcargs.len;
    value_t err, new_value;
    ival_t start = 0, end, step = 1;
    size_t i = 0, len2;
    value_t *val;

    if (args < 1 || args > 3) {
        err_msg_argnum(args, 1, 3, epoint);
        return val_reference(none_value);
    }
    switch (args) {
    case 1: 
        err = v[0].val->obj->ival(v[0].val, &end, 8*sizeof(ival_t), &v[0].epoint);
        break;
    case 3: 
        err = v[2].val->obj->ival(v[2].val, &step, 8*sizeof(ival_t), &v[2].epoint);
        if (err) return err; 
    case 2: 
        err = v[0].val->obj->ival(v[0].val, &start, 8*sizeof(ival_t), &v[0].epoint);
        if (err) return err; 
        err = v[1].val->obj->ival(v[1].val, &end, 8*sizeof(ival_t), &v[1].epoint);
        break;
    }
    if (err) return err;
    if (step == 0) {
        return new_error_obj(ERROR_NO_ZERO_VALUE, &v[2].epoint);
    }
    if (step > 0) {
        if (end < start) end = start;
        len2 = (end - start + step - 1) / step;
    } else {
        if (end > start) end = start;
        len2 = (start - end - step - 1) / -step;
    }
    new_value = val_alloc(LIST_OBJ);
    val = list_create_elements(new_value, len2);
    if (len2) {
        i = 0;
        while ((end > start && step > 0) || (end < start && step < 0)) {
            val[i] = int_from_ival(start);
            i++; start += step;
        }
    }
    new_value->u.list.len = len2;
    new_value->u.list.data = val;
    return new_value;
}
示例#3
0
static MUST_CHECK value_t repr(const value_t v1, linepos_t epoint) {
    uint8_t *s;
    const char *prefix;
    size_t len;
    value_t v;
    if (!epoint) return NULL;
    prefix = "<native_function '";
    len = strlen(prefix);
    v = val_alloc(STR_OBJ);
    v->u.str.len = v1->u.function.name.len + 2 + len;
    if (v->u.str.len < (2 + len)) err_msg_out_of_memory(); /* overflow */
    v->u.str.chars = v->u.str.len;
    s = str_create_elements(v, v->u.str.len);
    memcpy(s, prefix, len);
    memcpy(s + len, v1->u.function.name.data, v1->u.function.name.len);
    s[v->u.str.len - 2] = '\'';
    s[v->u.str.len - 1] = '>';
    v->u.str.data = s;
    return v;
}
示例#4
0
static MUST_CHECK value_t apply_func2(oper_t op, enum func_e func) {
    value_t err, v, v1 = op->v1, v2 = op->v2, val, *vals;
    double real, real2;

    if (v1->obj == TUPLE_OBJ || v1->obj == LIST_OBJ) {
        size_t i;
        if (v1->obj == v2->obj) {
            if (v1->u.list.len == v2->u.list.len) {
                if (v1->u.list.len) {
                    int error = 1;
                    v = val_alloc(v1->obj);
                    vals = list_create_elements(v, v1->u.list.len);
                    for (i = 0; i < v1->u.list.len; i++) {
                        op->v1 = v1->u.list.data[i];
                        op->v2 = v2->u.list.data[i];
                        val = apply_func2(op, func);
                        if (val->obj == ERROR_OBJ) { if (error) {err_msg_output(val); error = 0;} val_destroy(val); val = val_reference(none_value); }
                        vals[i] = val;
                    }
                    op->v1 = v1;
                    op->v2 = v2;
                    v->u.list.len = i;
                    v->u.list.data = vals;
                    return v;
                } 
                return val_reference(v1);
            } 
            if (v1->u.list.len == 1) {
                op->v1 = v1->u.list.data[0];
                v = apply_func2(op, func);
                op->v1 = v1;
                return v;
            } 
            if (v2->u.list.len == 1) {
                op->v2 = v2->u.list.data[0];
                v = apply_func2(op, func);
                op->v2 = v2;
                return v;
            } 
            v = new_error_obj(ERROR_CANT_BROADCAS, op->epoint3);
            v->u.error.u.broadcast.v1 = v1->u.list.len;
            v->u.error.u.broadcast.v2 = v2->u.list.len;
            return v;
        }
        if (v1->u.list.len) {
            int error = 1;
            v = val_alloc(v1->obj);
            vals = list_create_elements(v, v1->u.list.len);
            for (i = 0; i < v1->u.list.len; i++) {
                op->v1 = v1->u.list.data[i];
                val = apply_func2(op, func);
                if (val->obj == ERROR_OBJ) { if (error) {err_msg_output(val); error = 0;} val_destroy(val); val = val_reference(none_value); }
                vals[i] = val;
            }
            op->v1 = v1;
            v->u.list.len = i;
            v->u.list.data = vals;
            return v;
        }
        return val_reference(v1);
    }
    if (v2->obj == TUPLE_OBJ || v2->obj == LIST_OBJ) {
        if (v2->u.list.len) {
            int  error = 1;
            size_t i;
            v = val_alloc(v2->obj);
            vals = list_create_elements(v, v2->u.list.len);
            for (i = 0; i < v2->u.list.len; i++) {
                op->v2 = v2->u.list.data[i];
                val = apply_func2(op, func);
                if (val->obj == ERROR_OBJ) { if (error) {err_msg_output(val); error = 0;} val_destroy(val); val = val_reference(none_value); }
                vals[i] = val;
            }
            op->v2 = v2;
            v->u.list.len = i;
            v->u.list.data = vals;
            return v;
        }
        return val_reference(v2);
    }
    err = FLOAT_OBJ->create(v1, op->epoint);
    if (err->obj != FLOAT_OBJ) return err;
    real = err->u.real;
    val_destroy(err);
    err = FLOAT_OBJ->create(v2, op->epoint2);
    if (err->obj != FLOAT_OBJ) return err;
    real2 = err->u.real;
    val_destroy(err);
    switch (func) {
    case F_HYPOT: real = hypot(real, real2); break;
    case F_ATAN2: real = atan2(real, real2);break;
    case F_POW:
        if (real2 < 0.0 && !real) {
            return new_error_obj(ERROR_DIVISION_BY_Z, op->epoint3);
        }
        if (real < 0.0 && (double)((int)real2) != real2) {
            return new_error_obj(ERROR_NEGFRAC_POWER, op->epoint3);
        }
        real = pow(real, real2);
        break;
    default: real = HUGE_VAL; break;
    }
    return float_from_double2(real, op->epoint3);
}
示例#5
0
static MUST_CHECK value_t apply_func(value_t v1, enum func_e func, linepos_t epoint) {
    value_t err, v;
    double real;
    switch (func) {
    case F_ANY: return v1->obj->truth(v1, TRUTH_ANY, epoint);
    case F_ALL: return v1->obj->truth(v1, TRUTH_ALL, epoint);
    case F_LEN: return v1->obj->len(v1, epoint);
    default: break;
    }
    if (v1->obj == TUPLE_OBJ || v1->obj == LIST_OBJ) {
        if (v1->u.list.len) {
            int error = 1;
            size_t i;
            value_t *vals;
            v = val_alloc(v1->obj);
            vals = list_create_elements(v, v1->u.list.len);
            for (i = 0; i < v1->u.list.len; i++) {
                value_t val = apply_func(v1->u.list.data[i], func, epoint);
                if (val->obj == ERROR_OBJ) { if (error) {err_msg_output(val); error = 0;} val_destroy(val); val = val_reference(none_value); }
                vals[i] = val;
            }
            v->u.list.len = i;
            v->u.list.data = vals;
            return v;
        }
        return val_reference(v1);
    }
    switch (func) {
    case F_SIZE: return v1->obj->size(v1, epoint);
    case F_SIGN: return v1->obj->sign(v1, epoint);
    case F_ABS: return v1->obj->abs(v1, epoint);
    case F_REPR: return v1->obj->repr(v1, epoint);
    default: break;
    }
    err = FLOAT_OBJ->create(v1, epoint);
    if (err->obj != FLOAT_OBJ) return err;
    real = err->u.real;
    val_destroy(err);
    switch (func) {
    case F_FLOOR: real = floor(real);break;
    case F_CEIL: real = ceil(real);break;
    case F_SQRT: 
        if (real < 0.0) {
            return new_error_obj(ERROR_SQUARE_ROOT_N, epoint);
        }
        real = sqrt(real);
        break;
    case F_LOG10: 
        if (real <= 0.0) {
            return new_error_obj(ERROR_LOG_NON_POSIT, epoint);
        }
        real = log10(real);
        break;
    case F_LOG: 
        if (real <= 0.0) {
            return new_error_obj(ERROR_LOG_NON_POSIT, epoint);
        }
        real = log(real);
        break;
    case F_EXP: real = exp(real);break;
    case F_SIN: real = sin(real);break;
    case F_COS: real = cos(real);break;
    case F_TAN: real = tan(real);break;
    case F_ACOS: 
        if (real < -1.0 || real > 1.0) {
            return new_error_obj(ERROR___MATH_DOMAIN, epoint);
        }
        real = acos(real);
        break;
    case F_ASIN: 
        if (real < -1.0 || real > 1.0) {
            return new_error_obj(ERROR___MATH_DOMAIN, epoint);
        }
        real = asin(real);
        break;
    case F_ATAN: real = atan(real);break;
    case F_CBRT: real = cbrt(real);break;
    case F_ROUND: real = round(real);break;
    case F_TRUNC: real = trunc(real);break;
    case F_FRAC: real -= trunc(real);break;
    case F_RAD: real = real * M_PI / 180.0;break;
    case F_DEG: real = real * 180.0 / M_PI;break;
    case F_COSH: real = cosh(real);break;
    case F_SINH: real = sinh(real);break;
    case F_TANH: real = tanh(real);break;
    default: real = HUGE_VAL; break; /* can't happen */
    }
    return float_from_double2(real, epoint);
}