diff --git a/lang/boolean.c b/lang/boolean.c new file mode 100644 index 0000000..c2fe8d6 --- /dev/null +++ b/lang/boolean.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2023 John Watts and the LuminaSensum contributors + +#include "boolean.h" +#include "error.h" +#include "object.h" +#include "vm.h" +#include + +static struct object_class boolean_class; + +struct boolean { + bool value; +}; + +Object boolean_create(bool value) { + Object obj = object_create(&boolean_class, sizeof(struct boolean)); + abort_if(!obj, "unable to allocate boolean"); + struct boolean *boolean = + (struct boolean *)object_priv(obj, &boolean_class); + boolean->value = value; + return obj; +} + +static void boolean_cleanup(Object obj) { (void)obj; } + +bool boolean_value(Object obj) { + struct boolean *boolean = + (struct boolean *)object_priv(obj, &boolean_class); + return boolean->value; +} + +static void boolean_not(VmState state, Object obj, void *priv) { + (void)priv; + int arg_count = vm_stack_depth(state); + abort_if(arg_count != 1, "boolean_not called with extra arguments"); + bool value = boolean_value(obj); + bool not = !value; + vm_stack_set(state, 0, boolean_create(not )); +} + +static struct object_call calls[] = { + {.name = "Not", .handler = boolean_not, .priv = NULL}, + {.name = NULL, /* end */}}; + +static struct object_class boolean_class = { + .cleanup = boolean_cleanup, + .calls = &calls[0], +}; diff --git a/lang/boolean.h b/lang/boolean.h new file mode 100644 index 0000000..b4b053f --- /dev/null +++ b/lang/boolean.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT +// Copyright (c) 2023 John Watts and the LuminaSensum contributors + +#ifndef BOOLEAN_H +#define BOOLEAN_H + +#include "types.h" +#include + +// Creates a boolean +Object boolean_create(bool value); + +// Gets a boolean's value +bool boolean_value(Object obj); + +#endif