summaryrefslogtreecommitdiff
path: root/src/lib/aplwc_internal.h
blob: d97cbf7c7c722337f8363056172894aa9fe00d6f (plain) (blame)
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* 
 * Copyright (C) 2026 Peter Mikkelsen <petermikkelsen10@gmail.com>
 *
 * This file is part of aplwc.
 *
 * Aplwc is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Aplwc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with aplwc.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef APLWC_INTERNAL_H
#define APLWC_INTERNAL_H

#include <aplwc.h>
#include <aplwc_macros.h>
#include <assert.h>
#include <stdalign.h>
#include <stdbool.h>
#include <string.h>

struct aplwc {
	struct aplwc_fns fns;
	enum aplwc_rc last_error;
	struct aplwc_module *modules;

	/* Memory management */
	uint8_t *data;
	uint8_t *unaligned_data;
	size_t size;
	struct memory_ptr_frame *memptrs;
	struct aplwc_ref *refs;
	unsigned int reachable_bit:1;
};

struct memory_ptr_frame {
	struct memory_ptr_frame *link;
	void ***ptrs;
	size_t count;
};

struct aplwc_line {
	struct string *text;
	struct token_list *tokens;
};

struct string {
	size_t bytes;
	size_t chars;
	uint8_t utf8[1];
};

enum token_tag {
	TOKEN_TAG_IDENTIFIER,
	TOKEN_TAG_NEWLINE,
	TOKEN_TAG_NUMBER,
	TOKEN_TAG_LEFT_ARROW,
	TOKEN_TAG_DIAMOND,
	TOKEN_TAG_KEYWORD,
	TOKEN_TAG_TEXT,
	TOKEN_TAG_DEL,
	TOKEN_TAG_LEFT_PAREN,
	TOKEN_TAG_RIGHT_PAREN,
	TOKEN_TAG_IBEAM,
	TOKEN_TAG_QUAD,
	TOKEN_TAG_UNKNOWN_SYM,
	TOKEN_TAG_COMMENT
};

struct token {
	enum token_tag tag;
	size_t start;
	size_t end;
};

struct token_list {
	struct string *text;
	size_t length;
	struct token tokens[1];
};

enum value_tag {
	VALUE_NULL,
	VALUE_NUMBER
};

struct aplwc_value {
	enum value_tag tag;
};

struct aplwc_module {
	struct string *name;
	struct token_list *tokens;
	struct aplwc_module *link;
};

/* eval.c */
struct aplwc_value *eval_line(struct aplwc *, struct aplwc_line *);

/* memory.c */
void memory_init(struct aplwc *);
void memory_destroy(struct aplwc *);
struct aplwc_line *memory_alloc_aplwc_line(struct aplwc *);
struct string *memory_alloc_string(struct aplwc *, size_t);
struct token_list *memory_alloc_token_list(struct aplwc *, size_t);
struct aplwc_value *memory_alloc_aplwc_value(struct aplwc *);
struct aplwc_module *memory_alloc_aplwc_module(struct aplwc *);
struct module_imports *memory_alloc_module_imports(struct aplwc *, size_t);
void memory_root_new(struct aplwc *, void *, struct aplwc_ref *);
void *memory_root_get(struct aplwc_ref *);
void memory_root_free(struct aplwc_ref *);
void memptrs_add(struct aplwc *, struct memory_ptr_frame *, void ***, size_t);
void memptrs_remove(struct aplwc *, struct memory_ptr_frame *);
void clear_ref(struct aplwc_ref *);
int valid_ref(struct aplwc_ref *);

#define MEMPTRS(aplwc, n) \
	void **memptrs[n]; \
	struct memory_ptr_frame memptrs_frame; \
	memptrs_add(aplwc, &memptrs_frame, memptrs, n);
#define MEMPTR(n, ptr) memptrs[n] = (void **)&ptr
#define MEMPTRS_EXIT(aplwc) memptrs_remove(aplwc, &memptrs_frame)

/* string.c */
struct string *chars_to_string(struct aplwc *, const char *, int len);
uint32_t string_char(struct string *, size_t);
size_t char_length(struct string *, size_t);
int string_compare(struct string *, struct string *);

/* syntax.c */
struct token_list *scan_string(struct aplwc *, struct string *, int);
enum aplwc_rc check_tokens(struct token_list *);

/* module.c */
enum aplwc_rc load_module(struct aplwc *, struct string *, struct token_list *);

#endif /* APLWC_INTERNAL_H */