Newer
Older
Tardis / lang / error.c
// SPDX-License-Identifier: MIT
// Copyright (c) 2024 John Watts and the LuminaSensum contributors

#include "error.h"
#include <stdio.h>
#include <stdlib.h>

struct stacktrace {
	int size;
	int depth;
	const char *frames[];
};

__attribute__((noreturn)) void abort_print(const char *msg) {
	fprintf(stderr, "ERROR: %s\n", msg);
	abort();
}

StackTrace stacktrace_create(int frames) {
	size_t struct_size = sizeof(struct stacktrace);
	size_t frame_size = sizeof(const char *) * frames;
	size_t total_size = frame_size + struct_size;
	struct stacktrace *trace = malloc(total_size);
	if (trace == NULL)
		abort_print("stacktrace_create: unable to allocate trace");
	trace->size = frames;
	trace->depth = 0;
	return (StackTrace)trace;
}

void stacktrace_push(StackTrace trace, const char *name) {
	struct stacktrace *priv = (struct stacktrace *)trace;
	if (priv->depth == priv->size)
		abort_print("stacktrace_push: overflow");
	priv->frames[priv->depth++] = name;
}

void stacktrace_pop(StackTrace trace) {
	struct stacktrace *priv = (struct stacktrace *)trace;
	if (priv->depth == 0)
		abort_print("stacktrace_pop: underflow");
	--priv->depth;
}

void stacktrace_print(StackTrace trace) {
	struct stacktrace *priv = (struct stacktrace *)trace;
	fprintf(stderr, "TRACEBACK:\n");
	for (int i = 0; i < priv->depth; ++i) {
		const char *name = priv->frames[i];
		fprintf(stderr, "%i: %s\n", i, name);
	}
}