diff src/ploki/val.c @ 4223:ac0403686959

<oerjan> rm -rf src/ploki; mv ploki src
author HackBot
date Fri, 20 Dec 2013 22:18:50 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ploki/val.c	Fri Dec 20 22:18:50 2013 +0000
@@ -0,0 +1,219 @@
+#include "config.h"
+#include "IO.h"
+#include "Str.h"
+#include "val.h"
+#include "xmalloc.h"
+
+#include <stdlib.h>
+#include <assert.h>
+
+void v_init(struct val *v) {
+	v->ko = ko_new();
+	v->type = V_UNDEF;
+}
+
+void v_end(struct val *v) {
+	assert(v != NULL);
+	V_xxx_OFF(v);
+	ko_delete(v->ko);
+	v->type = V_UNDEF;
+}
+
+int v_cmp_ls(struct val *v, struct val *b) {
+	if (V_LIST_P(v) && V_LIST_P(b)) {
+		return li_cmp(v->magic.list, b->magic.list);
+	}
+	V_STR(v);
+	V_STR(b);
+	return ko_cmp(v->ko, b->ko);
+}
+
+void v_ok_str(struct val *v) {
+	if (V_STR_P(v)) {
+		return;
+	}
+
+	if (V_EXT_P(v)) {
+		ko_cpy_s(v->ko, io_name(v->magic.ext, NULL));
+	} else if (V_LIST_P(v)) {
+		size_t i;
+		struct list *li = v->magic.list;
+		struct val *cur;
+
+		ko_zero(v->ko);
+		for (i = 0; i < li_length(li); ++i) {
+			cur = li_at(li, i);
+			V_STR(cur);
+			ko_cat(v->ko, cur->ko);
+		}
+	} else if (V_NUM_P(v)) {
+		ko_num(v->ko, v->num);
+	} else if (V_SUB_P(v)) {
+		v_ok_num(v);
+		ko_num(v->ko, v->num);
+	} else {
+		ko_zero(v->ko);
+	}
+	v->type |= V_STR_K;
+}
+
+void v_ok_num(struct val *v) {
+	if (V_NUM_P(v)) {
+		return;
+	}
+
+	if (V_EXT_P(v)) {
+		v->num = __LINE__;
+	} else if (V_SUB_P(v)) {
+		v->num = sub_id(v->magic.sub);
+	} else if (V_LIST_P(v)) {
+		size_t i;
+
+		v->num = 0.0;
+		for (i = 0; i < li_length(v->magic.list); ++i) {
+			V_NUM(li_at(v->magic.list, i));
+			v->num += li_at(v->magic.list, i)->num;
+		}
+	} else if (V_STR_P(v)) {
+		v->num = strtod(ko_szp(v->ko), NULL);
+	} else {
+		v->num = 0.0;
+	}
+	v->type |= V_NUM_K;
+}
+
+int v_true(const struct val *v) {
+	if (V_EXT_P(v) || V_SUB_P(v)) {
+		return 1;
+	}
+	if (V_LIST_P(v)) {
+		return li_length(v->magic.list) != 0;
+	}
+	if (V_STR_P(v)) {
+		return ko_length(v->ko) != 0 && (ko_length(v->ko) > 1u || ko_at(v->ko, 0) != '0');
+	}
+	if (V_NUM_P(v)) {
+		return v->num != 0.0;
+	}
+	return 0;
+}
+
+void v_iniset(struct val *dst, const struct val *src) {
+	v_init(dst);
+	v_set(dst, src);
+}
+
+void v_set(struct val *dst, const struct val *src) {
+	assert(src != NULL);
+
+	V_xxx_OFF(dst);
+	dst->type = V_UNDEF;
+
+	if (V_SUB_P(src)) {
+		dst->magic.sub = sub_incr(src->magic.sub);
+		dst->type |= V_SUB_K;
+	} else if (V_EXT_P(src)) {
+		dst->magic.ext = io_incr(src->magic.ext);
+		dst->type |= V_EXT_K;
+	} else if (V_LIST_P(src)) {
+		dst->magic.list = li_dup(src->magic.list);
+		dst->type |= V_LIST_K;
+	}
+
+	if (V_STR_P(src)) {
+		ko_cpy(dst->ko, src->ko);
+		dst->type |= V_STR_K;
+	}
+	if (V_NUM_P(src)) {
+		dst->num = src->num;
+		dst->type |= V_NUM_K;
+	}
+}
+
+void v_set_n(struct val *v, double d) {
+	V_xxx_OFF(v);
+	v->num = d;
+	v->type = V_NUM_K;
+}
+
+void v_set_s(struct val *v, const String *s) {
+	V_xxx_OFF(v);
+	ko_cpy_m(v->ko, St_ptr(s), St_len(s));
+	v->type = V_STR_K;
+}
+
+void v_set_m(struct val *v, const void *p, size_t n) {
+	V_xxx_OFF(v);
+	ko_cpy_m(v->ko, p, n);
+	v->type = V_STR_K;
+}
+
+void v_set_io(struct val *v, IO *io) {
+	V_xxx_OFF(v);
+	v->magic.ext = io_incr(io);
+	v->type = V_EXT_K;
+}
+
+void v_set_sub(struct val *v, struct sub *s) {
+	V_xxx_OFF(v);
+	v->magic.sub = sub_incr(s);
+	v->type = V_SUB_K;
+}
+
+void v_set_undef(struct val *v) {
+	V_xxx_OFF(v);
+	v->type = V_UNDEF;
+}
+
+void v_cat(struct val *dst, struct val *src) {
+	if (V_LIST_P(dst) && V_LIST_P(src)) {
+		li_append(dst->magic.list, src->magic.list);
+		return;
+	}
+
+	V_STR(src);
+	V_STR(dst);
+	V_xxx_OFF(dst);
+	ko_cat(dst->ko, src->ko);
+	dst->type = V_STR_K;
+}
+
+void v_cat_m(struct val *v, const void *p, size_t n) {
+	V_STR(v);
+	V_xxx_OFF(v);
+	ko_cat_m(v->ko, p, n);
+	v->type = V_STR_K;
+}
+
+void v_cat_s(struct val *v, const String *s) {
+	v_cat_m(v, St_ptr(s), St_len(s));
+}
+
+void v_cat_c(struct val *v, char c) {
+	v_cat_m(v, &c, 1);
+}
+
+struct val *v_undef(void) {
+	struct val *v;
+	v = xmalloc(1, sizeof *v);
+	v_init(v);
+	return v;
+}
+
+void v_delete(struct val *v) {
+	v_end(v);
+	xfree(v);
+}
+
+const char *v_sptr(struct val *v, size_t *l) {
+	V_STR(v);
+	if (l) {
+		*l = ko_length(v->ko);
+	}
+	return ko_ptr(v->ko);
+}
+
+struct kork *v_kork(struct val *v) {
+	V_STR(v);
+	return v->ko;
+}