Newer
Older
Tardis / lang / boolean.c
// SPDX-License-Identifier: MIT
// Copyright (c) 2023 John Watts and the LuminaSensum contributors

#include "boolean.h"
#include "error.h"
#include "object.h"
#include "vm.h"
#include <stddef.h>

static struct object_class boolean_class;

struct boolean {
	bool value;
};

Object boolean_create(VmState state, bool value) {
	Object obj =
		object_create(state, &boolean_class, sizeof(struct boolean));
	abort_if(state, !obj, "unable to allocate boolean");
	struct boolean *boolean =
		(struct boolean *)object_priv(state, obj, &boolean_class);
	boolean->value = value;
	return obj;
}

static void boolean_cleanup(VmState state, Object obj) {
	(void)state;
	(void)obj;
}

bool boolean_value(VmState state, Object obj) {
	struct boolean *boolean =
		(struct boolean *)object_priv(state, obj, &boolean_class);
	return boolean->value;
}

static void boolean_invert(VmState state, Object obj, void *priv) {
	(void)priv;
	int arg_count = vm_stack_depth(state);
	abort_if(state, arg_count != 1,
		"boolean_invert called with extra arguments");
	bool value = boolean_value(state, obj);
	bool invert = !value;
	vm_stack_set(state, 0, boolean_create(state, invert));
}

static struct object_call calls[] = {
	{.name = "Invert", .handler = boolean_invert, .priv = NULL},
	{.name = NULL, /* end */}};

static struct object_class boolean_class = {
	.cleanup = boolean_cleanup,
	.calls = &calls[0],
};