// 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; } #define OP_ADD (void *)1 #define OP_MINUS (void *)2 static void number_math(VmState state, Object obj, void *priv) { int arg_count = vm_stack_depth(state); abort_if(arg_count != 2, "number_math called without 2 arguments"); Object arg1 = vm_stack_get(state, 1); int result = 0; if (priv == OP_ADD) { result = number_value(obj) + number_value(arg1); } else if (priv == OP_MINUS) { result = number_value(obj) - number_value(arg1); } else { abort_msg("number_math called with invalid priv"); } vm_stack_set(state, 0, number_create(result)); vm_stack_drop(state, 1); object_drop(&arg1); } static struct object_call calls[] = { {.name = "Add", .handler = number_math, .priv = OP_ADD}, {.name = "Minus", .handler = number_math, .priv = OP_MINUS}, {.name = NULL, /* end */}}; static struct object_class num_class = { .cleanup = number_cleanup, .calls = &calls[0], };