コード例 #1
0
ファイル: primitives.c プロジェクト: rpedde/minischeme
/**
 * dup an object
 */
lv_t *lisp_dup_item(lv_t *v) {
    lv_t *r;
    lv_t *vptr = v;
    lv_t *rptr;
    assert(v);

    switch(v->type) {
    case l_int:
        r = lisp_create_int(0);
        mpz_set(L_INT(r), L_INT(v));
        return r;
    case l_rational:
        r = lisp_create_rational(1, 1);
        mpq_set(L_RAT(r), L_RAT(v));
        return r;
    case l_float:
        r = lisp_create_float(0.0);
        mpfr_set(L_FLOAT(r), L_FLOAT(v), MPFR_ROUND_TYPE);
        return r;
    case l_bool:
        return v;
    case l_sym:
        return lisp_create_symbol(L_SYM(v));
    case l_str:
        return lisp_create_string(L_STR(v));
    case l_null:
        return v;
    case l_port:
        /* can't really copy this -- it's a socket or a file
           handle, or something else.  */
        return v;
    case l_char:
        return lisp_create_char(L_CHAR(v));
    case l_fn:
        /* can't really copy this either, but it's essentially
           immutable */
        return v;
    case l_err:
        return lisp_create_err(L_ERR(v));
    case l_hash:
        /* FIXME: should really be a copy */
        return v;
    case l_pair:
        r = lisp_create_pair(NULL, NULL);
        rptr = r;

        while(vptr && L_CAR(vptr)) {
            L_CAR(rptr) = lisp_dup_item(L_CAR(vptr));
            vptr = L_CDR(vptr);
            if(vptr) {
                L_CDR(rptr) = lisp_create_pair(NULL, NULL);
                rptr = L_CDR(rptr);
            }
        }
        return r;
    }

    assert(0);
}
コード例 #2
0
ファイル: primitives.c プロジェクト: rpedde/minischeme
lv_t *lisp_create_type(void *value, lisp_type_t type) {
    lv_t *result;

    result = safe_malloc(sizeof(lv_t));

    result->type = type;

    result->row = 0;
    result->col = 0;
    result->file = NULL;

    switch(type) {
    case l_char:
        L_CHAR(result) = *((char*)value);
        break;
    case l_int:
        mpz_init(L_INT(result));
        mpz_set_si(L_INT(result), *(int64_t *)value);
        break;
    case l_rational:
        mpq_init(L_RAT(result));
        break;
    case l_float:
        mpfr_init(L_FLOAT(result));
        mpfr_set_d(L_FLOAT(result), *(double*)value, MPFR_ROUND_TYPE);
        break;
    case l_bool:
        L_BOOL(result) = *((int*)value);
        break;
    case l_sym:
        L_SYM(result) = safe_strdup((char*)value);
        break;
    case l_str:
        L_STR(result) = safe_strdup((char*)value);
        break;
    case l_err:
        L_ERR(result) = *((lisp_errsubtype_t *)value);
        break;
    case l_fn:
        L_FN(result) = (lisp_method_t)value;
        break;
    case l_port:
        L_PORT(result) = (port_info_t *)value;
        break;
    default:
        assert(0);
        fprintf(stderr, "Bad type");
        exit(EXIT_FAILURE);
    }

    return result;
}
コード例 #3
0
ファイル: builtins.c プロジェクト: rpedde/minischeme
/**
 * c helper for equalp
 */
int c_equalp(lv_t *a1, lv_t *a2) {
    int result = 0;

    if(a1->type != a2->type)
        return 0;

    switch(a1->type) {
    case l_int:
        result = (mpz_cmp(L_INT(a1), L_INT(a2)) == 0);
        break;
    case l_float:
        result = (mpfr_cmp(L_FLOAT(a1), L_FLOAT(a2)) == 0);
        break;
    case l_bool:
        if((L_BOOL(a1) == 0 && L_BOOL(a2) == 0) ||
           (L_BOOL(a1) != 0 && L_BOOL(a1) != 0))
            result = 1;
        break;
    case l_sym:
        if(strcmp(L_SYM(a1), L_SYM(a2)) == 0)
            result = 1;
        break;
    case l_str:
        if(strcmp(L_STR(a1), L_STR(a2)) == 0)
            result = 1;
        break;
    case l_hash:
        result = (L_HASH(a1) == L_HASH(a2));
        break;
    case l_null:
        result = 1;
        break;
    case l_fn:
        result = (L_FN(a1) == L_FN(a1));
        break;
    case l_pair:
        /* this is perhaps not right */
        if(!(c_equalp(L_CAR(a1), L_CAR(a2))))
            return 0;
        if(L_CDR(a1) && L_CDR(a2))
            return c_equalp(L_CDR(a1), L_CDR(a2));
        if(!L_CDR(a1) && !L_CDR(a2))
            return 1;
        result = 0;
        break;
    }

    return result;
}
コード例 #4
0
ファイル: basic.c プロジェクト: skagedal/lipa
LObject *
lipa_new_float (gfloat i)
{
  LObject *obj = g_new0 (LObject, 1);

  obj->type = L_OBJ_FLOAT;
  L_FLOAT (obj) = i;

  return obj;
}
コード例 #5
0
ファイル: primitives.c プロジェクト: rpedde/minischeme
/**
 * lisp_create_type for float, using the string parser
 * (to be able to represent arbitrary precision).  This
 * is the preferred interface
 */
lv_t *lisp_create_float_str(char *value) {
    double v = 0;
    int flag;

    lv_t *new_value = lisp_create_type((void*)&v, l_float);

    /* now parse the string */
    flag = mpfr_set_str(L_FLOAT(new_value), value, 10, MPFR_ROUND_TYPE);
    assert(!flag);

    return new_value;
}
コード例 #6
0
ファイル: primitives.c プロジェクト: rpedde/minischeme
/**
 * print a value to a fd, in a debug form
 */
void lisp_dump_value(int fd, lv_t *v, int level) {
    switch(v->type) {
    case l_null:
        dprintf(fd, "()");
        break;
    case l_int:
        dprintf(fd, "%" PRIu64, L_INT(v));
        break;
    case l_float:
        dprintf(fd, "%0.16g", L_FLOAT(v));
        break;
    case l_bool:
        dprintf(fd, "%s", L_BOOL(v) ? "#t": "#f");
        break;
    case l_sym:
        dprintf(fd, "%s", L_SYM(v));
        break;
    case l_str:
        dprintf(fd, "\"%s\"", L_STR(v));
        break;
    case l_char:
        dprintf(fd, "#\%02x", L_CHAR(v));
        break;
    case l_pair:
        dprintf(fd, "(");
        lv_t *vp = v;
        while(vp && L_CAR(vp)) {
            lisp_dump_value(fd, L_CAR(vp), level + 1);
            if(L_CDR(vp) && (L_CDR(vp)->type != l_pair)) {
                dprintf(fd, " . ");
                lisp_dump_value(fd, L_CDR(vp), level + 1);
                vp = NULL;
            } else {
                vp = L_CDR(vp);
                dprintf(fd, "%s", vp ? " " : "");
            }
        }
        dprintf(fd, ")");
        break;
    case l_fn:
        if(L_FN(v) == NULL)
            dprintf(fd, "<lambda@%p>", v);
        else
            dprintf(fd, "<built-in@%p>", v);
        break;
    default:
        // missing a type check.
        assert(0);
    }
}
コード例 #7
0
ファイル: primitives.c プロジェクト: rpedde/minischeme
/**
 * print the object specified by v in the provided buffer.
 * follows standard snprintf rules, in that it returns the
 * number of bytes required to print if an insufficient buffer
 * length is provided.
 *
 * if display is true, then the results are printed as human
 * readable (p_display), otherwise it is printed as machine
 * readable (p_write)
 */
int lisp_snprintf(lexec_t *exec, char *buf, int len, lv_t *v, int display) {
    int pair_len = 0;

    switch(v->type) {
    case l_null:
        return snprintf(buf, len, "()");
    case l_int:
        /* return snprintf(buf, len, "%" PRIu64, L_INT(v)); */
        return gmp_snprintf(buf, len, "%Zd", L_INT(v));
    case l_rational:
        return gmp_snprintf(buf, len, "%Qd", L_RAT(v));
    case l_float:
        /* return snprintf(buf, len, "%0.16g", L_FLOAT(v)); */
        return mpfr_snprintf(buf, len, "%Rg", L_FLOAT(v));
    case l_bool:
        return snprintf(buf, len, "%s", L_BOOL(v) ? "#t": "#f");
    case l_sym:
        return snprintf(buf, len, "%s", L_SYM(v));
    case l_str:
        if(display)
            return snprintf(buf, len, "%s", L_STR(v));
        else
            return snprintf(buf, len, "\"%s\"", L_STR(v));
    case l_pair:
        if(len >= 1)
            sprintf(buf, "(");

        pair_len += 1;

        lv_t *vp = v;

        while(vp && L_CAR(vp)) {
            pair_len += lisp_snprintf(exec, buf + pair_len,
                                      (len - pair_len) > 0 ? len - pair_len : 0,
                                      L_CAR(vp), display);

            if(L_CDR(vp) && (L_CDR(vp)->type != l_pair)) {
                pair_len += snprintf(buf + pair_len,
                                     (len - pair_len) > 0 ? len - pair_len : 0,
                                     " . ");

                pair_len += lisp_snprintf(exec, buf + pair_len,
                                          (len - pair_len) > 0 ? len - pair_len : 0,
                                          L_CDR(vp), display);
                vp = NULL;
            } else {
                vp = L_CDR(vp);
                if(vp) {
                    if (len - pair_len > 0)
                        snprintf(buf + pair_len, len - pair_len, " ");
                    pair_len++;
                }
            }
        }

        if (len - pair_len > 0) {
            sprintf(buf + pair_len, ")");
        }

        pair_len++;
        return pair_len;
        break;
    case l_fn:
        rt_assert(!display, le_type, "cannot display function types");

        if(L_FN(v) == NULL)
            return snprintf(buf, len, "<lambda@%p>", v);
        else
            return snprintf(buf, len, "<built-in@%p>", v);
        break;
    case l_char:
        if(display)
            return snprintf(buf, len, "%c", L_CHAR(v));
        else
            return snprintf(buf, len, "#\\x%02x", L_CHAR(v));
        break;
    case l_port:
        rt_assert(!display, le_type, "cannot display port types");
        return snprintf(buf, len, "<port@%p>", v);
        break;
    case l_err:
        rt_assert(!display, le_type, "cannot display error types");
        return snprintf(buf, len, "<error@%p:%d>", v, L_ERR(v));
        break;
    default:
        // missing a type check.
        assert(0);
    }

}