Newer
Older
Tardis / lang / main.c
// MIT license or something
// Copyright 2023 Jookia

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <threads.h>
#include <stdatomic.h>

#define SYMBOL_LEN 32
#define SYMBOLS_MAX 32

typedef struct {
	char name[SYMBOL_LEN];
} symbol;

symbol symbols[SYMBOLS_MAX] = {0};
mtx_t symbols_lock;

int find_symbol(char *name) {
	mtx_lock(&symbols_lock);
	for(int i = 0; i < SYMBOLS_MAX; ++i) {
		symbol *curr_sym = &symbols[i];
		char *curr_name = curr_sym->name;
		if(curr_name[0] == 0) {
			strncpy(curr_name, name, SYMBOL_LEN);
			mtx_unlock(&symbols_lock);
			return i;
		} else {
			int cmp = strncmp(curr_name, name, SYMBOL_LEN);
			if(cmp == 0) {
				mtx_unlock(&symbols_lock);
				return i;
			}
		}
	}
	mtx_unlock(&symbols_lock);
	printf("ERROR: ran out of symbols\n");
	abort();
}

typedef struct {
	int value;
	atomic_int refcount;
} object;

object *create_object(int value) {
	object *obj = malloc(sizeof(object));
	if(!obj) {
		printf("ERROR: ran out of malloc memory\n");
		abort();
	}
	obj->value = value;
	obj->refcount = 1;
	return obj;
}

void drop_object(object **objptr) {
	if(*objptr) {
		object *obj = *objptr;
		atomic_int count = atomic_fetch_sub_explicit(&obj->refcount, 1, memory_order_relaxed);
		if(count == 1) {
			printf("freeing %p\n", (void*)obj);
			free(obj);
		}
	}
	*objptr = NULL;
}

object *add_objects(object *objA, object *objB) {
	if(objA == NULL) {
		printf("ERROR: objA is null\n");
		abort();
	}
	if(objB == NULL) {
		printf("ERROR: objA is null\n");
		abort();
	}
	int new_value = objA->value + objB->value;
	return create_object(new_value);
}

object *dispatch_call(object *obj, int sym, object *arg1) {
	if(sym == find_symbol("Add")) {
		return add_objects(obj, arg1);
	}
	printf("ERROR: invalid call\n");
	abort();
}

int main(void) {
	mtx_init(&symbols_lock, mtx_plain);
	printf("Hello world!\n");
	printf("symb %i\n", find_symbol("a"));
	printf("symb %i\n", find_symbol("b"));
	object *numA = create_object(5);
	object *numB = create_object(3);
	object *numC = dispatch_call(numA, find_symbol("Add"), numB);
	printf("numC value is %i\n", numC->value);
	printf("numA is %p\n", (void*)numA);
	printf("numB is %p\n", (void*)numB);
	printf("numC is %p\n", (void*)numC);
	drop_object(&numA);
	drop_object(&numB);
	drop_object(&numC);
	printf("numA is %p\n", (void*)numA);
	printf("numB is %p\n", (void*)numB);
	printf("numC is %p\n", (void*)numC);
	return 0;
}