view src/ploki/val.c @ 12292:d51f2100210c draft

<kspalaiologos> `` cat <<<"asmbf && bfi output.b" > /hackenv/ibin/asmbf
author HackEso <hackeso@esolangs.org>
date Thu, 02 Jan 2020 15:38:21 +0000
parents ac0403686959
children
line wrap: on
line source

#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;
}