Add low-level class support, stub of high level OOP wrapper
diff --git a/src/lisp/lib/classes.c b/src/lisp/lib/classes.c
new file mode 100644
index 0000000..11ed7f6
--- /dev/null
+++ b/src/lisp/lib/classes.c
@@ -0,0 +1,75 @@
+#include "classes.h"
+#include "../plat/plat.h"
+#include "std.h"
+
+value_t *class_member_ref(value_t class, int index)
+{
+	if (!classp(class))
+		return NULL;
+
+	struct class *c = (struct class *)(class ^ CLASS_TAG);
+
+	if (index >= c->num_members)
+		return NULL;
+
+	return &c->members[index];
+}
+
+value_t l_class_member(value_t class, value_t index)
+{
+	if (!integerp(index))
+		return nil;
+
+	value_t *member = class_member_ref(class, valint(index));
+
+	if (member)
+		return *member;
+	else
+		return nil;
+}
+
+value_t l_set_class_member(value_t class, value_t index, value_t value)
+{
+	if (!integerp(index))
+		return nil;
+
+	value_t *member = class_member_ref(class, valint(index));
+
+	if (member)
+		*member = value;
+
+	return nil;
+}
+
+// type = symbol representing this instances type
+// members = list of members
+value_t l_make_class(value_t type, value_t members)
+{
+	if (!integerp(members) || !symbolp(type))
+		return nil;
+
+	int nmemb = valint(members);
+	struct class_alloc *item = malloc_aligned(sizeof(struct class_alloc) +
+											  sizeof(value_t) * nmemb);
+	struct class *c = &item->class;
+
+	c->type = type;
+	c->num_members = nmemb;
+	c->cdata = NULL;
+
+	for (int i = 0; i < nmemb; i++)
+	{
+		c->members[i] = nil;
+	}
+
+	add_this_alloc(&item->alloc, CLASS_TAG);
+
+	return (value_t)c | CLASS_TAG;
+}
+
+void load_classes(struct environment *env)
+{
+	add_c_function(env, "set-class-member", l_set_class_member, 3);
+	add_c_function(env, "class-member", l_class_member, 2);
+	add_c_function(env, "make-class", l_make_class, 2);
+}