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 "stdio.h"
#include <stdlib.h>

struct object_class num_class;

struct number {
	struct object obj;
	int value;
};

struct object *number_create(int value) {
	struct number *num = malloc(sizeof(struct number));
	abort_if(!num, "unable to allocate number");
	num->obj.class_data = &num_class;
	num->obj.ref_count = 1;
	num->value = value;
	return (struct object *)num;
}

void number_cleanup(struct object *obj) {
	abort_if(obj->class_data != &num_class,
		"number_cleanup obj is not a number");
	struct number *num = (struct number *)obj;
	free(num);
}

int number_value(struct object *obj) {
	abort_if(obj->class_data != &num_class,
		"number_value obj is not a number");
	struct number *num = (struct number *)obj;
	return num->value;
}

struct object *number_add(
	struct object *obj, int arg_count, struct object **args) {
	abort_if(arg_count != 1, "number_add called with more than 1 argument");
	abort_if(!args[0], "number_add arg is NULL");
	abort_if(obj->class_data != &num_class,
		"number_add obj is not a number");
	abort_if(args[0]->class_data != &num_class,
		"number_add arg is not a number");
	struct number *numA = (struct number *)obj;
	struct number *numB = (struct number *)args[0];
	int added = numA->value + numB->value;
	return number_create(added);
}

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

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