aboutsummaryrefslogtreecommitdiff
path: root/test/tsupport.c
blob: 9b3582c95ec1329c5e1305f890e90c3284e6f71d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// This software disclaims copyright. Do what you want with it. Be gay, do
// crime. Originally written by Alexis Lockwood in 2021. Ⓐ

// --- DEPENDENCIES ------------------------------------------------------------

// This module
#include "tsupport.h"

// Supporting modules

// Standard headers
#include <stdbool.h>
#include <stddef.h>
#include <inttypes.h>

// --- PRIVATE MACROS ----------------------------------------------------------
// --- PRIVATE DATATYPES -------------------------------------------------------
// --- PRIVATE CONSTANTS -------------------------------------------------------
// --- PRIVATE FUNCTION PROTOTYPES ---------------------------------------------

static void _setup_pool(ls_value_t * pool, size_t n);
static void _setup_label_cache(ls_label_cache_t * label_cache);
static int _fetcher(void * ctx, uint16_t loc);

// --- PUBLIC VARIABLES --------------------------------------------------------
// --- PRIVATE VARIABLES -------------------------------------------------------

static ls_value_t _pool[LS_TEST_NPOOL];

// --- PUBLIC FUNCTIONS --------------------------------------------------------

void ls_test_setup(ls_context_t * ctx, char const * text)
{
	_setup_pool(_pool, LS_TEST_NPOOL);
	ctx->callstack = NULL;
	ctx->funcs = NULL;
	ctx->pool = _pool;
	ctx->pc = 0;
	ctx->fetcher = _fetcher;
	ctx->fetcher_ctx = (void *) text;
	ctx->line_trace_hook = NULL;
	_setup_label_cache(ctx->label_cache);
	ctx->label_cache_i = 0;
}

void ls_setup_run(ls_context_t * ctx, char const * text)
{
	ctx->fetcher = _fetcher;
	ctx->fetcher_ctx = (void *) text;
	ctx->line_trace_hook = NULL;
}

// --- PRIVATE FUNCTION DEFINITIONS --------------------------------------------

static void _setup_pool(ls_value_t * pool, size_t n)
{
	pool[0].prev = NULL;
	pool[0].next = &pool[1];
	pool[n - 1].prev = &pool[n - 2];
	pool[n - 1].next = NULL;
	for (size_t i = 1; i < (n - 1); i++)
	{
		pool[i].prev = &pool[i - 1];
		pool[i].next = &pool[i + 1];
	}
}

static void _setup_label_cache(ls_label_cache_t * label_cache)
{
	for (size_t i = 0; i < LS_LABEL_CACHE_SIZE; i++)
	{
		label_cache[i].pc = LS_ADDR_NULL;
		label_cache[i].num = 0;
	}
}

static int _fetcher(void * ctx, uint16_t loc)
{
	char const * text = (char const *) ctx;

	// Slightly naughty memoization of pointer bc i can't be arsed to
	// make the API cleaner right now. We just need to implement read-past-
	// end.
	static char const * p_memo = NULL;
	static size_t sz_memo = 0;

	size_t size;
	if (p_memo == text)
		size = sz_memo;
	else
		size = sz_memo = strlen(text);

	if (loc >= size)
		return 0;
	else
		return (unsigned char) text[loc];
}