// SPDX-License-Identifier: MIT // Copyright (c) 2023 John Watts and the LuminaSensum contributors #include "error.h" #include "object.h" #include <stdlib.h> static 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; } static 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; } static void number_add( struct object *obj, int arg_count, struct object **args) { abort_if( arg_count != 2, "number_add called with more than 2 arguments"); abort_if(args[0] != NULL, "number_add return is not NULL"); abort_if(!args[1], "number_add arg is NULL"); abort_if(obj->class_data != &num_class, "number_add obj is not a number"); abort_if(args[1]->class_data != &num_class, "number_add arg is not a number"); struct number *numA = (struct number *)obj; struct number *numB = (struct number *)args[1]; int added = numA->value + numB->value; args[0] = number_create(added); } static struct object_call calls[] = { {.name = "Add", .handler = number_add}, {.name = NULL, /* end */}}; static struct object_class num_class = { .cleanup = number_cleanup, .calls = &calls[0], };