/*
* builtin.c: builtin primitives
*
- * Copyright (C) 2007-2011 David Lutterkort
+ * Copyright (C) 2007-2015 David Lutterkort
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
return lns_make_prim(L_COUNTER, ref(info), NULL, ref(str->string));
}
-/* V_REGEXP -> V_LENS -> V_LENS */
-static struct value *lns_square(struct info *info, struct value *rxp,
- struct value *lns) {
- assert(rxp->tag == V_REGEXP);
- assert(lns->tag == V_LENS);
+/* V_LENS -> V_LENS -> V_LENS -> V_LENS */
+static struct value *lns_square(struct info *info, struct value *l1,
+ struct value *l2, struct value *l3) {
+ assert(l1->tag == V_LENS);
+ assert(l2->tag == V_LENS);
+ assert(l3->tag == V_LENS);
int check = info->error->aug->flags & AUG_TYPE_CHECK;
- return lns_make_square(ref(info), ref(rxp->regexp), ref(lns->lens), check);
+ return lns_make_square(ref(info), ref(l1->lens), ref(l2->lens), ref(l3->lens), check);
+}
+
+static void exn_lns_error_detail(struct value *exn, const char *label,
+ struct lens *lens) {
+ if (lens == NULL)
+ return;
+
+ char *s = format_info(lens->info);
+ exn_printf_line(exn, "%s: %s", label, s);
+ free(s);
}
static struct value *make_exn_lns_error(struct info *info,
struct value *v;
if (HAS_ERR(info))
- return exn_error();
+ return info->error->exn;
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);
- }
+ exn_lns_error_detail(v, "Lens", err->lens);
+ exn_lns_error_detail(v, " Last match", err->last);
+ exn_lns_error_detail(v, " Not matching", err->next);
if (err->pos >= 0) {
char *pos = format_pos(text, err->pos);
size_t line, ofs;
return make_unit(ref(info));
}
+/* V_TREE -> V_TREE */
+static struct value *pr_tree(ATTRIBUTE_UNUSED struct info *info,
+ struct value *t) {
+ print_tree_braces(stdout, 0, t->origin);
+ return ref(t);
+}
+
/*
* Lens inspection
*/
r = lns_format_atype(l->lens, &s);
if (r < 0)
- return exn_error();
+ return info->error->exn;
result = make_value(V_STRING, ref(info));
result->string = make_string(s);
return result;
match = strndup(str + regs.start[0], regs.end[0] - regs.start[0]);
}
if (match == NULL) {
- result = exn_error();
+ result = info->error->exn;
} else {
result = make_value(V_STRING, ref(info));
result->string = make_string(match);
DEFINE_NATIVE(modl, "label", 1, lns_label, T_STRING, T_LENS);
DEFINE_NATIVE(modl, "seq", 1, lns_seq, T_STRING, T_LENS);
DEFINE_NATIVE(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
- DEFINE_NATIVE(modl, "square", 2, lns_square, T_REGEXP, T_LENS, T_LENS);
+ DEFINE_NATIVE(modl, "square", 3, lns_square, T_LENS, T_LENS, T_LENS, T_LENS);
/* Applying lenses (mostly for tests) */
DEFINE_NATIVE(modl, "get", 2, lens_get, T_LENS, T_STRING, T_TREE);
DEFINE_NATIVE(modl, "put", 3, lens_put, T_LENS, T_TREE, T_STRING,
DEFINE_NATIVE(modl, "print_string", 1, pr_string, T_STRING, T_UNIT);
DEFINE_NATIVE(modl, "print_regexp", 1, pr_regexp, T_REGEXP, T_UNIT);
DEFINE_NATIVE(modl, "print_endline", 1, pr_endline, T_STRING, T_UNIT);
+ DEFINE_NATIVE(modl, "print_tree", 1, pr_tree, T_TREE, T_TREE);
/* Lens inspection */
DEFINE_NATIVE(modl, "lens_ctype", 1, lns_ctype, T_LENS, T_REGEXP);