Пример #1
0
static struct value *make_exn_lns_error(struct info *info,
                                        struct lns_error *err,
                                        const char *text) {
    struct value *v;

    if (HAS_ERR(info))
        return exn_error();

    v = make_exn_value(ref(info), "%s", err->message);
    if (err->lens != NULL) {
        char *s = format_info(err->lens->info);
        exn_printf_line(v, "Lens: %s", s);
        free(s);
    }
    if (err->pos >= 0) {
        char *pos = format_pos(text, err->pos);
        size_t line, ofs;
        calc_line_ofs(text, err->pos, &line, &ofs);
        exn_printf_line(v,
                     "Error encountered at %d:%d (%d characters into string)",
                        (int) line, (int) ofs, err->pos);
        if (pos != NULL)
            exn_printf_line(v, "%s", pos);
        free(pos);
    } else {
        exn_printf_line(v, "Error encountered at path %s", err->path);
    }

    return v;
}
Пример #2
0
static struct value *ambig_check(struct info *info, struct fa *fa1, struct fa *fa2,
                                 const char *msg) {
    char *upv, *pv, *v;
    size_t upv_len;
    fa_ambig_example(fa1, fa2, &upv, &upv_len, &pv, &v);
    struct value *exn = NULL;

    if (upv != NULL) {
        char *e_u = escape(upv, pv - upv);
        char *e_up = escape(upv, v - upv);
        char *e_upv = escape(upv, -1);
        char *e_pv = escape(pv, -1);
        char *e_v = escape(v, -1);
        exn = make_exn_value(ref(info), "%s", msg);
        exn_printf_line(exn, "  '%s' can be split into", e_upv);
        exn_printf_line(exn, "  '%s|=|%s'\n", e_u, e_pv);
        exn_printf_line(exn, " and");
        exn_printf_line(exn, "  '%s|=|%s'\n", e_up, e_v);
        free(e_u);
        free(e_up);
        free(e_upv);
        free(e_pv);
        free(e_v);
    }
    free(upv);
    return exn;
}
Пример #3
0
/* Construct a finite automaton from REGEXP and return it in *FA.
 *
 * Return NULL if REGEXP is valid, if the regexp REGEXP has syntax errors,
 * return an exception.
 */
static struct value *str_to_fa(struct info *info, const char *pattern,
                               struct fa **fa) {
    int error;
    struct value *exn = NULL;
    size_t re_err_len;
    char *re_str, *re_err;

    error = fa_compile(pattern, strlen(pattern), fa);
    if (error == REG_NOERROR)
        return NULL;

    re_str = escape(pattern, -1);
    if (re_str == NULL) {
        FIXME("Out of memory");
    }
    exn = make_exn_value(info, "Invalid regular expression /%s/", re_str);

    re_err_len = regerror(error, NULL, NULL, 0);
    if (ALLOC_N(re_err, re_err_len) < 0) {
        FIXME("Out of memory");
    }
    regerror(error, NULL, re_err, re_err_len);
    exn_printf_line(exn, "%s", re_err);

    free(re_str);
    free(re_err);
    return exn;
}
Пример #4
0
/*
 * Typechecking of lenses
 */
static struct value *disjoint_check(struct info *info, const char *msg,
                                    struct regexp *r1, struct regexp *r2) {
    struct fa *fa1 = NULL;
    struct fa *fa2 = NULL;
    struct fa *fa = NULL;
    struct value *exn = NULL;

    exn = regexp_to_fa(r1, &fa1);
    if (exn != NULL)
        goto done;

    exn = regexp_to_fa(r2, &fa2);
    if (exn != NULL)
        goto done;

    fa = fa_intersect(fa1, fa2);
    if (! fa_is_basic(fa, FA_EMPTY)) {
        size_t xmpl_len;
        char *xmpl;
        fa_example(fa, &xmpl, &xmpl_len);
        exn = make_exn_value(ref(info),
                             "overlapping lenses in %s", msg);

        exn_printf_line(exn, "Example matched by both: '%s'", xmpl);
        free(xmpl);
    }

 done:
    fa_free(fa);
    fa_free(fa1);
    fa_free(fa2);

    return exn;
}
Пример #5
0
/* V_LENS -> V_STRING -> V_TREE */
static struct value *lens_get(struct info *info, struct value *l,
                              struct value *str) {
    assert(l->tag == V_LENS);
    assert(str->tag == V_STRING);
    struct lns_error *err;
    struct value *v;
    const char *text = str->string->str;

    struct tree *tree = lns_get(info, l->lens, text, &err);
    if (err == NULL && ! HAS_ERR(info)) {
        v = make_value(V_TREE, ref(info));
        v->origin = make_tree_origin(tree);
    } else {
        struct tree *t = make_tree_origin(tree);
        if (t == NULL)
            free_tree(tree);
        tree = t;

        v = make_exn_lns_error(info, err, text);
        if (tree != NULL) {
            exn_printf_line(v, "Tree generated so far:");
            exn_print_tree(v, tree);
            free_tree(tree);
        }
        free_lns_error(err);
    }
    return v;
}
Пример #6
0
static void exn_print_tree(struct value *exn, struct tree *tree) {
    struct memstream ms;

    init_memstream(&ms);
    dump_tree(ms.stream, tree);
    close_memstream(&ms);
    exn_printf_line(exn, "%s", ms.buf);
    FREE(ms.buf);
}
Пример #7
0
static struct value *typecheck_union(struct info *info,
                                     struct lens *l1, struct lens *l2) {
    struct value *exn = NULL;

    exn = disjoint_check(info, "union.get", l1->ctype, l2->ctype);
    if (exn == NULL) {
        exn = disjoint_check(info, "tree union.put", l1->atype, l2->atype);
    }
    if (exn != NULL) {
        char *fi = format_info(l1->info);
        exn_printf_line(exn, "First lens: %s", fi);
        free(fi);

        fi = format_info(l2->info);
        exn_printf_line(exn, "Second lens: %s", fi);
        free(fi);
    }
    return exn;
}
Пример #8
0
static struct value *typecheck_concat(struct info *info,
                                      struct lens *l1, struct lens *l2) {
    struct value *result = NULL;

    result = ambig_concat_check(info, "ambiguous concatenation",
                                l1->ctype, l2->ctype);
    if (result == NULL) {
        result = ambig_concat_check(info, "ambiguous tree concatenation",
                                    l1->atype, l2->atype);
    }
    if (result != NULL) {
        char *fi = format_info(l1->info);
        exn_printf_line(result, "First lens: %s", fi);
        free(fi);
        fi = format_info(l2->info);
        exn_printf_line(result, "Second lens: %s", fi);
        free(fi);
    }
    return result;
}
Пример #9
0
static struct value *typecheck_iter(struct info *info, struct lens *l) {
    struct value *result = NULL;

    result = ambig_iter_check(info, "ambiguous iteration", l->ctype);
    if (result == NULL) {
        result = ambig_iter_check(info, "ambiguous tree iteration", l->atype);
    }
    if (result != NULL) {
        char *fi = format_info(l->info);
        exn_printf_line(result, "Iterated lens: %s", fi);
        free(fi);
    }
    return result;
}
Пример #10
0
static struct value *sys_read_file(struct info *info, struct value *n) {
    assert(n->tag == V_STRING);
    char *str = NULL;

    str = xread_file(n->string->str);
    if (str == NULL) {
        char error_buf[1024];
        const char *errmsg;
        errmsg = xstrerror(errno, error_buf, sizeof(error_buf));
        struct value *exn = make_exn_value(ref(info),
             "reading file %s failed:", n->string->str);
        exn_printf_line(exn, "%s", errmsg);
        return exn;
    }
    struct value *v = make_value(V_STRING, ref(info));
    v->string = make_string(str);
    return v;
}