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

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

static struct object_class num_class;

struct number {
	int value;
};

Object number_create(int value) {
	Object obj = object_create(&num_class, sizeof(struct number));
	abort_if(!obj, "unable to allocate number");
	struct number *num = (struct number *)object_priv(obj, &num_class);
	num->value = value;
	return obj;
}

static void number_cleanup(Object obj) { (void)obj; }

int number_value(Object obj) {
	struct number *num = (struct number *)object_priv(obj, &num_class);
	return num->value;
}

static void number_add(VmState state, Object obj) {
	int arg_count = vm_stack_depth(state);
	abort_if(arg_count != 2, "number_add called without 2 arguments");
	Object arg1 = vm_stack_get(state, 1);
	int added = number_value(obj) + number_value(arg1);
	vm_stack_set(state, 0, number_create(added));
	vm_stack_drop(state, 1);
	object_drop(&arg1);
}

static void number_minus(VmState state, Object obj) {
	int arg_count = vm_stack_depth(state);
	abort_if(arg_count != 2, "number_minus called without 2 arguments");
	Object arg1 = vm_stack_get(state, 1);
	int subbed = number_value(obj) - number_value(arg1);
	vm_stack_set(state, 0, number_create(subbed));
	vm_stack_drop(state, 1);
	object_drop(&arg1);
}

static struct object_call calls[] = {{.name = "Add", .handler = number_add},
	{.name = "Minus", .handler = number_minus}, {.name = NULL, /* end */}};

static struct object_class num_class = {
	.cleanup = number_cleanup,
	.calls = &calls[0],
};