// 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, void *priv) { (void)priv; 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, void *priv) { (void)priv; 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], };